View Javadoc

1   /*
2    * $Id: Mx4jAgent.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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  
11  package org.mule.management.agents;
12  
13  import org.mule.MuleManager;
14  import org.mule.config.i18n.CoreMessages;
15  import org.mule.management.support.AutoDiscoveryJmxSupportFactory;
16  import org.mule.management.support.JmxSupport;
17  import org.mule.management.support.JmxSupportFactory;
18  import org.mule.umo.UMOException;
19  import org.mule.umo.lifecycle.InitialisationException;
20  import org.mule.umo.manager.UMOAgent;
21  import org.mule.util.BeanUtils;
22  import org.mule.util.ClassUtils;
23  import org.mule.util.StringUtils;
24  import org.mule.util.SystemUtils;
25  
26  import java.net.URI;
27  import java.util.HashMap;
28  import java.util.Map;
29  
30  import javax.management.InstanceNotFoundException;
31  import javax.management.MBeanException;
32  import javax.management.MBeanRegistrationException;
33  import javax.management.MBeanServer;
34  import javax.management.MBeanServerFactory;
35  import javax.management.MalformedObjectNameException;
36  import javax.management.ObjectName;
37  import javax.management.ReflectionException;
38  
39  import mx4j.log.CommonsLogger;
40  import mx4j.log.Log;
41  import mx4j.tools.adaptor.http.HttpAdaptor;
42  import mx4j.tools.adaptor.http.XSLTProcessor;
43  import mx4j.tools.adaptor.ssl.SSLAdaptorServerSocketFactory;
44  import mx4j.tools.adaptor.ssl.SSLAdaptorServerSocketFactoryMBean;
45  import org.apache.commons.logging.LogFactory;
46  
47  /**
48   * <code>Mx4jAgent</code> configures an Mx4J Http Adaptor for Jmx management,
49   * statistics and configuration viewing of a Mule instance.
50   * <p/>
51   * TODO MULE-1353
52   */
53  public class Mx4jAgent implements UMOAgent
54  {
55      public static final String HTTP_ADAPTER_OBJECT_NAME = "name=Mx4jHttpAdapter";
56  
57      protected static final String DEFAULT_PATH_IN_JAR = StringUtils.replaceChars(ClassUtils.getPackageName(Mx4jAgent.class), '.', '/') +
58                                                          "/http/xsl";
59  
60      private static final org.apache.commons.logging.Log logger = LogFactory.getLog(Mx4jAgent.class);
61  
62      private static final String PROTOCOL_PREFIX = "http://";
63      public static final String DEFAULT_HOSTNAME = "localhost";
64      public static final int DEFAULT_PORT = 9999;
65      public static final String DEFAULT_JMX_ADAPTOR_URL = PROTOCOL_PREFIX + DEFAULT_HOSTNAME + ":" + DEFAULT_PORT;
66  
67      private String jmxAdaptorUrl;
68      private String host;
69      private String port;
70  
71      private String name = "MX4J Agent";
72  
73      private HttpAdaptor adaptor;
74      private MBeanServer mBeanServer;
75      private ObjectName adaptorName;
76  
77      // Adaptor overrides
78      private String login;
79  
80      private String password;
81  
82      private String authenticationMethod = "basic";
83  
84      // TODO AH check how an embedded scenario can be handled (no mule home) 
85      private String xslFilePath = System.getProperty("mule.home") + "/lib/mule/mule-module-management-" +
86              MuleManager.getConfiguration().getProductVersion() + ".jar";
87  
88      private String pathInJar = DEFAULT_PATH_IN_JAR;
89  
90      private boolean cacheXsl = true;
91  
92      // SSL/TLS socket factory config
93      private Map socketFactoryProperties = new HashMap();
94  
95      private JmxSupportFactory jmxSupportFactory = AutoDiscoveryJmxSupportFactory.getInstance();
96      private JmxSupport jmxSupport = jmxSupportFactory.getJmxSupport();
97  
98      protected HttpAdaptor createAdaptor() throws Exception
99      {
100 
101         Log.redirectTo(new CommonsLogger());
102         URI uri = new URI(StringUtils.stripToEmpty(jmxAdaptorUrl));
103         adaptor = new HttpAdaptor(uri.getPort(), uri.getHost());
104 
105         // Set the XSLT Processor with any local overrides
106         XSLTProcessor processor = new XSLTProcessor();
107 
108         if (StringUtils.isNotBlank(xslFilePath))
109         {
110             processor.setFile(xslFilePath.trim());
111         }
112 
113         if (StringUtils.isNotBlank(pathInJar))
114         {
115             processor.setPathInJar(pathInJar.trim());
116         }
117 
118         processor.setUseCache(cacheXsl);
119 
120         adaptor.setProcessor(processor);
121 
122         // Set endpoint authentication if required
123         if (login != null)
124         {
125             adaptor.addAuthorization(login, password);
126             adaptor.setAuthenticationMethod(authenticationMethod);
127         }
128 
129         if (socketFactoryProperties != null && !socketFactoryProperties.isEmpty())
130         {
131             SSLAdaptorServerSocketFactoryMBean factory;
132             if (SystemUtils.isIbmJDK())
133             {
134                 factory = new IBMSslAdapterServerSocketFactory();
135             }
136             else
137             {
138                 // BEA are using Sun's JSSE, so no extra checks necessary
139                 factory = new SSLAdaptorServerSocketFactory();
140             }
141             BeanUtils.populateWithoutFail(factory, socketFactoryProperties, true);
142             adaptor.setSocketFactory(factory);
143         }
144 
145         return adaptor;
146     }
147 
148     /* @see org.mule.umo.lifecycle.Initialisable#initialise() */
149     public void initialise() throws InitialisationException
150     {
151         try
152         {
153             mBeanServer = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
154 
155             if (StringUtils.isBlank(jmxAdaptorUrl))
156             {
157                 if (StringUtils.isNotBlank(host) && StringUtils.isNotBlank(port))
158                 {
159                     jmxAdaptorUrl = PROTOCOL_PREFIX + host + ":" + port;
160                 }
161                 else
162                 {
163                     jmxAdaptorUrl = DEFAULT_JMX_ADAPTOR_URL;
164                 }
165             }
166 
167             adaptor = createAdaptor();
168             adaptorName = jmxSupport.getObjectName(jmxSupport.getDomainName() + ":" + HTTP_ADAPTER_OBJECT_NAME);
169 
170             unregisterMBeansIfNecessary();
171             mBeanServer.registerMBean(adaptor, adaptorName);
172         }
173         catch (Exception e)
174         {
175             throw new InitialisationException(CoreMessages.failedToStart("mx4j agent"), e, this);
176         }
177     }
178 
179     /* @see org.mule.umo.lifecycle.Startable#start() */
180     public void start() throws UMOException
181     {
182         try
183         {
184             mBeanServer.invoke(adaptorName, "start", null, null);
185         }
186         catch (InstanceNotFoundException e)
187         {
188             throw new JmxManagementException(
189                 CoreMessages.failedToStart("Mx4j agent"), adaptorName, e);
190         }
191         catch (MBeanException e)
192         {
193             throw new JmxManagementException(
194                 CoreMessages.failedToStart("Mx4j agent"), adaptorName, e);
195         }
196         catch (ReflectionException e)
197         {
198             // ignore
199         }
200     }
201 
202     /* @see org.mule.umo.lifecycle.Stoppable#stop() */
203     public void stop() throws UMOException
204     {
205         if (mBeanServer == null)
206         {
207             return;
208         }
209         try
210         {
211             mBeanServer.invoke(adaptorName, "stop", null, null);
212         }
213         catch (InstanceNotFoundException e)
214         {
215             throw new JmxManagementException(
216                 CoreMessages.failedToStop("Mx4j agent"), adaptorName, e);
217         }
218         catch (MBeanException e)
219         {
220             throw new JmxManagementException(
221                 CoreMessages.failedToStop("Mx4j agent"), adaptorName, e);
222         }
223         catch (ReflectionException e)
224         {
225             // ignore
226         }
227     }
228 
229     /**
230      * Unregister all Mx4j MBeans if there are any left over the old deployment
231      */
232     protected void unregisterMBeansIfNecessary()
233         throws MalformedObjectNameException, InstanceNotFoundException, MBeanRegistrationException
234     {
235         if (mBeanServer != null && mBeanServer.isRegistered(adaptorName))
236         {
237             mBeanServer.unregisterMBean(adaptorName);
238         }
239     }
240 
241     /* @see org.mule.umo.lifecycle.Disposable#dispose() */
242     public void dispose()
243     {
244         try
245         {
246             stop();
247         }
248         catch (Exception e)
249         {
250             logger.warn("Failed to stop Mx4jAgent: " + e.getMessage());
251         }
252         finally
253         {
254             try
255             {
256                 unregisterMBeansIfNecessary();
257             }
258             catch (Exception e)
259             {
260                 logger.error("Couldn't unregister MBean: "
261                              + (adaptorName != null ? adaptorName.getCanonicalName() : "null"), e);
262             }
263         }
264     }
265 
266     /* @see org.mule.umo.manager.UMOAgent#registered() */
267     public void registered()
268     {
269         // nothing to do
270     }
271 
272     /* @see org.mule.umo.manager.UMOAgent#unregistered() */
273     public void unregistered()
274     {
275         // nothing to do
276     }
277 
278     // /////////////////////////////////////////////////////////////////////////
279     // Getters and setters
280     // /////////////////////////////////////////////////////////////////////////
281 
282     /* @see org.mule.umo.manager.UMOAgent#getDescription() */
283     public String getDescription()
284     {
285         return "MX4J Http adaptor: " + jmxAdaptorUrl;
286     }
287 
288     /* @see org.mule.umo.manager.UMOAgent#getName() */
289     public String getName()
290     {
291         return this.name;
292     }
293 
294     /* @see org.mule.umo.manager.UMOAgent#setName(java.lang.String) */
295     public void setName(String name)
296     {
297         this.name = name;
298     }
299 
300     /** @return Returns the jmxAdaptorUrl. */
301     public String getJmxAdaptorUrl()
302     {
303         return jmxAdaptorUrl;
304     }
305 
306     /** @param jmxAdaptorUrl The jmxAdaptorUrl to set. */
307     public void setJmxAdaptorUrl(String jmxAdaptorUrl)
308     {
309         this.jmxAdaptorUrl = jmxAdaptorUrl;
310     }
311 
312     public Map getSocketFactoryProperties()
313     {
314         return socketFactoryProperties;
315     }
316 
317     public void setSocketFactoryProperties(Map socketFactoryProperties)
318     {
319         this.socketFactoryProperties = socketFactoryProperties;
320     }
321 
322     public String getLogin()
323     {
324         return login;
325     }
326 
327     public void setLogin(String login)
328     {
329         this.login = login;
330     }
331 
332     public String getPassword()
333     {
334         return password;
335     }
336 
337     public void setPassword(String password)
338     {
339         this.password = password;
340     }
341 
342     public String getAuthenticationMethod()
343     {
344         return authenticationMethod;
345     }
346 
347     public void setAuthenticationMethod(String authenticationMethod)
348     {
349         this.authenticationMethod = authenticationMethod;
350     }
351 
352     public String getXslFilePath()
353     {
354         return xslFilePath;
355     }
356 
357     public void setXslFilePath(String xslFilePath)
358     {
359         this.xslFilePath = xslFilePath;
360     }
361 
362     public String getPathInJar()
363     {
364         return pathInJar;
365     }
366 
367     public void setPathInJar(String pathInJar)
368     {
369         this.pathInJar = pathInJar;
370     }
371 
372     public boolean isCacheXsl()
373     {
374         return cacheXsl;
375     }
376 
377     public void setCacheXsl(boolean cacheXsl)
378     {
379         this.cacheXsl = cacheXsl;
380     }
381 
382 
383     public String getHost()
384     {
385         return host;
386     }
387 
388     public void setHost(String host)
389     {
390         this.host = host;
391     }
392 
393     public String getPort()
394     {
395         return port;
396     }
397 
398     public void setPort(String port)
399     {
400         this.port = port;
401     }
402 }