1   /*
2    * Copyright 1999,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  
18  package org.apache.commons.modeler.demo;
19  
20  
21  import java.io.InputStream;
22  import java.net.URL;
23  import java.util.Iterator;
24  
25  import javax.management.Attribute;
26  import javax.management.Descriptor;
27  import javax.management.MBeanAttributeInfo;
28  import javax.management.MBeanConstructorInfo;
29  import javax.management.MBeanException;
30  import javax.management.MBeanNotificationInfo;
31  import javax.management.MBeanOperationInfo;
32  import javax.management.MBeanServer;
33  import javax.management.MBeanServerFactory;
34  import javax.management.Notification;
35  import javax.management.NotificationListener;
36  import javax.management.ObjectInstance;
37  import javax.management.ObjectName;
38  import javax.management.modelmbean.ModelMBean;
39  import javax.management.modelmbean.ModelMBeanInfo;
40  
41  import org.apache.commons.modeler.ManagedBean;
42  import org.apache.commons.modeler.Registry;
43  
44  
45  /***
46   * <p>Demonstration program for the Modeller package.  Instantiates a set
47   * of simple managed objects, and a set of corresponding MBeans, then
48   * manipulates the objects through the MBean interfaces.
49   *
50   * @author Craig R. McClanahan
51   * @version $Revision: 155428 $ $Date: 2005-02-26 08:12:25 -0500 (Sat, 26 Feb 2005) $
52   */
53  
54  public class Demo implements NotificationListener {
55  
56  
57      // ----------------------------------------------------- Instance Variables
58  
59  
60      // ------------------------------------------------------- Instance Methods
61  
62  
63      /***
64       * Handle the notification of a JMX event.
65       *
66       * @param notification The event that has occurred
67       * @param handback The handback object for this event
68       */
69      public void handleNotification(Notification notification,
70                                     Object handback) {
71  
72          System.out.println("NOTIFICATION=" + notification +
73                             ", HANDBACK=" + handback);
74  
75      }
76  
77  
78      // ------------------------------------------------------- Static Variables
79  
80  
81      /***
82       * The attribute notification listener.
83       */
84      private static Demo demo = null;
85  
86  
87      /***
88       * The configuration information registry for our managed beans.
89       */
90      private static Registry registry = null;
91  
92  
93      /***
94       * The <code>MBeanServer</code> for this application.
95       */
96      private static MBeanServer server = null;
97  
98  
99      /***
100      * The managed object tree.
101      */
102     private static Server tree = null;
103 
104 
105     // ----------------------------------------------------------- Main Program
106 
107 
108     /***
109      * The main program for this demonstration.
110      *
111      * @param args Command line arguments
112      */
113     public static void main(String arg[]) {
114 
115         createRegistry();
116         createServer();
117         createTree();
118         createMBeans();
119         listMBeans();
120         dumpServer();
121         updateServer();
122 
123     }
124 
125 
126     // -------------------------------------------------------- Support Methods
127 
128 
129     /***
130      * Create the MBeans that correspond to every node of our tree.
131      */
132     private static void createMBeans() {
133 
134         try {
135 
136             // NOTE:  JMXRI crashes on server.setAttribute() unless there has
137             // been an attribute change listener registered at some point
138             // on every ModelMBean. :-(
139             // NOTE:  Despite the documentation, you cannot register an
140             // attribute change listener for all attributes.  :-(
141             Demo demo = new Demo();
142 
143             System.out.println("Creating MBeans ...");
144 
145             // Create the MBean for the top-level Server object
146             String domain = server.getDefaultDomain();
147             ManagedBean managed = registry.findManagedBean("StandardServer");
148             ModelMBean mm = managed.createMBean(tree);
149             mm.addAttributeChangeNotificationListener(demo, "shutdown", tree);
150             mm.addAttributeChangeNotificationListener(demo, "port", tree);
151             server.registerMBean(mm, createName(domain, tree));
152 
153             // Create the MBean for each associated Service and friendes
154             Service services[] = tree.findServices();
155             for (int i = 0; i < services.length; i++) {
156 
157                 // The MBean for the Service itself
158                 managed = registry.findManagedBean("StandardService");
159                 mm = managed.createMBean(services[i]);
160                 mm.addAttributeChangeNotificationListener(demo, "name",
161                                                           services[i]);
162                 server.registerMBean(mm, createName(domain, services[i]));
163 
164                 // The MBean for the corresponding Engine
165                 managed = registry.findManagedBean("StandardEngine");
166                 Engine container = (Engine) services[i].getContainer();
167                 mm = managed.createMBean(container);
168                 mm.addAttributeChangeNotificationListener(demo, "name",
169                                                           container);
170                 server.registerMBean(mm, createName(domain, container));
171 
172                 // The MBeans for the corresponding Connectors
173                 managed = registry.findManagedBean("HttpConnector");
174                 Connector connectors[] = services[i].findConnectors();
175                 for (int j = 0; j < connectors.length; j++) {
176                     mm = managed.createMBean(connectors[j]);
177                     mm.addAttributeChangeNotificationListener(demo, "port",
178                                                               connectors[j]);
179                     server.registerMBean
180                         (mm, createName(domain, connectors[j]));
181                 }
182 
183             }
184 
185         } catch (MBeanException t) {
186 
187             Exception e = t.getTargetException();
188             if (e == null)
189                 e = t;
190             System.out.println(e.getMessage());
191             e.printStackTrace(System.out);
192 
193         } catch (Throwable t) {
194 
195             System.out.println(t.getMessage());
196             t.printStackTrace(System.out);
197 
198         }
199 
200     }
201 
202 
203     /***
204      * Create an <code>ObjectName</code> for this object.
205      *
206      * @param domain Domain in which this name is to be created
207      * @param connector The Connector to be named
208      */
209     private static ObjectName createName(String domain, Connector connector) {
210 
211         ObjectName name = null;
212         try {
213             name = new ObjectName(domain + ":type=Connector,port=" +
214                                   connector.getPort() + ",service=" +
215                                   connector.getService().getName());
216         } catch (Throwable t) {
217             System.out.println("Creating name for " + connector);
218             t.printStackTrace(System.out);
219             System.exit(1);
220         }
221         return (name);
222 
223     }
224 
225 
226     /***
227      * Create an <code>ObjectName</code> for this object.
228      *
229      * @param domain Domain in which this name is to be created
230      * @param engine The Engine to be named
231      */
232     private static ObjectName createName(String domain, Engine engine) {
233 
234         ObjectName name = null;
235         try {
236             name = new ObjectName(domain + ":type=Engine,service=" +
237                                   engine.getService().getName());
238         } catch (Throwable t) {
239             System.out.println("Creating name for " + engine);
240             t.printStackTrace(System.out);
241             System.exit(1);
242         }
243         return (name);
244 
245     }
246 
247 
248     /***
249      * Create an <code>ObjectName</code> for this object.
250      *
251      * @param domain Domain in which this name is to be created
252      * @param server The Server to be named
253      */
254     private static ObjectName createName(String domain, Server server) {
255 
256         ObjectName name = null;
257         try {
258             name = new ObjectName(domain + ":type=Server");
259         } catch (Throwable t) {
260             System.out.println("Creating name for " + server);
261             t.printStackTrace(System.out);
262             System.exit(1);
263         }
264         return (name);
265 
266     }
267 
268 
269     /***
270      * Create an <code>ObjectName</code> for this object.
271      *
272      * @param domain Domain in which this name is to be created
273      * @param service The Service to be named
274      */
275     private static ObjectName createName(String domain, Service service) {
276 
277         ObjectName name = null;
278         try {
279             name = new ObjectName(domain + ":type=Service,name=" +
280                                   service.getName());
281         } catch (Throwable t) {
282             System.out.println("Creating name for " + server);
283             t.printStackTrace(System.out);
284             System.exit(1);
285         }
286         return (name);
287 
288     }
289 
290 
291     /***
292      * Create and configure the registry of managed objects.
293      */
294     private static void createRegistry() {
295 
296         System.out.println("Create configuration registry ...");
297         try {
298             URL url = Demo.class.getResource
299                 ("/org/apache/commons/modeler/demo/mbeans-descriptors.xml");
300             InputStream stream = url.openStream();
301             Registry.loadRegistry(stream);
302             stream.close();
303             registry = Registry.getRegistry();
304         } catch (Throwable t) {
305             t.printStackTrace(System.out);
306             System.exit(1);
307         }
308 
309     }
310 
311 
312     /***
313      * Create the <code>MBeanServer</code> with which we will be
314      * registering our <code>ModelMBean</code> implementations.
315      */
316     private static void createServer() {
317 
318         System.out.println("Creating MBeanServer ...");
319         try {
320             //            System.setProperty("LEVEL_TRACE", "true");
321             server = MBeanServerFactory.createMBeanServer();
322         } catch (Throwable t) {
323             t.printStackTrace(System.out);
324             System.exit(1);
325         }
326 
327     }
328 
329 
330     /***
331      * Create the tree of managed objects.
332      */
333     private static void createTree() {
334 
335         System.out.println("Create managed object tree ...");
336         tree = new Server(8005, "SHUTDOWN");
337 
338         Service service = new Service("Standard Service", tree);
339         tree.addService(service);
340 
341         Engine engine = new Engine("Standard Engine", "localhost", service);
342         service.setContainer(engine);
343 
344         Connector conn1 = new Connector(8080, "http", false,
345                                         service, engine);
346         service.addConnector(conn1);
347         Connector conn2 = new Connector(8443, "https", true,
348                                         service, engine);
349         service.addConnector(conn2);
350 
351     }
352 
353 
354     /***
355      * Dump known information about the "Server" we are managing.
356      */
357     private static void dumpServer() {
358 
359         try {
360 
361             System.out.println("Dump ModelMBeanInfo for Server:");
362             ObjectName name =
363                 new ObjectName(server.getDefaultDomain() + ":type=Server");
364 
365             // Return static ModelMBeanInfo information
366             ModelMBeanInfo info = (ModelMBeanInfo) server.getMBeanInfo(name);
367             System.out.println("  className=" + info.getClassName());
368             System.out.println("  description=" + info.getDescription());
369             System.out.println("  mbeanDescriptor=" + info.getMBeanDescriptor());
370             MBeanAttributeInfo attrs[] = info.getAttributes();
371             for (int i = 0; i < attrs.length; i++)
372                 System.out.println("  AttributeInfo=" + attrs[i]);
373             MBeanConstructorInfo consts[] = info.getConstructors();
374             for (int i = 0; i < consts.length; i++)
375                 System.out.println("  ConstructorInfo=" + consts[i]);
376             Descriptor descs[] = info.getDescriptors(null);
377             for (int i = 0; i < descs.length; i++)
378                 System.out.println("  Descriptor=" + descs[i]);
379             MBeanNotificationInfo notifs[] = info.getNotifications();
380             for (int i = 0; i < notifs.length; i++)
381                 System.out.println("  Notification=" + notifs[i]);
382             MBeanOperationInfo opers[] = info.getOperations();
383             for (int i = 0; i < opers.length; i++)
384                 System.out.println("  Operation=" + opers[i]);
385 
386         } catch (MBeanException t) {
387 
388             Exception e = t.getTargetException();
389             if (e == null)
390                 e = t;
391             System.out.println(e.getMessage());
392             e.printStackTrace(System.out);
393 
394         } catch (Throwable t) {
395 
396             System.out.println(t.getMessage());
397             t.printStackTrace(System.out);
398 
399         }
400 
401 
402     }
403 
404 
405     /***
406      * List information about all registered MBeans.
407      */
408     private static void listMBeans() {
409 
410         System.out.println("There are " + server.getMBeanCount().intValue() +
411                            " registered MBeans");
412         Iterator instances = server.queryMBeans(null, null).iterator();
413         while (instances.hasNext()) {
414             ObjectInstance instance = (ObjectInstance) instances.next();
415             System.out.println("  objectName=" + instance.getObjectName() +
416                                ", className=" + instance.getClassName());
417         }
418 
419 
420     }
421 
422 
423     /***
424      * Test updating an attribute through the JMX interfaces.
425      */
426     private static void updateServer() {
427 
428         try {
429 
430             System.out.println("===========================================");
431 
432             System.out.println("Test updating Server properties ...");
433             ObjectName name =
434                 new ObjectName(server.getDefaultDomain() + ":type=Server");
435 
436             System.out.println("  Retrieving current value of 'shutdown'");
437             String value = (String) server.getAttribute(name, "shutdown");
438             if (!"SHUTDOWN".equals(value))
439                 throw new IllegalStateException("Current shutdown value is '" +
440                                                 value + "'");
441 
442             System.out.println("  Setting new value of 'shutdown'");
443             server.setAttribute(name,
444                                 new Attribute("shutdown", "NEW VALUE"));
445 
446             System.out.println("  Checking new value of 'shutdown'");
447             value = (String) server.getAttribute(name, "shutdown");
448             if (!"NEW VALUE".equals(value))
449                 throw new IllegalStateException("New shutdown value is '" +
450                                                 value + "'");
451 
452             System.out.println("===========================================");
453 
454             System.out.println("Test updating Server properties ...");
455 
456             System.out.println("  Retrieving current value of 'port'");
457             Integer ivalue = (Integer) server.getAttribute(name, "port");
458             if (ivalue.intValue() != 8005)
459                 throw new IllegalStateException("Current port value is '" +
460                                                 ivalue + "'");
461 
462             System.out.println("  Setting new value of 'port'");
463             server.setAttribute(name,
464                                 new Attribute("port", new Integer(8765)));
465             /*
466             server.invoke(name, "setPort",
467                           new Object[] { new java.lang.Integer(8765) },
468                           new String[] { "int" });
469 
470             */
471             System.out.println("  Checking new value of 'port'");
472             ivalue = (Integer) server.getAttribute(name, "port");
473             if (ivalue.intValue() != 8765)
474                 throw new IllegalStateException("New port value is '" +
475                                                 ivalue + "'");
476 
477         } catch (MBeanException t) {
478 
479             Exception e = t.getTargetException();
480             if (e == null)
481                 e = t;
482             System.out.println(e.getMessage());
483             e.printStackTrace(System.out);
484 
485         } catch (Throwable t) {
486 
487             System.out.println(t.getMessage());
488             t.printStackTrace(System.out);
489 
490         }
491 
492 
493     }
494 
495 
496 }