1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package zeus.agents;
29
30 import java.util.*;
31 import java.io.*;
32
33 import zeus.util.*;
34 import zeus.concepts.*;
35 import zeus.actors.*;
36 import zeus.actors.event.*;
37
38
39
40
41 /***
42 * The implementation of the Zeus Facilitator agent. An agent society can have
43 * any number of facilitators whose role is to provide an ability-identity
44 * look-up service (analogous to the Yellow Pages).
45 *
46 * It is unlikely that users will need to change or call directly any of the
47 * methods of this class.
48 */
49
50 public class Facilitator extends BasicAgent implements Runnable {
51 protected String ABILITY_KEY;
52 public static final String SERVICE_KEY = "ACC_DAMLS_KEY";
53 protected long timeout;
54 protected boolean query_mode = true;
55
56
57 public Facilitator(String name, String file, Vector nameservers) {
58 this(name,file,nameservers,-1);
59 }
60
61 public Facilitator(String name, String filename,
62 Vector nameservers, long user_timeout) {
63 super(SystemProps.getProperty("agent.names.facilitator"),
64 name,nameservers);
65
66 context.set(new OntologyDb(context.GenSym()));
67 new OrganisationDb(context);
68
69 OntologyDb db = context.OntologyDb();
70 int status = db.openFile(new File(filename));
71 if ( (status & OntologyDb.ERROR_MASK) != 0 ) {
72 System.err.println("File I/O Error: " + db.getError());
73 System.exit(0);
74 }
75 else if ( (status & OntologyDb.WARNING_MASK) != 0 ) {
76 System.err.println("Warning: " + db.getWarning());
77 }
78
79 query_mode = (user_timeout != 0);
80 timeout= (long)(60000*SystemProps.getDouble("facilitator.period.default"));
81 if ( user_timeout > 0 )
82 timeout = user_timeout;
83
84
85 Performative msg;
86 Address addr;
87
88 ABILITY_KEY = context.newId();
89 String key = context.newId();
90 String[] pattern1 = { "type", "inform", "in-reply-to", key };
91 String[] pattern2 = { "type", "inform", "in-reply-to", ABILITY_KEY,
92 "content", "//A//(:fact(.*)//Z"};
93
94 String[] serviceProfile = {"type", "inform",
95 "content", "//A.*:serviceProfile.*",
96 "in-reply-to", ABILITY_KEY};
97 String[] serviceInstance = {"type", "inform",
98 "content", "//A.*:serviceInstance.*",
99 "in-reply-to", ABILITY_KEY};
100 String[] serviceRange = {"type", "inform",
101 "content", "//A.*:serviceRange.*",
102 "in-reply-to", ABILITY_KEY};
103 String[] processModel = {"type", "inform",
104 "content", "//A.*:processModel.*",
105 "in-reply-to", ABILITY_KEY};
106
107 context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
108 pattern1,this,"addressReceived")
109 );
110 context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
111 pattern2,this,"abilityReceived")
112 );
113
114
115 /***
116 Object receiver = new ServiceDescriptionReceiver(context);
117
118 context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
119 serviceProfile, receiver,"serviceProfileReceived"));
120 context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
121 serviceInstance, receiver,"serviceInstanceReceived"));
122 context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
123 serviceRange, receiver,"serviceRangeReceived"));
124 context.MsgHandler().addRule(new MessageRuleImpl(context.newId("Rule"),
125 processModel, receiver,"processModelReceived"));
126 */
127 for(int i = 0; i < nameservers.size(); i++ ) {
128 addr = (Address)nameservers.elementAt(i);
129
130 msg = new Performative("subscribe");
131 msg.setReceiver(addr.getName());
132 msg.setReplyWith(key);
133 msg.setContent("log_address");
134 context.MailBox().sendMsg(msg);
135 }
136 if ( query_mode ) new Thread(this).start();
137 }
138
139 /***
140 * addressReceived updates the address book of the facilitator so that
141 *it can send requests for service registrations to an agent
142 */
143 public void addressReceived(Performative msg) {
144 Core.DEBUG(2, "addressReceived: " + msg);
145 Vector List = ZeusParser.addressList(msg.getContent());
146 context.MailBox().add(List);
147 advertise(List);
148
149
150
151 if ( query_mode ) dispatchRequests(List);
152
153 }
154
155 /***
156 *abilityReceived updates the Zeus internal database of the Facilitator for
157 *services that it knows about and can respond to queries about
158 */
159 public void abilityReceived(Performative msg) {
160
161 Core.DEBUG(2, "abilityReceived: " + msg);
162 Vector List = ZeusParser.abilitySpecList(context.OntologyDb(),msg.getContent());
163 String agent = msg.getSender();
164 context.OrganisationDb().add(agent,List);
165 msg.setReceiver("df");
166 msg.setContent(msg.getContent());
167 msg.setInReplyTo("ACC_FIPA_DF_KEY");
168 msg.send(context);
169 }
170
171 protected void dispatchRequests(Vector v) {
172 Performative msg;
173 Address addr;
174 String me = context.whoami();
175 String agent = SystemProps.getProperty("agent.names.agent");
176 for(int i = 0; i < v.size(); i++ ) {
177 addr = (Address)v.elementAt(i);
178 if (!(addr.getName().equals(me)) && addr.getType().equals(agent)) {
179 msg = new Performative("query-ref");
180 msg.setReceiver(addr.getName());
181 msg.setReplyWith(ABILITY_KEY);
182 msg.setContent("your_abilities");
183 context.MailBox().sendMsg(msg);
184 }
185 }
186 }
187
188 protected void advertise(Vector v) {
189 Performative msg;
190 Address addr;
191 String me = context.whoami();
192 String agent = SystemProps.getProperty("agent.names.agent");
193 for(int i = 0; i < v.size(); i++ ) {
194 addr = (Address)v.elementAt(i);
195 if (!(addr.getName().equals(me)) && addr.getType().equals(agent)) {
196 msg = new Performative("inform");
197 msg.setReceiver(addr.getName());
198 msg.setContent("isa_facilitator " + me);
199 context.MailBox().sendMsg(msg);
200 }
201 }
202 }
203
204 public void run() {
205 Thread me = Thread.currentThread();
206 while( true ) {
207 try {
208 me.sleep(timeout);
209 }
210 catch(InterruptedException e) {
211 }
212 Vector List = context.MailBox().listAddresses();
213 dispatchRequests(List);
214 me.yield();
215 }
216 }
217
218 public void addAbilityMonitor(AbilityMonitor monitor, long type) {
219 context.OrganisationDb().addAbilityMonitor(monitor,type);
220 }
221 public void addRelationMonitor(RelationMonitor monitor, long type) {
222 context.OrganisationDb().addRelationMonitor(monitor,type);
223 }
224 public void removeAbilityMonitor(AbilityMonitor monitor, long type) {
225 context.OrganisationDb().removeAbilityMonitor(monitor,type);
226 }
227 public void removeRelationMonitor(RelationMonitor monitor, long type) {
228 context.OrganisationDb().removeRelationMonitor(monitor,type);
229 }
230
231 protected static void version() {
232 System.err.println("Facilitator version: " +
233 SystemProps.getProperty("version.id"));
234 System.exit(0);
235 }
236 protected static void usage() {
237 System.err.println("Usage: java zeus.agents.Facilitator <name> " +
238 "-o <ontology_file> -s <dns_file>] " +
239 "[-t <period>] [-gui ViewerProg] [-e ExternalProg] " +
240 "[-debug] [-v] [-h]");
241 System.exit(0);
242 }
243
244 public static void main(String[] arg) {
245
246
247 try {
248 Class c = Class.forName("java.lang.Object");
249 }
250 catch (ClassNotFoundException cnfe) {
251 System.out.println("Java cannot find java.lang.Object.\n This indicates that the rt.jar file is not in your classpath.\n Ensure that $java_install_dir//jre//rt.jar is present in the classpath and then continue");
252 cnfe.printStackTrace();}
253 try {
254
255 Class c = Class.forName("zeus.gui.help.HelpWindow");
256 }
257 catch (ClassNotFoundException cnfe) {
258 System.out.println("Java cannot find a zeus class.\n This indicates that the zeus.jar file is not in your classpath.\n Ensure that zeus_install_dir//lib//zeus.jar is present in the classpath and then continue");
259 cnfe.printStackTrace();}
260
261
262
263
264
265
266 Vector nameservers = null;
267 String dns_file = null;
268 String recycle_period = null;
269 long timeout = 0;
270 String gui = null;
271 String external = null;
272 String ontology = null;
273
274 if ( arg.length < 5 ) usage();
275 else
276 for( int i = 1; i < arg.length; i++ ) {
277 if ( arg[i].equals("-s") && ++i < arg.length )
278 dns_file = arg[i];
279 else if ( arg[i].equals("-t") && ++i < arg.length )
280 recycle_period = arg[i];
281 else if ( arg[i].equals("-o") && ++i < arg.length )
282 ontology = arg[i];
283 else if ( arg[i].equals("-gui") && ++i < arg.length )
284 gui = arg[i];
285 else if ( arg[i].equals("-e") && ++i < arg.length )
286 external = arg[i];
287 else if ( arg[i].equals("-debug") ) {
288 Core.debug = true;
289 Core.setDebuggerOutputFile(arg[0] + ".log");
290 }
291 else if ( arg[i].equals("-h") )
292 usage();
293 else if ( arg[i].equals("-v") )
294 version();
295 else
296 usage();
297 }
298
299 if ( ontology == null ) {
300 System.err.println("Ontology Database file must be specified with -o option");
301 usage();
302 }
303 if ( dns_file == null ) {
304 System.err.println("Domain nameserver file must be specified with -s option");
305 usage();
306 }
307
308 try {
309 nameservers = ZeusParser.addressList(new FileInputStream(dns_file));
310 if ( nameservers == null || nameservers.isEmpty() )
311 throw new IOException();
312
313 if ( recycle_period != null ) {
314 double d = (Double.valueOf(recycle_period)).doubleValue();
315 timeout = (long)(d*60000);
316 }
317
318 Facilitator f = new Facilitator(arg[0],ontology,nameservers,timeout);
319
320 Class c;
321 AgentContext context = f.getAgentContext();
322
323 if ( gui != null ) {
324 c = Class.forName(gui);
325 BasicAgentUI ui = (BasicAgentUI) c.newInstance();
326 context.set(ui);
327 ui.set(context);
328 }
329
330 if ( external != null ) {
331 c = Class.forName(external);
332 ZeusExternal user_prog = (ZeusExternal)c.newInstance();
333 context.set(user_prog);
334 user_prog.exec(context);
335 }
336
337
338
339 }
340 catch (Exception e) {
341 e.printStackTrace();
342 System.exit(0);
343 }
344 }
345 }