001 /**
002 *
003 * Copyright 2004 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.jmxremoting;
018
019 import java.net.InetSocketAddress;
020 import java.util.HashMap;
021 import java.util.Map;
022 import javax.management.remote.JMXConnectorServer;
023 import javax.management.remote.JMXConnectorServerFactory;
024 import javax.management.remote.JMXServiceURL;
025 import javax.management.remote.JMXConnectionNotification;
026 import javax.management.MBeanServer;
027 import javax.management.NotificationFilterSupport;
028
029 import org.apache.commons.logging.Log;
030 import org.apache.commons.logging.LogFactory;
031 import org.apache.geronimo.gbean.GBeanInfo;
032 import org.apache.geronimo.gbean.GBeanInfoBuilder;
033 import org.apache.geronimo.gbean.GBeanLifecycle;
034 import org.apache.geronimo.system.jmx.MBeanServerReference;
035
036 /**
037 * A Connector that supports the server sideof JSR 160 JMX Remoting.
038 *
039 * @version $Rev: 395155 $ $Date: 2006-04-18 23:44:24 -0700 (Tue, 18 Apr 2006) $
040 */
041 public class JMXConnector implements GBeanLifecycle {
042 private final MBeanServer mbeanServer;
043 private final Log log;
044 private final ClassLoader classLoader;
045 private String applicationConfigName;
046 private Authenticator authenticator;
047
048 private String protocol;
049 private String host;
050 private int port = -1;
051 private String urlPath;
052
053 private JMXConnectorServer server;
054 private JMXServiceURL jmxServiceURL;
055
056 // todo remove this as soon as Geronimo supports factory beans
057 public JMXConnector(MBeanServerReference mbeanServerReference, String objectName, ClassLoader classLoader) {
058 this(mbeanServerReference.getMBeanServer(), objectName, classLoader);
059 }
060
061 /**
062 * Constructor for creating the connector. The ClassLoader must be
063 * able to load all the LoginModules used in the JAAS login
064 *
065 * @param mbeanServer the mbean server
066 * @param objectName this connector's object name
067 * @param classLoader the classLoader used to create this connector
068 */
069 public JMXConnector(MBeanServer mbeanServer, String objectName, ClassLoader classLoader) {
070 this.mbeanServer = mbeanServer;
071 this.classLoader = classLoader;
072 log = LogFactory.getLog(objectName);
073 }
074
075 /**
076 * Return the name of the JAAS Application Configuration Entry this
077 * connector uses to authenticate users. If null, users are not
078 * be authenticated (not recommended).
079 *
080 * @return the authentication configuration name
081 */
082 public String getApplicationConfigName() {
083 return applicationConfigName;
084 }
085
086 /**
087 * Set the name of the JAAS Application Configuration Entry this
088 * connector should use to authenticate users. If null, users will not
089 * be authenticated (not recommended).
090 *
091 * @param applicationConfigName the authentication configuration name
092 */
093 public void setApplicationConfigName(String applicationConfigName) {
094 this.applicationConfigName = applicationConfigName;
095 }
096
097 /**
098 * Every connector must specify a property of type InetSocketAddress
099 * 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 }