1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package zeus.agents;
22 import zeus.actors.*;
23 import zeus.concepts.*;
24 import zeus.util.GenSym;
25 import java.net.*;
26 import java.util.*;
27 import JADE_SL.*;
28 import JADE_SL.lang.sl.*;
29 import JADE_SL.abs.*;
30 import JADE_SL.onto.basic.*;
31 import zeus.util.*;
32
33 /***
34 * FIPA_DF_Services is used by the ACC agent to wrap the Facilitator
35 * so that it can be accessed exernally.
36 *
37 *This class was tested against the Agentcities test suit, http://leap.crm-paris.com/agentcities/Services/Testsuite.jsp
38 *
39 */
40 public class FIPA_DF_Services extends FIPA_Services {
41
42 private String NOT_AUTHORISED = "not authorised";
43 private String UNEXPECTED = "zeus didn't expect that";
44 private GenSym rand = new GenSym("df");
45
46
47 String hack = new String(" (set (df-agent-description :name (agent-identifier :name pingagent@adastralcity.agentcities.net) :services (set (service-description :name ping :type ping_acl_alpha_v1.0 )) :protocol FIPA-Request :ontology Agentcities :language Ping :ownership //\"Simon//\") ");
48
49
50 private Hashtable registered_agents = new Hashtable();
51
52
53 private Hashtable registered_dfs = new Hashtable();
54 private SLCodec codec = new SLCodec();
55 String ABILITY_KEY = "ACC_FIPA_DF_KEY";
56 String SERVICE_KEY = "ACC_DAMLS_KEY";
57 public void exec(AgentContext context) {
58 this.context = context;
59 this.type = new String("df");
60 debug("trying registration");
61 registerAlias(this.type);
62 setName();
63 setRegister();
64 setDeregister();
65 setModify();
66 setSearch();
67
68
69
70 String[] serviceDesc = {"type","inform", "content","//A(.*)daml(.*)//Z","in-reply-to",SERVICE_KEY};
71 context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"), serviceDesc,this,"serviceDescriptionReceived"));
72 }
73
74
75
76
77
78 private String getServiceName(Performative msg) {
79
80 String type;
81
82 String description = msg.getContent();
83 String serviceDir = SystemProps.getProperty("http_root");
84
85 if(description.indexOf("<service:serviceProfile ") > 0) {
86 type = "Profile";
87 }
88 else if(description.indexOf("<service:Service") > 0 &&
89 description.indexOf("<service:presents") > 0) {
90 type = "Instance";
91 }
92 else {
93 System.out.println("Unknown type of description");
94 return ("unknown");
95 }
96
97 int nameBegin = description.indexOf("service:serviceProfile ");
98 nameBegin = description.indexOf("rdf:ID", nameBegin);
99 nameBegin = description.indexOf("\"", nameBegin) + 1;
100
101 int nameEnd = description.indexOf("\"", nameBegin);
102
103 String name = description.substring(nameBegin, nameEnd);
104 return name;
105
106 }
107
108 /***
109 *this is a message that is likely to have the name of the task in it
110 */
111 public void serviceDescriptionReceived(Performative perf) {
112 System.out.println("GOT SERVICE DESCRIPTION!!!!");
113
114 String agent = perf.getSender();
115 DF_Description desc = new DF_Description();
116 Vector language = new Vector();
117 language.addElement("FIPA-SL");
118 language.addElement("Zeus");
119 desc.setLanguage(language);
120 Vector protocols = new Vector();
121 protocols.addElement("FIPA-Inform-Protocol");
122 protocols.addElement("FIPA-Request-Protocol");
123 protocols.addElement("FIPA-Iterated-ContractNet-Protocol");
124 desc.setProtocol(protocols);
125 Vector ontos = new Vector();
126 ontos.addElement("agentcities");
127 desc.setOntology(ontos);
128 Address addr = context.getMailBox().getAddress();
129 String host = addr.getHost();
130 desc.setName(new FIPA_AID_Address (perf.getSender(), host ));
131 FIPA_Service_Description service = new FIPA_Service_Description();
132 service.setOwnership(agent);
133 service.setType("Backward-Chain-Task");
134 String sname = getServiceName(perf);
135 System.out.println("sname = " + sname);
136 if (!sname.equals("Profile")) {
137 service.setName(sname);
138 protocols = new Vector();
139 protocols.addElement("FIPA-Iterated-ContractNet-Protocol");
140 service.setProtocol(protocols);
141 service.setLanguage(language);
142 service.setOntology(ontos);
143 Vector props = new Vector();
144 String content = perf.getContent();
145
146 String classification = new String();
147 String domain = "Leisure";
148 String scope = "Local";
149 if (sname == "BookTable") classification ="Restaurant";
150 if (sname == "BookTicket") classification = "Entertainment";
151 if (sname == "BookRoom") classification = "Hotel";
152 service.setAgentcitiesProperties(classification,domain,scope);
153 if (!inServiceList(agent+sname)) {
154 System.out.println("sname " + sname +" not in service list");
155 desc.addService(service);
156 addServiceList(agent+sname);
157 System.out.println("sname "+ sname +" added to service list");
158 String key = agent+sname;
159 registered_agents.put(key,desc);
160 }
161 else{
162 System.out.println("sname " + sname + "was in service list");
163
164 }
165 }
166
167 }
168 Hashtable serviceList = new Hashtable();
169
170 private void addServiceList(String name) {
171
172 serviceList.put(name,name);
173 }
174
175
176 private boolean inServiceList(String name) {
177 return (serviceList.containsValue(name));
178 }
179
180 /***
181 *the problem is to get the name of the task and to register it
182 *here
183 *Perhaps we this should be triggered by the second message?
184 */
185 public void abilityReceived(Performative perf) {
186 System.out.println("ADDING SERVICES");
187 Vector List = ZeusParser.abilitySpecList(context.OntologyDb(),perf.getContent());
188 String agent = perf.getSender();
189 DF_Description desc = new DF_Description();
190 Vector language = new Vector();
191 language.addElement("FIPA-SL");
192 language.addElement("Zeus");
193 desc.setLanguage(language);
194 Vector protocols = new Vector();
195 protocols.addElement("FIPA-Inform-Protocol");
196 protocols.addElement("FIPA-Request-Protocol");
197 protocols.addElement("FIPA-Iterated-ContractNet-Protocol");
198 desc.setProtocol(protocols);
199 Vector ontos = new Vector();
200 ontos.addElement("agentcities");
201 desc.setOntology(ontos);
202
203 FIPA_Service_Description service = new FIPA_Service_Description();
204 service.setOwnership(agent);
205 service.setType("Backward-Chain-Task");
206 service.setName(rand.newId(perf.getSender()));
207 protocols = new Vector();
208 protocols.addElement("FIPA-Iterated-ContractNet-Protocol");
209 service.setProtocol(protocols);
210 service.setLanguage(language);
211 service.setOntology(ontos);
212 Vector props = new Vector();
213 String content = perf.getContent();
214 AbilitySpec spec = ZeusParser.abilitySpec(context.getOntologyDb(), content);
215 props.addElement(spec.getFact().toSL());
216
217
218 service.setAgentcitiesProperties("none","none","none");
219 desc.addService(service);
220
221 String key = rand.newId();
222 registered_agents.put(key,desc);
223 }
224
225
226 /***
227 * method for handleing a registration message to the df
228 */
229 public void handleRegister(Performative perf) {
230 try {
231
232 String content = perf.getContent();
233 String agreeCont = new String(content);
234 AbsContentElement slcontent = codec.decode(SLOntology.getInstance(),content);
235 AbsAgentAction act = (AbsAgentAction) slcontent.getAbsObject("ACTION");
236
237
238 if (act != null) {
239 if (act.getTypeName().equalsIgnoreCase("register")) {
240 sendAgree(perf);
241 }
242 else {
243 simpleReply(perf,UNEXPECTED,"not_understood");
244 }
245 }
246 AbsConcept absActor = (AbsConcept) slcontent.getAbsObject("ACTOR");
247 AbsAggregate agentAddresses = (AbsAggregate) absActor.getAbsObject("addresses");
248 AbsPrimitive agentName = (AbsPrimitive) absActor.getAbsObject("name");
249 String addr = SL_Util.makeAddressString(agentName,agentAddresses);
250 boolean proceed = checkAuthority("df", agentName, agentAddresses, perf);
251 if (!proceed) {
252 simpleReply(perf, NOT_AUTHORISED,"refuse");
253 }
254
255 if (agentName.getString().equals("df")) {
256 registered_dfs.put(addr, makeDescription(act));
257 }
258 else {
259 registered_agents.put(addr, makeDescription(act));}
260 informDone(perf);
261 } catch (Exception e) {
262 e.printStackTrace();
263 }
264 }
265
266
267
268
269
270 public DF_Description makeDescription(AbsConcept act) {
271 try {
272 AbsConcept target_descr = (AbsConcept) act.getAbsObject("_SL.UNNAMED0");
273 AbsConcept desName = (AbsConcept) target_descr.getAbsObject("name");
274 AbsPrimitive targName = (AbsPrimitive) desName.getAbsObject("name");
275 AbsAggregate targAddresses = (AbsAggregate) desName.getAbsObject("addresses");
276 FIPA_AID_Address agent = new FIPA_AID_Address(SL_Util.makeAddressString(targName, targAddresses));
277 AbsAggregate targLanguage = (AbsAggregate) target_descr.getAbsObject("language");
278 AbsAggregate targProtocol = (AbsAggregate) target_descr.getAbsObject("protocol");
279 AbsAggregate targOntology = (AbsAggregate) target_descr.getAbsObject("ontology");
280 AbsAggregate targServices = (AbsAggregate) target_descr.getAbsObject("services");
281 DF_Description desc = new DF_Description();
282 desc.setName(agent);
283 desc.setLanguage(SL_Util.makeVector(targLanguage));
284 desc.setProtocol(SL_Util.makeVector(targProtocol));
285 desc.setOntology(SL_Util.makeVector(targOntology));
286
287 Iterator iter = (targServices).iterator();
288 while (iter.hasNext()) {
289 AbsConcept current = (AbsConcept) iter.next();
290 FIPA_Service_Description service = new FIPA_Service_Description(current);
291 desc.addService(service);
292 }
293 return (desc);}
294 catch (Exception e) {
295
296 return (null);
297 }
298
299 }
300
301
302
303 public boolean checkAuthority(String agent, AbsPrimitive attempter, AbsAggregate attempterAddresses, Performative perf) {
304 return true;
305 }
306
307
308 public void handleDeregister(Performative perf) {
309 debug("handleDeregister in df called");
310 try {
311
312 String content = perf.getContent();
313 String agreeCont = new String(content);
314 AbsContentElement slcontent = codec.decode(SLOntology.getInstance(),content);
315 AbsAgentAction act = (AbsAgentAction) slcontent.getAbsObject("ACTION");
316
317
318 if (act != null) {
319 if (act.getTypeName().equalsIgnoreCase("deregister")) {
320 sendAgree(perf);
321 }
322 else {
323 simpleReply(perf,UNEXPECTED,"not_understood");
324 }
325 }
326 String name = new String();
327 AbsConcept absActor = (AbsConcept) slcontent.getAbsObject("ACTOR");
328 AbsAggregate agentAddresses = (AbsAggregate) absActor.getAbsObject("addresses");
329 AbsPrimitive agentName = (AbsPrimitive) absActor.getAbsObject("name");
330 boolean proceed = checkAuthority("df", agentName, agentAddresses, perf);
331 if (!proceed) {
332 simpleReply(perf, NOT_AUTHORISED,"refuse");
333 }
334 String searchAddr = SL_Util.makeAddressString(agentName,agentAddresses);
335 Enumeration allAddresses = registered_agents.keys();
336 while (allAddresses.hasMoreElements()) {
337 String current = (String) allAddresses.nextElement();
338 if (current.equals(searchAddr)) {
339 registered_agents.remove(current);
340 informDone(perf);
341 return;
342 }
343 }
344 } catch (Exception e) {
345 e.printStackTrace();
346 }
347 }
348
349
350
351
352
353
354 public void handleModify(Performative perf) {
355 debug("handleModify in df called");
356 try {
357
358 String content = perf.getContent();
359 String agreeCont = new String(content);
360 AbsContentElement slcontent = codec.decode(SLOntology.getInstance(),content);
361 AbsAgentAction act = (AbsAgentAction) slcontent.getAbsObject("ACTION");
362 if (act != null) {
363 if (act.getTypeName().equalsIgnoreCase("modify")) {
364 AbsConcept absActor = (AbsConcept) slcontent.getAbsObject("ACTOR");
365 AbsAggregate agentAddresses = (AbsAggregate) absActor.getAbsObject("addresses");
366 AbsPrimitive agentName = (AbsPrimitive) absActor.getAbsObject("name");
367 String searchAddr = SL_Util.makeAddressString(agentName,agentAddresses);
368 Enumeration allAddresses = registered_agents.keys();
369 while (allAddresses.hasMoreElements()) {
370 String current = (String) allAddresses.nextElement();
371 if (current.equals(searchAddr)) {
372 registered_agents.remove(current);
373 registered_agents.put(searchAddr, makeDescription(act));
374 informDone(perf);
375 return;
376 }
377 }}
378 else {
379 simpleReply(perf,UNEXPECTED,"not_understood");
380 }
381 }
382 } catch (Exception e ) {
383 e.printStackTrace();
384 }
385 }
386
387
388
389
390 public void handleSearch(Performative perf) {
391 try {
392 debug("In handle search");
393 Enumeration members = registered_agents.elements();
394 String content = perf.getContent();
395 debug("content = " + content);
396 AbsContentElement slcontent = codec.decode(SLOntology.getInstance(),content);
397 AbsAgentAction act = (AbsAgentAction) slcontent.getAbsObject("ACTION");
398
399 if (act != null) {
400 System.out.println("not a null action");
401 if (act.getTypeName().equalsIgnoreCase("search")) {
402 System.out.println("action is search");
403 sendAgree(perf);
404
405 }
406 else {
407 System.out.println("was not a search!");
408 simpleReply(perf,UNEXPECTED,"not_understood");
409 }
410 }
411 else {
412 System.out.println("was a null action!"); }
413 if (!registered_dfs.isEmpty()) {
414 Enumeration allDfs = registered_dfs.keys();
415 while (allDfs.hasMoreElements()) {
416
417
418
419 }
420 }
421 DF_Description toMatch = makeDescription(act);
422 String results = getDescriptions(toMatch);
423 Performative inform = new Performative("inform");
424 inform.setSender("df");
425 inform.setReceiver(perf.getSender());
426 inform.setLanguage("FIPA-SL0");
427 inform.setProtocol("FIPA-Request");
428 inform.setOntology("FIPA-Agent-Management");
429 inform.setConversationId(perf.getConversationId());
430 inform.setInReplyTo(perf.getReplyWith());
431 String in = perf.getContent();
432 String rcontent = new String("((result "+ in.substring(1,in.length()-1) + " (set " );
433 rcontent += results;
434 rcontent+= ")))";
435 inform.setContent(rcontent);
436 inform.send(context);
437 }
438 catch (Exception e) {
439 e.printStackTrace() ;
440 }
441 }
442
443 /***
444 *returns a string that contains the df_descriptions that are matches for this df_description.
445 */
446 public String getDescriptions(DF_Description toMatch) {
447 Enumeration allDescriptions = registered_agents.elements();
448 String results = new String();
449
450 if (toMatch != null) {
451 while (allDescriptions.hasMoreElements()) {
452 DF_Description desc = (DF_Description) allDescriptions.nextElement();
453 if (toMatch.match(desc)) {
454 results+=desc.toString() +" ";
455 }}
456 }
457
458 else {
459 while (allDescriptions.hasMoreElements()) {
460 DF_Description desc = (DF_Description) allDescriptions.nextElement();
461 results+=desc.toString() +" ";
462 }
463 }
464 return results;
465 }
466
467
468
469
470 public String agentDescToSL(Fact fact) {
471 return new String();
472 }
473
474
475 public void informDone(Performative perf) {
476 String content = perf.getContent();
477 Performative inform = new Performative("inform");
478 inform.setSender("df");
479 inform.setReceiver(perf.getSender());
480 inform.setLanguage("FIPA-SL0");
481 inform.setProtocol("FIPA-Request");
482 inform.setOntology("FIPA-Agent-Management");
483 inform.setConversationId(perf.getConversationId());
484 inform.setInReplyTo(perf.getReplyWith());
485 inform.setContent("(done" + content + ")");
486 send(inform);
487 }
488
489 /***
490 * simpleReply lets you reply to a message using the result convention of FIPA
491 * what I mean is: in FIPA there are alot of messages like "refuse original reason"
492 * or "not_understood original reason", and this method lets you send them
493 * pretty simply
494 **/
495 public void simpleReply(Performative inPerf, String reason, String replyType) {
496 Performative outPerf = new Performative(replyType);
497 outPerf.setReceiver(inPerf.getSender());
498 outPerf.setSender("df");
499 outPerf.setLanguage("FIPA-SL0");
500 outPerf.setProtocol("FIPA-Request");
501 outPerf.setOntology("FIPA-Agent-Management");
502 outPerf.setConversationId(inPerf.getConversationId());
503 outPerf.setInReplyTo(inPerf.getReplyWith());
504 String content = inPerf.getContent();
505
506
507 FIPA_DF_Management_Content cont = ZeusParser.FIPA_DF_Management_Content(content);
508 cont.setResult(reason);
509 outPerf.setContent(cont.toString());
510 }
511
512
513 /***
514 *make an "agree" response in SL
515 **/
516 public void sendAgree(Performative perf) {
517 Performative agree = new Performative("agree");
518 agree.setContent( perf.getContent().substring(0,perf.getContent().length() -1)+"true)");
519 agree.setLanguage("FIPA-SL0");
520 agree.setProtocol("FIPA-Request");
521 agree.setOntology("FIPA-Agent-Management");
522 agree.setConversationId(perf.getConversationId());
523 agree.setInReplyTo(perf.getReplyWith());
524 agree.setReceiver(perf.getSender());
525 agree.setSender("df");
526 agree.send(context);
527 }
528
529
530
531 void debug(String str) {
532 System.out.println(str);
533 }
534
535
536 public static void main(String param[]) {
537 Performative perf = new Performative("request");
538 perf.setContent( "((action (agent-identifier :name df@foo.com :addresses (sequence iiop://foo.com/acc)) (search (df-agent-description :ontology (set meeting-scheduler) :language (set FIPA-SL0 KIF) :services (set (service-description :name profiling :type meeting-scheduler-service))) (search-constraints :min-depth 2))))");
539 perf.setSender("Ion");
540 perf.setReceiver("me");
541 FIPA_DF_Services df = new FIPA_DF_Services();
542 df.handleSearch(perf);
543
544 }
545 }