summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-11-25 11:54:51 -0700
committerJason Gerard DeRose <jderose@redhat.com>2008-11-25 11:54:51 -0700
commit7350ccbffefdf81992b3ccd8aac814f3bb954be8 (patch)
treecdd07d157a310f2bb801d736f5d44e65eaa032e2
parent2d458a12339fbb7ef006ff7defc1e2f541e2f23f (diff)
downloadfreeipa-7350ccbffefdf81992b3ccd8aac814f3bb954be8.tar.gz
freeipa-7350ccbffefdf81992b3ccd8aac814f3bb954be8.tar.xz
freeipa-7350ccbffefdf81992b3ccd8aac814f3bb954be8.zip
Started fleshing out doodles in xmlrpc.execute()
-rw-r--r--ipa_server/rpc.py29
-rw-r--r--ipalib/errors.py15
-rw-r--r--tests/test_ipa_server/test_rpc.py14
3 files changed, 54 insertions, 4 deletions
diff --git a/ipa_server/rpc.py b/ipa_server/rpc.py
index 51007134b..34de915cb 100644
--- a/ipa_server/rpc.py
+++ b/ipa_server/rpc.py
@@ -18,14 +18,24 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
-Dispatcher for RPC server.
+Execute an RPC request.
"""
+from xmlrpclib import dumps, loads, Fault
from ipalib import Backend
-from ipalib.errors import CommandError
+from ipalib.errors import HandledError, CommandError
from ipalib.rpc import xmlrpc_wrap, xmlrpc_unwrap
+def params_2_args_options(params):
+ assert type(params) is tuple
+ if len(params) == 0:
+ return (tuple(), dict())
+ if type(params[-1]) is dict:
+ return (params[:-1], params[-1])
+ return (params, dict())
+
+
class xmlrpc(Backend):
def dispatch(self, method, params):
@@ -34,4 +44,17 @@ class xmlrpc(Backend):
self.info('Received RPC call to %r', method)
if method not in self.Command:
raise CommandError(name=method)
- params = xml_unwrap(params)
+ (args, options) = params_2_args_options(xmlrpc_unwrap(params))
+ result = self.Command[method](*args, **options)
+ return (xmlrpc_wrap(result),)
+
+ def execute(self, data, ccache=None, client_ip=None, locale=None):
+ try:
+ (params, method) = loads(data)
+ response = self.dispatch(method, params)
+ except Exception, e:
+ if not isinstance(e, HandledError):
+ e = UnknownError()
+ assert isinstance(e, HandledError)
+ response = Fault(e.code, e.message)
+ return dumps(response)
diff --git a/ipalib/errors.py b/ipalib/errors.py
index a01082504..8412d1f65 100644
--- a/ipalib/errors.py
+++ b/ipalib/errors.py
@@ -125,6 +125,9 @@ class HandledError(StandardError):
"""
Base class for errors that can be raised across a remote procecdure call.
"""
+
+ code = 1
+
def __init__(self, message=None, **kw):
self.kw = kw
if message is None:
@@ -132,12 +135,22 @@ class HandledError(StandardError):
StandardError.__init__(self, message)
+
+class UnknownError(HandledError):
+ """
+ Raised when the true error is not a handled error.
+ """
+
+ format = _('An unknown internal error has occurred')
+
+
class CommandError(HandledError):
format = _('Unknown command %(name)r')
+
class RemoteCommandError(HandledError):
- format = 'Server at %(uri)r has no command %(command)r'
+ format = 'Server at %(uri)r has no command %(name)r'
class UnknownHelpError(InvocationError):
diff --git a/tests/test_ipa_server/test_rpc.py b/tests/test_ipa_server/test_rpc.py
index 56ad3f064..6c46b130a 100644
--- a/tests/test_ipa_server/test_rpc.py
+++ b/tests/test_ipa_server/test_rpc.py
@@ -26,6 +26,20 @@ from ipalib import errors, Command
from ipa_server import rpc
+def test_params_2_args_options():
+ """
+ Test the `ipa_server.rpc.params_2_args_options` function.
+ """
+ f = rpc.params_2_args_options
+ args = ('Hello', u'world!')
+ options = dict(one=1, two=u'Two', three='Three')
+ assert f(tuple()) == (tuple(), dict())
+ assert f(args) == (args, dict())
+ assert f((options,)) == (tuple(), options)
+ assert f(args + (options,)) == (args, options)
+ assert f((options,) + args) == ((options,) + args, dict())
+
+
class test_xmlrpc(PluginTester):
"""
Test the `ipa_server.rpc.xmlrpc` plugin.