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.server.RMIClientSocketFactory;
31 import java.rmi.server.RMIServerSocketFactory;
32 import java.util.HashMap;
33
34 import javax.management.MBeanServer;
35 import javax.management.remote.JMXConnectorServer;
36 import javax.management.remote.JMXConnectorServerFactory;
37 import javax.management.remote.JMXServiceURL;
38 import javax.management.remote.rmi.RMIConnectorServer;
39 import javax.rmi.ssl.SslRMIClientSocketFactory;
40 import javax.rmi.ssl.SslRMIServerSocketFactory;
41
42
43
44
45
46
47
48
49 public class JMXListener implements Coprocessor {
50
51 public 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 int defMasterRMIRegistryPort = 10101;
55 public static int defRegionserverRMIRegistryPort = 10102;
56
57 private JMXConnectorServer jmxCS = null;
58
59 public static JMXServiceURL buildJMXServiceURL(int rmiRegistryPort,
60 int rmiConnectorPort) throws IOException {
61
62 StringBuilder url = new StringBuilder();
63 url.append("service:jmx:rmi://localhost:");
64 url.append(rmiConnectorPort);
65 url.append("/jndi/rmi://localhost:");
66 url.append(rmiRegistryPort);
67 url.append("/jmxrmi");
68
69 return new JMXServiceURL(url.toString());
70
71 }
72
73 public void startConnectorServer(int rmiRegistryPort, int rmiConnectorPort)
74 throws IOException {
75 boolean rmiSSL = false;
76 boolean authenticate = true;
77 String passwordFile = null;
78 String accessFile = null;
79
80 System.setProperty("java.rmi.server.randomIDs", "true");
81
82 String rmiSSLValue = System.getProperty("com.sun.management.jmxremote.ssl",
83 "false");
84 rmiSSL = Boolean.parseBoolean(rmiSSLValue);
85
86 String authenticateValue =
87 System.getProperty("com.sun.management.jmxremote.authenticate", "false");
88 authenticate = Boolean.parseBoolean(authenticateValue);
89
90 passwordFile = System.getProperty("com.sun.management.jmxremote.password.file");
91 accessFile = System.getProperty("com.sun.management.jmxremote.access.file");
92
93 LOG.info("rmiSSL:" + rmiSSLValue + ",authenticate:" + authenticateValue
94 + ",passwordFile:" + passwordFile + ",accessFile:" + accessFile);
95
96
97 HashMap<String, Object> jmxEnv = new HashMap<String, Object>();
98
99 RMIClientSocketFactory csf = null;
100 RMIServerSocketFactory ssf = null;
101
102 if (rmiSSL) {
103 if (rmiRegistryPort == rmiConnectorPort) {
104 throw new IOException("SSL is enabled. " +
105 "rmiConnectorPort cannot share with the rmiRegistryPort!");
106 }
107 csf = new SslRMIClientSocketFactory();
108 ssf = new SslRMIServerSocketFactory();
109 }
110
111 if (csf != null) {
112 jmxEnv.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
113 }
114 if (ssf != null) {
115 jmxEnv.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
116 }
117
118
119 if (authenticate) {
120 jmxEnv.put("jmx.remote.x.password.file", passwordFile);
121 jmxEnv.put("jmx.remote.x.access.file", accessFile);
122 }
123
124
125 LocateRegistry.createRegistry(rmiRegistryPort);
126
127 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
128
129
130 JMXServiceURL serviceUrl = buildJMXServiceURL(rmiRegistryPort, rmiConnectorPort);
131
132 try {
133
134 jmxCS = JMXConnectorServerFactory.newJMXConnectorServer(serviceUrl, jmxEnv, mbs);
135 jmxCS.start();
136 LOG.info("ConnectorServer started!");
137 } catch (IOException e) {
138 LOG.error("fail to start connector server!", e);
139 }
140
141 }
142
143 public void stopConnectorServer() throws IOException {
144 if (jmxCS != null) {
145 jmxCS.stop();
146 LOG.info("ConnectorServer stopped!");
147 jmxCS = null;
148 }
149 }
150
151
152 @Override
153 public void start(CoprocessorEnvironment env) throws IOException {
154 int rmiRegistryPort = -1;
155 int rmiConnectorPort = -1;
156 Configuration conf = env.getConfiguration();
157
158 if (env instanceof MasterCoprocessorEnvironment) {
159
160 rmiRegistryPort =
161 conf.getInt("master" + RMI_REGISTRY_PORT_CONF_KEY,
162 defMasterRMIRegistryPort);
163 rmiConnectorPort =
164 conf.getInt("master" + RMI_CONNECTOR_PORT_CONF_KEY, rmiRegistryPort);
165 LOG.info("Master rmiRegistryPort:" + rmiRegistryPort
166 + ",Master rmiConnectorPort:" + rmiConnectorPort);
167
168 } else if (env instanceof RegionServerCoprocessorEnvironment) {
169
170 rmiRegistryPort =
171 conf.getInt("regionserver" + RMI_REGISTRY_PORT_CONF_KEY,
172 defRegionserverRMIRegistryPort);
173 rmiConnectorPort =
174 conf.getInt("regionserver" + RMI_CONNECTOR_PORT_CONF_KEY, rmiRegistryPort);
175 LOG.info("RegionServer rmiRegistryPort:" + rmiRegistryPort
176 + ",RegionServer rmiConnectorPort:" + rmiConnectorPort);
177
178 } else if (env instanceof RegionCoprocessorEnvironment) {
179 LOG.error("JMXListener should not be loaded in Region Environment!");
180 }
181
182 startConnectorServer(rmiRegistryPort, rmiConnectorPort);
183 }
184
185 @Override
186 public void stop(CoprocessorEnvironment env) throws IOException {
187 stopConnectorServer();
188 }
189
190 }