Package spade :: Module RPC
[hide private]
[frames] | no frames]

Source Code for Module spade.RPC

  1  import Behaviour 
  2  import xmlrpclib 
  3  import xmpp 
  4   
  5  import types 
  6   
7 -class RPCServerBehaviour(Behaviour.EventBehaviour):
8
9 - def _process(self):
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())): #service.getP(): 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 #Check outputs 71 try: 72 fail=False 73 outputs={} 74 if type(result) == types.DictType: 75 for q in eval(str(service.getOutputs())): #service.getQ(): 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 #Everything was ok. Return results 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
107 -class RPCClientBehaviour(Behaviour.OneShotBehaviour):
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
122 - def _process(self):
123 self.result=None 124 125 #send IQ methodCall 126 params = self.inputs 127 ps = None 128 ps = self.service.getP() #self.service.getDAD().getServices()[0].getProperty("P") 129 for p in ps: #check all Preconditions are True 130 #if not p in self.inputs.keys(): 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 #else: params[p] = self.inputs[p] 136 137 #params = tuple(ps) 138 self.myAgent.DEBUG("Params processed: "+str(params),"info","rpc") 139 140 #if agent is a BDIAgent check preconditions 141 #if "askBelieve" in dir(self.myAgent): 142 # for p in params: 143 # if not self.myAgent.askBelieve(p): 144 # self.result=False 145 # self.myAgent.DEBUG("Precondition "+ str(p) + " is not satisfied. Can't call method "+self.service.getName(),'error',"rpc") 146 # return 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 #receive IQ methodResponse 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 #if agent is a BDIAgent add result params as postconditions 168 for k,v in self.result.items(): #[0]: 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