1 import Behaviour
2 import xmlrpclib
3 import xmpp
4
5 import types
6
8
10 self.result=None
11 self.msg = self._receive(False)
12 if self.msg != None:
13 if self.msg.getType() == "set":
14
15 self.myAgent.DEBUG("RPC request received: "+str(self.msg),'info',"rpc")
16
17 mc = self.msg.getTag('query')
18 params, name = xmlrpclib.loads("<?xml version='1.0'?>%s" % str(mc))
19 name=name.lower()
20 self.myAgent.DEBUG("Params processed: name="+name+" params="+str(params) + " in " + str(self.myAgent.RPC.keys()),"info","rpc")
21
22 if not self.myAgent.RPC.has_key(name):
23 self.myAgent.DEBUG("RPC: 404 method not found",'error',"rpc")
24 xmlrpc_res = xmlrpclib.dumps( xmlrpclib.Fault(404, "method not found"))
25 reply = self.msg.buildReply("error")
26 reply.setQueryPayload([xmpp.simplexml.XML2Node(xmlrpc_res)])
27 reply.setType("result")
28 reply.setFrom(self.myAgent.JID)
29 self.myAgent.send(reply)
30 return
31
32 service,methodCall = self.myAgent.RPC[name]
33
34 self.myAgent.DEBUG("service and method: "+ str(service) + " --> " + str(methodCall),"info","rpc")
35
36 self.myAgent.DEBUG("Comparing service.getInputs(): "+ str(service.getInputs()) + " with params--> " + str(params),"info","rpc")
37 ps = params[0].keys()
38 for p in eval(str(service.getInputs())):
39 self.myAgent.DEBUG("Comparing input "+str(p)+ " with "+str(ps))
40 if str(p) not in ps:
41 self.myAgent.DEBUG("RPC: 500 missing input: "+str(p)+ " is not in "+str(params),'error',"rpc")
42 xmlrpc_res = xmlrpclib.dumps( xmlrpclib.Fault(500, "missing input"))
43 reply = self.msg.buildReply("error")
44 reply.setQueryPayload([xmpp.simplexml.XML2Node(xmlrpc_res)])
45 reply.setType("result")
46 reply.setFrom(self.myAgent.JID)
47 self.myAgent.send(reply)
48 return
49
50 try:
51 self.myAgent.DEBUG("Calling method "+str(methodCall)+" with params "+str(params),"info","rpc")
52 if params == (None,):
53 result = methodCall()
54 else:
55 args=""
56 for k,v in params[0].items():
57 args+=str(k)+"="+str(v)+","
58 args=args[:-1]
59 result = eval("methodCall("+args+")")
60 except Exception,e:
61 self.myAgent.DEBUG("RPC: 500 method error: "+str(e),'error',"rpc")
62 xmlrpc_res = xmlrpclib.dumps( xmlrpclib.Fault(500, "method error: "+str(e)))
63 reply = self.msg.buildReply("error")
64 reply.setQueryPayload([xmpp.simplexml.XML2Node(xmlrpc_res)])
65 reply.setType("result")
66 reply.setFrom(self.myAgent.JID)
67 self.myAgent.send(reply)
68 return
69
70
71 try:
72 fail=False
73 outputs={}
74 if type(result) == types.DictType:
75 for q in eval(str(service.getOutputs())):
76 if q not in result.keys():
77 fail=True
78 break
79 else: outputs[q]=result[q]
80 params = (outputs,)
81 else:
82 self.myAgent.DEBUG("RPC method MUST return a dict.",'error',"rpc")
83 fail=True
84 except:
85 fail=True
86 if fail:
87 self.myAgent.DEBUG("RPC: 500 missing output: "+str(service.getQ()),'error',"rpc")
88 xmlrpc_res = xmlrpclib.dumps( xmlrpclib.Fault(500, "missing output"))
89 reply = self.msg.buildReply("error")
90 reply.setQueryPayload([xmpp.simplexml.XML2Node(xmlrpc_res)])
91 reply.setType("result")
92 reply.setFrom(self.myAgent.JID)
93 self.myAgent.send(reply)
94 return
95
96
97 xmlrpc_res = xmlrpclib.dumps( params , methodresponse=True,allow_none=True)
98 reply = self.msg.buildReply("result")
99 reply.setQueryPayload([xmpp.simplexml.XML2Node(xmlrpc_res)])
100 self.myAgent.send(reply)
101 self.myAgent.DEBUG("RPC: method succesfully served: "+ str(reply),'ok',"rpc")
102
103
104 else:
105 self.myAgent.DEBUG("RPCServerBehaviour returned with no message", "warn","rpc")
106
108
109 - def __init__(self, service, inputs, num):
110 '''
111 This behaviour makes the Remote Procedure Call to the server
112 Usage:
113 service - DF.Service to be called
114 inputs - dictionary of inputs where key=input name, value=input value
115 num - a numeric id
116 '''
117 Behaviour.OneShotBehaviour.__init__(self)
118 self.service = service
119 self.inputs = inputs
120 self.num = num
121
123 self.result=None
124
125
126 params = self.inputs
127 ps = None
128 ps = self.service.getP()
129 for p in ps:
130
131 if not self.myAgent.askBelieve(p):
132 self.myAgent.DEBUG("Precondition "+ str(p) + " is not satisfied. Can't call method "+self.service.getName(),'error',"rpc")
133 self.result=False
134 return
135
136
137
138 self.myAgent.DEBUG("Params processed: "+str(params),"info","rpc")
139
140
141
142
143
144
145
146
147
148 payload = xmlrpclib.dumps( (params,) , methodname=self.service.getName(),allow_none=True)
149 self.myAgent.DEBUG("Marshalled "+payload,"info","rpc")
150 payload_node = xmpp.simplexml.XML2Node(payload)
151 to = xmpp.protocol.JID(self.service.getOwner().getName())
152 iq = xmpp.protocol.Iq(typ='set',queryNS="jabber:iq:rpc",frm=self.myAgent.JID,to=to,attrs={'id':self.num})
153 iq.setQueryPayload([payload_node])
154 self.myAgent.DEBUG("Calling method with: "+str(iq),"info","rpc")
155 self.myAgent.send(iq)
156 self.myAgent.DEBUG(self.service.getName() + " method called. Waiting for response",'ok',"rpc")
157
158
159 self.msg = self._receive(True)
160 if self.msg != None:
161 self.myAgent.DEBUG("Response received for method "+self.service.getName()+":" +str(self.msg),'ok',"rpc")
162 if self.msg.getType() == "result":
163 try:
164 params, method = xmlrpclib.loads("<?xml version='1.0'?>%s" % self.msg)
165 self.DEBUG("Returned params "+str(params),'ok',"rpc")
166 self.result = params[0]
167
168 for k,v in self.result.items():
169 self.myAgent.kb.set(k,v)
170 for q in self.service.getQ():
171 if not self.myAgent.askBelieve(q):
172 raise Exception("PostCondition "+str(q)+ " not satisfied.")
173 return self.result
174 except Exception,e:
175 self.myAgent.DEBUG("Error executing RPC service: "+str(e),"error","rpc")
176 self.result = False
177 return False
178 else:
179 self.result = False
180 return False
181 else:
182 self.result = False
183 return False
184