[REF] service: A new openerp.service.rpc decorator is provided to replace the ExportService class.

bzr revid: vmt@openerp.com-20130131131051-5189susswxlshp29
This commit is contained in:
Vo Minh Thu 2013-01-31 14:10:51 +01:00
parent 7b789f0865
commit b303bfe5a4
7 changed files with 64 additions and 10 deletions

View File

@ -35,6 +35,7 @@ OpenERP Server API
:maxdepth: 1
api_models.rst
routing.rst
Concepts
''''''''

18
doc/routing.rst Normal file
View File

@ -0,0 +1,18 @@
.. _routing:
Routing
=======
The OpenERP framework, as an HTTP server, serves a few hard-coded URLs
(``models``, ``db``, ...) to expose RPC endpoints. When running the web addons
(which is almost always the case), it also serves URLs without them being RPC
endpoints.
In older version of OpenERP, adding RPC endpoints was done by subclassing the
``openerp.netsvc.ExportService`` class. Adding WSGI handlers was done by
registering them with the ``openerp.wsgi.register_wsgi_handler()`` function.
Starting with OpenERP 7.1, exposing a new arbitrary WSGI handler is done with
the ``openerp.service.handler`` decorator while adding an RPC endpoint is done
with the ``openerp.service.rpc`` decorator.

View File

@ -29,7 +29,6 @@ import logging.handlers
import os
import platform
import release
import socket
import sys
import threading
import time
@ -242,16 +241,17 @@ def dispatch_rpc(service_name, method, params):
threading.current_thread().uid = None
threading.current_thread().dbname = None
service = None
if service_name == 'object':
service = openerp.service.model
if service_name == 'db':
service = openerp.service.db
if service_name == 'common':
service = openerp.service.common
if service_name == 'report':
service = openerp.service.report
result = service.dispatch(method, params)
dispatch = openerp.service.common.dispatch
elif service_name == 'db':
dispatch = openerp.service.db.dispatch
elif service_name == 'object':
dispatch = openerp.service.model.dispatch
elif service_name == 'report':
dispatch = openerp.service.report.dispatch
else:
dispatch = openerp.service.wsgi_server.rpc_handlers.get(service_name)
result = dispatch(method, params)
if rpc_request_flag or rpc_response_flag:
end_time = time.time()

View File

@ -150,4 +150,22 @@ def restart_server():
openerp.phoenix = True
os.kill(os.getpid(), signal.SIGINT)
def handler():
"""TODO"""
def decorator(f):
wsgi_server.register_wsgi_handler(f)
return decorator
def route(url):
"""TODO"""
def decorator(f):
pass # TODO Same as handler() but register the handler under a specific url.
return decorator
def rpc(endpoint):
"""TODO"""
def decorator(f):
wsgi_server.register_rpc_endpoint(endpoint, f)
return decorator
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -34,6 +34,7 @@ import errno
import logging
import os
import signal
import socket
import sys
import threading
import traceback
@ -373,6 +374,8 @@ def parse_http_response(s):
# WSGI handlers registered through the register_wsgi_handler() function below.
module_handlers = []
# RPC endpoints registered through the register_rpc_endpoint() function below.
rpc_handlers = {}
def register_wsgi_handler(handler):
""" Register a WSGI handler.
@ -382,6 +385,11 @@ def register_wsgi_handler(handler):
"""
module_handlers.append(handler)
def register_rpc_endpoint(endpoint, handler):
""" Register a handler for a given RPC enpoint.
"""
rpc_handlers[endpoint] = handler
def application_unproxied(environ, start_response):
""" WSGI entry point."""
openerp.service.start_internal()

View File

@ -133,6 +133,7 @@ class RpcCase(unittest2.TestCase):
self.proxy.common_60 = xmlrpclib.ServerProxy(url_60 + 'common')
self.proxy.db_60 = xmlrpclib.ServerProxy(url_60 + 'db')
self.proxy.object_60 = xmlrpclib.ServerProxy(url_60 + 'object')
#self.proxy.edi_60 = xmlrpclib.ServerProxy(url_60 + 'edi')
# Use the new (6.1) API.
self.proxy.url_61 = url_61 = 'http://%s:%d/openerp/xmlrpc/1/' % (HOST, PORT)

View File

@ -64,6 +64,14 @@ class test_xmlrpc(common.RpcCase):
ids = proxy.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'search', [], {})
assert ids
# This test was written to test the creation of a new RPC endpoint, not
# really for the EDI itself.
#def test_xmlrpc_import_edi_document(self):
# """ Try to call an EDI method. """
# msg_re = 'EDI Document is empty!'
# with self.assertRaisesRegexp(Exception, msg_re):
# self.proxy.edi_60.import_edi_document(DB, ADMIN_USER_ID, ADMIN_PASSWORD, {})
def test_zz_xmlrpc_drop_database(self):
"""
Simulate a OpenERP client requesting the deletion of a database.