001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. 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: */package org.apache.geronimo.jmxremoting;
017:
018: import java.net.InetSocketAddress;
019: import java.util.HashMap;
020: import java.util.Map;
021:
022: import javax.management.MBeanServer;
023: import javax.management.NotificationFilterSupport;
024: import javax.management.remote.JMXConnectionNotification;
025: import javax.management.remote.JMXConnectorServer;
026: import javax.management.remote.JMXConnectorServerFactory;
027: import javax.management.remote.JMXServiceURL;
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: 555111 $ $Date: 2007-07-10 16:25:31 -0700 (Tue, 10 Jul 2007) $
040: */
041: public class JMXConnector implements JMXConnectorInfo, 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,
058: String objectName, ClassLoader classLoader) {
059: this (mbeanServerReference.getMBeanServer(), objectName,
060: classLoader);
061: }
062:
063: /**
064: * Constructor for creating the connector. The ClassLoader must be
065: * able to load all the LoginModules used in the JAAS login
066: *
067: * @param mbeanServer the mbean server
068: * @param objectName this connector's object name
069: * @param classLoader the classLoader used to create this connector
070: */
071: public JMXConnector(MBeanServer mbeanServer, String objectName,
072: ClassLoader classLoader) {
073: this .mbeanServer = mbeanServer;
074: this .classLoader = classLoader;
075: log = LogFactory.getLog(objectName);
076: }
077:
078: /**
079: * Return the name of the JAAS Application Configuration Entry this
080: * connector uses to authenticate users. If null, users are not
081: * be authenticated (not recommended).
082: *
083: * @return the authentication configuration name
084: */
085: public String getApplicationConfigName() {
086: return applicationConfigName;
087: }
088:
089: /**
090: * Set the name of the JAAS Application Configuration Entry this
091: * connector should use to authenticate users. If null, users will not
092: * be authenticated (not recommended).
093: *
094: * @param applicationConfigName the authentication configuration name
095: */
096: public void setApplicationConfigName(String applicationConfigName) {
097: this .applicationConfigName = applicationConfigName;
098: }
099:
100: /**
101: * Every connector must specify a property of type InetSocketAddress
102: * because we use that to identify the network services to print a list
103: * during startup. However, this can be read-only since the host and port
104: * are set in the url attribute.
105: */
106: public InetSocketAddress getListenAddress() {
107: return new InetSocketAddress(getHost(), getPort());
108: }
109:
110: /**
111: * Gets the protocol to use for the connection.
112: * @return the protocol to use for the connection
113: */
114: public String getProtocol() {
115: return protocol;
116: }
117:
118: /**
119: * Sets the protocol to use for the connection.
120: * @param protocol the protocol to use for the connection
121: */
122: public void setProtocol(String protocol) {
123: this .protocol = protocol;
124: }
125:
126: /**
127: * Gets the JMX host for this connector.
128: *
129: * @return the JMX host for this connector
130: */
131: public String getHost() {
132: return host;
133: }
134:
135: /**
136: * Sets the JMX host for this connector.
137: * @param host the JMX host for this connector
138: */
139: public void setHost(String host) {
140: this .host = host;
141: }
142:
143: /**
144: * Gets the JMX port for this connector.
145: *
146: * @return the JMX port for this connector
147: */
148: public int getPort() {
149: return port;
150: }
151:
152: /**
153: * Sets the JMX port for this connector.
154: * @param port the JMX port for this connector
155: */
156: public void setPort(int port) {
157: this .port = port;
158: }
159:
160: /**
161: * Gets the path within the target server to look for the connection. This is commonly
162: * /jndi/rmi://localhost:1099/JMXConnector
163: * @return the path used to loacate the connector on the target server
164: */
165: public String getUrlPath() {
166: return urlPath;
167: }
168:
169: /**
170: * Sets the path within the target server to look for the connection. This is commonly
171: * /jndi/rmi://localhost:1099/JMXConnector
172: * @param urlPath the path used to loacate the connector on the target server
173: */
174: public void setUrlPath(String urlPath) {
175: this .urlPath = urlPath;
176: }
177:
178: public void doStart() throws Exception {
179: jmxServiceURL = new JMXServiceURL(protocol, host, port, urlPath);
180: Map env = new HashMap();
181: if (applicationConfigName != null) {
182: authenticator = new Authenticator(applicationConfigName,
183: classLoader);
184: env.put(JMXConnectorServer.AUTHENTICATOR, authenticator);
185: } else {
186: log.warn("Starting unauthenticating JMXConnector for "
187: + jmxServiceURL);
188: }
189: server = JMXConnectorServerFactory.newJMXConnectorServer(
190: jmxServiceURL, env, mbeanServer);
191: NotificationFilterSupport filter = new NotificationFilterSupport();
192: filter.enableType(JMXConnectionNotification.OPENED);
193: filter.enableType(JMXConnectionNotification.CLOSED);
194: filter.enableType(JMXConnectionNotification.FAILED);
195: server.addNotificationListener(authenticator, filter, null);
196: server.start();
197: log.debug("Started JMXConnector " + server.getAddress());
198: }
199:
200: public void doStop() throws Exception {
201: try {
202: server.stop();
203: } catch (java.io.IOException e) {
204: // java.io.IOException is expected.
205: } catch (Exception e) {
206: // Otherwise, something bad happened. Rethrow the exception.
207: throw e;
208: } finally {
209: server = null;
210: log.debug("Stopped JMXConnector " + jmxServiceURL);
211: }
212: }
213:
214: public void doFail() {
215: try {
216: doStop();
217: log.warn("Failure in JMXConnector " + jmxServiceURL);
218: } catch (Exception e) {
219: log.warn("Error stopping JMXConnector after failure", e);
220: }
221: }
222:
223: public static final GBeanInfo GBEAN_INFO;
224:
225: static {
226: GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(
227: "JMX Remoting Connector", JMXConnector.class);
228: infoFactory.addReference("MBeanServerReference",
229: MBeanServerReference.class);
230: infoFactory.addAttribute("objectName", String.class, false);
231: infoFactory.addAttribute("classLoader", ClassLoader.class,
232: false);
233:
234: infoFactory.addAttribute("protocol", String.class, true, true);
235: infoFactory.addAttribute("host", String.class, true, true);
236: infoFactory.addAttribute("port", int.class, true, true);
237: infoFactory.addAttribute("urlPath", String.class, true, true);
238: infoFactory.addAttribute("applicationConfigName", String.class,
239: true, true);
240:
241: infoFactory.addInterface(JMXConnectorInfo.class);
242:
243: infoFactory.setConstructor(new String[] {
244: "MBeanServerReference", "objectName", "classLoader" });
245: GBEAN_INFO = infoFactory.getBeanInfo();
246: }
247:
248: public static GBeanInfo getGBeanInfo() {
249: return GBEAN_INFO;
250: }
251: }
|