KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > mbeans > JahiaMBeanServer


1 package org.jahia.mbeans;
2
3 import java.io.IOException JavaDoc;
4 import java.io.InputStream JavaDoc;
5 import java.net.URL JavaDoc;
6 import java.util.Iterator JavaDoc;
7 import javax.management.Attribute JavaDoc;
8 import javax.management.AttributeNotFoundException JavaDoc;
9 import javax.management.Descriptor JavaDoc;
10 import javax.management.InstanceAlreadyExistsException JavaDoc;
11 import javax.management.InstanceNotFoundException JavaDoc;
12 import javax.management.InvalidAttributeValueException JavaDoc;
13 import javax.management.MBeanAttributeInfo JavaDoc;
14 import javax.management.MBeanConstructorInfo JavaDoc;
15 import javax.management.MBeanException JavaDoc;
16 import javax.management.MBeanNotificationInfo JavaDoc;
17 import javax.management.MBeanOperationInfo JavaDoc;
18 import javax.management.MBeanRegistrationException JavaDoc;
19 import javax.management.MBeanServer JavaDoc;
20 import javax.management.MBeanServerFactory JavaDoc;
21 import javax.management.MalformedObjectNameException JavaDoc;
22 import javax.management.NotCompliantMBeanException JavaDoc;
23 import javax.management.Notification JavaDoc;
24 import javax.management.NotificationListener JavaDoc;
25 import javax.management.ObjectInstance JavaDoc;
26 import javax.management.ObjectName JavaDoc;
27 import javax.management.ReflectionException JavaDoc;
28 import javax.management.modelmbean.ModelMBean JavaDoc;
29 import javax.management.modelmbean.ModelMBeanInfo JavaDoc;
30
31 import org.apache.commons.modeler.ManagedBean;
32 import org.apache.commons.modeler.Registry;
33 import org.jahia.registries.ServicesRegistry;
34 import org.jahia.services.JahiaService;
35 import org.jahia.services.cache.CacheFactory;
36 import org.jahia.settings.SettingsBean;
37 import mx4j.adaptor.http.HttpAdaptor;
38 import org.jahia.services.cache.Cache;
39 import mx4j.adaptor.rmi.jrmp.JRMPAdaptorMBean;
40 import mx4j.util.StandardMBeanProxy;
41 import javax.management.JMException JavaDoc;
42 import javax.naming.NamingException JavaDoc;
43 import java.rmi.RemoteException JavaDoc;
44 import mx4j.adaptor.ssl.SSLAdaptorServerSocketFactoryMBean;
45 import javax.management.modelmbean.InvalidTargetObjectTypeException JavaDoc;
46
47 /**
48  * <p>Title: </p>
49  * <p>Description: </p>
50  * <p>Copyright: Copyright (c) 2002</p>
51  * <p>Company: Jahia Ltd</p>
52  * @author Serge Huber
53  * @version 1.0
54  */

55
56 public class JahiaMBeanServer implements NotificationListener JavaDoc {
57
58     /** logging */
59     static final private org.apache.log4j.Logger logger =
60         org.apache.log4j.Logger.getLogger(JahiaMBeanServer.class);
61
62     /** class unique instance */
63     private static JahiaMBeanServer instance;
64     /**
65      * The configuration information registry for our managed beans.
66      */

67     private Registry registry = null;
68
69     /**
70      * The <code>MBeanServer</code> for this application.
71      */

72     private MBeanServer JavaDoc server = null;
73
74     private SettingsBean settings = null;
75
76     private JahiaMBeanServer () {
77     }
78
79     /** Return the unique instance of this class.
80      *
81      * @return the class' unique instance.
82      */

83     public static synchronized JahiaMBeanServer getInstance () {
84
85         if (instance == null) {
86             instance = new JahiaMBeanServer();
87         }
88         return instance;
89     }
90
91     public void init(SettingsBean settings) {
92         this.settings = settings;
93         if (settings.isJmxActivated()) {
94             createRegistry();
95             createServer();
96             createAdaptors();
97             // createMBeans();
98
// dumpServer();
99
}
100     }
101
102     public void registerManagedInstance (Object JavaDoc managedInstance,
103                                          String JavaDoc mbeanName, String JavaDoc instanceName) {
104         if (!settings.isJmxActivated()) {
105             return;
106         }
107         // Create the MBean for the top-level Server object
108
String JavaDoc domain = server.getDefaultDomain();
109         logger.debug("Trying to register MBean for instance with mbeanName " + mbeanName);
110         try {
111             ManagedBean managedBean = registry.findManagedBean(mbeanName);
112             if (managedBean != null) {
113                 ModelMBean JavaDoc modelMBean = managedBean.createMBean(managedInstance);
114                 // mm.addAttributeChangeNotificationListener(this, "shutdown", cacheFactory);
115
// mm.addAttributeChangeNotificationListener(this, "port", cacheFactory);
116

117                 ObjectName JavaDoc name = null;
118                 name = new ObjectName JavaDoc(domain + ":type=" + mbeanName + ",name=" + instanceName );
119                 server.registerMBean(modelMBean, name);
120             } else {
121                 logger.warn("ManagedBean " + mbeanName +
122                     " not found in descriptor file, not adding managed instance to MBean server");
123             }
124         } catch (MalformedObjectNameException JavaDoc mone) {
125             logger.error(
126                 "Error in object name, not adding managed instance with mbeanName=" +
127                 mbeanName + " to MBean server", mone);
128         } catch (InstanceNotFoundException JavaDoc infe) {
129             logger.error("Instance not found for mbeanName " + mbeanName +
130                          ", not adding managed instance to MBean server", infe);
131         } catch (InstanceAlreadyExistsException JavaDoc iaee) {
132             logger.error("This instance with mbeanName " + mbeanName +
133                 " already exists in the MBean server, not adding again", iaee);
134         } catch (NotCompliantMBeanException JavaDoc mcmbe) {
135             logger.error(
136                 "Trying to add a non-compliant MBean to server, ignoring mbeanName" +
137                 mbeanName + " registration", mcmbe);
138         } catch (MBeanException JavaDoc mbe) {
139             logger.error("MBean exception, not registering mbeanName " +
140                          mbeanName + " into MBean server", mbe);
141         } catch (InvalidTargetObjectTypeException JavaDoc itote) {
142             logger.error(
143                 "Invalid target object type exception, not registering mbeanName " +
144                 mbeanName + " into MBean server", itote);
145         }
146     }
147
148
149
150     /**
151      * Create and configure the registry of managed objects.
152      */

153     private void createRegistry () {
154
155         logger.debug("Create configuration registry ...");
156         try {
157             URL JavaDoc url = JahiaMBeanServer.class.getResource
158                 ("/mbeans-descriptors.xml");
159             InputStream JavaDoc stream = url.openStream();
160             registry = new Registry();
161             registry.loadDescriptors(stream);
162             stream.close();
163         } catch (Throwable JavaDoc t) {
164             logger.error("Error while initializing managed bean registry", t);
165         }
166
167     }
168
169     /**
170      * Create the <code>MBeanServer</code> with which we will be
171      * registering our <code>ModelMBean</code> implementations.
172      */

173     private void createServer () {
174
175         logger.debug("Creating MBeanServer ...");
176         try {
177             // System.setProperty("LEVEL_TRACE", "true");
178
server = MBeanServerFactory.createMBeanServer();
179         } catch (Throwable JavaDoc t) {
180             logger.error("Error while creating MBeanServer", t);
181         }
182
183     }
184
185     /**
186      * Create the MBeans that correspond to every node of our tree.
187      */

188     private void createAdaptors () {
189
190         try {
191
192             if (settings.isJmxHTTPAdaptorActivated()) {
193                 createHttpAdaptor();
194             }
195             if (settings.isJmxRMIAdaptorActivated()) {
196                 createRMIAdaptor();
197             }
198
199         } catch (MBeanException JavaDoc t) {
200
201             Exception JavaDoc e = t.getTargetException();
202             if (e == null)
203                 e = t;
204
205             logger.error("Error creating MBeans", e);
206
207         } catch (Throwable JavaDoc t) {
208
209             logger.error("Error creating MBeans", t);
210
211         }
212
213     }
214
215     /**
216      * Create the MBeans that correspond to every node of our tree.
217      */

218     private void createMBeans () {
219
220         try {
221
222             // NOTE: JMXRI crashes on server.setAttribute() unless there has
223
// been an attribute change listener registered at some point
224
// on every ModelMBean. :-(
225
// NOTE: Despite the documentation, you cannot register an
226
// attribute change listener for all attributes. :-(
227

228             logger.debug("Creating MBeans ...");
229
230             // Create the MBean for the top-level Server object
231
String JavaDoc domain = server.getDefaultDomain();
232
233             Iterator JavaDoc serviceIterator = ServicesRegistry.getInstance().getRegistry().values().iterator();
234             while (serviceIterator.hasNext()) {
235                 JahiaService curService = (JahiaService) serviceIterator.next();
236                 ManagedBean managedService = registry.findManagedBean(curService.getServiceName());
237                 if (managedService != null) {
238                     ModelMBean JavaDoc mmService = managedService.createMBean(
239                         curService);
240                     // mm.addAttributeChangeNotificationListener(this, "shutdown", cacheFactory);
241
// mm.addAttributeChangeNotificationListener(this, "port", cacheFactory);
242
server.registerMBean(mmService,
243                                          createName(domain, curService));
244                 } else {
245                     managedService = registry.findManagedBean("JahiaService");
246                     if (managedService != null) {
247                         ModelMBean JavaDoc mmService = managedService.createMBean(
248                             curService);
249                         // mm.addAttributeChangeNotificationListener(this, "shutdown", cacheFactory);
250
// mm.addAttributeChangeNotificationListener(this, "port", cacheFactory);
251
server.registerMBean(mmService,
252                                              createName(domain, curService));
253                     } else {
254                         logger.warn(
255                             "Couldn't find descriptor for managed bean with name " +
256                             curService.getServiceName() +
257                             " or JahiaService, not adding to JMX server");
258                     }
259                 }
260             }
261
262             CacheFactory cacheFactory = ServicesRegistry.getInstance().
263                 getJahiaCacheServiceBis();
264             Iterator JavaDoc cacheNameIte = cacheFactory.getNames().iterator();
265             while (cacheNameIte.hasNext()) {
266                 String JavaDoc curCacheName = (String JavaDoc) cacheNameIte.next();
267                 Cache curCache = cacheFactory.getCache(curCacheName);
268                 ManagedBean managedCache = registry.findManagedBean("Cache");
269                 ModelMBean JavaDoc mmCache = managedCache.createMBean(curCache);
270                 server.registerMBean(mmCache, createName(domain, curCache));
271             }
272
273             ManagedBean managedSettings = registry.findManagedBean("SettingsBean");
274             ModelMBean JavaDoc mmSettings = managedSettings.createMBean(settings);
275             server.registerMBean(mmSettings, createName(domain, settings));
276
277             if (settings.isJmxHTTPAdaptorActivated()) {
278                 createHttpAdaptor();
279             }
280             if (settings.isJmxRMIAdaptorActivated()) {
281                 createRMIAdaptor();
282             }
283
284         } catch (MBeanException JavaDoc t) {
285
286             Exception JavaDoc e = t.getTargetException();
287             if (e == null)
288                 e = t;
289
290             logger.error("Error creating MBeans", e);
291
292         } catch (Throwable JavaDoc t) {
293
294             logger.error("Error creating MBeans", t);
295
296         }
297
298     }
299
300     private void createHttpAdaptor ()
301         throws IOException JavaDoc, InstanceAlreadyExistsException JavaDoc,
302         MBeanRegistrationException JavaDoc, NotCompliantMBeanException JavaDoc,
303         MalformedObjectNameException JavaDoc, InstanceNotFoundException JavaDoc, MBeanException JavaDoc,
304         ReflectionException JavaDoc, InvalidAttributeValueException JavaDoc,
305         AttributeNotFoundException JavaDoc {
306
307         logger.debug("Creating an Http protocol adapter");
308         // the following is MX4J specific
309
HttpAdaptor adapter = new HttpAdaptor();
310         ObjectName JavaDoc name = new ObjectName JavaDoc("Server:name=HttpAdaptor");
311         server.registerMBean(adapter, name);
312         adapter.setPort(settings.getJmxHTTPPort());
313         adapter.setHost(settings.getJmxHTTPHostname());
314         if (settings.isJmxXSLProcessorActivated()) {
315             ObjectName JavaDoc processorName = new ObjectName JavaDoc("Server:name=XSLTProcessor");
316             server.createMBean("mx4j.adaptor.http.XSLTProcessor", processorName, null);
317             /*
318             // set it to use a dir
319             server.setAttribute(processorName, new Attribute("File", "/home/tibu/devel/mx4j/src/core/mx4j/adaptor/http/xsl"));
320             // set it to use a compressed file
321             server.setAttribute(processorName, new Attribute("File", "/home/tibu/skins.jar"));
322             // set the target dir
323             server.setAttribute(processorName, new Attribute("PathInJar", "/mx4j/adaptor/http/xsl"));
324             // set not to use cache
325             server.setAttribute(processorName, new Attribute("UseCache", Boolean.FALSE));
326             // set not to use cache
327             server.setAttribute(processorName, new Attribute("LocaleString", "fi"));
328             // adds a mime type
329             server.invoke(processorName, "addMimeType", new Object[] {".pdf", "application/pdf"}, new String[] {"java.lang.String", "java.lang.String"});
330             */

331         }
332
333         if (settings.getJmxHTTPAutorizationMode() != null) {
334             adapter.setAuthenticationMethod(settings.getJmxHTTPAutorizationMode());
335             if ( (settings.getJmxHTTPAuthorizationUser() != null) &&
336                  (settings.getJmxHTTPAuthorizationPassword() != null) ) {
337                 adapter.addAuthorization(settings.getJmxHTTPAuthorizationUser(),
338                                          settings.getJmxHTTPAuthorizationPassword());
339             }
340         }
341         if (settings.getJmxHTTPProcessorNameString() != null) {
342             adapter.setProcessorNameString(settings.getJmxHTTPProcessorNameString());
343         }
344         if (settings.getJmxHTTPSocketFactoryNameString() != null) {
345             adapter.setSocketFactoryNameString(settings.getJmxHTTPSocketFactoryNameString());
346         }
347         adapter.start();
348     }
349
350     private void createRMIAdaptor ()
351         throws JMException JavaDoc, NamingException JavaDoc, RemoteException JavaDoc {
352
353         logger.debug("Creating an RMI protocol adapter");
354         // the following is MX4J specific
355

356         SSLAdaptorServerSocketFactoryMBean factory = null;
357         ObjectName JavaDoc ssl = null;
358         if (settings.isJmxRMISSLServerSocketFactoryActivated()) {
359             // Create the SSL ServerSocket factory
360
ssl = new ObjectName JavaDoc("Adaptor:service=SSLServerSocketFactory");
361             server.createMBean("mx4j.adaptor.ssl.SSLAdaptorServerSocketFactory",
362                                ssl, null);
363             factory = (SSLAdaptorServerSocketFactoryMBean) StandardMBeanProxy.
364                 create(
365                 SSLAdaptorServerSocketFactoryMBean.class, server, ssl);
366             factory.setKeyStoreName(settings.getJmxRMISSLServerSocketFactoryKeyStoreName());
367             factory.setKeyStorePassword(settings.getJmxRMISSLServerSocketFactoryKeyStorePassword());
368             factory.setKeyManagerPassword(settings.getJmxRMISSLServerSocketFactoryKeyManagerPassword());
369         }
370
371         // Create and start the naming service
372
ObjectName JavaDoc naming = new ObjectName JavaDoc("Naming:type=rmiregistry");
373         server.createMBean("mx4j.tools.naming.NamingService", naming, null);
374         server.invoke(naming, "start", null, null);
375
376         // Create the JRMP adaptor
377
ObjectName JavaDoc adaptor = new ObjectName JavaDoc("Adaptor:protocol=JRMP");
378         server.createMBean("mx4j.adaptor.rmi.jrmp.JRMPAdaptor", adaptor, null);
379         JRMPAdaptorMBean mbean = (JRMPAdaptorMBean) StandardMBeanProxy.create(
380             JRMPAdaptorMBean.class, server, adaptor);
381
382         // Set the JNDI name with which will be registered
383
String JavaDoc jndiName = "jrmp";
384         mbean.setJNDIName(jndiName);
385         /*
386               // Optionally, you can specify the JNDI properties,
387               // instead of having in the classpath a jndi.properties file
388               mbean.putJNDIProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
389              mbean.putJNDIProperty(Context.PROVIDER_URL, "rmi://localhost:1099");
390          */

391         if (factory != null) {
392             // Set the SSL ServerSocket Factory
393
mbean.setSSLFactory(ssl.toString());
394         }
395
396         // Registers the JRMP adaptor in JNDI and starts it
397
mbean.start();
398     }
399
400     /**
401      * Create an <code>ObjectName</code> for this object.
402      *
403      * @param domain Domain in which this name is to be created
404      * @param connector The Connector to be named
405      */

406     private static ObjectName JavaDoc createName (String JavaDoc domain,
407                                           JahiaService jahiaService) {
408
409         ObjectName JavaDoc name = null;
410         try {
411             name = new ObjectName JavaDoc(domain + ":type=JahiaService,service=" +
412                                   jahiaService.getServiceName());
413             /*
414             name = new ObjectName(domain + ":type=JahiaService");
415             */

416         } catch (Throwable JavaDoc t) {
417             logger.error("Error while creating name for service " +
418                          jahiaService.getServiceName(), t);
419         }
420         return (name);
421
422     }
423
424     /**
425      * Create an <code>ObjectName</code> for this object.
426      *
427      * @param domain Domain in which this name is to be created
428      * @param connector The Connector to be named
429      */

430     private static ObjectName JavaDoc createName (String JavaDoc domain,
431                                           Cache cache) {
432
433         ObjectName JavaDoc name = null;
434         try {
435             name = new ObjectName JavaDoc(domain + ":type=Cache,name=" +
436                                   cache.getName());
437             /*
438             name = new ObjectName(domain + ":type=JahiaService");
439             */

440         } catch (Throwable JavaDoc t) {
441             logger.error("Error while creating name for cache " +
442                          cache.getName(), t);
443         }
444         return (name);
445
446     }
447
448     /**
449      * Create an <code>ObjectName</code> for this object.
450      *
451      * @param domain Domain in which this name is to be created
452      * @param connector The Connector to be named
453      */

454     private static ObjectName JavaDoc createName (String JavaDoc domain,
455                                           SettingsBean settings) {
456
457         ObjectName JavaDoc name = null;
458         try {
459             name = new ObjectName JavaDoc(domain + ":type=SettingsBean");
460         } catch (Throwable JavaDoc t) {
461             logger.error("Error while creating name for settings ", t);
462         }
463         return (name);
464
465     }
466
467     /**
468      * Handle the notification of a JMX event.
469      *
470      * @param notification The event that has occurred
471      * @param handback The handback object for this event
472      */

473     public void handleNotification (Notification JavaDoc notification,
474                                     Object JavaDoc handback) {
475         if (!settings.isJmxActivated()) {
476             return;
477         }
478         logger.debug("NOTIFICATION=" + notification +
479                      ", HANDBACK=" + handback);
480
481     }
482
483     /**
484      * Dump known information about the "Server" we are managing.
485      */

486     private void dumpServer () {
487
488         try {
489
490             logger.debug("Dump ModelMBeanInfo for JahiaService:");
491             ObjectName JavaDoc name =
492                 new ObjectName JavaDoc(server.getDefaultDomain() + ":type=JahiaService");
493
494             // Return static ModelMBeanInfo information
495
ModelMBeanInfo JavaDoc info = (ModelMBeanInfo JavaDoc) server.getMBeanInfo(name);
496             logger.debug(" className=" + info.getClassName());
497             logger.debug(" description=" + info.getDescription());
498             logger.debug(" mbeanDescriptor=" + info.getMBeanDescriptor());
499             MBeanAttributeInfo JavaDoc attrs[] = info.getAttributes();
500             for (int i = 0; i < attrs.length; i++)
501                 logger.debug(" AttributeInfo=" + attrs[i]);
502             MBeanConstructorInfo JavaDoc consts[] = info.getConstructors();
503             for (int i = 0; i < consts.length; i++)
504                 logger.debug(" ConstructorInfo=" + consts[i]);
505             Descriptor JavaDoc descs[] = info.getDescriptors(null);
506             for (int i = 0; i < descs.length; i++)
507                 logger.debug(" Descriptor=" + descs[i]);
508             MBeanNotificationInfo JavaDoc notifs[] = info.getNotifications();
509             for (int i = 0; i < notifs.length; i++)
510                 logger.debug(" Notification=" + notifs[i]);
511             MBeanOperationInfo JavaDoc opers[] = info.getOperations();
512             for (int i = 0; i < opers.length; i++)
513                 logger.debug(" Operation=" + opers[i]);
514
515         } catch (MBeanException JavaDoc t) {
516
517             Exception JavaDoc e = t.getTargetException();
518             if (e == null)
519                 e = t;
520             logger.error("Error while dumping server info", e);
521
522         } catch (Throwable JavaDoc t) {
523
524             logger.error("Error while dumping server info", t);
525
526         }
527
528     }
529
530     /**
531      * List information about all registered MBeans.
532      */

533     private void listMBeans () {
534
535         logger.debug("There are " + server.getMBeanCount().intValue() +
536                      " registered MBeans");
537         Iterator JavaDoc instances = server.queryMBeans(null, null).iterator();
538         while (instances.hasNext()) {
539             ObjectInstance JavaDoc instance = (ObjectInstance JavaDoc) instances.next();
540             logger.debug(" objectName=" + instance.getObjectName() +
541                          ", className=" + instance.getClassName());
542         }
543
544     }
545
546     /**
547      * Test updating an attribute through the JMX interfaces.
548      */

549     private void updateServer () {
550
551         try {
552
553             logger.debug("===========================================");
554
555             logger.debug("Test updating Server properties ...");
556             ObjectName JavaDoc name =
557                 new ObjectName JavaDoc(server.getDefaultDomain() + ":type=Server");
558
559             logger.debug(" Retrieving current value of 'shutdown'");
560             String JavaDoc value = (String JavaDoc) server.getAttribute(name, "shutdown");
561             if (!"SHUTDOWN".equals(value))
562                 throw new IllegalStateException JavaDoc("Current shutdown value is '" +
563                                                 value + "'");
564
565             logger.debug(" Setting new value of 'shutdown'");
566             server.setAttribute(name,
567                                 new Attribute JavaDoc("shutdown", "NEW VALUE"));
568
569             logger.debug(" Checking new value of 'shutdown'");
570             value = (String JavaDoc) server.getAttribute(name, "shutdown");
571             if (!"NEW VALUE".equals(value))
572                 throw new IllegalStateException JavaDoc("New shutdown value is '" +
573                                                 value + "'");
574
575             logger.debug("===========================================");
576
577             logger.debug("Test updating Server properties ...");
578
579             logger.debug(" Retrieving current value of 'port'");
580             Integer JavaDoc ivalue = (Integer JavaDoc) server.getAttribute(name, "port");
581             if (ivalue.intValue() != 8005)
582                 throw new IllegalStateException JavaDoc("Current port value is '" +
583                                                 ivalue + "'");
584
585             logger.debug(" Setting new value of 'port'");
586             server.setAttribute(name,
587                                 new Attribute JavaDoc("port", new Integer JavaDoc(8765)));
588             /*
589                          server.invoke(name, "setPort",
590                           new Object[] { new java.lang.Integer(8765) },
591                           new String[] { "int" });
592              */

593             logger.debug(" Checking new value of 'port'");
594             ivalue = (Integer JavaDoc) server.getAttribute(name, "port");
595             if (ivalue.intValue() != 8765)
596                 throw new IllegalStateException JavaDoc("New port value is '" +
597                                                 ivalue + "'");
598
599         } catch (MBeanException JavaDoc t) {
600
601             Exception JavaDoc e = t.getTargetException();
602             if (e == null)
603                 e = t;
604             logger.error("Error while updating", e);
605
606         } catch (Throwable JavaDoc t) {
607
608             logger.error("Error while updating", t);
609
610         }
611
612     }
613
614 }
615
Popular Tags