/[papo]/gnue/common/src/commdrivers/xmlrpc/ServerAdapter.py
ViewVC logotype

Diff of /gnue/common/src/commdrivers/xmlrpc/ServerAdapter.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by charlie, Tue Aug 27 18:15:52 2002 UTC revision 1.4 by styxman, Fri Nov 15 15:32:55 2002 UTC
# Line 25  Line 25 
25  # Set of classes that implement the XML-RPC server driver for GNUe Comm.  # Set of classes that implement the XML-RPC server driver for GNUe Comm.
26  #  #
27  # NOTES:  # NOTES:
28  # Requires py-xmlrpc from http://sf.net/projects/python-xmlrpc  # Requires py-xmlrpc from http://sf.net/projects/py-xmlrpc
29  #  #
30  #  #
31  # Server Parameters:  # Server Parameters:
32  #  #
33  #    port        The port that the service is located on  #    port        The port that the service is located on
34    #    loglevel    Loglevel of the internal server
35  #  #
36    
37    
# Line 46  SERVER = 1      # ServerAdapter Line 47  SERVER = 1      # ServerAdapter
47    
48    
49  from gnue.common import GComm, GDebug  from gnue.common import GComm, GDebug
50  from gnue.common.commdrivers._helpers import ObjectLibrarian  from gnue.common.commdrivers._helpers import ObjectLibrarian,ObjectEnabler
51  from gnue.common.commdrivers._directory import DirectoryServer  from gnue.common.commdrivers._directory import DirectoryServer
52  from gnue.common.commdrivers import GCommBase  from gnue.common.commdrivers import GCommBase
53    
# Line 79  _datatypeMap = { Line 80  _datatypeMap = {
80  #  #
81  # ServerAdapter  # ServerAdapter
82  #  #
83  class ServerAdapter(DirectoryServer.DirectoryServer):  class ServerAdapter(ObjectEnabler.ObjectEnabler):
84    
85    def __init__(self, rpcdef, bindings, params):    def __init__(self, rpcdef, bindings, params):
86    
# Line 94  class ServerAdapter(DirectoryServer.Dire Line 95  class ServerAdapter(DirectoryServer.Dire
95      self.server=XMLRPC_Server()      self.server=XMLRPC_Server()
96    
97            
98      ## Build up Service Directory      ## Build up Service Directory and enable object dispatching
99      DirectoryServer.DirectoryServer.__init__(self, rpcdef, \      ObjectEnabler.ObjectEnabler.__init__(self, rpcdef, \
100                                               bindings, params)                                           bindings, params)
101            
102      if hasattr(params,'loglevel'):      if hasattr(params,'loglevel'):
103        self._loglevel = params['loglevel']        self._loglevel = params['loglevel']
# Line 110  class ServerAdapter(DirectoryServer.Dire Line 111  class ServerAdapter(DirectoryServer.Dire
111      self.server.setOnErr(self.OnErr)      self.server.setOnErr(self.OnErr)
112    
113    def serve(self):    def serve(self):
114      while 1:      quit=0
115        while quit==0:
116        try:        try:
117          self.server.work()          self.server.work()
118          # you could set a timeout if desired          # you could set a timeout if desired
119        except:        except:
120          e = sys.exc_info()          e = sys.exc_info()
121          if e[0] in (KeyboardInterrupt, SystemExit):          if e[0] in (KeyboardInterrupt, SystemExit):
122            raise e[0], e[1], e[2]            # shut down server without showing error message
123          traceback.print_exc()            quit=1
124              # raise e[0], e[1], e[2]
125            else:
126              print "*" * 60
127              print "Error occured on server:"
128              print "*" * 60
129              traceback.print_exc()
130              print "*" * 60
131              print "\n\n"
132    
133    def addRpMethod(self,object,parent,binding):        def addRpMethod(self,object,parent,binding):    
134    
# Line 145  class ServerAdapter(DirectoryServer.Dire Line 155  class ServerAdapter(DirectoryServer.Dire
155                                binding})                                binding})
156    
157    
158    def OnErr(server,source):    def OnErr(self,server,source):
159      print _("Internal server error occured:\n"+      print _("Internal server error occured:\n"+
160              " server %s \n on source %s.") % (server,source)              " server %s \n on source %s.") % (server,source)
161      return xmlrpc.ONERR_KEEP_WORK      return xmlrpc.ONERR_KEEP_WORK
   
   
   #  
   # Call the requested method  
   #  
   def call(self, method, params):  
     if self._loglevel>0:  
       print _("Dispatching: "), method, params  
       
   
     ## Check if the Method is part of a service or a pointer to a  
     ## single object  
     ##  
     ## Call to an object:  method="_Management:235423456_.getAttr"  
     ##                     params=""  
     ## Call to an method: (of a service=one object)  
     ##                     method="DonutPlace.Management.Restart"  
   
     if method[0]=='[':  
       # call to an object  
       # 1. get the object from the objectlibrarian  
       # 2. check, if the object is supported by the gfd  
       try:  
         i=string.index(method,']',1)  
         objhandle=method[1:i]  
         method=method[i+2:]  
       except ValueError:  
         raise AttributeError, \  
               _("Wrong format of object handler ")+\  
               _("in method call %s") % method  
       # TODO check in service dir, if obj is supported or not  
       o=ObjectLibrarian.retrieveObject(objhandle)  
       try:  
         server_method=getattr(o,method)  
         server_attribute=None  
       except AttributeError:  
         server_method=None  
         try:  
           server_attribute=getattr(o,method[4:])  
         except AttributeError:  
             
           if method!="_close":                        
             msg=_("Internal XMLRPC server error: method %s can be ")% \  
                  method +\  
                  _("found in the directory (build out of a .grpc file),")+\  
                  _(" but the object doesn't contain this method/attribut.")+\  
                  _(" Please check you .grpc file for wrong return types.")  
               
             raise AttributeError, msg  
           
       if method!="_close":  
         direntry = self.getMethodDirEntry(o._type+"."+method)  
         signature=direntry['signature']  
       else:  
         signature= ('string',)                  
   
     else:  
   
       # call to a service method or a helper call (get/set) for  
       # a service attribut  
       try:  
         direntry = self.getMethodDirEntry(method)  
         server_method = direntry['binding']  
         server_attribute = None  
           
         # check if it is an real method (binding -> method)  
         # or an get/set method for an attribut (binding-> attribut)  
         if (type(server_method)!=type(self.call)):  
           server_attribute = server_method  
           server_method=None  
             
         signature=direntry['signature']  
   
         if (server_method==None) and (server_attribute==None):  
           raise AttributeError, \  
               _("Server XML-RPC method %s  is not ")% method +\  
               _("bound to real 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)  
162            
163    
     # replace object handles in param with the real object  
     counter=0  
     while counter<len(params):  
       p=params[counter]  
       if type(p)==type(""):  
         if (len(p)==42) and (p[0]=="[") and (p[41]=="]"):  
           try:  
             p=p[1:41]  
             obj=ObjectLibrarian.retrieveObject(p)  
             newp=params[0:counter-1]+(obj,)+params[counter+1:]  
             params=newp  
           except:  
             pass  
       counter=counter+1;  
   
     # check if it is an real method (binding -> method)  
     # or an get/set method for an attribut (binding-> attribut)  
   
     if (server_method!=None):  
               
       # call method with params  
       result=server_method(*params)  
   
     # check if it's the close object method  
     elif (method=="_close"):  
         
       result=self.releaseDynamicObject(o)  
         
     else:  
         
       ## check wether its the set or the get method for the attribut  
       mparts=string.splitfields(method,'.')  
       mparts.reverse()  
       calltype=mparts[0]  
       calltype=calltype[:4]  
       GDebug.printMesg(7,'method %s has calling type %s' %\  
                        (method,calltype))  
       if calltype=='set_':  
         # setAttribut method  
         server_attribute=params[0]  
       elif calltype=='get_':  
         # getAttribut method  
         result=server_attribute  
       else:  
         raise AttributeError, \  
             _("Internal Server XML-RPC error: method type") +\  
             _("(get/set attribute) couldn't be detected (method %s)") \  
             % method        
       
   
     # 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.registerDynamicObject(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  
   
164    def registerDynamicObject(self,objhandle,type):    def registerDynamicObject(self,objhandle,type):
165      #      #
166      #  add new methods to the xmlrpc server      #  add new methods to the xmlrpc server
# Line 344  class ServerAdapter(DirectoryServer.Dire Line 194  class ServerAdapter(DirectoryServer.Dire
194    
195      # remove the method to close this object      # remove the method to close this object
196      self.server.removeMethods({"["+objhandle+"]._close":None})      self.server.removeMethods({"["+objhandle+"]._close":None})
   
   def releaseDynamicObject(self,object):  
     # delete bindings for this object in the xmlrpc method directory  
     self.deregisterDynamicObject(object)  
     # release object for Object Librarian  
     ObjectLibrarian.deferenceObject(object)  
197            
198    
199  class XMLRPC_Server(xmlrpc.server):  class XMLRPC_Server(xmlrpc.server):
# Line 367  class XMLRPC_Server(xmlrpc.server): Line 211  class XMLRPC_Server(xmlrpc.server):
211        # del self._o.comtab[name]        # del self._o.comtab[name]
212        # or        # or
213        # self._o.removeMethods(d)        # self._o.removeMethods(d)
   
 ##############################################################################  
 #  
 # Used internally by the XML-RPC server to proxy  
 # between Object-by-Ref and actual objects.  
 #  
 class _ObjectByReferenceHandler:  
   
   def __init__(self, oclass):  
     self._class = oclass  
   
   # If this makes absolutely no sense, move on and trust the code :)  
   def requestHandler(self, method, *params, **args):  
   
     if len(params):  
   
       # If parameters were passed, the first one is always the handle  
       refid = params[0]  
   
       # The object's real method doesn't expect to receive the object handle  
       params = params[1:]  
   
     else:  
   
       try:  
   
         # If only named parameters are present, then  
         # obj_handle should be the object handle...  
         refid = args['obj_handle']  
   
         # The object's real method doesn't expect to receive the object handle  
         del args['obj_handle']  
   
       except KeyError:  
         raise StandardError, _('Object handle not returned')   # TODO  
   
     try:  
       return ObjectLibrarian. \  
         retrieveObject(refid).__dict__[method](*params, **args)  
     except KeyError:  
   
       # Attempt to use an invalid objecthandle  
       raise StandardError, _('Invalid object handle') # TODO  
   

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26