View Javadoc

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