001: /*
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */
008:
009: package mx4j.tools.remote.http;
010:
011: import java.io.IOException;
012: import java.net.MalformedURLException;
013: import java.util.HashMap;
014: import java.util.Map;
015:
016: import javax.management.MBeanServer;
017: import javax.management.remote.JMXServiceURL;
018:
019: import mx4j.log.Log;
020: import mx4j.log.Logger;
021: import mx4j.remote.ConnectionResolver;
022: import mx4j.tools.remote.AbstractJMXConnectorServer;
023: import mx4j.tools.remote.ConnectionManager;
024:
025: /**
026: * @version $Revision: 1.5 $
027: */
028: public class HTTPConnectorServer extends AbstractJMXConnectorServer {
029: /**
030: * MX4J's implementation uses this property to specify a String that points to the configuration
031: * resource used to configure the HTTP server for JSR 160 connectors that use HTTP as transport.
032: * For Jetty, the default HTTP server, this can be a URL or a relative path (in this latter case
033: * the resource must be in classpath).
034: */
035: public static final String WEB_CONTAINER_CONFIGURATION = "jmx.remote.x.http.server.configuration";
036: public static final String USE_EXTERNAL_WEB_CONTAINER = "jmx.remote.x.http.use.external.web.container";
037: public static final String EMBEDDED_WEB_CONTAINER_CLASS = "jmx.remote.x.http.embedded.web.container.class";
038:
039: private static Map instances = new HashMap();
040:
041: private WebContainer webContainer;
042: private ConnectionManager connectionManager;
043:
044: public HTTPConnectorServer(JMXServiceURL url, Map environment,
045: MBeanServer server) {
046: super (url, environment, server);
047: }
048:
049: protected void doStart() throws IOException, IllegalStateException {
050: MBeanServer server = getMBeanServer();
051: if (server == null)
052: throw new IllegalStateException(
053: "This JMXConnectorServer is not attached to an MBeanServer");
054:
055: JMXServiceURL address = getAddress();
056: String protocol = address.getProtocol();
057: Map environment = getEnvironment();
058: ConnectionResolver resolver = ConnectionResolver
059: .newConnectionResolver(protocol, environment);
060: if (resolver == null)
061: throw new MalformedURLException("Unsupported protocol: "
062: + protocol);
063:
064: webContainer = (WebContainer) resolver.createServer(address,
065: environment);
066:
067: setAddress(resolver.bindServer(webContainer, address,
068: environment));
069:
070: connectionManager = createConnectionManager(this , address,
071: environment);
072:
073: // Here is where we give to clients the possibility to access us
074: register(getAddress(), connectionManager);
075: }
076:
077: protected ConnectionManager createConnectionManager(
078: AbstractJMXConnectorServer server, JMXServiceURL url,
079: Map environment) {
080: return new HTTPConnectionManager(server, url.getProtocol(),
081: environment);
082: }
083:
084: private void register(JMXServiceURL url, ConnectionManager manager)
085: throws IOException {
086: synchronized (HTTPConnectorServer.class) {
087: // TODO: must use weak references to connection managers, otherwise they're not GC'ed
088: // TODO: in case the connector server is not stopped cleanly
089: if (instances.get(url) != null)
090: throw new IOException(
091: "A JMXConnectorServer is already serving at address "
092: + url);
093: instances.put(url, manager);
094: }
095: }
096:
097: private void unregister(JMXServiceURL url) throws IOException {
098: synchronized (HTTPConnectorServer.class) {
099: Object removed = instances.remove(url);
100: if (removed == null)
101: throw new IOException(
102: "No JMXConnectorServer is present for address "
103: + url);
104: }
105: }
106:
107: static ConnectionManager find(JMXServiceURL address) {
108: synchronized (HTTPConnectorServer.class) {
109: ConnectionManager manager = (ConnectionManager) instances
110: .get(address);
111: if (manager != null)
112: return manager;
113:
114: Logger logger = Log.getLogger(HTTPConnectorServer.class
115: .getName());
116: if (logger.isEnabledFor(Logger.DEBUG))
117: logger.debug("Known HTTPConnectorServers bound at "
118: + instances.keySet());
119: return null;
120: }
121: }
122:
123: protected void doStop() throws IOException {
124: JMXServiceURL url = getAddress();
125: unregister(url);
126:
127: if (connectionManager != null) {
128: connectionManager.close();
129: connectionManager = null;
130: }
131:
132: String protocol = url.getProtocol();
133: Map environment = getEnvironment();
134: ConnectionResolver resolver = ConnectionResolver
135: .newConnectionResolver(protocol, environment);
136: if (resolver == null)
137: throw new MalformedURLException("Unsupported protocol: "
138: + protocol);
139:
140: resolver.unbindServer(webContainer, url, environment);
141:
142: resolver.destroyServer(webContainer, url, environment);
143: }
144: }
|