[Top][All Lists]
[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 ----
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- gnue/common doc/RPC-abstraction.txt doc/RPC-sta...,
Jan Ischebeck <=