[REF] service: A new openerp.service.rpc decorator is provided to replace the ExportS...
authorVo Minh Thu <vmt@openerp.com>
Thu, 31 Jan 2013 13:10:51 +0000 (14:10 +0100)
committerVo Minh Thu <vmt@openerp.com>
Thu, 31 Jan 2013 13:10:51 +0000 (14:10 +0100)
bzr revid: vmt@openerp.com-20130131131051-5189susswxlshp29

doc/index.rst
doc/routing.rst [new file with mode: 0644]
openerp/netsvc.py
openerp/service/__init__.py
openerp/service/wsgi_server.py
openerp/tests/common.py
openerp/tests/test_xmlrpc.py

index 33474e2..daa212d 100644 (file)
@@ -35,6 +35,7 @@ OpenERP Server API
    :maxdepth: 1
 
    api_models.rst
+   routing.rst
 
 Concepts
 ''''''''
diff --git a/doc/routing.rst b/doc/routing.rst
new file mode 100644 (file)
index 0000000..1e4f76d
--- /dev/null
@@ -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.
+
index 14ee0d6..6b70dc9 100644 (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()
index 9db7322..db5d454 100644 (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:
index f55f9de..8d9d7b4 100644 (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()
index 3f0143e..f8472e8 100644 (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)
index 1198c0f..8c9d691 100644 (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.