Rebase XML-RPC client and server

Fix error handling in server to return exceptions generated in library code
This commit is contained in:
Rob Crittenden 2008-09-25 23:53:53 -04:00 committed by Jason Gerard DeRose
parent afdc721038
commit b965e558b5
4 changed files with 62 additions and 17 deletions

View File

@ -25,8 +25,12 @@ import frontend, errors
class Add(frontend.Method):
def get_args(self):
yield self.obj.primary_key
def get_options(self):
return self.obj.params()
for param in self.obj.params_minus_pk():
yield param.__clone__(required=False)
class Get(frontend.Method):

View File

@ -26,7 +26,8 @@ from ipalib import frontend
from ipalib import crud
from ipalib.frontend import Param
from ipalib import api
from ipalib import servercore
import ldap
class user(frontend.Object):
'User object'
@ -78,6 +79,8 @@ api.register(envtest)
# Register some methods for the 'user' object:
class user_add(crud.Add):
'Add a new user.'
def execute(self, *args, **kw):
return 1
api.register(user_add)
class user_del(crud.Del):
@ -90,6 +93,10 @@ api.register(user_mod)
class user_find(crud.Find):
'Search the users.'
def execute(self, *args, **kw):
uid=args[0]
result = servercore.get_sub_entry(servercore.basedn, "uid=%s" % uid, ["*"])
return result
api.register(user_find)
class user_show(crud.Get):

View File

@ -5,12 +5,19 @@ import xmlrpclib
server = xmlrpclib.ServerProxy("http://localhost:8888/")
print server.system.listMethods()
#print server.system.methodHelp("user_add")
print server.system.methodHelp("user_add")
user = {'givenname':'Joe', 'sn':'Smith'}
result = server.user_add(user)
print "returned %s" % result
try:
args="admin"
kw = {'givenname':'Joe', 'sn':'Smith'}
result = server.user_add(args, kw)
print "returned %s" % result
except xmlrpclib.Fault, e:
print e.faultString
user = {'givenname':'Joe', 'sn':'Smith', 'uid':'admin'}
result = server.user_find(user)
print "returned %s" % result
try:
args="admin"
result = server.user_find(args)
print "returned %s" % result
except xmlrpclib.Fault, e:
print e.faultString

View File

@ -12,6 +12,7 @@ import commands
from ipalib import api, conn
from ipalib.conn import context
import ipalib.load_plugins
import traceback
PORT=8888
@ -43,11 +44,6 @@ class LoggingSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHa
Methods beginning with an '_' are considered private and will
not be called.
"""
if (params):
(args, kw) = self.parse(*params)
else:
args = []
kw = {}
# this is fine for our test server
uid = commands.getoutput('/usr/bin/id -u')
@ -62,12 +58,41 @@ class LoggingSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHa
func = funcs[method]
except KeyError:
raise Exception('method "%s" is not supported' % method)
return func(**kw)
if len(params) > 1 and isinstance(params[-1], dict):
kw = params[-1]
params = params[:-1]
return func(*params, **kw)
else:
return func(*params)
finally:
# Clean up any per-request data and connections
for k in context.__dict__.keys():
del context.__dict__[k]
def _marshaled_dispatch(self, data, dispatch_method = None):
try:
params, method = xmlrpclib.loads(data)
# generate response
if dispatch_method is not None:
response = dispatch_method(method, params)
else:
response = self._dispatch(method, params)
# wrap response in a singleton tuple
response = (response,)
response = xmlrpclib.dumps(response, methodresponse=1)
except:
# report exception back to client. This is needed to report
# tracebacks found in server code.
e_class, e = sys.exc_info()[:2]
# FIXME, need to get this number from somewhere...
faultCode = getattr(e_class,'faultCode',1)
tb_str = ''.join(traceback.format_exception(*sys.exc_info()))
faultString = tb_str
response = xmlrpclib.dumps(xmlrpclib.Fault(faultCode, faultString))
return response
def do_POST(self):
clientIP, port = self.client_address
# Log client IP and Port
@ -82,14 +107,16 @@ class LoggingSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHa
# Log client request
logger.info('Client request: \n%s\n' % data)
response = self.server._marshaled_dispatch(
# response = self.server._marshaled_dispatch(
response = self._marshaled_dispatch(
data, getattr(self, '_dispatch', None))
# Log server response
logger.info('Server response: \n%s\n' % response)
except:
except Exception, e:
# This should only happen if the module is buggy
# internal error, report as HTTP server error
print e
self.send_response(500)
self.end_headers()
else: