KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > dyade > aaa > agent > AdminProxy


1 /*
2  * Copyright (C) 2001 - 2004 ScalAgent Distributed Technologies
3  * Copyright (C) 1996 - 2000 BULL
4  * Copyright (C) 1996 - 2000 INRIA
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA.
20  */

21 package fr.dyade.aaa.agent;
22
23 import java.io.*;
24 import java.net.*;
25 import java.text.*;
26 import java.util.*;
27 import java.lang.reflect.*;
28
29 import org.objectweb.util.monolog.api.BasicLevel;
30 import org.objectweb.util.monolog.api.Logger;
31
32 import fr.dyade.aaa.util.Daemon;
33 import fr.dyade.aaa.agent.conf.A3CML;
34 import fr.dyade.aaa.agent.conf.A3CMLConfig;
35
36 /**
37  * A <code>AdminProxy</code> service provides an interface to access
38  * to administration functions in running agent servers.
39  * <p>
40  * The <code>AdminProxy</code> service can be configured by the way of
41  * service argument:
42  * the TCP port number, by default this port is 8091.
43  * the number of monitor needed to handled requests.
44  */

45 public class AdminProxy {
46
47   static AdminProxy proxy = null;
48
49   public static boolean debug = true;
50
51   /** Property that define the TCP listen port */
52   public final static String JavaDoc LISTENPORT = "fr.dyade.aaa.agent.AdminProxy.port";
53   /** The TCP listen port */
54   private static int port = 8091;
55   /** The number of monitors.*/
56   private static int nbm;
57   /** Property that define the number of monitor */
58   public final static String JavaDoc NBMONITOR = "fr.dyade.aaa.agent.AdminProxy.nbm";
59   /** Hashtable that contain all <code>Process</code> of running AgentServer */
60 // Hashtable ASP = null;
61

62   AdminMonitor monitors[] = null;
63   ServerSocket listen = null;
64
65   static Logger xlogmon = null;
66
67   /**
68    * Initializes the package as a well known service.
69    * <p>
70    * Creates a <code>AdminProxy</code> proxy listen on .
71    *
72    * @param args parameters from the configuration file
73    * @param firstTime <code>true</code> when service starts anew
74    */

75   public static void init(String JavaDoc args, boolean firstTime) throws Exception JavaDoc {
76     try {
77       if (args.length()!=0) {
78     port = Integer.parseInt(args);
79       } else {
80         port = Integer.parseInt(AgentServer.getProperty(LISTENPORT, "8091"));
81       }
82     } catch (NumberFormatException JavaDoc exc) {
83       port = 8091;
84     }
85
86     try {
87       nbm = Integer.parseInt(AgentServer.getProperty(NBMONITOR, "1"));
88     } catch (NumberFormatException JavaDoc exc) {
89       nbm = 1;
90     }
91
92     // Get the logging monitor from current server MonologMonitorFactory
93
xlogmon = Debug.getLogger(Debug.A3Service + ".AdminProxy" +
94                                ".#" + AgentServer.getServerId());
95
96     if (proxy != null) {
97       xlogmon.log(BasicLevel.ERROR,
98                   "AdminProxy#" + AgentServer.getServerId() +
99                   ": already initialized.");
100       throw new Exception JavaDoc("AdminProxy" + ".#" + AgentServer.getServerId() +
101                           ": already initialized.");
102     }
103
104     try {
105       proxy = new AdminProxy();
106     } catch (IOException exc) {
107       xlogmon.log(BasicLevel.ERROR,
108                   "AdminProxy#" + AgentServer.getServerId() +
109                   ", can't get listen port", exc);
110       throw exc;
111     }
112     start();
113   }
114
115   /**
116    * Creates an AdminProxy service.
117    *
118    * @param port TCP listen port of this proxy
119    */

120   private AdminProxy() throws IOException {
121     for (int i=0; ; i++) {
122       try {
123         listen = new ServerSocket(port);
124         break;
125       } catch (BindException exc) {
126         if (i > 5) throw exc;
127         try {
128       // Wait ~15s: n*(n+1)*500 ms with n=5
129
Thread.sleep(i * 500);
130         } catch (InterruptedException JavaDoc e) {}
131       }
132     }
133
134 // ASP = new Hashtable();
135

136     monitors = new AdminMonitor[nbm];
137     for (int i=0; i<monitors.length; i++) {
138       monitors[i] = new AdminMonitor("AdminProxy#" +
139                                      AgentServer.getServerId() + '.' + i);
140     }
141   }
142
143   public static void start() {
144     for (int i=0; i<proxy.monitors.length; i++) {
145       proxy.monitors[i].start();
146     }
147   }
148
149   public static void stopService() {
150     for (int i=0; i<proxy.monitors.length; i++) {
151       if (proxy.monitors[i] != null) proxy.monitors[i].stop();
152       proxy.monitors[i] = null;
153     }
154     proxy = null;
155   }
156
157   static final String JavaDoc HELP = "help";
158   static final String JavaDoc NONE = "";
159
160   // Server's administration commands
161
public static final String JavaDoc STOP_SERVER = "halt";
162   public static final String JavaDoc CRASH_SERVER = "crash";
163   public static final String JavaDoc PING = "ping";
164   public static final String JavaDoc CONFIG = "config";
165
166   // Environment control
167
static final String JavaDoc SET_VARIABLE = "set";
168   static final String JavaDoc GET_VARIABLE = "get";
169
170   // JVM's monitoring and control
171
static final String JavaDoc GC = "gc";
172   static final String JavaDoc THREADS = "threads";
173
174   // Consumer's administration commands
175
static final String JavaDoc LIST_MCONS = "consumers";
176   static final String JavaDoc START_MCONS = "start";
177   static final String JavaDoc STOP_MCONS = "stop";
178
179   // Service's administration commands
180
static final String JavaDoc LIST_SERVICE = "services";
181   static final String JavaDoc ADD_SERVICE = "add";
182   static final String JavaDoc REMOVE_SERVICE = "remove";
183
184   // Debug's tool
185
static final String JavaDoc DUMP = "dump";
186
187   // update traces configuration
188
public static final String JavaDoc LOG = "log";
189
190   /**
191    * Provides a string image for this object.
192    */

193   public String JavaDoc toString() {
194     StringBuffer JavaDoc strBuf = new StringBuffer JavaDoc();
195
196     strBuf.append("(").append(super.toString());
197     strBuf.append(",port=").append(port);
198     strBuf.append(",monitors=[");
199     for (int i=0; i<monitors.length; i++) {
200       strBuf.append(monitors[i].toString()).append(",");
201     }
202     strBuf.append("]");
203     strBuf.append(")");
204
205     return strBuf.toString();
206   }
207
208   class AdminMonitor extends Daemon {
209     Socket socket = null;
210     BufferedReader reader = null;
211     PrintWriter writer = null;
212
213     /**
214      * Constructor.
215      */

216     protected AdminMonitor(String JavaDoc name) {
217       // Get the logging monitor from AdminProxy (overload Daemon setup)
218
super(name, AdminProxy.xlogmon);
219       this.setThreadGroup(AgentServer.getThreadGroup());
220     }
221
222     /**
223      * Provides a string image for this object.
224      *
225      * @return printable image of this object
226      */

227     public String JavaDoc toString() {
228       return "(" + super.toString() +
229     ",socket=" + socket + ")";
230     }
231
232     public void run() {
233       try {
234         while (running) {
235           canStop = true;
236           try {
237             logmon.log(BasicLevel.DEBUG, getName() + ", waiting: " + listen);
238             socket = listen.accept();
239             logmon.log(BasicLevel.DEBUG, getName() + ", receiving.");
240             canStop = false;
241           } catch (IOException exc) {
242             if (running)
243               logmon.log(BasicLevel.ERROR,
244                          getName() + ", error during accept", exc);
245           }
246
247           if (! running) break;
248
249           try {
250             // Get the streams
251
reader = new BufferedReader(
252               new InputStreamReader(socket.getInputStream()));
253             writer = new PrintWriter(socket.getOutputStream(), true);
254       
255             // Reads then parses the request
256
doRequest(reader.readLine());
257
258             writer.flush();
259           } catch (Exception JavaDoc exc) {
260             logmon.log(BasicLevel.ERROR,
261                        getName() + ", error during connection", exc);
262           } finally {
263             // Closes the connection
264
try {
265               reader.close();
266             } catch (Exception JavaDoc exc) {}
267             reader = null;
268             try {
269               writer.close();
270             } catch (Exception JavaDoc exc) {}
271             writer = null;
272             try {
273               socket.close();
274             } catch (Exception JavaDoc exc) {}
275             socket = null;
276           }
277         }
278       } finally {
279         logmon.log(BasicLevel.DEBUG, getName() + ", finishing.");
280         finish();
281       }
282     }
283
284     protected void close() {
285       try {
286         logmon.log(BasicLevel.DEBUG, getName() + ", closing: " + listen);
287     listen.close();
288       } catch (Exception JavaDoc exc) {}
289       listen = null;
290     }
291
292     protected void shutdown() {
293       logmon.log(BasicLevel.DEBUG, getName() + ", close(): ");
294       close();
295     }
296
297     public void doRequest(String JavaDoc request) {
298       String JavaDoc cmd = null;
299
300       logmon.log(BasicLevel.DEBUG, getName() + ", request=" + request);
301
302       try {
303     // Tokenizes the request to parse it.
304
StringTokenizer st = new StringTokenizer(request);
305
306     cmd = st.nextToken();
307     if (cmd.equals(STOP_SERVER)) {
308           // Stop the AgentServer
309
AgentServer.stop(false);
310           logmon.log(BasicLevel.WARN, getName() + ", bye.");
311     } else if (cmd.equals(CRASH_SERVER)) {
312           // Kill the AgentServer
313
logmon.log(BasicLevel.WARN, getName() + ", crash!");
314       System.exit(0);
315     } else if (cmd.equals(GC)) {
316       Runtime JavaDoc runtime = Runtime.getRuntime();
317       writer.println("before: " +
318              runtime.freeMemory() + " octets free / " +
319              runtime.totalMemory() + " octets.");
320       runtime.gc();
321       writer.println("after: " +
322              runtime.freeMemory() + " octets free / " +
323              runtime.totalMemory() + " octets.");
324     } else if (cmd.equals(SET_VARIABLE)) {
325       try {
326         if (st.countTokens() != 2)
327           throw new Exception JavaDoc("Usage: set property value");
328
329         String JavaDoc property = st.nextToken();
330         String JavaDoc value = st.nextToken();
331
332         // finds variable class and name
333
int pindex = property.lastIndexOf('.');
334         if (pindex == -1) {
335           // bad formed property name, ignores
336
throw new Exception JavaDoc("bad formed property name: " + property);
337         }
338         String JavaDoc varClassName = property.substring(0, pindex);
339         String JavaDoc varName = property.substring(pindex + 1);
340
341         try {
342           // finds variable
343
Class JavaDoc varClass = Class.forName(varClassName);
344           Field var = varClass.getDeclaredField(varName);
345           // sets variable according to its type
346
String JavaDoc varType = var.getType().getName();
347           if (varType.equals("boolean") ||
348           varType.equals("java.lang.Boolean")) {
349         var.set(null, new Boolean JavaDoc(value));
350           } else if (varType.equals("int") ||
351              varType.equals("java.lang.Integer")) {
352         var.set(null, new Integer JavaDoc(value));
353           } else if (varType.equals("java.lang.String")) {
354         var.set(null, value);
355           } else {
356         throw new Exception JavaDoc("error setting property " +
357                     varClassName + "." + varName +
358                     ": unexpected type " + varType);
359           }
360         } catch (Exception JavaDoc exc) {
361           if (debug) exc.printStackTrace(writer);
362           throw new Exception JavaDoc("error setting property " +
363                   varClassName + "." + varName +
364                   ": " + exc.getMessage());
365         }
366         writer.println("done.");
367       } catch (Exception JavaDoc exc) {
368         writer.println(exc.getMessage());
369       }
370     } else if (cmd.equals(GET_VARIABLE)) {
371       try {
372         if (st.countTokens() != 1)
373           throw new Exception JavaDoc("Usage: get property");
374
375         String JavaDoc property = st.nextToken();
376
377         // finds variable class and name
378
int pindex = property.lastIndexOf('.');
379         if (pindex == -1) {
380           // bad formed property name, ignores
381
throw new Exception JavaDoc("bad formed property name: " + property);
382         }
383         String JavaDoc varClassName = property.substring(0, pindex);
384         String JavaDoc varName = property.substring(pindex + 1);
385
386         try {
387           // finds variable
388
Class JavaDoc varClass = Class.forName(varClassName);
389           Field var = varClass.getDeclaredField(varName);
390           // get the variable value
391
Object JavaDoc value = var.get(null);
392           writer.println(property + " = " + value);
393         } catch (Exception JavaDoc exc) {
394           if (debug) exc.printStackTrace(writer);
395           throw new Exception JavaDoc("error getting property " +
396                   varClassName + "." + varName +
397                   ": " + exc.getMessage());
398         }
399       } catch (Exception JavaDoc exc) {
400         writer.println(exc.getMessage());
401       }
402     } else if (cmd.equals(THREADS)) {
403       String JavaDoc group = null;
404       if (st.hasMoreTokens())
405         group = st.nextToken();
406
407       ThreadGroup JavaDoc tg = Thread.currentThread().getThreadGroup();
408       while (tg.getParent() != null)
409         tg = tg.getParent();
410       int nbt = tg.activeCount();
411       Thread JavaDoc[] tab = new Thread JavaDoc[nbt];
412       tg.enumerate(tab);
413
414       for (int j=0; j<nbt; j++) {
415         if ((group != null) &&
416         ! tab[j].getThreadGroup().getName().equals(group))
417           continue;
418         writer.println("+----------------------------------------");
419         writer.println("[" +
420                ((group==null)?(tab[j].getThreadGroup().getName() + "."):"") +
421                tab[j].getName() + "]" +
422                (tab[j].isAlive()?" alive":"") +
423                (tab[j].isDaemon()?" daemon":"") + "\n " +
424                tab[j]);
425       }
426     } else if (cmd.equals(LIST_MCONS)) {
427           for (Enumeration c=AgentServer.getConsumers();
428                c.hasMoreElements(); ) {
429             MessageConsumer cons = (MessageConsumer) c.nextElement();
430         writer.println("+----------------------------------------");
431         writer.println(cons);
432       }
433     } else if (cmd.equals(START_MCONS)) {
434       String JavaDoc domain = null;
435       if (st.hasMoreTokens()) {
436         // start the identified consumer.
437
domain = st.nextToken();
438       }
439           for (Enumeration c=AgentServer.getConsumers();
440                c.hasMoreElements(); ) {
441             MessageConsumer cons = (MessageConsumer) c.nextElement();
442       
443         if (((domain == null) || domain.equals(cons.getName()))) {
444           try {
445         cons.start();
446         writer.println("start " + cons.getName() + " done.");
447           } catch (Exception JavaDoc exc) {
448         writer.println("Can't start "+ cons.getName() + ": " +
449                    exc.getMessage());
450         if (debug) exc.printStackTrace(writer);
451           }
452         }
453       }
454     } else if (cmd.equals(STOP_MCONS)) {
455       String JavaDoc domain = null;
456       if (st.hasMoreTokens()) {
457         // stop the identified consumer.
458
domain = st.nextToken();
459       }
460           for (Enumeration c=AgentServer.getConsumers();
461                c.hasMoreElements(); ) {
462             MessageConsumer cons = (MessageConsumer) c.nextElement();
463       
464         if (((domain == null) || domain.equals(cons.getName()))) {
465           cons.stop();
466           writer.println("stop " + cons.getName() + " done.");
467         }
468       }
469     } else if (cmd.equals(LIST_SERVICE)) {
470       ServiceDesc services[] = ServiceManager.getServices();
471       for (int i=0; i<services.length; i++ ){
472         writer.println("+----------------------------------------");
473         writer.println(services[i].getClassName() + " (" +
474                services[i].getArguments() + ")" +
475                (services[i].isInitialized()?" initialized ":"") +
476                (services[i].isRunning()?" running":""));
477       }
478     } else if (cmd.equals(ADD_SERVICE)) {
479           try {
480             // Add a new Service
481
String JavaDoc sclass = null;
482             String JavaDoc args = null;
483             try {
484               sclass = st.nextToken();
485               if (st.hasMoreTokens())
486                 args = st.nextToken();
487             } catch (NoSuchElementException exc) {
488               throw new Exception JavaDoc("Usage: add <sclass> [<args>]");
489             }
490             try {
491               ServiceManager.register(sclass, args);
492               writer.println("Service <" + sclass + "> registred.");
493               ServiceManager.start(sclass);
494               writer.println("Service <" + sclass + "> started.");
495             } catch (Exception JavaDoc exc) {
496               // Report the error
497
writer.println("Can't start service: " + exc.getMessage());
498               if (debug) exc.printStackTrace(writer);
499             }
500           } catch (Exception JavaDoc exc) {
501             writer.println(exc.getMessage());
502           }
503     } else if (cmd.equals(REMOVE_SERVICE)) {
504       // Remove an existing Service
505
String JavaDoc sclass = null;
506       try {
507         sclass = st.nextToken();
508       } catch (NoSuchElementException exc) {
509         writer.println("Usage: " + REMOVE_SERVICE + " <sclass> [<args>]");
510             return;
511       }
512       try {
513         ServiceManager.stop(sclass);
514         writer.println("Service <" + sclass + "> stopped.");
515       } catch (Exception JavaDoc exc) {
516         writer.println("Can't stop service: " + exc.getMessage());
517         if (debug) exc.printStackTrace(writer);
518       }
519       try {
520         ServiceManager.unregister(sclass);
521         writer.println("Service <" + sclass + "> unregistred.");
522       } catch (Exception JavaDoc exc) {
523         writer.println("Can't unregister service: " + exc.getMessage());
524         if (debug) exc.printStackTrace(writer);
525       }
526     } else if (cmd.equals(DUMP)) {
527           AgentId id = null;
528           try {
529             id = AgentId.fromString(st.nextToken());
530           } catch (IllegalArgumentException JavaDoc exc) {
531             writer.println("Usage: " + DUMP + " #x.y.z");
532             return;
533           }
534           try {
535             writer.println(AgentServer.getEngine().dumpAgent(id));
536           } catch (Exception JavaDoc exc) {
537             writer.println("Can't launch server: " + exc.getMessage());
538             if (debug) exc.printStackTrace(writer);
539           }
540     } else if (cmd.equals(NONE)) {
541     } else if (cmd.equals(PING)) {
542           writer.println(AgentServer.getServerId());
543         } else if (cmd.equals(CONFIG)) {
544           try {
545             A3CMLConfig a3CMLConfig = AgentServer.getConfig();
546             ByteArrayOutputStream baos = new ByteArrayOutputStream();
547             PrintWriter out = new PrintWriter(baos);
548             A3CML.toXML(a3CMLConfig, out);
549             out.flush();
550             baos.flush();
551             baos.close();
552             byte[] bytes = baos.toByteArray();
553             writer.println(new String JavaDoc(bytes));
554           } catch (Exception JavaDoc exc) {
555             writer.println("Can't load configuration: " + exc.getMessage());
556             if (debug) exc.printStackTrace(writer);
557           }
558         } else if (cmd.equals(LOG)){
559           PrintStream oldErr = System.err;
560           try {
561             System.setErr(new PrintStream(socket.getOutputStream()));
562             String JavaDoc topic = st.nextToken();
563             String JavaDoc level = st.nextToken();
564             int intLevel;
565             if (level.equals("DEBUG")) {
566               intLevel = org.objectweb.util.monolog.api.BasicLevel.DEBUG;
567             } else if (level.equals("ERROR")) {
568               intLevel = org.objectweb.util.monolog.api.BasicLevel.ERROR;
569             } else if (level.equals("FATAL")) {
570               intLevel = org.objectweb.util.monolog.api.BasicLevel.FATAL;
571             } else if (level.equals("INFO")) {
572               intLevel = org.objectweb.util.monolog.api.BasicLevel.INFO;
573             } else if (level.equals("INHERIT")) {
574               intLevel = org.objectweb.util.monolog.api.BasicLevel.INHERIT;
575             } else if (level.equals("WARN")) {
576               intLevel = org.objectweb.util.monolog.api.BasicLevel.WARN;
577             } else {
578               writer.println("Unknown level: " + level);
579               return;
580             }
581             Debug.setLoggerLevel(topic, intLevel);
582           } catch(Exception JavaDoc exc){
583             writer.println(exc.getMessage());
584           } finally{
585             System.setErr(oldErr);
586             writer.println("OK");
587           }
588         } else if (cmd.equals(HELP)) {
589       writer.println(
590         "Description of available commands:\n" +
591         "\t" + HELP +
592         "\n\t\tGives the summary of the options.\n" +
593         "\t" + STOP_SERVER +
594         "\n\t\tStops the server.\n" +
595         "\t" + SET_VARIABLE + "variable value" +
596         "\n\t\tSet the specified static variable with the given value.\n" +
597         "\t" + GET_VARIABLE +
598         "\n\t\tReturn the value of the specified static variable.\n" +
599         "\t" + GC +
600         "\n\t\tRun the garbage collector in the specified A3 server.\n" +
601         "\t" + THREADS + " [group]" +
602         "\n\t\tList all threads in server JVM.\n" +
603         "\t" + LIST_MCONS +
604         "\n\t\tList all defined consumers.\n" +
605         "\t" + START_MCONS + " [domain]" +
606         "\n\t\tStarts the specified MessageConsumer.\n" +
607         "\t" + STOP_MCONS + " [domain]" +
608         "\n\t\tStops the specified MessageConsumer.\n" +
609         "\t" + LIST_SERVICE +
610         "\n\t\tList all registered services.\n" +
611         "\t" + ADD_SERVICE + " classname arguments" +
612         "\n\t\tRegisters and starts the specified Service.\n" +
613         "\t" + REMOVE_SERVICE + " classname" +
614         "\n\t\tStops then unregister the specified Service.\n" +
615             "\t" + CONFIG +
616             "\n\t\tReturns the configuration of the server in XML format.\n");
617     } else {
618       writer.println("unknown command:" + cmd);
619     }
620       } finally {
621       }
622     }
623   }
624 }
625
Popular Tags