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