1
2
3
4
5
6
7 package org.mule.module.management.agent;
8
9 import org.mule.AbstractAgent;
10 import org.mule.api.MuleException;
11 import org.mule.api.MuleRuntimeException;
12 import org.mule.api.context.notification.MuleContextNotificationListener;
13 import org.mule.api.lifecycle.InitialisationException;
14 import org.mule.api.model.Model;
15 import org.mule.api.service.Service;
16 import org.mule.api.transport.Connector;
17 import org.mule.api.transport.MessageReceiver;
18 import org.mule.config.i18n.CoreMessages;
19 import org.mule.construct.AbstractFlowConstruct;
20 import org.mule.context.notification.MuleContextNotification;
21 import org.mule.context.notification.NotificationException;
22 import org.mule.management.stats.FlowConstructStatistics;
23 import org.mule.module.management.i18n.ManagementMessages;
24 import org.mule.module.management.mbean.ApplicationService;
25 import org.mule.module.management.mbean.ConnectorService;
26 import org.mule.module.management.mbean.ConnectorServiceMBean;
27 import org.mule.module.management.mbean.EndpointService;
28 import org.mule.module.management.mbean.EndpointServiceMBean;
29 import org.mule.module.management.mbean.FlowConstructService;
30 import org.mule.module.management.mbean.FlowConstructServiceMBean;
31 import org.mule.module.management.mbean.ModelService;
32 import org.mule.module.management.mbean.ModelServiceMBean;
33 import org.mule.module.management.mbean.MuleConfigurationService;
34 import org.mule.module.management.mbean.MuleConfigurationServiceMBean;
35 import org.mule.module.management.mbean.MuleService;
36 import org.mule.module.management.mbean.MuleServiceMBean;
37 import org.mule.module.management.mbean.ServiceService;
38 import org.mule.module.management.mbean.ServiceServiceMBean;
39 import org.mule.module.management.mbean.StatisticsService;
40 import org.mule.module.management.mbean.StatisticsServiceMBean;
41 import org.mule.module.management.support.AutoDiscoveryJmxSupportFactory;
42 import org.mule.module.management.support.JmxSupport;
43 import org.mule.module.management.support.JmxSupportFactory;
44 import org.mule.module.management.support.SimplePasswordJmxAuthenticator;
45 import org.mule.transport.AbstractConnector;
46 import org.mule.util.StringUtils;
47
48 import java.lang.management.ManagementFactory;
49 import java.net.URI;
50 import java.rmi.RemoteException;
51 import java.rmi.registry.LocateRegistry;
52 import java.rmi.registry.Registry;
53 import java.rmi.server.ExportException;
54 import java.util.Collections;
55 import java.util.HashMap;
56 import java.util.Map;
57 import java.util.Set;
58
59 import javax.management.InstanceAlreadyExistsException;
60 import javax.management.MBeanRegistrationException;
61 import javax.management.MBeanServer;
62 import javax.management.MBeanServerFactory;
63 import javax.management.MalformedObjectNameException;
64 import javax.management.NotCompliantMBeanException;
65 import javax.management.ObjectName;
66 import javax.management.remote.JMXConnectorServer;
67 import javax.management.remote.JMXConnectorServerFactory;
68 import javax.management.remote.JMXServiceURL;
69 import javax.management.remote.rmi.RMIConnectorServer;
70
71 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
72
73 import org.apache.commons.logging.Log;
74 import org.apache.commons.logging.LogFactory;
75
76
77
78
79 public class JmxAgent extends AbstractAgent
80 {
81 public static final String NAME = "jmx-agent";
82
83 public static final String DEFAULT_REMOTING_URI = "service:jmx:rmi:///jndi/rmi://localhost:1099/server";
84
85
86 public static final Map<String, String> DEFAULT_CONNECTOR_SERVER_PROPERTIES;
87
88
89
90
91 public static final String DEFAULT_JMX_AUTHENTICATOR = SimplePasswordJmxAuthenticator.class.getName();
92
93
94
95
96 protected static final Log logger = LogFactory.getLog(JmxAgent.class);
97
98
99
100
101 protected boolean locateServer = true;
102
103 protected boolean containerMode = true;
104
105
106 private boolean createServer = false;
107 private String connectorServerUrl;
108 private MBeanServer mBeanServer;
109 private JMXConnectorServer connectorServer;
110 private Map<String, Object> connectorServerProperties = null;
111 private boolean enableStatistics = true;
112 private final AtomicBoolean serverCreated = new AtomicBoolean(false);
113 private final AtomicBoolean initialized = new AtomicBoolean(false);
114
115 private JmxSupportFactory jmxSupportFactory = AutoDiscoveryJmxSupportFactory.getInstance();
116 private JmxSupport jmxSupport = jmxSupportFactory.getJmxSupport();
117 private ConfigurableJMXAuthenticator jmxAuthenticator;
118
119
120 private Registry rmiRegistry;
121 private boolean createRmiRegistry = true;
122
123
124
125
126 private Map<String, String> credentials = new HashMap<String, String>();
127
128 static
129 {
130 Map<String, String> props = new HashMap<String, String>(1);
131 props.put(RMIConnectorServer.JNDI_REBIND_ATTRIBUTE, "true");
132 DEFAULT_CONNECTOR_SERVER_PROPERTIES = Collections.unmodifiableMap(props);
133 }
134
135 public JmxAgent()
136 {
137 super(NAME);
138 connectorServerProperties = new HashMap<String, Object>(DEFAULT_CONNECTOR_SERVER_PROPERTIES);
139 }
140
141 @Override
142 public String getDescription()
143 {
144 if (connectorServerUrl != null)
145 {
146 return name + ": " + connectorServerUrl;
147 }
148 else
149 {
150 return "JMX Agent";
151 }
152 }
153
154
155
156
157 public void initialise() throws InitialisationException
158 {
159 if (initialized.get())
160 {
161 return;
162 }
163
164 this.containerMode = muleContext.getConfiguration().isContainerMode();
165
166 try
167 {
168 Object agent = muleContext.getRegistry().lookupObject(this.getClass());
169
170 if (agent == this && this.initialized.get())
171 {
172 if (logger.isDebugEnabled())
173 {
174 logger.debug("Found an existing JMX agent in the registry, we're done here.");
175 }
176 return;
177 }
178 }
179 catch (Exception e)
180 {
181 throw new InitialisationException(e, this);
182 }
183
184
185 if (mBeanServer == null && createServer)
186 {
187
188 mBeanServer = MBeanServerFactory.createMBeanServer();
189 serverCreated.set(true);
190 }
191
192 if (mBeanServer == null && locateServer)
193 {
194 mBeanServer = ManagementFactory.getPlatformMBeanServer();
195 }
196
197 if (mBeanServer == null)
198 {
199 throw new InitialisationException(ManagementMessages.cannotLocateOrCreateServer(), this);
200 }
201
202 if (StringUtils.isBlank(muleContext.getConfiguration().getId()))
203 {
204
205 throw new IllegalArgumentException(
206 "Manager ID is mandatory when running with JmxAgent. Give your Mule configuration a valid ID.");
207 }
208
209 try
210 {
211
212 muleContext.registerListener(new MuleContextStartedListener());
213
214 muleContext.registerListener(new MuleContextStoppedListener());
215 }
216 catch (NotificationException e)
217 {
218 throw new InitialisationException(e, this);
219 }
220 initialized.compareAndSet(false, true);
221 }
222
223 protected void initRMI() throws Exception
224 {
225 String connectUri = (connectorServerUrl != null ? connectorServerUrl : StringUtils.EMPTY);
226 if (connectUri.contains("jmx:rmi"))
227 {
228 int i = connectUri.lastIndexOf("rmi://");
229 URI uri = new URI(connectUri.substring(i));
230 if (rmiRegistry == null)
231 {
232 try
233 {
234 if (isCreateRmiRegistry())
235 {
236 try
237 {
238 rmiRegistry = LocateRegistry.createRegistry(uri.getPort());
239 }
240 catch (ExportException e)
241 {
242 logger.info("Registry on " + uri + " already bound. Attempting to use that instead");
243 rmiRegistry = LocateRegistry.getRegistry(uri.getHost(), uri.getPort());
244 }
245 }
246 else
247 {
248 rmiRegistry = LocateRegistry.getRegistry(uri.getHost(), uri.getPort());
249 }
250 }
251 catch (RemoteException e)
252 {
253 throw new InitialisationException(e, this);
254 }
255 }
256 }
257 }
258
259 public void start() throws MuleException
260 {
261 try
262 {
263
264 initRMI();
265 if (connectorServerUrl == null)
266 {
267 return;
268 }
269
270 logger.info("Creating and starting JMX agent connector Server");
271 JMXServiceURL url = new JMXServiceURL(connectorServerUrl);
272 if (connectorServerProperties == null)
273 {
274 connectorServerProperties = new HashMap<String, Object>(DEFAULT_CONNECTOR_SERVER_PROPERTIES);
275 }
276 if (!credentials.isEmpty())
277 {
278 connectorServerProperties.put(JMXConnectorServer.AUTHENTICATOR,
279 this.getJmxAuthenticator());
280 }
281 connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url,
282 connectorServerProperties,
283 mBeanServer);
284 connectorServer.start();
285 }
286 catch (ExportException e)
287 {
288 throw new JmxManagementException(CoreMessages.failedToStart("Jmx Agent"), e);
289 }
290 catch (Exception e)
291 {
292 throw new JmxManagementException(CoreMessages.failedToStart("Jmx Agent"), e);
293 }
294 }
295
296 public void stop() throws MuleException
297 {
298 if (connectorServer != null)
299 {
300 try
301 {
302 connectorServer.stop();
303 }
304 catch (Exception e)
305 {
306 throw new JmxManagementException(CoreMessages.failedToStop("Jmx Connector"), e);
307 }
308 }
309 }
310
311
312
313
314 public void dispose()
315 {
316 unregisterMBeansIfNecessary();
317 if (serverCreated.get())
318 {
319 MBeanServerFactory.releaseMBeanServer(mBeanServer);
320 }
321 mBeanServer = null;
322 serverCreated.compareAndSet(true, false);
323 initialized.set(false);
324 }
325
326
327
328
329
330
331 protected void registerWrapperService() throws MuleException
332 {
333
334 final WrapperManagerAgent wmAgent = new WrapperManagerAgent();
335 if (muleContext.getRegistry().lookupAgent(wmAgent.getName()) == null)
336 {
337 muleContext.getRegistry().registerAgent(wmAgent);
338 }
339 }
340
341 protected void registerStatisticsService() throws NotCompliantMBeanException, MBeanRegistrationException,
342 InstanceAlreadyExistsException, MalformedObjectNameException
343 {
344 ObjectName on = jmxSupport.getObjectName(String.format("%s:%s", jmxSupport.getDomainName(muleContext, !containerMode), StatisticsServiceMBean.DEFAULT_JMX_NAME));
345 StatisticsService service = new StatisticsService();
346 service.setMuleContext(muleContext);
347 service.setEnabled(isEnableStatistics());
348 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, StatisticsServiceMBean.class, muleContext.getExecutionClassLoader());
349 logger.debug("Registering statistics with name: " + on);
350 mBeanServer.registerMBean(mBean, on);
351 }
352
353 protected void registerModelServices() throws NotCompliantMBeanException, MBeanRegistrationException,
354 InstanceAlreadyExistsException, MalformedObjectNameException
355 {
356 for (Model model : muleContext.getRegistry().lookupObjects(Model.class))
357 {
358 ModelServiceMBean service = new ModelService(model);
359 String rawName = service.getName() + "(" + service.getType() + ")";
360 String name = jmxSupport.escape(rawName);
361 final String jmxName = String.format("%s:%s%s", jmxSupport.getDomainName(muleContext, !containerMode), ModelServiceMBean.DEFAULT_JMX_NAME_PREFIX, name);
362 ObjectName on = jmxSupport.getObjectName(jmxName);
363 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, ModelServiceMBean.class, muleContext.getExecutionClassLoader());
364 logger.debug("Registering model with name: " + on);
365 mBeanServer.registerMBean(mBean, on);
366 }
367 }
368
369 protected void registerMuleService() throws NotCompliantMBeanException, MBeanRegistrationException,
370 InstanceAlreadyExistsException, MalformedObjectNameException
371 {
372 ObjectName on = jmxSupport.getObjectName(String.format("%s:%s", jmxSupport.getDomainName(muleContext, !containerMode), MuleServiceMBean.DEFAULT_JMX_NAME));
373 if (muleContext.getConfiguration().isContainerMode() && mBeanServer.isRegistered(on))
374 {
375
376 return;
377 }
378 MuleService service = new MuleService(muleContext);
379 ClassloaderSwitchingMBeanWrapper serviceMBean = new ClassloaderSwitchingMBeanWrapper(service, MuleServiceMBean.class, muleContext.getExecutionClassLoader());
380 logger.debug("Registering mule with name: " + on);
381 mBeanServer.registerMBean(serviceMBean, on);
382 }
383
384 protected void registerConfigurationService() throws NotCompliantMBeanException, MBeanRegistrationException,
385 InstanceAlreadyExistsException, MalformedObjectNameException
386 {
387 ObjectName on = jmxSupport.getObjectName(String.format("%s:%s", jmxSupport.getDomainName(muleContext, !containerMode), MuleConfigurationServiceMBean.DEFAULT_JMX_NAME));
388 MuleConfigurationServiceMBean service = new MuleConfigurationService(muleContext.getConfiguration());
389 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, MuleConfigurationServiceMBean.class, muleContext.getExecutionClassLoader());
390 logger.debug("Registering configuration with name: " + on);
391 mBeanServer.registerMBean(mBean, on);
392 }
393
394 protected void registerServiceServices() throws NotCompliantMBeanException, MBeanRegistrationException,
395 InstanceAlreadyExistsException, MalformedObjectNameException
396 {
397 for (Service service : muleContext.getRegistry().lookupObjects(Service.class))
398 {
399 final String rawName = service.getName();
400 final String escapedName = jmxSupport.escape(rawName);
401 final String jmxName = String.format("%s:%s%s",
402 jmxSupport.getDomainName(muleContext, !containerMode),
403 ServiceServiceMBean.DEFAULT_JMX_NAME_PREFIX, escapedName);
404 ObjectName on = jmxSupport.getObjectName(jmxName);
405
406 ServiceServiceMBean serviceMBean = new ServiceService(rawName, muleContext);
407 ClassloaderSwitchingMBeanWrapper wrapper = new ClassloaderSwitchingMBeanWrapper(serviceMBean, ServiceServiceMBean.class, muleContext.getExecutionClassLoader());
408
409 logger.debug("Registering service with name: " + on);
410 mBeanServer.registerMBean(wrapper, on);
411 }
412 }
413
414 protected void registerFlowConstructServices() throws NotCompliantMBeanException, MBeanRegistrationException,
415 InstanceAlreadyExistsException, MalformedObjectNameException
416 {
417 for (AbstractFlowConstruct flowConstruct : muleContext.getRegistry().lookupObjects(AbstractFlowConstruct.class))
418 {
419 final String rawName = flowConstruct.getName();
420 final String name = jmxSupport.escape(rawName);
421 final String jmxName = String.format("%s:type=%s,name=%s", jmxSupport.getDomainName(muleContext, !containerMode), flowConstruct.getConstructType(), name);
422 ObjectName on = jmxSupport.getObjectName(jmxName);
423 FlowConstructServiceMBean fcMBean = new FlowConstructService(flowConstruct.getConstructType(), rawName, muleContext, flowConstruct.getStatistics());
424 ClassloaderSwitchingMBeanWrapper wrapper = new ClassloaderSwitchingMBeanWrapper(fcMBean, FlowConstructServiceMBean.class, muleContext.getExecutionClassLoader());
425 logger.debug("Registering service with name: " + on);
426 mBeanServer.registerMBean(wrapper, on);
427 }
428 }
429
430 protected void registerApplicationServices() throws NotCompliantMBeanException, MBeanRegistrationException,
431 InstanceAlreadyExistsException, MalformedObjectNameException
432 {
433 FlowConstructStatistics appStats = muleContext.getStatistics().getApplicationStatistics();
434 if (appStats != null)
435 {
436 final String rawName = appStats.getName();
437 final String name = jmxSupport.escape(rawName);
438 final String jmxName = String.format("%s:type=%s,name=%s", jmxSupport.getDomainName(muleContext, !containerMode), appStats.getFlowConstructType(), name);
439 ObjectName on = jmxSupport.getObjectName(jmxName);
440 FlowConstructServiceMBean fcMBean = new ApplicationService(appStats.getFlowConstructType(), rawName, muleContext,appStats);
441 ClassloaderSwitchingMBeanWrapper wrapper = new ClassloaderSwitchingMBeanWrapper(fcMBean, FlowConstructServiceMBean.class, muleContext.getExecutionClassLoader());
442 logger.debug("Registering application statistics with name: " + on);
443 mBeanServer.registerMBean(wrapper, on);
444 }
445 }
446
447 protected void registerEndpointServices() throws NotCompliantMBeanException, MBeanRegistrationException,
448 InstanceAlreadyExistsException, MalformedObjectNameException
449 {
450 for (Connector connector : muleContext.getRegistry().lookupObjects(Connector.class))
451 {
452 if (connector instanceof AbstractConnector)
453 {
454 for (MessageReceiver messageReceiver : ((AbstractConnector) connector).getReceivers().values())
455 {
456 EndpointServiceMBean service = new EndpointService(messageReceiver);
457
458 String fullName = buildFullyQualifiedEndpointName(service, connector);
459 if (logger.isInfoEnabled())
460 {
461 logger.info("Attempting to register service with name: " + fullName);
462 }
463
464 ObjectName on = jmxSupport.getObjectName(fullName);
465 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, EndpointServiceMBean.class, muleContext.getExecutionClassLoader());
466 mBeanServer.registerMBean(mBean, on);
467 if (logger.isInfoEnabled())
468 {
469 logger.info("Registered Endpoint Service with name: " + on);
470 }
471 }
472 }
473 else
474 {
475 logger.warn("Connector: " + connector
476 + " is not an istance of AbstractConnector, cannot obtain Endpoint MBeans from it");
477 }
478 }
479 }
480
481 protected String buildFullyQualifiedEndpointName(EndpointServiceMBean mBean, Connector connector)
482 {
483 String rawName = jmxSupport.escape(mBean.getName());
484
485 StringBuilder fullName = new StringBuilder(128);
486 fullName.append(jmxSupport.getDomainName(muleContext, !containerMode));
487 fullName.append(":type=Endpoint,service=");
488 fullName.append(jmxSupport.escape(mBean.getComponentName()));
489 fullName.append(",connector=");
490 fullName.append(connector.getName());
491 fullName.append(",name=");
492 fullName.append(rawName);
493 return fullName.toString();
494 }
495
496 protected void registerConnectorServices() throws MalformedObjectNameException,
497 NotCompliantMBeanException, MBeanRegistrationException, InstanceAlreadyExistsException
498 {
499 for (Connector connector : muleContext.getRegistry().lookupObjects(Connector.class))
500 {
501 ConnectorServiceMBean service = new ConnectorService(connector);
502 final String rawName = service.getName();
503 final String name = jmxSupport.escape(rawName);
504 final String jmxName = String.format("%s:%s%s", jmxSupport.getDomainName(muleContext, !containerMode), ConnectorServiceMBean.DEFAULT_JMX_NAME_PREFIX, name);
505 if (logger.isDebugEnabled())
506 {
507 logger.debug("Attempting to register service with name: " + jmxName);
508 }
509 ObjectName oName = jmxSupport.getObjectName(jmxName);
510 ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(service, ConnectorServiceMBean.class, muleContext.getExecutionClassLoader());
511 mBeanServer.registerMBean(mBean, oName);
512 logger.info("Registered Connector Service with name " + oName);
513 }
514 }
515
516 public boolean isCreateServer()
517 {
518 return createServer;
519 }
520
521 public void setCreateServer(boolean createServer)
522 {
523 this.createServer = createServer;
524 }
525
526 public boolean isLocateServer()
527 {
528 return locateServer;
529 }
530
531 public void setLocateServer(boolean locateServer)
532 {
533 this.locateServer = locateServer;
534 }
535
536 public String getConnectorServerUrl()
537 {
538 return connectorServerUrl;
539 }
540
541 public void setConnectorServerUrl(String connectorServerUrl)
542 {
543 this.connectorServerUrl = connectorServerUrl;
544 }
545
546 public boolean isEnableStatistics()
547 {
548 return enableStatistics;
549 }
550
551 public void setEnableStatistics(boolean enableStatistics)
552 {
553 this.enableStatistics = enableStatistics;
554 }
555
556 public MBeanServer getMBeanServer()
557 {
558 return mBeanServer;
559 }
560
561 public void setMBeanServer(MBeanServer mBeanServer)
562 {
563 this.mBeanServer = mBeanServer;
564 }
565
566 public Map<String, Object> getConnectorServerProperties()
567 {
568 return connectorServerProperties;
569 }
570
571
572
573
574
575
576
577
578 public void setConnectorServerProperties(Map<String, Object> connectorServerProperties)
579 {
580 this.connectorServerProperties = connectorServerProperties;
581 }
582
583 public JmxSupportFactory getJmxSupportFactory()
584 {
585 return jmxSupportFactory;
586 }
587
588 public void setJmxSupportFactory(JmxSupportFactory jmxSupportFactory)
589 {
590 this.jmxSupportFactory = jmxSupportFactory;
591 }
592
593
594
595
596
597
598
599 public void setCredentials(final Map<String, String> newCredentials)
600 {
601 this.credentials.clear();
602 if (newCredentials != null && !newCredentials.isEmpty())
603 {
604 this.credentials.putAll(newCredentials);
605 }
606 }
607
608 protected void unregisterMBeansIfNecessary()
609 {
610 unregisterMBeansIfNecessary(false);
611 }
612
613
614
615
616 protected void unregisterMBeansIfNecessary(boolean containerMode)
617 {
618 if (mBeanServer == null)
619 {
620 return;
621 }
622
623 try
624 {
625
626
627
628 final String domain = jmxSupport.getDomainName(muleContext, false);
629 ObjectName query = jmxSupport.getObjectName(domain + ":*");
630 Set<ObjectName> mbeans = mBeanServer.queryNames(query, null);
631 while (!mbeans.isEmpty())
632 {
633 ObjectName name = mbeans.iterator().next();
634 try
635 {
636 if (!(containerMode && MuleServiceMBean.DEFAULT_JMX_NAME.equals(name.getCanonicalKeyPropertyListString())))
637 {
638 mBeanServer.unregisterMBean(name);
639 }
640 }
641 catch (Exception e)
642 {
643 logger.warn(String.format("Failed to unregister MBean: %s. Error is: %s", name, e.getMessage()));
644 }
645
646
647
648 mbeans = mBeanServer.queryNames(query, null);
649
650 if (containerMode)
651 {
652
653 mbeans.remove(jmxSupport.getObjectName(String.format("%s:%s", domain, MuleServiceMBean.DEFAULT_JMX_NAME)));
654 }
655 }
656 }
657 catch (MalformedObjectNameException e)
658 {
659 logger.warn("Failed to create ObjectName query", e);
660 }
661 }
662
663 public Registry getRmiRegistry()
664 {
665 return rmiRegistry;
666 }
667
668 public void setRmiRegistry(Registry rmiRegistry)
669 {
670 this.rmiRegistry = rmiRegistry;
671 }
672
673 public boolean isCreateRmiRegistry()
674 {
675 return createRmiRegistry;
676 }
677
678 public void setCreateRmiRegistry(boolean createRmiRegistry)
679 {
680 this.createRmiRegistry = createRmiRegistry;
681 }
682
683 protected class MuleContextStartedListener implements MuleContextNotificationListener<MuleContextNotification>
684 {
685
686 public void onNotification(MuleContextNotification notification)
687 {
688 if (notification.getAction() == MuleContextNotification.CONTEXT_STARTED)
689 {
690 try
691 {
692 registerWrapperService();
693 registerStatisticsService();
694 registerMuleService();
695 registerConfigurationService();
696 registerModelServices();
697 registerServiceServices();
698 registerFlowConstructServices();
699 registerEndpointServices();
700 registerConnectorServices();
701 registerApplicationServices();
702 }
703 catch (Exception e)
704 {
705 throw new MuleRuntimeException(CoreMessages.objectFailedToInitialise("MBeans"), e);
706 }
707 }
708 }
709 }
710
711 protected class MuleContextStoppedListener implements MuleContextNotificationListener<MuleContextNotification>
712 {
713
714 public void onNotification(MuleContextNotification notification)
715 {
716 if (notification.getAction() == MuleContextNotification.CONTEXT_STOPPED)
717 {
718 boolean containerMode = notification.getMuleContext().getConfiguration().isContainerMode();
719 unregisterMBeansIfNecessary(containerMode);
720 }
721 }
722 }
723
724 public ConfigurableJMXAuthenticator getJmxAuthenticator()
725 {
726 if (this.jmxAuthenticator == null)
727 {
728 this.jmxAuthenticator = new SimplePasswordJmxAuthenticator();
729 this.jmxAuthenticator.configure(credentials);
730 }
731 return jmxAuthenticator;
732 }
733
734 public void setJmxAuthenticator(ConfigurableJMXAuthenticator jmxAuthenticator)
735 {
736 this.jmxAuthenticator = jmxAuthenticator;
737 }
738 }