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 java.io.IOException;
22
23 import javax.management.remote.JMXConnector;
24 import javax.management.remote.JMXConnectorFactory;
25 import javax.naming.ServiceUnavailableException;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.conf.Configuration;
30 import org.apache.hadoop.hbase.client.Admin;
31 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
32 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
33 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
34 import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
35 import org.apache.hadoop.hbase.security.AccessDeniedException;
36 import org.apache.hadoop.hbase.security.access.AccessController;
37 import org.apache.hadoop.hbase.testclassification.MediumTests;
38 import org.apache.hadoop.hbase.testclassification.MiscTests;
39 import org.junit.After;
40 import org.junit.Assert;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.junit.experimental.categories.Category;
44
45
46
47
48 @Category({ MiscTests.class, MediumTests.class })
49 public class TestJMXConnectorServer {
50 private static final Log LOG = LogFactory.getLog(TestJMXConnectorServer.class);
51 private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
52
53 private static Configuration conf = null;
54 private static Admin admin;
55
56 private static int rmiRegistryPort = 61120;
57
58 static boolean hasAccess;
59
60 @Before
61 public void setUp() throws Exception {
62 UTIL = new HBaseTestingUtility();
63 conf = UTIL.getConfiguration();
64 }
65
66 @After
67 public void tearDown() throws Exception {
68
69 hasAccess = true;
70 admin.close();
71 UTIL.shutdownMiniCluster();
72 }
73
74
75
76
77 @Test(timeout = 180000)
78 public void testHMConnectorServerWhenStopMaster() throws Exception {
79 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
80 JMXListener.class.getName() + "," + MyAccessController.class.getName());
81 conf.setInt("master.rmi.registry.port", rmiRegistryPort);
82 UTIL.startMiniCluster();
83 admin = UTIL.getConnection().getAdmin();
84
85
86 boolean accessDenied = false;
87 try {
88 hasAccess = false;
89 LOG.info("Stopping HMaster...");
90 admin.stopMaster();
91 } catch (AccessDeniedException e) {
92 LOG.info("Exception occured while stopping HMaster. ", e);
93 accessDenied = true;
94 }
95 Assert.assertTrue(accessDenied);
96
97
98 JMXConnector connector = null;
99 try {
100 connector = JMXConnectorFactory
101 .connect(JMXListener.buildJMXServiceURL(rmiRegistryPort, rmiRegistryPort));
102 } catch (IOException e) {
103 if (e.getCause() instanceof ServiceUnavailableException) {
104 Assert.fail("Can't connect to HMaster ConnectorServer.");
105 }
106 }
107 Assert.assertNotNull("JMXConnector should not be null.", connector);
108 connector.close();
109 }
110
111
112
113
114
115 @Test(timeout = 180000)
116 public void testRSConnectorServerWhenStopRegionServer() throws Exception {
117 conf.set(CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,
118 JMXListener.class.getName() + "," + MyAccessController.class.getName());
119 conf.setInt("regionserver.rmi.registry.port", rmiRegistryPort);
120 UTIL.startMiniCluster();
121 admin = UTIL.getConnection().getAdmin();
122
123 hasAccess = false;
124 ServerName serverName = UTIL.getHBaseCluster().getRegionServer(0).getServerName();
125 LOG.info("Stopping Region Server...");
126 admin.stopRegionServer(serverName.getHostname() + ":" + serverName.getPort());
127
128
129 JMXConnector connector = null;
130 try {
131 connector = JMXConnectorFactory
132 .connect(JMXListener.buildJMXServiceURL(rmiRegistryPort, rmiRegistryPort));
133 } catch (IOException e) {
134 if (e.getCause() instanceof ServiceUnavailableException) {
135 Assert.fail("Can't connect to Region Server ConnectorServer.");
136 }
137 }
138 Assert.assertNotNull("JMXConnector should not be null.", connector);
139 connector.close();
140 }
141
142
143
144
145 @Test(timeout = 180000)
146 public void testHMConnectorServerWhenShutdownCluster() throws Exception {
147 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
148 JMXListener.class.getName() + "," + MyAccessController.class.getName());
149 conf.setInt("master.rmi.registry.port", rmiRegistryPort);
150
151 UTIL.startMiniCluster();
152 admin = UTIL.getConnection().getAdmin();
153
154 boolean accessDenied = false;
155 try {
156 hasAccess = false;
157 LOG.info("Stopping HMaster...");
158 admin.shutdown();
159 } catch (AccessDeniedException e) {
160 LOG.error("Exception occured while stopping HMaster. ", e);
161 accessDenied = true;
162 }
163 Assert.assertTrue(accessDenied);
164
165
166 JMXConnector connector = null;
167 try {
168 connector = JMXConnectorFactory
169 .connect(JMXListener.buildJMXServiceURL(rmiRegistryPort, rmiRegistryPort));
170 } catch (IOException e) {
171 if (e.getCause() instanceof ServiceUnavailableException) {
172 Assert.fail("Can't connect to HMaster ConnectorServer.");
173 }
174 }
175 Assert.assertNotNull("JMXConnector should not be null.", connector);
176 connector.close();
177 }
178
179
180
181
182
183 public static class MyAccessController extends AccessController {
184 @Override
185 public void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> c) throws IOException {
186 if (!hasAccess) {
187 throw new AccessDeniedException("Insufficient permissions to stop master");
188 }
189 }
190
191 @Override
192 public void preStopRegionServer(ObserverContext<RegionServerCoprocessorEnvironment> ctx)
193 throws IOException {
194 if (!hasAccess) {
195 throw new AccessDeniedException("Insufficient permissions to stop region server.");
196 }
197 }
198
199 @Override
200 public void preShutdown(ObserverContext<MasterCoprocessorEnvironment> c) throws IOException {
201 if (!hasAccess) {
202 throw new AccessDeniedException("Insufficient permissions to shut down cluster.");
203 }
204 }
205 }
206 }