View Javadoc
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.agent.Agent;
12  import org.mule.api.lifecycle.InitialisationException;
13  import org.mule.api.registry.MuleRegistry;
14  import org.mule.api.registry.RegistrationException;
15  import org.mule.util.StringUtils;
16  
17  import java.rmi.server.RMIClientSocketFactory;
18  import java.text.MessageFormat;
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import javax.management.remote.rmi.RMIConnectorServer;
23  
24  public class DefaultJmxSupportAgent extends AbstractAgent
25  {
26  
27      public static final String DEFAULT_HOST = "localhost";
28      public static final String DEFAULT_PORT = "1099";
29  
30      private boolean loadLog4jAgent = true;
31      private boolean loadJdmkAgent = false;
32      private boolean loadMx4jAgent = false;
33      private boolean loadProfilerAgent = false;
34      private String port;
35      private String host;
36      
37      private ConfigurableJMXAuthenticator jmxAuthenticator;
38  
39      public DefaultJmxSupportAgent()
40      {
41          super("jmx-default-config");
42      }
43  
44      /**
45       * Username/password combinations for JMX Remoting
46       * authentication.
47       */
48      private Map<String, String> credentials = new HashMap<String, String>();
49  
50      /**
51       * Should be a 1 line description of the agent
52       *
53       * @return agent description
54       */
55      @Override
56      public String getDescription()
57      {
58          return "Default Jmx Support Agent";
59      }
60  
61      /** {@inheritDoc} */
62      public void start() throws MuleException
63      {
64          // nothing to do
65      }
66  
67      /** {@inheritDoc} */
68      public void stop() throws MuleException
69      {
70          // nothing to do
71      }
72  
73      /**
74       * A lifecycle method where implementor should free up any resources. If an
75       * exception is thrown it should just be logged and processing should continue.
76       * This method should not throw Runtime exceptions.
77       */
78      public void dispose()
79      {
80          // nothing to do
81      }
82  
83      /**
84       * Method used to perform any initialisation work. If a fatal error occurs during
85       * initialisation an <code>InitialisationException</code> should be thrown,
86       * causing the Mule instance to shutdown. If the error is recoverable, say by
87       * retrying to connect, a <code>RecoverableException</code> should be thrown.
88       * There is no guarantee that by throwing a Recoverable exception that the Mule
89       * instance will not shut down.
90       *
91       * @throws org.mule.api.lifecycle.InitialisationException
92       *          if a fatal error occurs
93       *          causing the Mule instance to shutdown
94       */
95      public void initialise() throws InitialisationException
96      {
97          try
98          {
99              Agent agent = createRmiAgent();
100             final MuleRegistry registry = muleContext.getRegistry();
101             if (!isAgentRegistered(agent))
102             {
103                 registry.registerAgent(agent);
104             }
105 
106             // any existing jmx agent will be modified with remote connector settings
107             agent = createJmxAgent();
108             // there must be only one jmx agent, so lookup by type instead
109             if (registry.lookupObject(JmxAgent.class) == null)
110             {
111                 registry.registerAgent(agent);
112             }
113             
114             if (loadLog4jAgent)
115             {
116                 agent = createLog4jAgent();
117                 if (!isAgentRegistered(agent))
118                 {
119                     registry.registerAgent(agent);
120                 }
121             }
122             
123             agent = createJmxNotificationAgent();
124             if (!isAgentRegistered(agent))
125             {
126                 registry.registerAgent(agent);
127             }
128             
129             if (loadJdmkAgent)
130             {
131                 agent = createJdmkAgent();
132                 if (!isAgentRegistered(agent))
133                 {
134                     registry.registerAgent(agent);
135                 }
136             }
137 
138             if (loadMx4jAgent)
139             {
140                 agent = createMx4jAgent();
141                 if (!isAgentRegistered(agent))
142                 {
143                     registry.registerAgent(agent);
144                 }
145             }
146 
147             if (loadProfilerAgent)
148             {
149                 agent = createProfilerAgent();
150                 if (!isAgentRegistered(agent))
151                 {
152                     registry.registerAgent(agent);
153                 }
154             }
155 
156             // remove this agent once it has registered the other agents
157             //TODO RM* this currently does nothing!!!
158             registry.unregisterAgent(name);
159         }
160         catch (MuleException e)
161         {
162             throw new InitialisationException(e, this);
163         }
164     }
165 
166     public JmxAgent createJmxAgent()
167     {
168         JmxAgent agent;
169         try
170         {
171             agent = muleContext.getRegistry().lookupObject(JmxAgent.class);
172             if (agent == null)
173             {
174                 // nothing registered yet
175                 agent = new JmxAgent();
176             }
177         }
178         catch (RegistrationException e)
179         {
180             throw new RuntimeException(e);
181         }
182 
183         // otherwise, just augment an existing jmx agent with remote connector
184 
185         String remotingUri = null;
186         if (StringUtils.isBlank(host) && StringUtils.isBlank(port))
187         {
188             remotingUri = JmxAgent.DEFAULT_REMOTING_URI;
189         }
190         else if (StringUtils.isNotBlank(host))
191         {
192             // enable support for multi-NIC servers by configuring
193             // a custom RMIClientSocketFactory
194             Map<String, Object> props = agent.getConnectorServerProperties();
195             Map<String, Object> mergedProps = new HashMap<String, Object>(props.size() + 1);
196             mergedProps.putAll(props);
197             
198             RMIClientSocketFactory factory = new FixedHostRmiClientSocketFactory(host);
199             mergedProps.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,
200                             factory);
201             agent.setConnectorServerProperties(mergedProps);
202         }
203 
204         // if defaults haven't been used
205         if (StringUtils.isBlank(remotingUri))
206         {
207             remotingUri = MessageFormat.format("service:jmx:rmi:///jndi/rmi://{0}:{1}/server",
208                 StringUtils.defaultString(host, DEFAULT_HOST),
209                 StringUtils.defaultString(port, DEFAULT_PORT));
210         }
211 
212         if (credentials != null && !credentials.isEmpty())
213         {
214             agent.setCredentials(credentials);
215         }
216         agent.setConnectorServerUrl(remotingUri);
217         agent.setJmxAuthenticator(this.jmxAuthenticator);
218         return agent;
219     }
220 
221     protected Log4jAgent createLog4jAgent()
222     {
223         return new Log4jAgent();
224     }
225 
226     protected RmiRegistryAgent createRmiAgent()
227     {
228         final RmiRegistryAgent agent = new RmiRegistryAgent();
229         agent.setHost(StringUtils.defaultString(host, DEFAULT_HOST));
230         agent.setPort(StringUtils.defaultString(port, DEFAULT_PORT));
231         return agent;
232     }
233 
234     protected JmxServerNotificationAgent createJmxNotificationAgent()
235     {
236         return new JmxServerNotificationAgent();
237     }
238 
239     protected Mx4jAgent createMx4jAgent()
240     {
241         return new Mx4jAgent();
242     }
243 
244     protected JdmkAgent createJdmkAgent()
245     {
246         return new JdmkAgent();
247     }
248 
249     protected YourKitProfilerAgent createProfilerAgent()
250     {
251         return new YourKitProfilerAgent();
252     }
253 
254     protected boolean isAgentRegistered(Agent agent)
255     {
256         return muleContext.getRegistry().lookupAgent(agent.getName()) != null;
257     }
258 
259     public boolean isLoadLog4jAgent()
260     {
261         return loadLog4jAgent;
262     }
263 
264     public void setLoadLog4jAgent(boolean loadLog4jAgent)
265     {
266         this.loadLog4jAgent = loadLog4jAgent;
267     }
268 
269     public boolean isLoadJdmkAgent()
270     {
271         return loadJdmkAgent;
272     }
273 
274     public void setLoadJdmkAgent(boolean loadJdmkAgent)
275     {
276         this.loadJdmkAgent = loadJdmkAgent;
277     }
278 
279     public boolean isLoadMx4jAgent()
280     {
281         return loadMx4jAgent;
282     }
283 
284     public void setLoadMx4jAgent(boolean loadMx4jAgent)
285     {
286         this.loadMx4jAgent = loadMx4jAgent;
287     }
288 
289     public boolean isLoadProfilerAgent()
290     {
291         return loadProfilerAgent;
292     }
293 
294     public void setLoadProfilerAgent(boolean loadProfilerAgent)
295     {
296         this.loadProfilerAgent = loadProfilerAgent;
297     }
298 
299     public String getPort()
300     {
301         return port;
302     }
303 
304     public void setPort(final String port)
305     {
306         this.port = port;
307     }
308 
309     public String getHost()
310     {
311         return host;
312     }
313 
314     public void setHost(final String host)
315     {
316         this.host = host;
317     }
318 
319     public void setCredentials(Map<String, String> credentials)
320     {
321         this.credentials = credentials;
322     }
323 
324     public ConfigurableJMXAuthenticator getJmxAuthenticator()
325     {
326         return jmxAuthenticator;
327     }
328 
329     public void setJmxAuthenticator(ConfigurableJMXAuthenticator jmxAuthenticator)
330     {
331         this.jmxAuthenticator = jmxAuthenticator;
332     }
333 }