1 package org.jahia.mbeans; 2 3 import java.io.IOException ; 4 import java.io.InputStream ; 5 import java.net.URL ; 6 import java.util.Iterator ; 7 import javax.management.Attribute ; 8 import javax.management.AttributeNotFoundException ; 9 import javax.management.Descriptor ; 10 import javax.management.InstanceAlreadyExistsException ; 11 import javax.management.InstanceNotFoundException ; 12 import javax.management.InvalidAttributeValueException ; 13 import javax.management.MBeanAttributeInfo ; 14 import javax.management.MBeanConstructorInfo ; 15 import javax.management.MBeanException ; 16 import javax.management.MBeanNotificationInfo ; 17 import javax.management.MBeanOperationInfo ; 18 import javax.management.MBeanRegistrationException ; 19 import javax.management.MBeanServer ; 20 import javax.management.MBeanServerFactory ; 21 import javax.management.MalformedObjectNameException ; 22 import javax.management.NotCompliantMBeanException ; 23 import javax.management.Notification ; 24 import javax.management.NotificationListener ; 25 import javax.management.ObjectInstance ; 26 import javax.management.ObjectName ; 27 import javax.management.ReflectionException ; 28 import javax.management.modelmbean.ModelMBean ; 29 import javax.management.modelmbean.ModelMBeanInfo ; 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 ; 42 import javax.naming.NamingException ; 43 import java.rmi.RemoteException ; 44 import mx4j.adaptor.ssl.SSLAdaptorServerSocketFactoryMBean; 45 import javax.management.modelmbean.InvalidTargetObjectTypeException ; 46 47 55 56 public class JahiaMBeanServer implements NotificationListener { 57 58 59 static final private org.apache.log4j.Logger logger = 60 org.apache.log4j.Logger.getLogger(JahiaMBeanServer.class); 61 62 63 private static JahiaMBeanServer instance; 64 67 private Registry registry = null; 68 69 72 private MBeanServer server = null; 73 74 private SettingsBean settings = null; 75 76 private JahiaMBeanServer () { 77 } 78 79 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 } 100 } 101 102 public void registerManagedInstance (Object managedInstance, 103 String mbeanName, String instanceName) { 104 if (!settings.isJmxActivated()) { 105 return; 106 } 107 String 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 modelMBean = managedBean.createMBean(managedInstance); 114 117 ObjectName name = null; 118 name = new ObjectName (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 mone) { 125 logger.error( 126 "Error in object name, not adding managed instance with mbeanName=" + 127 mbeanName + " to MBean server", mone); 128 } catch (InstanceNotFoundException infe) { 129 logger.error("Instance not found for mbeanName " + mbeanName + 130 ", not adding managed instance to MBean server", infe); 131 } catch (InstanceAlreadyExistsException iaee) { 132 logger.error("This instance with mbeanName " + mbeanName + 133 " already exists in the MBean server, not adding again", iaee); 134 } catch (NotCompliantMBeanException mcmbe) { 135 logger.error( 136 "Trying to add a non-compliant MBean to server, ignoring mbeanName" + 137 mbeanName + " registration", mcmbe); 138 } catch (MBeanException mbe) { 139 logger.error("MBean exception, not registering mbeanName " + 140 mbeanName + " into MBean server", mbe); 141 } catch (InvalidTargetObjectTypeException 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 153 private void createRegistry () { 154 155 logger.debug("Create configuration registry ..."); 156 try { 157 URL url = JahiaMBeanServer.class.getResource 158 ("/mbeans-descriptors.xml"); 159 InputStream stream = url.openStream(); 160 registry = new Registry(); 161 registry.loadDescriptors(stream); 162 stream.close(); 163 } catch (Throwable t) { 164 logger.error("Error while initializing managed bean registry", t); 165 } 166 167 } 168 169 173 private void createServer () { 174 175 logger.debug("Creating MBeanServer ..."); 176 try { 177 server = MBeanServerFactory.createMBeanServer(); 179 } catch (Throwable t) { 180 logger.error("Error while creating MBeanServer", t); 181 } 182 183 } 184 185 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 t) { 200 201 Exception e = t.getTargetException(); 202 if (e == null) 203 e = t; 204 205 logger.error("Error creating MBeans", e); 206 207 } catch (Throwable t) { 208 209 logger.error("Error creating MBeans", t); 210 211 } 212 213 } 214 215 218 private void createMBeans () { 219 220 try { 221 222 228 logger.debug("Creating MBeans ..."); 229 230 String domain = server.getDefaultDomain(); 232 233 Iterator 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 mmService = managedService.createMBean( 239 curService); 240 server.registerMBean(mmService, 243 createName(domain, curService)); 244 } else { 245 managedService = registry.findManagedBean("JahiaService"); 246 if (managedService != null) { 247 ModelMBean mmService = managedService.createMBean( 248 curService); 249 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 cacheNameIte = cacheFactory.getNames().iterator(); 265 while (cacheNameIte.hasNext()) { 266 String curCacheName = (String ) cacheNameIte.next(); 267 Cache curCache = cacheFactory.getCache(curCacheName); 268 ManagedBean managedCache = registry.findManagedBean("Cache"); 269 ModelMBean mmCache = managedCache.createMBean(curCache); 270 server.registerMBean(mmCache, createName(domain, curCache)); 271 } 272 273 ManagedBean managedSettings = registry.findManagedBean("SettingsBean"); 274 ModelMBean 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 t) { 285 286 Exception e = t.getTargetException(); 287 if (e == null) 288 e = t; 289 290 logger.error("Error creating MBeans", e); 291 292 } catch (Throwable t) { 293 294 logger.error("Error creating MBeans", t); 295 296 } 297 298 } 299 300 private void createHttpAdaptor () 301 throws IOException , InstanceAlreadyExistsException , 302 MBeanRegistrationException , NotCompliantMBeanException , 303 MalformedObjectNameException , InstanceNotFoundException , MBeanException , 304 ReflectionException , InvalidAttributeValueException , 305 AttributeNotFoundException { 306 307 logger.debug("Creating an Http protocol adapter"); 308 HttpAdaptor adapter = new HttpAdaptor(); 310 ObjectName name = new ObjectName ("Server:name=HttpAdaptor"); 311 server.registerMBean(adapter, name); 312 adapter.setPort(settings.getJmxHTTPPort()); 313 adapter.setHost(settings.getJmxHTTPHostname()); 314 if (settings.isJmxXSLProcessorActivated()) { 315 ObjectName processorName = new ObjectName ("Server:name=XSLTProcessor"); 316 server.createMBean("mx4j.adaptor.http.XSLTProcessor", processorName, null); 317 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 , NamingException , RemoteException { 352 353 logger.debug("Creating an RMI protocol adapter"); 354 356 SSLAdaptorServerSocketFactoryMBean factory = null; 357 ObjectName ssl = null; 358 if (settings.isJmxRMISSLServerSocketFactoryActivated()) { 359 ssl = new ObjectName ("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 ObjectName naming = new ObjectName ("Naming:type=rmiregistry"); 373 server.createMBean("mx4j.tools.naming.NamingService", naming, null); 374 server.invoke(naming, "start", null, null); 375 376 ObjectName adaptor = new ObjectName ("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 String jndiName = "jrmp"; 384 mbean.setJNDIName(jndiName); 385 391 if (factory != null) { 392 mbean.setSSLFactory(ssl.toString()); 394 } 395 396 mbean.start(); 398 } 399 400 406 private static ObjectName createName (String domain, 407 JahiaService jahiaService) { 408 409 ObjectName name = null; 410 try { 411 name = new ObjectName (domain + ":type=JahiaService,service=" + 412 jahiaService.getServiceName()); 413 416 } catch (Throwable t) { 417 logger.error("Error while creating name for service " + 418 jahiaService.getServiceName(), t); 419 } 420 return (name); 421 422 } 423 424 430 private static ObjectName createName (String domain, 431 Cache cache) { 432 433 ObjectName name = null; 434 try { 435 name = new ObjectName (domain + ":type=Cache,name=" + 436 cache.getName()); 437 440 } catch (Throwable t) { 441 logger.error("Error while creating name for cache " + 442 cache.getName(), t); 443 } 444 return (name); 445 446 } 447 448 454 private static ObjectName createName (String domain, 455 SettingsBean settings) { 456 457 ObjectName name = null; 458 try { 459 name = new ObjectName (domain + ":type=SettingsBean"); 460 } catch (Throwable t) { 461 logger.error("Error while creating name for settings ", t); 462 } 463 return (name); 464 465 } 466 467 473 public void handleNotification (Notification notification, 474 Object handback) { 475 if (!settings.isJmxActivated()) { 476 return; 477 } 478 logger.debug("NOTIFICATION=" + notification + 479 ", HANDBACK=" + handback); 480 481 } 482 483 486 private void dumpServer () { 487 488 try { 489 490 logger.debug("Dump ModelMBeanInfo for JahiaService:"); 491 ObjectName name = 492 new ObjectName (server.getDefaultDomain() + ":type=JahiaService"); 493 494 ModelMBeanInfo info = (ModelMBeanInfo ) server.getMBeanInfo(name); 496 logger.debug(" className=" + info.getClassName()); 497 logger.debug(" description=" + info.getDescription()); 498 logger.debug(" mbeanDescriptor=" + info.getMBeanDescriptor()); 499 MBeanAttributeInfo attrs[] = info.getAttributes(); 500 for (int i = 0; i < attrs.length; i++) 501 logger.debug(" AttributeInfo=" + attrs[i]); 502 MBeanConstructorInfo consts[] = info.getConstructors(); 503 for (int i = 0; i < consts.length; i++) 504 logger.debug(" ConstructorInfo=" + consts[i]); 505 Descriptor descs[] = info.getDescriptors(null); 506 for (int i = 0; i < descs.length; i++) 507 logger.debug(" Descriptor=" + descs[i]); 508 MBeanNotificationInfo notifs[] = info.getNotifications(); 509 for (int i = 0; i < notifs.length; i++) 510 logger.debug(" Notification=" + notifs[i]); 511 MBeanOperationInfo opers[] = info.getOperations(); 512 for (int i = 0; i < opers.length; i++) 513 logger.debug(" Operation=" + opers[i]); 514 515 } catch (MBeanException t) { 516 517 Exception e = t.getTargetException(); 518 if (e == null) 519 e = t; 520 logger.error("Error while dumping server info", e); 521 522 } catch (Throwable t) { 523 524 logger.error("Error while dumping server info", t); 525 526 } 527 528 } 529 530 533 private void listMBeans () { 534 535 logger.debug("There are " + server.getMBeanCount().intValue() + 536 " registered MBeans"); 537 Iterator instances = server.queryMBeans(null, null).iterator(); 538 while (instances.hasNext()) { 539 ObjectInstance instance = (ObjectInstance ) instances.next(); 540 logger.debug(" objectName=" + instance.getObjectName() + 541 ", className=" + instance.getClassName()); 542 } 543 544 } 545 546 549 private void updateServer () { 550 551 try { 552 553 logger.debug("==========================================="); 554 555 logger.debug("Test updating Server properties ..."); 556 ObjectName name = 557 new ObjectName (server.getDefaultDomain() + ":type=Server"); 558 559 logger.debug(" Retrieving current value of 'shutdown'"); 560 String value = (String ) server.getAttribute(name, "shutdown"); 561 if (!"SHUTDOWN".equals(value)) 562 throw new IllegalStateException ("Current shutdown value is '" + 563 value + "'"); 564 565 logger.debug(" Setting new value of 'shutdown'"); 566 server.setAttribute(name, 567 new Attribute ("shutdown", "NEW VALUE")); 568 569 logger.debug(" Checking new value of 'shutdown'"); 570 value = (String ) server.getAttribute(name, "shutdown"); 571 if (!"NEW VALUE".equals(value)) 572 throw new IllegalStateException ("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 ivalue = (Integer ) server.getAttribute(name, "port"); 581 if (ivalue.intValue() != 8005) 582 throw new IllegalStateException ("Current port value is '" + 583 ivalue + "'"); 584 585 logger.debug(" Setting new value of 'port'"); 586 server.setAttribute(name, 587 new Attribute ("port", new Integer (8765))); 588 593 logger.debug(" Checking new value of 'port'"); 594 ivalue = (Integer ) server.getAttribute(name, "port"); 595 if (ivalue.intValue() != 8765) 596 throw new IllegalStateException ("New port value is '" + 597 ivalue + "'"); 598 599 } catch (MBeanException t) { 600 601 Exception e = t.getTargetException(); 602 if (e == null) 603 e = t; 604 logger.error("Error while updating", e); 605 606 } catch (Throwable t) { 607 608 logger.error("Error while updating", t); 609 610 } 611 612 } 613 614 } 615 | Popular Tags |