001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@ow2.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id:JMXRemoteHelper.java 1537 2007-07-08 15:31:22Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.jmx;
025:
026: import static org.ow2.easybeans.jmx.MBeanServerHelper.getMBeanServerServer;
027:
028: import java.io.IOException;
029: import java.net.MalformedURLException;
030: import java.net.URI;
031: import java.net.URISyntaxException;
032: import java.util.HashMap;
033: import java.util.Map;
034:
035: import javax.management.InstanceAlreadyExistsException;
036: import javax.management.InstanceNotFoundException;
037: import javax.management.MBeanRegistrationException;
038: import javax.management.MalformedObjectNameException;
039: import javax.management.NotCompliantMBeanException;
040: import javax.management.ObjectName;
041: import javax.management.remote.JMXConnectorServer;
042: import javax.management.remote.JMXConnectorServerFactory;
043: import javax.management.remote.JMXServiceURL;
044:
045: import org.ow2.easybeans.component.itf.RegistryComponent;
046: import org.ow2.util.log.Log;
047: import org.ow2.util.log.LogFactory;
048:
049: /**
050: * This helper class allow to start a JMX remote connector allowing to connect remote applications.
051: * This could be for example a JSR88 provider.
052: * @author Florent Benoit
053: */
054: public final class JMXRemoteHelper {
055:
056: /**
057: * Logger.
058: */
059: private static Log logger = LogFactory
060: .getLog(JMXRemoteHelper.class);
061:
062: /**
063: * JMX connector (server side).
064: */
065: private static JMXConnectorServer jmxConnectorServer = null;
066:
067: /**
068: * Prefix for the URL Service.
069: */
070: private static final String PREFIX_URL_SERVICE = "service:jmx:";
071:
072: /**
073: * Suffix for the URL Service.
074: */
075: private static final String SUFFIX_URL_SERVICE = ":///jndi/";
076:
077: /**
078: * Default RMI host.
079: */
080: private static final String DEFAULT_RMI = "rmi://localhost:1099";
081:
082: /**
083: * Suffix for the URL.
084: */
085: private static final String SUFFIX_URL = "/EasyBeansConnector";
086:
087: /**
088: * ObjectName for the connector.
089: */
090: private static final String DEFAULT_NAME_CONNECTOR = "connectors:name=JMXRemoteConnector";
091:
092: /**
093: * Utility class, no public constructor.
094: */
095: private JMXRemoteHelper() {
096:
097: }
098:
099: /**
100: * Build a new JMX Remote connector.
101: * @param registryComponent to get the provider URL.
102: * @throws JMXRemoteException if jmx connector can't be built.
103: */
104: private static void init(final RegistryComponent registryComponent)
105: throws JMXRemoteException {
106:
107: // Create connector
108: Map<String, String> environment = new HashMap<String, String>();
109: JMXServiceURL jmxServiceURL = null;
110:
111: // Build URL
112: StringBuilder sb = new StringBuilder(PREFIX_URL_SERVICE);
113: URI providerURI = null;
114: if (registryComponent != null) {
115: try {
116: providerURI = new URI(registryComponent
117: .getProviderURL());
118: } catch (URISyntaxException e) {
119: throw new JMXRemoteException(
120: "Cannot get URL from registry component", e);
121: }
122: } else {
123: try {
124: providerURI = new URI(DEFAULT_RMI);
125: } catch (URISyntaxException e) {
126: throw new JMXRemoteException("Cannot get URL from '"
127: + DEFAULT_RMI + "'", e);
128: }
129: }
130:
131: // Switch for the protocol
132: String protocol = providerURI.getScheme();
133: String protocolName = "rmi";
134: if ("iiop".equals(protocol)) {
135: protocolName = "iiop";
136: }
137:
138: sb.append(protocolName);
139:
140: // Add suffix URL of the service
141: sb.append(SUFFIX_URL_SERVICE);
142:
143: // Add rmi URL
144: sb.append(protocolName);
145: sb.append("://localhost:");
146: sb.append(providerURI.getPort());
147:
148: // Connector
149: sb.append(SUFFIX_URL);
150: String url = sb.toString();
151:
152: try {
153: jmxServiceURL = new JMXServiceURL(url);
154: } catch (MalformedURLException e) {
155: throw new JMXRemoteException(
156: "Cannot create jmxservice url with url '" + url
157: + "'.", e);
158: }
159: environment.put("jmx.remote.jndi.rebind", "true");
160: try {
161: jmxConnectorServer = JMXConnectorServerFactory
162: .newJMXConnectorServer(jmxServiceURL, environment,
163: getMBeanServerServer());
164: } catch (IOException e) {
165: throw new JMXRemoteException(
166: "Cannot create new JMX Connector", e);
167: }
168: logger.info("Creating JMXRemote connector with URL ''{0}''",
169: url);
170:
171: }
172:
173: /**
174: * Start a JMX connector (used to do remote administration).
175: * @param registryComponent to get the provider URL.
176: * @throws JMXRemoteException if the connector can't be started.
177: */
178: public static synchronized void startConnector(
179: final RegistryComponent registryComponent)
180: throws JMXRemoteException {
181: // Create connector if null
182: if (jmxConnectorServer == null) {
183: init(registryComponent);
184: }
185:
186: ObjectName connectorServerName = getConnectorObjectName();
187: // register it
188: try {
189: getMBeanServerServer().registerMBean(jmxConnectorServer,
190: connectorServerName);
191: } catch (InstanceAlreadyExistsException e) {
192: throw new JMXRemoteException(
193: "Cannot register Mbean with the name '"
194: + connectorServerName + "'", e);
195: } catch (MBeanRegistrationException e) {
196: throw new JMXRemoteException(
197: "Cannot register Mbean with the name '"
198: + connectorServerName + "'", e);
199: } catch (NotCompliantMBeanException e) {
200: throw new JMXRemoteException(
201: "Cannot register Mbean with the name '"
202: + connectorServerName + "'", e);
203: }
204:
205: // Start connector
206: try {
207: jmxConnectorServer.start();
208: } catch (IOException e) {
209: throw new JMXRemoteException(
210: "Cannot start the jmx connector", e);
211: }
212: }
213:
214: /**
215: * Start a JMX connector (used to do remote administration).
216: * @throws JMXRemoteException if the connector can't be started.
217: */
218: public static synchronized void stopConnector()
219: throws JMXRemoteException {
220: // Do nothing if there is no Connector
221: if (jmxConnectorServer != null) {
222: ObjectName connectorServerName = getConnectorObjectName();
223: try {
224: // Stop
225: jmxConnectorServer.stop();
226: // Unregister
227: getMBeanServerServer().unregisterMBean(
228: connectorServerName);
229: // unget the ref
230: jmxConnectorServer = null;
231: } catch (InstanceNotFoundException e) {
232: throw new JMXRemoteException(
233: "Cannot unregister JMX Connector with name '"
234: + connectorServerName + "'", e);
235: } catch (MBeanRegistrationException e) {
236: throw new JMXRemoteException(
237: "Cannot unregister JMX Connector with name '"
238: + connectorServerName + "'", e);
239: } catch (IOException e) {
240: throw new JMXRemoteException(
241: "Cannot Stop JMX Connector with name '"
242: + connectorServerName + "'", e);
243: }
244: }
245: }
246:
247: /**
248: * @return Returns the Connector ObjectName.
249: * @throws JMXRemoteException if unable to create the ObjectName.
250: */
251: private static ObjectName getConnectorObjectName()
252: throws JMXRemoteException {
253: ObjectName connectorServerName = null;
254: String objName = null;
255: try {
256: objName = DEFAULT_NAME_CONNECTOR;
257: connectorServerName = new ObjectName(objName);
258: } catch (MalformedObjectNameException e) {
259: throw new JMXRemoteException(
260: "Cannot create ObjectName with name '" + objName
261: + "'", e);
262: } catch (NullPointerException e) {
263: throw new JMXRemoteException(
264: "Cannot create ObjectName with name '" + objName
265: + "'", e);
266: }
267: return connectorServerName;
268: }
269: }
|