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 }