2 # PLCAPI XML-RPC and SOAP interfaces
4 # Aaron Klingaman <alk@absarokasoft.com>
5 # Mark Huang <mlhuang@cs.princeton.edu>
7 # Copyright (C) 2004-2006 The Trustees of Princeton University
17 from SOAPpy.Parser import parseSOAPRPC
18 from SOAPpy.Types import faultType
19 from SOAPpy.NS import NS
20 from SOAPpy.SOAPBuilder import buildSOAP
22 from PLC.Config import Config
23 from PLC.PostgreSQL import PostgreSQL
24 from PLC.Faults import *
28 methods = PLC.Methods.methods
30 def __init__(self, config = "/etc/planetlab/plc_config"):
31 # Better just be documenting the API
36 self.config = Config(config)
38 # Initialize database connection
39 if self.config.PLC_DB_TYPE == "postgresql":
40 self.db = PostgreSQL(self)
42 raise PLCAPIError, "Unsupported database type " + config.PLC_DB_TYPE
44 def callable(self, method):
46 Return a new instance of the specified method.
50 if method not in self.methods:
51 raise PLCInvalidAPIMethod, method
53 # Get new instance of method
55 classname = method.split(".")[-1]
56 module = __import__("PLC.Methods." + method, globals(), locals(), [classname])
57 return getattr(module, classname)(self)
58 except ImportError, AttributeError:
59 raise PLCInvalidAPIMethod, method
61 def call(self, source, method, *args):
63 Call the named method from the specified source with the
67 function = self.callable(method)
68 function.source = source
69 return function(*args)
71 def handle(self, source, data):
73 Handle an XML-RPC or SOAP request from the specified source.
76 # Parse request into method name and arguments
79 (args, method) = xmlrpclib.loads(data)
83 (r, header, body, attrs) = parseSOAPRPC(data, header = 1, body = 1, attrs = 1)
86 # XXX Support named arguments
89 result = self.call(source, method, *args)
90 except PLCFault, fault:
91 # Handle expected faults
92 if interface == xmlrpclib:
95 elif interface == SOAPpy:
96 result = faultParameter(NS.ENV_T + ":Server", "Method Failed", method)
97 result._setDetail("Fault %d: %s" % (fault.faultCode, fault.faultString))
100 if interface == xmlrpclib:
101 if not isinstance(result, PLCFault):
103 data = xmlrpclib.dumps(result, methodresponse = True)
104 elif interface == SOAPpy:
105 data = buildSOAP(kw = {'%sResponse' % method: {'Result': result}})