1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.conf.Configuration;
24 import org.apache.hadoop.hbase.CoprocessorEnvironment;
25 import org.apache.hadoop.hbase.coprocessor.*;
26
27 import java.io.IOException;
28 import java.lang.management.ManagementFactory;
29 import java.rmi.registry.LocateRegistry;
30 import java.rmi.registry.Registry;
31 import java.rmi.server.RMIClientSocketFactory;
32 import java.rmi.server.RMIServerSocketFactory;
33 import java.rmi.server.UnicastRemoteObject;
34 import java.util.HashMap;
35
36 import javax.management.MBeanServer;
37 import javax.management.remote.JMXConnectorServer;
38 import javax.management.remote.JMXConnectorServerFactory;
39 import javax.management.remote.JMXServiceURL;
40 import javax.management.remote.rmi.RMIConnectorServer;
41
42
43
44
45
46
47
48
49 public class JMXListener implements Coprocessor {
50
51 private static final Log LOG = LogFactory.getLog(JMXListener.class);
52 public static final String RMI_REGISTRY_PORT_CONF_KEY = ".rmi.registry.port";
53 public static final String RMI_CONNECTOR_PORT_CONF_KEY = ".rmi.connector.port";
54 public static final int defMasterRMIRegistryPort = 10101;
55 public static final int defRegionserverRMIRegistryPort = 10102;
56
57
58
59
60
61
62
63 private static JMXConnectorServer JMX_CS = null;
64 private Registry rmiRegistry = null;
65
66 public static JMXServiceURL buildJMXServiceURL(int rmiRegistryPort,
67 int rmiConnectorPort) throws IOException {
68
69 StringBuilder url = new StringBuilder();
70 url.append("service:jmx:rmi://localhost:");
71 url.append(rmiConnectorPort);
72 url.append("/jndi/rmi://localhost:");
73 url.append(rmiRegistryPort);
74 url.append("/jmxrmi");
75
76 return new JMXServiceURL(url.toString());
77
78 }
79
80 public void startConnectorServer(int rmiRegistryPort, int rmiConnectorPort)
81 throws IOException {
82 boolean rmiSSL = false;
83 boolean authenticate = true;
84 String passwordFile = null;
85 String accessFile = null;
86
87 System.setProperty("java.rmi.server.randomIDs", "true");
88
89 String rmiSSLValue = System.getProperty("com.sun.management.jmxremote.ssl",
90 "false");
91 rmiSSL = Boolean.parseBoolean(rmiSSLValue);
92
93 String authenticateValue =
94 System.getProperty("com.sun.management.jmxremote.authenticate", "false");
95 authenticate = Boolean.parseBoolean(authenticateValue);
96
97 passwordFile = System.getProperty("com.sun.management.jmxremote.password.file");
98 accessFile = System.getProperty("com.sun.management.jmxremote.access.file");
99
100 LOG.info("rmiSSL:" + rmiSSLValue + ",authenticate:" + authenticateValue
101 + ",passwordFile:" + passwordFile + ",accessFile:" + accessFile);
102
103
104 HashMap<String, Object> jmxEnv = new HashMap<String, Object>();
105
106 RMIClientSocketFactory csf = null;
107 RMIServerSocketFactory ssf = null;
108
109 if (rmiSSL) {
110 if (rmiRegistryPort == rmiConnectorPort) {
111 throw new IOException("SSL is enabled. " +
112 "rmiConnectorPort cannot share with the rmiRegistryPort!");
113 }
114 csf = new SslRMIClientSocketFactorySecure();
115 ssf = new SslRMIServerSocketFactorySecure();
116 }
117
118 if (csf != null) {
119 jmxEnv.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
120 }
121 if (ssf != null) {
122 jmxEnv.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
123 }
124
125
126 if (authenticate) {
127 jmxEnv.put("jmx.remote.x.password.file", passwordFile);
128 jmxEnv.put("jmx.remote.x.access.file", accessFile);
129 }
130
131
132 rmiRegistry = LocateRegistry.createRegistry(rmiRegistryPort);
133
134 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
135
136
137 JMXServiceURL serviceUrl = buildJMXServiceURL(rmiRegistryPort, rmiConnectorPort);
138
139 try {
140
141 synchronized(JMXListener.class) {
142 if (JMX_CS != null) {
143 throw new RuntimeException("Started by another thread?");
144 }
145 JMX_CS = JMXConnectorServerFactory.newJMXConnectorServer(serviceUrl, jmxEnv, mbs);
146 JMX_CS.start();
147 }
148 LOG.info("ConnectorServer started!");
149 } catch (IOException e) {
150 LOG.error("fail to start connector server!", e);
151
152 if (rmiRegistry != null) {
153 UnicastRemoteObject.unexportObject(rmiRegistry, true);
154 }
155 }
156
157 }
158
159 public void stopConnectorServer() throws IOException {
160 synchronized (JMXListener.class) {
161 if (JMX_CS != null) {
162 JMX_CS.stop();
163 LOG.info("ConnectorServer stopped!");
164 JMX_CS = null;
165 }
166
167 if (rmiRegistry != null) {
168 UnicastRemoteObject.unexportObject(rmiRegistry, true);
169 }
170 }
171 }
172
173
174 @Override
175 public void start(CoprocessorEnvironment env) throws IOException {
176 int rmiRegistryPort = -1;
177 int rmiConnectorPort = -1;
178 Configuration conf = env.getConfiguration();
179
180 if (env instanceof MasterCoprocessorEnvironment) {
181
182 rmiRegistryPort =
183 conf.getInt("master" + RMI_REGISTRY_PORT_CONF_KEY, defMasterRMIRegistryPort);
184 rmiConnectorPort = conf.getInt("master" + RMI_CONNECTOR_PORT_CONF_KEY, rmiRegistryPort);
185 LOG.info("Master rmiRegistryPort:" + rmiRegistryPort + ",Master rmiConnectorPort:"
186 + rmiConnectorPort);
187 } else if (env instanceof RegionServerCoprocessorEnvironment) {
188
189 rmiRegistryPort =
190 conf.getInt("regionserver" + RMI_REGISTRY_PORT_CONF_KEY,
191 defRegionserverRMIRegistryPort);
192 rmiConnectorPort =
193 conf.getInt("regionserver" + RMI_CONNECTOR_PORT_CONF_KEY, rmiRegistryPort);
194 LOG.info("RegionServer rmiRegistryPort:" + rmiRegistryPort
195 + ",RegionServer rmiConnectorPort:" + rmiConnectorPort);
196
197 } else if (env instanceof RegionCoprocessorEnvironment) {
198 LOG.error("JMXListener should not be loaded in Region Environment!");
199 return;
200 }
201
202 synchronized(JMXListener.class) {
203 if (JMX_CS != null) {
204 LOG.info("JMXListener has been started at Registry port " + rmiRegistryPort);
205 }
206 else {
207 startConnectorServer(rmiRegistryPort, rmiConnectorPort);
208 }
209 }
210 }
211
212 @Override
213 public void stop(CoprocessorEnvironment env) throws IOException {
214 stopConnectorServer();
215 }
216
217 }