Initial checkin of new API implementation
[plcapi.git] / PLC / Methods / system / multicall.py
1 import sys
2 import xmlrpclib
3
4 from PLC.Parameter import Parameter, Mixed
5 from PLC.Method import Method
6
7 class multicall(Method):
8     """
9     Process an array of calls, and return an array of results. Calls
10     should be structs of the form
11
12     {'methodName': string, 'params': array}
13
14     Each result will either be a single-item array containg the result
15     value, or a struct of the form
16
17     {'faultCode': int, 'faultString': string}
18
19     This is useful when you need to make lots of small calls without
20     lots of round trips.
21     """
22
23     roles = []
24     accepts = [[{'methodName': Parameter(str, "Method name"),
25                  'params': Parameter(list, "Method arguments")}]]
26     returns = Mixed([Mixed()],
27                     {'faultCode': Parameter(int, "XML-RPC fault code"),
28                      'faultString': Parameter(int, "XML-RPC fault detail")})
29
30     def __init__(self, api):
31         Method.__init__(self, api)
32         self.name = "system.multicall"
33
34     def call(self, calls):
35         # Some error codes, borrowed from xmlrpc-c.
36         REQUEST_REFUSED_ERROR = -507
37
38         results = []
39         for call in calls:
40             try:
41                 name = call['methodName']
42                 params = call['params']
43                 if name == 'system.multicall':
44                     errmsg = "Recursive system.multicall forbidden"
45                     raise xmlrpclib.Fault(REQUEST_REFUSED_ERROR, errmsg)
46                 result = [self.api.call(self.source, name, *params)]
47             except xmlrpclib.Fault, fault:
48                 result = {'faultCode': fault.faultCode,
49                           'faultString': fault.faultString}
50             except:
51                 errmsg = "%s:%s" % (sys.exc_type, sys.exc_value)
52                 result = {'faultCode': 1, 'faultString': errmsg}
53             results.append(result)
54         return results