commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gnue/common doc/RPC-abstraction.txt doc/RPC-sta...


From: Jan Ischebeck
Subject: gnue/common doc/RPC-abstraction.txt doc/RPC-sta...
Date: Tue, 30 Apr 2002 19:52:31 -0400

CVSROOT:        /cvsroot/gnue
Module name:    gnue
Changes by:     Jan Ischebeck <address@hidden>  02/04/30 19:52:31

Modified files:
        common/doc     : RPC-abstraction.txt RPC-status.txt 
        common/src     : GServerApp.py 
        common/src/commdrivers: GCommBase.py 
        common/src/commdrivers/_parser: Parser.py 
        common/src/commdrivers/_test: client.php server.py 
        common/src/commdrivers/xmlrpc: ClientAdapter.py ServerAdapter.py 
Added files:
        common/src/commdrivers/_directory: DirectoryServer.py 
                                           __init__.py 
        common/src/commdrivers/pw_xmlrpc: ClientAdapter.py 
                                          DebugSocketServer.py RpcDoc.py 
                                          ServerAdapter.py __init__.py 

Log message:
        Big RPC update: 1. add new gpl'd xmlrpc library
        2. added Status file
        3. add threading support for multiple server
        4. updated examples

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/doc/RPC-abstraction.txt.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/doc/RPC-status.txt.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/GServerApp.py.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/GCommBase.py.diff?tr1=1.14&tr2=1.15&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/_directory/DirectoryServer.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/_directory/__init__.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/_parser/Parser.py.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/_test/client.php.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/_test/server.py.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/pw_xmlrpc/ClientAdapter.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/pw_xmlrpc/DebugSocketServer.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/pw_xmlrpc/RpcDoc.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/pw_xmlrpc/ServerAdapter.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/pw_xmlrpc/__init__.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/xmlrpc/ClientAdapter.py.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnue/gnue/common/src/commdrivers/xmlrpc/ServerAdapter.py.diff?tr1=1.8&tr2=1.9&r1=text&r2=text

Patches:
Index: gnue/common/doc/RPC-abstraction.txt
diff -c gnue/common/doc/RPC-abstraction.txt:1.5 
gnue/common/doc/RPC-abstraction.txt:1.6
*** gnue/common/doc/RPC-abstraction.txt:1.5     Mon Dec 17 00:20:16 2001
--- gnue/common/doc/RPC-abstraction.txt Tue Apr 30 19:52:30 2002
***************
*** 64,69 ****
--- 64,90 ----
  but it's true.)
  
  
+ How to call methods of dynamic objects with non-object RPC?
+ ===========================================================
+ 
+ If you want to call a method of a dynamic object, you need a
+ handle for this dynamic object. Now there are two ways to
+ transfer the handle from the client to the server:
+ 
+ a) the first parameters to any "Object" methods is a 
+    "passed reference" (i.e. the object handle)
+    f.e.:  Bakery.BakingUnit.setFlavor("34345634635","glaced")
+    this is similar to the method definitions in
+    python
+ 
+ b) put the object handler in front of the method name.
+    f.e.: [23523sdfser3234345].setFlavor("glazed")
+ 
+ Because the implementation of one of these two methods is
+ protocoll specific. Both ways can happyly coexit in different
+ protokoll plugins.
+ 
+ 
  
  Design Considerations
  =====================
Index: gnue/common/doc/RPC-status.txt
diff -c gnue/common/doc/RPC-status.txt:1.1 gnue/common/doc/RPC-status.txt:1.2
*** gnue/common/doc/RPC-status.txt:1.1  Tue Apr 30 14:12:25 2002
--- gnue/common/doc/RPC-status.txt      Tue Apr 30 19:52:30 2002
***************
*** 8,19 ****
  
  Corba:                     not implemented yet
  
! PYRO:                not implemented yet
  
! XML-RPC:             server: alpha (but working ok)  xmlrpclib.py from
! (Pythonware)       client: alpha (but working ok)  www.pythonware.com 
  
! XMLRPC:              server: pre alpha (not working)  py-xmlrpc.sf.net or
!  (py-xmlrpc)       client: alpha (but working ok)  apt-get install 
python-xmlrpc
  
  
--- 8,24 ----
  
  Corba:                     not implemented yet
  
! Pyro:                not implemented yet
  
! SOAP:              not implemented yet
  
! XMLRPC*:             server: alpha (working ok)  xmlrpclib.py from
! (Pythonware)       client: alpha (working ok)  www.pythonware.com 
  
+ XMLRPC**:            server: alpha (working ok)  py-xmlrpc.sf.net or
+  (py-xmlrpc)       client: alpha (working ok)  apt-get install python-xmlrpc
  
+ 
+ 
+ * XMLRPC (Pythonware) can be accessed by: "pw_xmlrpc"
+ * XMLRPC (py-xmlrpc) is gpl'd and made the standart for "xmlrpc"
Index: gnue/common/src/GServerApp.py
diff -c gnue/common/src/GServerApp.py:1.3 gnue/common/src/GServerApp.py:1.4
*** gnue/common/src/GServerApp.py:1.3   Wed Oct 24 14:39:58 2001
--- gnue/common/src/GServerApp.py       Tue Apr 30 19:52:30 2002
***************
*** 34,40 ****
  from GLogger import Logger
  import sys, os
  
! # TODO: Implement RPC abstraction layer
  # TODO: Implement either multi-threading or asynchronous IO support
  
  class GServerApp(GBaseApp):
--- 34,40 ----
  from GLogger import Logger
  import sys, os
  
! 
  # TODO: Implement either multi-threading or asynchronous IO support
  
  class GServerApp(GBaseApp):
Index: gnue/common/src/commdrivers/GCommBase.py
diff -c gnue/common/src/commdrivers/GCommBase.py:1.14 
gnue/common/src/commdrivers/GCommBase.py:1.15
*** gnue/common/src/commdrivers/GCommBase.py:1.14       Tue Jan  1 13:31:35 2002
--- gnue/common/src/commdrivers/GCommBase.py    Tue Apr 30 19:52:30 2002
***************
*** 30,36 ****
  
  from gnue.common import GComm
  from gnue.common import GDebug
! import string, sys
  
  
  
--- 30,36 ----
  
  from gnue.common import GComm
  from gnue.common import GDebug
! import string, sys, thread
  
  
  
***************
*** 48,53 ****
--- 48,56 ----
    def runMethod(self, method, path, *args, **params):
      pass
  
+   def setLocalArgumentChecking(self,enable):
+     pass
+ 
    # Try to shut our services down
    def __del__(self):
      try:
***************
*** 65,78 ****
    def __init__(self, rpcdef, bindings, params):
      self._bindings = bindings
      self._rpcdef = rpcdef
  
    def serve(self):
      pass
! 
    def runService(self, method, data):
      pass
  
!   def raiseException(self, exception, message):
      raise exception, message
  
  
--- 68,114 ----
    def __init__(self, rpcdef, bindings, params):
      self._bindings = bindings
      self._rpcdef = rpcdef
+     
+     parseParameter(self, params)
  
+   def allowObjectIntrospection(self,allow):
+      # allow the remote client to get the type of an object by its handle
+      # an to get other introspection details by that
+      pass
+    
    def serve(self):
      pass
!   
!   def serveAsNewThread(self):
!     thread.start_new_thread(self.serve,())
! 
!   ## ObjectMethodChecking means, to check if the method of an object is
!   ## included in the grpc
!   ## in the service directory
!   def setObjectMethodChecking(self,checking_on):
!     self._objectMethodChecking=checking_on
!     pass 
!     
    def runService(self, method, data):
      pass
  
!   def serveAsNewThread(self):
!     thread.start_new_thread(self.serve,())
! 
!     
!   def parseParameter(self, params):
!     server.__init__(self)
!     try:
!       self._port = params['port']
!     except KeyError:
!       raise GComm.AdapterConfigurationError,\
!             'Required parameter "port" not supplied'
! 
!     
!   #
!   # Return an exception
!   #
!   def raiseException(self, exception, message, event=None):
      raise exception, message
  
  
***************
*** 96,102 ****
  
      self._attrPath.append(attr)
  
!     #print "Creating ProxyObject %s" % string.join(self._attrPath,'.')
  
      try:
        self._subobject = params['subobject']
--- 132,138 ----
  
      self._attrPath.append(attr)
  
!     # print "Creating ProxyObject %s" % string.join(self._attrPath,'.')
  
      try:
        self._subobject = params['subobject']
Index: gnue/common/src/commdrivers/_parser/Parser.py
diff -c gnue/common/src/commdrivers/_parser/Parser.py:1.5 
gnue/common/src/commdrivers/_parser/Parser.py:1.6
*** gnue/common/src/commdrivers/_parser/Parser.py:1.5   Wed Feb 27 15:45:52 2002
--- gnue/common/src/commdrivers/_parser/Parser.py       Tue Apr 30 19:52:30 2002
***************
*** 87,92 ****
--- 87,94 ----
                 'Typecast': GTypecast.name,
                 'Required': 1 },
              'binding': {
+                'Typecast': GTypecast.name }, 
+             'helptext': {
                 'Typecast': GTypecast.name } },
           'ParentTags': ('gnurpc','service') },
  
***************
*** 99,105 ****
                 'Typecast': GTypecast.name,
                 'Required': 1 },
              'return': {
!                'Typecast': GTypecast.name }  },
           'ParentTags': ('gnurpc','service') },
  
        'object': {
--- 101,109 ----
                 'Typecast': GTypecast.name,
                 'Required': 1 },
              'return': {
!                'Typecast': GTypecast.name },
!             'helptext': {
!                'Typecast': GTypecast.name } },
           'ParentTags': ('gnurpc','service') },
  
        'object': {
***************
*** 108,114 ****
           'Attributes': {
              'name': {
                 'Typecast': GTypecast.name,
!                'Required': 1 } },
           'ParentTags': ('gnurpc','service') },
  
        'argument': {
--- 112,120 ----
           'Attributes': {
              'name': {
                 'Typecast': GTypecast.name,
!                'Required': 1 },
!             'helptext': {
!                'Typecast': GTypecast.name }}, 
           'ParentTags': ('gnurpc','service') },
  
        'argument': {
***************
*** 121,127 ****
                 'Typecast': GTypecast.name,
                 'Required': 1 },
              'default': {
!                'Typecast': GTypecast.text }  },
           'ParentTags': ('method',) },
  
        'attribute': {
--- 127,135 ----
                 'Typecast': GTypecast.name,
                 'Required': 1 },
              'default': {
!                'Typecast': GTypecast.text },
!             'helptext': {
!                'Typecast': GTypecast.name } },
           'ParentTags': ('method',) },
  
        'attribute': {
***************
*** 138,144 ****
                 'Default': 0 },
              'writeonly': {
                 'Typecast': GTypecast.boolean,
!                'Default': 0 } },
           'ParentTags': ('object',) },
  
        'exception': {
--- 146,154 ----
                 'Default': 0 },
              'writeonly': {
                 'Typecast': GTypecast.boolean,
!                'Default': 0 },
!             'helptext': {
!                'Typecast': GTypecast.name }  },
           'ParentTags': ('object',) },
  
        'exception': {
***************
*** 146,152 ****
           'Attributes': {
              'name': {
                 'Typecast': GTypecast.name,
!                'Required': 1 } },
           'ParentTags': ('gnurpc','service') },
  
        'raises': {
--- 156,164 ----
           'Attributes': {
              'name': {
                 'Typecast': GTypecast.name,
!                'Required': 1 },
!             'helptext': {
!                'Typecast': GTypecast.name }  },
           'ParentTags': ('gnurpc','service') },
  
        'raises': {
Index: gnue/common/src/commdrivers/_test/client.php
diff -c gnue/common/src/commdrivers/_test/client.php:1.1 
gnue/common/src/commdrivers/_test/client.php:1.2
*** gnue/common/src/commdrivers/_test/client.php:1.1    Wed Feb 27 15:45:11 2002
--- gnue/common/src/commdrivers/_test/client.php        Tue Apr 30 19:52:30 2002
***************
*** 3,8 ****
--- 3,12 ----
  <body>
  <H1>XML-RPC Backery testing for GNUE</H1>
  <?php
+ /*
+ XMLRPC can be downloaded at: http://phpxmlrpc.sourceforge.net/
+ But will replaced with a version under the GPL a (ez-xmlrpc) soon
+ */
  include("xmlrpc.inc");
  $c=new xmlrpc_client("/", "localhost", 8765);
  $c->setDebug(0);  # set to 1 for debbugging output
Index: gnue/common/src/commdrivers/_test/server.py
diff -c gnue/common/src/commdrivers/_test/server.py:1.8 
gnue/common/src/commdrivers/_test/server.py:1.9
*** gnue/common/src/commdrivers/_test/server.py:1.8     Sun Apr 21 21:02:00 2002
--- gnue/common/src/commdrivers/_test/server.py Tue Apr 30 19:52:30 2002
***************
*** 76,88 ****
  
    def run(self):
  
      # Create the various servers
      servers=bind(self.requestDonutPlace)
  
!     # Daemonize (if appropriate)
!     GServerApp.run(self)
  
!     servers["xmlrpc"].serve()
      
  
    def requestDonutPlace(self):
--- 76,93 ----
  
    def run(self):
  
+     # Daemonize (if appropriate)
+     GServerApp.run(self)
+ 
      # Create the various servers
      servers=bind(self.requestDonutPlace)
  
!     # Start server for the different protocolls
!     for key in servers.keys():
!       servers[key].serveAsNewThread()
  
!     # wait for the servers shut down
!     wait()
      
  
    def requestDonutPlace(self):
Index: gnue/common/src/commdrivers/xmlrpc/ClientAdapter.py
diff -c gnue/common/src/commdrivers/xmlrpc/ClientAdapter.py:1.3 
gnue/common/src/commdrivers/xmlrpc/ClientAdapter.py:1.4
*** gnue/common/src/commdrivers/xmlrpc/ClientAdapter.py:1.3     Sun Apr 21 
21:02:00 2002
--- gnue/common/src/commdrivers/xmlrpc/ClientAdapter.py Tue Apr 30 19:52:31 2002
***************
*** 55,69 ****
  
    # xmlrpclib could be in a package, so try both
    try:
!     import xmlrpclib
    except ImportError:
!     from xmlrpclib import xmlrpclib
  
  except ImportError:
    raise GComm.AdapterInitializationError, \
!         "\nUnable to load xmlrpclib.  To use the XML-RPC interface, \n" \
        + "please install xmlrpc from:\n" \
!       + "    http://www.pythonware.com/products/xmlrpc/";
  
  
  ##############################################################################
--- 55,70 ----
  
    # xmlrpclib could be in a package, so try both
    try:
!     import xmlrpc
    except ImportError:
!     from xmlrpc import xmlrpc
  
  except ImportError:
    raise GComm.AdapterInitializationError, \
!         "\nUnable to load xmlrpc.  To use the XML-RPC interface, \n" \
        + "please install xmlrpc from:\n" \
!       + "    http://py-xmlrpc.sourceforge.net/"; \
!       + "the appropriate DEBIAN package is python-xmlrpc.deb"
  
  
  ##############################################################################
***************
*** 74,96 ****
  
    def __init__(self, params):
  
! 
      try:
  
        try:
          url = params['url']
          if not len(url):
            raise KeyError
        except KeyError:
          try:
            transport = params['transport']
          except KeyError:
!           transport = 'https'
  
          url = "%s://%s:%s/" % \
!             ( transport, params['host'], params['port'] )
! 
!       self._server = xmlrpclib.Server(url)
  
  
      except KeyError:
--- 75,112 ----
  
    def __init__(self, params):
  
!     self._timeout = 1.0
!     
      try:
  
        try:
          url = params['url']
          if not len(url):
            raise KeyError
+         ## todo: split url into server + host + path parts
        except KeyError:
          try:
            transport = params['transport']
          except KeyError:
!           transport = 'http'
!           
!         try:
!           path = params['path']
!         except KeyError:
!           path = '/'
  
          url = "%s://%s:%s/" % \
!           ( transport, params['host'], params['port'] )
!         
!       # setLoglevel
!       if hasattr(params,'loglevel'):
!         xmlrpc.setLogLevel(params['loglevel'])
!       else:
!          xmlrpc.setLogLevel(1)
! 
!       self._client = xmlrpc.client(params['host'],
!                                    params['port'],path)
!       
  
  
      except KeyError:
***************
*** 103,124 ****
  
  
    def request(self, service, params={}):
!     proxy = _ProxyObject(self, service, 
servicer=self._server.__getattr__(service))
      return proxy
  
  
    def close(self):
      # do a cleanup of the proxy objects and the object stubs
      # on the XMLRPC server side
!     pass 
  
  
    def runMethod(self, method, *args, **params):
      # print "Calling method: %s with attr %s " % method,string.join(args,",")
  
-     to_call=getattr(self._server,method);
-         
-     result=to_call.__call__(*args, **params)
      # print "the result is",result,"of type",type(result)
      
      # check, if an object handle is send    
--- 119,150 ----
  
  
    def request(self, service, params={}):
!     proxy = _ProxyObject(self, service)
      return proxy
  
  
    def close(self):
      # do a cleanup of the proxy objects and the object stubs
      # on the XMLRPC server side
!     pass
! 
!   def setTimeout(self,timeout):
!     self._timeout=timeout
!     
!   def setAuthentification(self,name,passw):
!     self._auth_name=name
!     self._auth_passw=passw
  
  
    def runMethod(self, method, *args, **params):
      # print "Calling method: %s with attr %s " % method,string.join(args,",")
+     # send authentification info?
+     if hasattr(self,'_auth_name'):
+       result = self._client.execute(method, args, self._timeout, \
+                                     self._auth_name, self._auth_passw)
+     else:
+       result = self._client.execute(method, args,self._timeout)
  
      # print "the result is",result,"of type",type(result)
      
      # check, if an object handle is send    
Index: gnue/common/src/commdrivers/xmlrpc/ServerAdapter.py
diff -c gnue/common/src/commdrivers/xmlrpc/ServerAdapter.py:1.8 
gnue/common/src/commdrivers/xmlrpc/ServerAdapter.py:1.9
*** gnue/common/src/commdrivers/xmlrpc/ServerAdapter.py:1.8     Wed Feb 27 
15:45:53 2002
--- gnue/common/src/commdrivers/xmlrpc/ServerAdapter.py Tue Apr 30 19:52:31 2002
***************
*** 25,32 ****
  # Set of classes that implement the XML-RPC server driver for GNUe Comm.
  #
  # NOTES:
! # Requires xmlrpclib from http://www.pythonware.com/products/xmlrpc/
! # or Python 2.2+
  #
  # Server Parameters:
  #
--- 25,32 ----
  # Set of classes that implement the XML-RPC server driver for GNUe Comm.
  #
  # NOTES:
! # Requires py-xmlrpc from http://sf.net/projects/python-xmlrpc
! # 
  #
  # Server Parameters:
  #
***************
*** 44,72 ****
  
  #from gnue.common.commdrivers._helpers.AsyncSocketServer import 
AsyncHTTPServer
  
! from DebugSocketServer import HTTPServer,MyHTTPServer
! import BaseHTTPServer
! import SocketServer
  from gnue.common import GComm, GDebug
  from gnue.common.commdrivers._helpers import ObjectLibrarian
  from gnue.common.commdrivers import GCommBase
  
! import string, sys
  
  try:
! 
!   # xmlrpclib could be in a package, so try both
!   try:
!     import xmlrpclib
!   except ImportError:
!     from xmlrpclib import xmlrpclib
  
  except ImportError:
    raise GComm.AdapterInitializationError, \
!         "\nUnable to load xmlrpclib.  To use the XML-RPC interface, \n" \
        + "please install xmlrpc from:\n" \
!       + "    http://www.pythonware.com/products/xmlrpc/";
! 
  
  
  # Mapping from GRPC's datatype to XML-RPC datatypes
--- 44,66 ----
  
  #from gnue.common.commdrivers._helpers.AsyncSocketServer import 
AsyncHTTPServer
  
! 
  from gnue.common import GComm, GDebug
  from gnue.common.commdrivers._helpers import ObjectLibrarian
+ from gnue.common.commdrivers._directory import DirectoryServer
  from gnue.common.commdrivers import GCommBase
  
! import string, sys, thread, traceback
  
  try:
!   import xmlrpc
  
  except ImportError:
    raise GComm.AdapterInitializationError, \
!         "\nUnable to load xmlrpc.  To use the XML-RPC interface, \n" \
        + "please install xmlrpc from:\n" \
!       + "    http://py-xmlrpc.sourceforge.net/"; \
!       + "the appropriate DEBIAN package is python-xmlrpc"
  
  
  # Mapping from GRPC's datatype to XML-RPC datatypes
***************
*** 85,397 ****
  #
  # ServerAdapter
  #
! class ServerAdapter(HTTPServer):
  
    def __init__(self, rpcdef, bindings, params):
-     HTTPServer.__init__(self, params)
- 
- 
-     # Keep a directory of all methods we expose and
-     # various attributes of those methods (such as
-     # "signatures" [as defined by the XML-RPC docs]
-     # and help/description information.
-     self.directory = {
-        'system.listMethods':
-            { 'signature': ('string',),
-              'binding':   self.system__listMethods,
-              'help':      'Returns an array of all supported methods' },
-        'system.methodSignature':
-            { 'signature': ('string',),
-              'binding':   self.system__methodSignature,
-              'help':      'Returns an array containing the method signature' 
},
-        'system.methodHelp':
-            { 'signature': ('string','string'),
-              'binding':   self.system__methodHelp,
-              'help':      'Returns an string with documentation for ' \
-                         + 'the specified function' }
-        }
- 
-     # Add all the grpc defined methods
-     # to our internal "service directory"
-     self._xmlrpc_mapObjects(rpcdef,bindings)
- 
-     GDebug.printMesg(3,'XML-RPC Service Directory:\n * %s' % \
-             string.join(self.directory.keys(),'\n * '))
-     GDebug.printMesg(5,'XML-RPC Service Directory:\n%s' % \
-             self.directory.keys())
- 
- 
-   #
-   # Create an internal "service directory"
-   #
-   def _xmlrpc_mapObjects(self, object, bindings, parent=None):
- 
-     # For servicable objects, maintain a complete "path" for reference
-     if object._type in ('RpService','RpMethod','RpObject'):
-       if parent and hasattr(parent,'_xmlrpc__path'):
-         object._xmlrpc__path = "%s.%s" % (parent._xmlrpc__path, object.name)
-       else:
-         object._xmlrpc__path = object.name
- 
- 
-     ##    
-     ## Add binding informations to the objects
-     ##
-     ## services are static objects and
-     ## objects  are dynamic ones
-     ##
-     if hasattr(object,'binding'):      
- 
-       # the direct mapping
-       if bindings.has_key(object.binding):
-         GDebug.printMesg(3,'XML-RPC Binding Information:');
-         GDebug.printMesg(3,' * %s is bound to \n * %s' % \
-                          (object.binding,bindings[object.binding]))
- 
-         # for services create an "static" object
-         if object._type == 'RpService':
-           object._realbinding=bindings[object.binding]()
- 
-         else:
-           
-           # in all other cases just save the binding information
-           object._realbinding=bindings[object.binding]          
-         
-         
-       else:
-         print "Missing Binding information. Please add binding ",\
-               "information for ", \
-               object.binding      
-         
-     # care for bindings in all Services
-     if object._type == 'RpService':
-       if hasattr(object,'_realbinding'):
-         pass  # nothing to do
-       else:
-         if parent._type == 'RpService':
-           try:
-             object._realbinding=getattr(parent._realbinding,\
-                                          object.name)
-           except:
-             raise AttributeError, \
-                   "XML-RPC can't bind service '%s' to service '%s'" %\
-                   (object.name,parent.name)
-         elif parent._type == 'RpGnuRpc':
-           pass
-         else:
-           raise AttributeError, \
-                 "XML-RPC: cannot bind service '%s' to %s" %\
-                 (object.name,parent._type) 
-           
- 
-     # Add all methods to our directory
-     if object._type == 'RpMethod':
- 
-       # Build the signature list...
-       signature = []
- 
-       # The first element is the return type (can be None)
-       if hasattr(object,'type') and len(object.type):
-         signature.append(_datatypeMap[object.type])
-       else:
-         signature.append(None)
- 
-       # To make "Object" definitions with w/non-object RPC,
-       # the first parameters to any "Object" methods are
-       # a "passed reference"
-       if parent._type == 'RpObject':
-         signature.append(_datatypeMap['string'])
- 
-       # Then add the argument datatypes...
-       for arg in object._arguments:
-         signature.append(_datatypeMap[arg.type])
- 
- 
-       # check for the binding
-       if hasattr(object,'_realbinding'):
-         bindto=object._realbinding
-       else:
-         if parent._type == 'RpService':
-           try:
-             bindto=getattr(parent._realbinding,object.name)
-           except:
-             raise AttributeError, \
-                       "XML-RPC can't bind method '%s' to service '%s'" %\
-                       (object.name,parent.name)
-             pass
-         else:
-           bindto=None
-         
-       # Add the directory entry
-       self.directory[object._xmlrpc__path] = \
-         { 'signature': tuple(signature),
-           'help': '',         # TODO
-           'binding': bindto  }
  
  
!     #
!     # Add all attribute methods to our directory..
!     # XML-RPC doesn't support "Attributes", so an
!     # attribute is exposed as a pair of get_<name>
!     # and set_<name> methods.
!     #
!     if object._type == 'RpAttribute':
  
-       # To simulate "Object" definitions with w/this
-       # non-object RPC, the first parameters to any
-       # "Object" methods are a "passed reference"
-       if parent._type == 'RpObject':
-         getsig = (_datatypeMap[object.type], _datatypeMap['string'])
-         setsig = (None, _datatypeMap['string'], _datatypeMap[object.type])
-       else:
-         getsig = (_datatypeMap[object.type],)
-         setsig = (None, _datatypeMap[object.type])
- 
-       if not object.readonly:
-         # Add the get_* directory entry
-         self.directory['%s.get_%s' % (parent._xmlrpc__path, object.name)] = \
-           { 'signature': getsig,
-             'help': '',         # TODO
-             'binding': None   } # TODO
- 
-       if not object.writeonly:
-         # Add the set_* directory entry
-         self.directory['%s.set_%s' % (parent._xmlrpc__path, object.name)] = \
-           { 'signature': setsig,
-             'help': '',         # TODO
-             'binding': None   } # TODO
- 
- 
-     # Now, map our children
-     for child in object._children:
-       self._xmlrpc_mapObjects(child, bindings, object)
- 
-     # Sigh... what kind of drugs was I on to volunteer for RPC abstraction?
-   def getObject(self,name):
-     return obj
- 
-   def getMethodDirEntry(self,method):
-     GDebug.printMesg(6,'XML-RPC Directory entry:\n (%s,%s,%s)' % \
-                      (self.directory[method]['signature'],\
-                       self.directory[method]['help'],\
-                       self.directory[method]['binding']))
      
!     return self.directory[method]
  
    #
    # Return an exception
    #
    def raiseException(self, exception, message, event=None):
!     xmlrpclib.dumps(xmlrpclib.Fault(34543, '%s: %s' % (exception, message)))
! 
! 
! 
! 
!   ##########################################################################
!   #                                                                        #
!   # XML-RPC introspection support                                          #
!   # (not part of the "standard",
!   # but widely used and expected)
!   #
  
-   def system__listMethods(self):
-     return self.directory.keys()
- 
- 
-   def system__methodHelp(self, method):
-     if self.directory.has_key(method):
-       try:
-         return self.directory[method]['help']
-       except KeyError:
-         return "No help available for %s" % method
-     else:
-       # TODO: Is this right? If the requested method is not available?
-       self.raiseException('InvalidMethodName',
-                           'Requested method does not exist')
- 
- 
-   def system__methodSignature(self, method):
-     if self.directory.has_key(method):
-       try:
-         return (self.directory[method]['signature'],)
-       except KeyError:
-         return None
-     else:
-       # TODO: Is this right? If the requested method is not available?
-       self.raiseException('InvalidMethodName',
-                           'Requested method does not exist')
-   #
-   #                                                                        #
-   #                                                                        #
-   ##########################################################################
    def serve(self):
!     self._requestHandler = RequestHandler
!     self._tcpserver = MyHTTPServer(('',self._port),
!                                              self._requestHandler)
!     self._tcpserver.setParent(self)
!     try: 
!       self._tcpserver.serve_forever()
!     except KeyboardInterrupt:
!       pass
!       
  
  ##############################################################################
  ##############################################################################
  ##############################################################################
  ##############################################################################
  
  
! ##############################################################################
! #
! # Class to Handle the HTTP Post Request
! #
! 
! class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
! 
!   #
!   # Handle the HTTP POST command
!   #
!   # This method is based largely on the
!   # sample code in xmlrpcserver.
!   #
!   def do_POST(self):
!     try:
!       # get arguments
!       data = self.rfile.read(int(self.headers["content-length"]))
!       params, method = xmlrpclib.loads(data)
! 
!       # generate response
!       try:
!         response = self.call(method, params)
!         if response==None:
!           response=()
!         elif type(response) != type(()):
!           response = (response,)
!       except:
!         # report exception back to server
!         GDebug.printMesg(1,
!             'Unexpected Exception in XML-RPC code: %s:%s' % \
!                       (sys.exc_type, sys.exc_value))
!         response = xmlrpclib.dumps(
!            xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value)))
!       else:
!         response = xmlrpclib.dumps(response,methodresponse=1)
!     except:
!       # internal error, report as HTTP server error
!       self.send_response(500)
!       self.end_headers()
!     else:
!       # got a valid XML RPC response
!       self.send_response(200)
!       self.send_header("Content-type", "text/xml")
!       self.send_header("Content-length", str(len(response)))
!       self.end_headers()
!       self.wfile.write(response)
! 
!       # shut down the connection
!       self.wfile.flush()
!       self.connection.shutdown(1)
  
  
    #
    # Call the requested method
--- 79,164 ----
  #
  # ServerAdapter
  #
! class ServerAdapter(DirectoryServer.DirectoryServer):
  
    def __init__(self, rpcdef, bindings, params):
  
+     ## Check parameters
+     try:
+       self._port = params['port']
+     except KeyError:
+       raise GComm.AdapterConfigurationError,\
+             'Required parameter "port" not supplied'
  
!     # Create Subserver
!     self.server=XMLRPC_Server()
  
      
!     ## Build up Service Directory
!     DirectoryServer.DirectoryServer.__init__(self, rpcdef, \
!                                              bindings, params)
!     
!     if hasattr(params,'loglevel'):
!       xmlrpc.setLogLevel(params['loglevel'])
!     else:
!       xmlrpc.setLogLevel(1)
!       
!     self.server.setParent(self)
!     self.server.bindAndListen(self._port)
!     self.server.setOnErr(self.OnErr)
! 
  
    #
    # Return an exception
    #
    def raiseException(self, exception, message, event=None):
!     print xmlrpc.buildFault(34543, '%s: %s' % (exception, message),{})
  
    def serve(self):
!     while 1:
!       try:
!       self.server.work()
!       # you could set a timeout if desired
!       except:
!         e = sys.exc_info()
!         if e[0] in (KeyboardInterrupt, SystemExit):
!           raise e[0], e[1], e[2]
!         traceback.print_exc()
  
  ##############################################################################
  ##############################################################################
  ##############################################################################
  ##############################################################################
  
+   def addRpMethod(self,object,parent,binding):
+     
+     DirectoryServer.DirectoryServer.addRpMethod(self,object, \
+                                                 parent,binding)
+     self.server.addMethods({object._path:binding})
+     
  
!   def addRpAttribut(self,object,parent,binding):
!     
!     DirectoryServer.DirectoryServer.addRpAttribut(self,object,\
!                                                   parent,binding)
!     
!     if not object.readonly:
!       # Add the get_* directory entry
!       self.server.addMethods({'%s.get_%s' % \
!                               (parent._path, object.name):\
!                               binding})
!                              
!     if not object.writeonly:
!       # Add the set_* directory entry
!       self.server.addMethods({'%s.set_%s' % \
!                               (parent._path, object.name):\
!                               binding})
  
+         
+   def OnErr(server,source):
+     print "Error occured with s: %s on source %s." % (server,source)
+     return xmlrpc.ONERR_KEEP_WORK
+          
  
    #
    # Call the requested method
***************
*** 422,449 ****
        # TODO check in service dir, if obj is supported or not
        o=ObjectLibrarian.retrieveObject(objhandle)
        server_method=getattr(o,method)
      else:
  
        # call to a service method            
!       try:      
!         direntry = self.server._parent.getMethodDirEntry(method)      
          server_method = direntry['binding']
          
          if server_method==None:
            raise AttributeError, \
!               "Server XML-RPC method %s has is not " \
                "bound to real method" % method
!       except:
          raise AttributeError, \
                "Server does not have XML-RPC " \
                "procedure %s" % method
!       try:
!         attr=direntry['signature']
          # TODO:  Compare submitted attributs with signature
!       except:
!         raise AttributeError, \
!               "Server XML-RPC " \
!               "procedure %s accepts just %s as attributs" % (method,attr)
  
      # replace object handles in param with the real object
      counter=0
--- 189,220 ----
        # TODO check in service dir, if obj is supported or not
        o=ObjectLibrarian.retrieveObject(objhandle)
        server_method=getattr(o,method)
+       direntry = self.getMethodDirEntry(o._type+"."+method)
+       signature=direntry['signature']
      else:
  
        # call to a service method            
!       try:
!         direntry = self.getMethodDirEntry(method)
          server_method = direntry['binding']
+         signature=direntry['signature']
          
          if server_method==None:
            raise AttributeError, \
!               "Server XML-RPC method %s  is not " \
                "bound to real method" % method
!       except KeyError:
          raise AttributeError, \
                "Server does not have XML-RPC " \
                "procedure %s" % method
!     try:
!       #
!       pass
          # TODO:  Compare submitted attributs with signature
!     except KeyError:
!       raise AttributeError, \
!             "Server XML-RPC " \
!             "procedure %s accepts just %s as attributs" % (method,attr)
  
      # replace object handles in param with the real object
      counter=0
***************
*** 489,499 ****
--- 260,326 ----
      # replace real object in param with an object handle
      if type(result)==type(self):  ## both should be instances
         ObjectLibrarian.archiveObject(result)
+ 
+        # get the type of the result
+        rtype=signature[0]
+        # delete the surrounding brackets < >
+        rtype=rtype[1:len(rtype)-1]
+        # store typeinfo in new object
+        result._type=rtype
+ 
         result=ObjectLibrarian.getObjectReference(result)
+        self.addRegisterDynamicObject(result,rtype)
+ 
+     # check for empty results (not allowed for XMLRPC)
+     if result==None:
+       GDebug.printMesg(3,'Transform result None into 1')
+       result=1      
      
      return result
+   
+   def addRegisterDynamicObject(self,result,type):
+     #
+     #  add new methods to the xmlrpc server
+     #
+     tl=len(type)    
+     for i in self.directory.keys():
+       if i[0:tl]==type:
+         method="["+result+"]"+i[tl:]        
+         GDebug.printMesg(1,'Method %s registered to py-xmlrpc ' \
+                          % method +\
+                          ' internal directory.')
+         self.server.addMethods({method:None})
+     ## check if any methods were added, if no methods were added
+     ## kill this useless object
+ 
+   def deRegisterDynamicObject(self,object):
+     #
+     #  remove the new methods from the xmlrpc server
+     #
+     type=object._type
+     tl=len(type)    
+     for i in self.directory.keys():
+       if i[0:tl]==type:
+         method="["+result+"]"+i[tl:]        
+         GDebug.printMesg(1,'Method %s registered to py-xmlrpc ' \
+                          % method +\
+                          ' internal directory.')
+         self.server.deleteMethods({method:None})
+     ## check if any methods were added, if no methods were added
+     ## kill this useless object
+ 
  
  
+ class XMLRPC_Server(xmlrpc.server):
+   def setParent(self, parent):
+     self._parent=parent
+     
+   def dispatch(self, servp, srcp, uri, method, params):
+     return self._parent.call(method,params)      
+ 
+   def deleteMethods(self, dic):
+     pass
+ 
  ##############################################################################
  #
  # Used internally by the XML-RPC server to proxy
***************
*** 536,541 ****
  
        # Attempt to use an invalid objecthandle
        raise StandardError, 'Invalid object handle' # TODO
- 
- 
  
--- 363,366 ----



reply via email to

[Prev in Thread] Current Thread [Next in Thread]