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