001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.management;
006:
007: import java.io.IOException;
008: import java.lang.reflect.InvocationHandler;
009: import java.lang.reflect.InvocationTargetException;
010: import java.lang.reflect.Method;
011: import java.lang.reflect.Proxy;
012: import java.rmi.ConnectException;
013: import java.text.MessageFormat;
014: import java.util.Map;
015:
016: import javax.management.ListenerNotFoundException;
017: import javax.management.MBeanServerConnection;
018: import javax.management.NotificationFilter;
019: import javax.management.NotificationListener;
020: import javax.management.remote.JMXConnector;
021: import javax.management.remote.JMXConnectorFactory;
022: import javax.management.remote.JMXServiceURL;
023: import javax.security.auth.Subject;
024:
025: public class JMXConnectorProxy implements JMXConnector {
026: private String m_host;
027: private int m_port;
028: private Map m_env;
029: private JMXServiceURL m_serviceURL;
030: private JMXConnector m_connector;
031: private JMXConnector m_connectorProxy;
032:
033: public static final String JMXMP_URI_PATTERN = "service:jmx:jmxmp://{0}:{1}";
034: public static final String JMXRMI_URI_PATTERN = "service:jmx:rmi:///jndi/rmi://{0}:{1}/jmxrmi";
035:
036: public JMXConnectorProxy(final String host, final int port,
037: final Map env) {
038: m_host = host;
039: m_port = port;
040: m_env = env;
041: m_connectorProxy = getConnectorProxy();
042: }
043:
044: public JMXConnectorProxy(final String host, final int port) {
045: this (host, port, null);
046: }
047:
048: private JMXConnector getConnectorProxy() {
049: JMXConnector connector = (JMXConnector) Proxy.newProxyInstance(
050: JMXConnector.class.getClassLoader(),
051: new Class[] { JMXConnector.class },
052: new ConnectorInvocationHandler());
053: return connector;
054: }
055:
056: static boolean isConnectException(IOException ioe) {
057: Throwable t = ioe;
058:
059: while (t != null) {
060: if (t instanceof ConnectException) {
061: return true;
062: }
063: t = t.getCause();
064: }
065:
066: return false;
067: }
068:
069: private void determineConnector() throws Exception {
070: JMXServiceURL url = new JMXServiceURL(getSecureJMXConnectorURL(
071: m_host, m_port));
072:
073: try {
074: m_connector = JMXConnectorFactory.connect(url, m_env);
075: m_serviceURL = url;
076: } catch (IOException ioe) {
077: if (isConnectException(ioe)) {
078: throw ioe;
079: }
080: url = new JMXServiceURL(getJMXConnectorURL(m_host, m_port));
081: m_connector = JMXConnectorFactory.connect(url, m_env);
082: m_serviceURL = url;
083: }
084: }
085:
086: private void ensureConnector() throws Exception {
087: if (m_connector == null) {
088: determineConnector();
089: }
090: }
091:
092: class ConnectorInvocationHandler implements InvocationHandler {
093: public Object invoke(Object proxy, Method method, Object[] args)
094: throws Throwable {
095: ensureConnector();
096:
097: try {
098: Class c = m_connector.getClass();
099: Method m = c.getMethod(method.getName(), method
100: .getParameterTypes());
101: return m.invoke(m_connector, args);
102: } catch (InvocationTargetException ite) {
103: Throwable cause = ite.getCause();
104: if (cause != null)
105: throw cause;
106: else
107: throw ite;
108: }
109: }
110: }
111:
112: public String getHost() {
113: return m_host;
114: }
115:
116: public int getPort() {
117: return m_port;
118: }
119:
120: public JMXServiceURL getServiceURL() {
121: return m_serviceURL;
122: }
123:
124: public static String getJMXConnectorURL(final String host,
125: final int port) {
126: return MessageFormat.format(JMXMP_URI_PATTERN, new Object[] {
127: host, port + "" });
128: }
129:
130: public static String getSecureJMXConnectorURL(final String host,
131: final int port) {
132: return MessageFormat.format(JMXRMI_URI_PATTERN, new Object[] {
133: host, port + "" });
134: }
135:
136: public void addConnectionNotificationListener(
137: NotificationListener listener, NotificationFilter filter,
138: Object data) {
139: m_connectorProxy.addConnectionNotificationListener(listener,
140: filter, data);
141: }
142:
143: public void close() throws IOException {
144: m_connectorProxy.close();
145: }
146:
147: public void connect() throws IOException {
148: m_connectorProxy.connect();
149: }
150:
151: public void connect(Map env) throws IOException {
152: m_connectorProxy.connect(env);
153: }
154:
155: public String getConnectionId() throws IOException {
156: return m_connectorProxy.getConnectionId();
157: }
158:
159: public MBeanServerConnection getMBeanServerConnection()
160: throws IOException {
161: return m_connectorProxy.getMBeanServerConnection();
162: }
163:
164: public MBeanServerConnection getMBeanServerConnection(
165: Subject subject) throws IOException {
166: return m_connectorProxy.getMBeanServerConnection(subject);
167: }
168:
169: public void removeConnectionNotificationListener(
170: NotificationListener listener)
171: throws ListenerNotFoundException {
172: m_connectorProxy.removeConnectionNotificationListener(listener);
173: }
174:
175: public void removeConnectionNotificationListener(
176: NotificationListener listener, NotificationFilter filter,
177: Object data) throws ListenerNotFoundException {
178: m_connectorProxy.removeConnectionNotificationListener(listener,
179: filter, data);
180: }
181:
182: public String toString() {
183: return m_host + ":" + m_port;
184: }
185: }
|