View Javadoc

1   /**
2    *
3    * Copyright 2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.geronimo.jmxremoting;
18  
19  import java.net.InetSocketAddress;
20  import java.util.HashMap;
21  import java.util.Map;
22  import javax.management.remote.JMXConnectorServer;
23  import javax.management.remote.JMXConnectorServerFactory;
24  import javax.management.remote.JMXServiceURL;
25  import javax.management.remote.JMXConnectionNotification;
26  import javax.management.MBeanServer;
27  import javax.management.NotificationFilterSupport;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.apache.geronimo.gbean.GBeanInfo;
32  import org.apache.geronimo.gbean.GBeanInfoBuilder;
33  import org.apache.geronimo.gbean.GBeanLifecycle;
34  import org.apache.geronimo.system.jmx.MBeanServerReference;
35  
36  /**
37   * A Connector that supports the server sideof JSR 160 JMX Remoting.
38   *
39   * @version $Rev: 395155 $ $Date: 2006-04-18 23:44:24 -0700 (Tue, 18 Apr 2006) $
40   */
41  public class JMXConnector implements GBeanLifecycle {
42      private final MBeanServer mbeanServer;
43      private final Log log;
44      private final ClassLoader classLoader;
45      private String applicationConfigName;
46      private Authenticator authenticator;
47  
48      private String protocol;
49      private String host;
50      private int port = -1;
51      private String urlPath;
52  
53      private JMXConnectorServer server;
54      private JMXServiceURL jmxServiceURL;
55  
56      // todo remove this as soon as Geronimo supports factory beans
57      public JMXConnector(MBeanServerReference mbeanServerReference, String objectName, ClassLoader classLoader) {
58          this(mbeanServerReference.getMBeanServer(), objectName, classLoader);
59      }
60  
61      /**
62       * Constructor for creating the connector. The ClassLoader must be
63       * able to load all the LoginModules used in the JAAS login
64       *
65       * @param mbeanServer the mbean server
66       * @param objectName this connector's object name
67       * @param classLoader the classLoader used to create this connector
68       */
69      public JMXConnector(MBeanServer mbeanServer, String objectName, ClassLoader classLoader) {
70          this.mbeanServer = mbeanServer;
71          this.classLoader = classLoader;
72          log = LogFactory.getLog(objectName);
73      }
74  
75      /**
76       * Return the name of the JAAS Application Configuration Entry this
77       * connector uses to authenticate users. If null, users are not
78       * be authenticated (not recommended).
79       *
80       * @return the authentication configuration name
81       */
82      public String getApplicationConfigName() {
83          return applicationConfigName;
84      }
85  
86      /**
87       * Set the name of the JAAS Application Configuration Entry this
88       * connector should use to authenticate users. If null, users will not
89       * be authenticated (not recommended).
90       *
91       * @param applicationConfigName the authentication configuration name
92       */
93      public void setApplicationConfigName(String applicationConfigName) {
94          this.applicationConfigName = applicationConfigName;
95      }
96  
97      /**
98       * Every connector must specify a property of type InetSocketAddress
99       * because we use that to identify the network services to print a list
100      * during startup.  However, this can be read-only since the host and port
101      * are set in the url attribute.
102      */
103     public InetSocketAddress getListenAddress() {
104         return new InetSocketAddress(getHost(), getPort());
105     }
106 
107     /**
108      * Gets the protocol to use for the connection.
109      * @return the protocol to use for the connection
110      */
111     public String getProtocol() {
112         return protocol;
113     }
114 
115     /**
116      * Sets the protocol to use for the connection.
117      * @param protocol the protocol to use for the connection
118      */
119     public void setProtocol(String protocol) {
120         this.protocol = protocol;
121     }
122 
123     /**
124      * Gets the JMX host for this connector.
125      *
126      * @return the JMX host for this connector
127      */
128     public String getHost() {
129         return host;
130     }
131 
132     /**
133      * Sets the JMX host for this connector.
134      * @param host the JMX host for this connector
135      */
136     public void setHost(String host) {
137         this.host = host;
138     }
139 
140     /**
141      * Gets the JMX port for this connector.
142      *
143      * @return the JMX port for this connector
144      */
145     public int getPort() {
146         return port;
147     }
148 
149     /**
150      * Sets the JMX port for this connector.
151      * @param port the JMX port for this connector
152      */
153     public void setPort(int port) {
154         this.port = port;
155     }
156 
157     /**
158      * Gets the path within the target server to look for the connection.  This is commonly
159      * /jndi/rmi://localhost:1099/JMXConnector
160      * @return the path used to loacate the connector on the target server
161      */
162     public String getUrlPath() {
163         return urlPath;
164     }
165 
166     /**
167      * Sets the path within the target server to look for the connection.  This is commonly
168      * /jndi/rmi://localhost:1099/JMXConnector
169      * @param urlPath the path used to loacate the connector on the target server
170      */
171     public void setUrlPath(String urlPath) {
172         this.urlPath = urlPath;
173     }
174 
175     public void doStart() throws Exception {
176         jmxServiceURL = new JMXServiceURL(protocol, host, port, urlPath);
177         Map env = new HashMap();
178         if (applicationConfigName != null) {
179             authenticator = new Authenticator(applicationConfigName, classLoader);
180             env.put(JMXConnectorServer.AUTHENTICATOR, authenticator);
181         } else {
182             log.warn("Starting unauthenticating JMXConnector for " + jmxServiceURL);
183         }
184         server = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, env, mbeanServer);
185         NotificationFilterSupport filter = new NotificationFilterSupport();
186         filter.enableType(JMXConnectionNotification.OPENED);
187         filter.enableType(JMXConnectionNotification.CLOSED);
188         filter.enableType(JMXConnectionNotification.FAILED);
189         server.addNotificationListener(authenticator, filter, null);
190         server.start();
191         log.debug("Started JMXConnector " + server.getAddress());
192     }
193 
194     public void doStop() throws Exception {
195         try {
196               server.stop();
197         } catch (java.io.IOException e) {
198               // java.io.IOException is expected.
199         } catch (Exception e) {
200               // Otherwise, something bad happened.  Rethrow the exception.
201               throw e;
202         }
203         finally {
204           server = null;
205           log.debug("Stopped JMXConnector " + jmxServiceURL);
206         }
207     }
208 
209     public void doFail() {
210         try {
211             doStop();
212             log.warn("Failure in JMXConnector " + jmxServiceURL);
213         } catch (Exception e) {
214             log.warn("Error stopping JMXConnector after failure", e);
215         }
216     }
217 
218     public static final GBeanInfo GBEAN_INFO;
219 
220     static {
221         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("JMX Remoting Connector", JMXConnector.class);
222         infoFactory.addReference("MBeanServerReference", MBeanServerReference.class);
223         infoFactory.addAttribute("objectName", String.class, false);
224         infoFactory.addAttribute("classLoader", ClassLoader.class, false);
225 
226         infoFactory.addAttribute("protocol", String.class, true, true);
227         infoFactory.addAttribute("host", String.class, true, true);
228         infoFactory.addAttribute("port", int.class, true, true);
229         infoFactory.addAttribute("urlPath", String.class, true, true);
230         infoFactory.addAttribute("applicationConfigName", String.class, true, true);
231 
232         infoFactory.setConstructor(new String[]{"MBeanServerReference", "objectName", "classLoader"});
233         GBEAN_INFO = infoFactory.getBeanInfo();
234     }
235 
236     public static GBeanInfo getGBeanInfo() {
237         return GBEAN_INFO;
238     }
239 }