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