1
2
3 from Agent import PlatformAgent
4 import AID
5 import Behaviour
6 from SL0Parser import *
7 import copy
8
9 import xmpp
10
11 from spade.msgtypes import *
12 from content import ContentObject
13
14 -class AMS(PlatformAgent):
15 """
16 Agent Management System
17 """
18
23
26
27
28
29
30
31
32
33
34
35
38 msg = None
39 msg = self._receive(block=True)
40 if msg:
41 self.myAgent.DEBUG("AMS received presence message "+ str(msg),"info")
42 typ = msg.getType()
43 frm = msg.getFrom()
44 status = msg.getStatus()
45 show = msg.getShow()
46 reply_address = frm
47 if typ == "subscribe":
48 frm=AID.aid(name=str(frm), addresses=["xmpp://"+str(frm)])
49 aad = AmsAgentDescription()
50 aad.name = frm
51 if status: aad.state = status
52 if show: aad.ownership = show
53 else: aad.ownership = frm.getName()
54
55 if not self.myAgent.agentdb.has_key(frm.getName()):
56 self.myAgent.agentdb[frm.getName()] = aad
57 elif self.myAgent.agentdb[frm.getName()].getOwnership() == aad.getOwnership():
58 self.myAgent.agentdb[frm.getName()] = aad
59 else:
60 presence = xmpp.Presence(reply_address,typ="unsubscribed",xmlns=xmpp.NS_CLIENT)
61 presence.setFrom(self.myAgent.JID)
62 self.myAgent.send(presence)
63 return
64
65 self.myAgent.DEBUG("AMS succesfully registered agent " + frm.getName(),"ok")
66 presence = xmpp.Presence(reply_address,typ="subscribed")
67 presence.setFrom(self.myAgent.JID)
68 self.myAgent.DEBUG("AMS sends "+str(presence),"info")
69 self.myAgent.send(presence)
70 elif typ == "unsubscribe":
71 if self.myAgent.agentdb.has_key(str(frm)):
72 del self.myAgent.agentdb[str(frm)]
73 self.myAgent.DEBUG("Agent " + str(frm) + " deregistered from AMS","ok")
74 else:
75 self.myAgent.DEBUG("Agent " + str(frm) + " deregistered from AMS","error")
76 return
77
78
80 error = False
81 msg = self._receive(True)
82 if msg != None:
83 if msg.getPerformative().lower() == 'request':
84 if msg.getOntology() and msg.getOntology().lower() == "fipa-agent-management":
85 if msg.getLanguage().lower() == "fipa-sl0":
86 content = self.sl0parser.parse(msg.getContent())
87 ACLtemplate = Behaviour.ACLTemplate()
88 ACLtemplate.setConversationId(msg.getConversationId())
89 ACLtemplate.setSender(msg.getSender())
90 template = (Behaviour.MessageTemplate(ACLtemplate))
91
92 if "action" in content:
93 self.myAgent.DEBUG("AMS: "+str(content.action)+ " request. " + str(content),"info")
94 if "register" in content.action \
95 or "deregister" in content.action:
96 self.myAgent.addBehaviour(AMS.RegisterBehaviour(msg,content), template)
97 elif "get-description" in content.action:
98 self.myAgent.addBehaviour(AMS.PlatformBehaviour(msg,content), template)
99 elif "search" in content.action:
100 self.myAgent.addBehaviour(AMS.SearchBehaviour(msg,content), template)
101 elif "modify" in content.action:
102 self.myAgent.addBehaviour(AMS.ModifyBehaviour(msg,content), template)
103 else:
104 reply = msg.createReply()
105 reply.setSender(self.myAgent.getAID())
106 reply.setPerformative("refuse")
107 reply.setContent("( "+msg.getContent() +"(unsuported-function "+ content.keys()[0] +"))")
108 self.myAgent.send(reply)
109
110 return -1
111
112 elif msg.getLanguage().lower() == "rdf":
113
114 co = msg.getContentObject()
115 content = msg.getContent()
116 ACLtemplate = Behaviour.ACLTemplate()
117 ACLtemplate.setConversationId(msg.getConversationId())
118 ACLtemplate.setSender(msg.getSender())
119 template = (Behaviour.MessageTemplate(ACLtemplate))
120
121 if co.has_key("fipa:action") and co["fipa:action"].has_key("fipa:act"):
122 self.myAgent.DEBUG("AMS: "+str(co["fipa:action"]["fipa:act"])+ " request. " + str(co.asRDFXML()),"info")
123 if co["fipa:action"]["fipa:act"] in ["register","deregister"]:
124 self.myAgent.addBehaviour(AMS.RegisterBehaviour(msg,content), template)
125 elif co["fipa:action"]["fipa:act"] == "get-description":
126 self.myAgent.addBehaviour(AMS.PlatformBehaviour(msg,content), template)
127 elif co["fipa:action"]["fipa:act"] == "search":
128 self.myAgent.addBehaviour(AMS.SearchBehaviour(msg,content), template)
129 elif co["fipa:action"]["fipa:act"] == "modify":
130 self.myAgent.addBehaviour(AMS.ModifyBehaviour(msg,content), template)
131 else:
132 reply = msg.createReply()
133 reply.setSender(self.myAgent.getAID())
134 reply.setPerformative("refuse")
135 co["unsuported-function"] = "true"
136 reply.setContentObject(co)
137 self.myAgent.send(reply)
138 return -1
139
140
141
142 else: error = "(unsupported-language "+msg.getLanguage()+")"
143 else: error = "(unsupported-ontology "+msg.getOntology()+")"
144
145
146
147
148 elif msg.getPerformative().lower() not in ['failure','refuse','not-understood']:
149 error = "(unsupported-act " + msg.getPerformative() + ")"
150 if error:
151 reply = msg.createReply()
152 reply.setSender(self.myAgent.getAID())
153 reply.setPerformative("not-understood")
154 reply.setContent("( "+msg.getContent() + error+")")
155 self.myAgent.send(reply)
156 return -1
157
158
159 return 1
160
250
319
321
326
328
329 error = False
330 rdf = True
331 max = 1000
332
333 reply = self.msg.createReply()
334 reply.setSender(self.myAgent.getAID())
335 reply.setPerformative("agree")
336
337 if "rdf" in self.msg.getLanguage().lower():
338 rdf = True
339 co = self.msg.getContentObject()
340 co["fipa:done"] = "true"
341 reply.setContentObject(co)
342
343 else:
344
345 rdf = False
346 reply.setContent("(" + str(self.msg.getContent()) + " true)")
347
348 self.myAgent.send(reply)
349
350 if not rdf:
351 if "search-constraints" in self.content.action.search:
352 if "max-results" in self.content.action.search["search-constraints"]:
353 try:
354 max = int(self.content.action.search["search-constraints"]["max-results"])
355 except Exception, err:
356 error = '(internal-error "max-results is not an integer")'
357 if error:
358 reply = self.msg.createReply()
359 reply.setSender(self.myAgent.getAID())
360 reply.setPerformative("failure")
361 reply.setContent("( "+self.msg.getContent() + error+")")
362 self.myAgent.send(reply)
363 return -1
364
365
366 result = []
367 if "ams-agent-description" in self.content.action.search:
368 aad = AmsAgentDescription(self.content.action.search['ams-agent-description'])
369 for a in self.myAgent.agentdb.values():
370 if max >= 0:
371 if a.match(aad):
372 result.append(a)
373 max -= 1
374 else: break
375
376 else:
377 result = self.myAgent.agentdb.values()
378
379 content = "((result "
380 if len(result)>0:
381 content += " (set "
382 for i in result:
383 content += str(i) + " "
384 content += ")"
385 else:
386 content+= 'None'
387 content += "))"
388
389 reply.setContent(content)
390
391 else:
392
393
394 del co["fipa:done"]
395
396 if co["fipa:action"].has_key("constraints"):
397 try:
398 max = int(co["fipa:action"]["constraints"])
399 except:
400 error = 'constraints-error'
401 if error:
402 reply = self.msg.createReply()
403 reply.setSender(self.myAgent.getAID())
404 reply.setPerformative("failure")
405 co["fipa:error"] = error
406 reply.setContentObject(co)
407 self.myAgent.send(reply)
408 return -1
409
410
411 result = []
412 if co["fipa:action"].has_key("fipa:argument") and co["fipa:action"]["fipa:argument"]:
413 aad = AmsAgentDescription(co=co["fipa:action"]["fipa:argument"])
414 for a in self.myAgent.agentdb.values():
415 if max >= 0:
416 if a.match(aad):
417 result.append(a)
418 max -= 1
419 else: break
420 else:
421 result = self.myAgent.agentdb.values()
422
423 co2 = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"})
424 co2["fipa:result"] = []
425 for i in result:
426 co2["fipa:result"].append(i.asContentObject())
427 reply.setContentObject(co2)
428
429
430 reply.setPerformative("inform")
431 self.myAgent.send(reply)
432
433 return 1
434
581
582
583 - def __init__(self,node,passw,server="localhost",port=5347,config={}):
585
586
615
617 """
618 Agent Descriptor for AMS registering
619 """
620
621 - def __init__(self, content = None, co = None):
622 """
623 AAD constructor
624 Optionally accepts a string containing a SL definition of the AAD
625 or a ContentObject version of the AAD
626 """
627
628 self.name = None
629 self.ownership = None
630 self.state = "active"
631
632 if co:
633 try:
634 self.name = AID.aid(co=co["fipa:aid"])
635 except:
636 self.name = None
637 try:
638 self.ownership = co["fipa:ownership"]
639 except:
640 self.ownership = None
641 try:
642 self.state = co["fipa:state"]
643 except:
644 self.state = None
645 elif content != None:
646 self.loadSL0(content)
647
649 """
650 sets the AID class
651 """
652 self.name = copy.copy(a)
653
655 """
656 returns the AID class
657 """
658 return self.name
659
661 """
662 sets the ownership
663 """
664 self.ownership = str(owner)
665
667 """
668 returns the ownership
669 """
670 return self.ownership
671
673 """sets state"""
674 self.state = str(state)
675
677 """
678 returns the state of the agent
679 """
680 return self.state
681
683 """
684 returns True if y is part of the AAD
685 """
686 if self.name != None and y.getAID() != None and (not self.name.match(y.getAID())):
687 return False
688 if self.ownership != None and y.getOwnership() != None and not (y.getOwnership().lower() in self.ownership.lower()):
689 return False
690 if self.state != None and y.getState() != None and not (y.getState().lower() in self.state.lower()):
691 return False
692
693 return True
694
695
697 """
698 equal operator (==)
699 returns False if the AADs are different
700 else returns True
701 """
702
703 if not self.name == y.getAID() \
704 and self.name != None and y.getAID() != None:
705 return False
706 if self.ownership!= y.getOwnership() \
707 and self.ownership != None and y.getOwnership() != None:
708 return False
709 if self.state != y.getState() \
710 and self.state != None and y.getState() != None:
711 return False
712
713 return True
714
716 """
717 non equal operator (!=)
718 returns True if the AADs are different
719 else returns False
720 """
721 return not self == y
722
723
738
739 - def asContentObject(self):
740 """
741 returns a version of the AAD in ContentObject format
742 """
743 co = ContentObject()
744 try:
745 co["fipa:aid"] = self.name.asContentObject()
746 except:
747 co["fipa:aid"] = ContentObject()
748 co["fipa:ownership"] = str(self.ownership)
749 co["fipa:state"] = str(self.state)
750 return co
751
752
754 """
755 returns a printable version of the AAD in RDF/XML format
756 """
757 return str(self.asContentObject())
758
760 """
761 returns a printable version of the AAD in SL format
762 """
763
764 if ( (self.name == None) and (self.ownership == None) and (self.state == None) ):
765 return "None"
766 sb = "(ams-agent-description\n"
767 if (self.name != None):
768 sb = sb + ":name " + str(self.name) + "\n"
769
770 if self.ownership != None:
771 sb += ":ownership " + self.ownership +"\n"
772
773 if self.state != None:
774 sb += ":state " + str(self.state)
775
776 sb = sb + ")\n"
777 return sb
778