1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.rsgroup;
21
22 import com.google.common.collect.Lists;
23 import com.google.common.collect.Sets;
24
25 import com.google.common.net.HostAndPort;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.HBaseTestingUtility;
29 import org.apache.hadoop.hbase.HColumnDescriptor;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.MiniHBaseCluster;
33 import org.apache.hadoop.hbase.NamespaceDescriptor;
34 import org.apache.hadoop.hbase.ServerName;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.Waiter;
37 import org.apache.hadoop.hbase.Waiter.Predicate;
38 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
39 import org.apache.hadoop.hbase.master.HMaster;
40 import org.apache.hadoop.hbase.master.MasterServices;
41 import org.apache.hadoop.hbase.master.ServerManager;
42 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
43 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
44 import org.apache.hadoop.hbase.testclassification.MediumTests;
45 import org.apache.hadoop.hbase.util.Bytes;
46 import org.junit.After;
47 import org.junit.AfterClass;
48 import org.junit.Assert;
49 import org.junit.Before;
50 import org.junit.BeforeClass;
51 import org.junit.Test;
52 import org.junit.experimental.categories.Category;
53 import org.mockito.Mockito;
54 import org.mockito.invocation.InvocationOnMock;
55 import org.mockito.stubbing.Answer;
56
57 import javax.management.MBeanServer;
58 import javax.management.ObjectName;
59 import java.io.IOException;
60 import java.lang.management.ManagementFactory;
61 import java.util.Iterator;
62 import java.util.List;
63 import java.util.concurrent.atomic.AtomicReference;
64
65 import static org.junit.Assert.assertEquals;
66 import static org.junit.Assert.assertNotNull;
67 import static org.junit.Assert.assertTrue;
68 import static org.junit.Assert.fail;
69
70 @Category({MediumTests.class})
71 public class TestRSGroups extends TestRSGroupsBase {
72 protected static final Log LOG = LogFactory.getLog(TestRSGroups.class);
73 private static HMaster master;
74 private static boolean init = false;
75 private static RSGroupAdminEndpoint RSGroupAdminEndpoint;
76
77
78 @BeforeClass
79 public static void setUp() throws Exception {
80 TEST_UTIL = new HBaseTestingUtility();
81 TEST_UTIL.getConfiguration().set(
82 HConstants.HBASE_MASTER_LOADBALANCER_CLASS,
83 RSGroupBasedLoadBalancer.class.getName());
84 TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
85 RSGroupAdminEndpoint.class.getName());
86 TEST_UTIL.getConfiguration().setBoolean(
87 HConstants.ZOOKEEPER_USEMULTI,
88 true);
89 TEST_UTIL.startMiniCluster(NUM_SLAVES_BASE);
90 TEST_UTIL.getConfiguration().set(
91 ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART,
92 ""+NUM_SLAVES_BASE);
93
94 admin = TEST_UTIL.getHBaseAdmin();
95 cluster = TEST_UTIL.getHBaseCluster();
96 master = ((MiniHBaseCluster)cluster).getMaster();
97
98
99 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
100 @Override
101 public boolean evaluate() throws Exception {
102 return master.isInitialized() &&
103 ((RSGroupBasedLoadBalancer) master.getLoadBalancer()).isOnline();
104 }
105 });
106 admin.setBalancerRunning(false,true);
107 rsGroupAdmin = new VerifyingRSGroupAdminClient(rsGroupAdmin.newClient(TEST_UTIL.getConnection()),
108 TEST_UTIL.getConfiguration());
109 RSGroupAdminEndpoint =
110 master.getMasterCoprocessorHost().findCoprocessors(RSGroupAdminEndpoint.class).get(0);
111 }
112
113 @AfterClass
114 public static void tearDown() throws Exception {
115 TEST_UTIL.shutdownMiniCluster();
116 }
117
118 @Before
119 public void beforeMethod() throws Exception {
120 if(!init) {
121 init = true;
122 afterMethod();
123 }
124
125 }
126
127 @After
128 public void afterMethod() throws Exception {
129 deleteTableIfNecessary();
130 deleteNamespaceIfNecessary();
131 deleteGroups();
132
133 int missing = NUM_SLAVES_BASE - getNumServers();
134 LOG.info("Restoring servers: "+missing);
135 for(int i=0; i<missing; i++) {
136 ((MiniHBaseCluster)cluster).startRegionServer();
137 }
138
139 rsGroupAdmin.addRSGroup("master");
140 ServerName masterServerName =
141 ((MiniHBaseCluster)cluster).getMaster().getServerName();
142
143 try {
144 rsGroupAdmin.moveServers(
145 Sets.newHashSet(masterServerName.getHostPort()),
146 "master");
147 } catch (Exception ex) {
148
149 }
150 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
151 @Override
152 public boolean evaluate() throws Exception {
153 LOG.info("Waiting for cleanup to finish " + rsGroupAdmin.listRSGroups());
154
155
156
157 return rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getServers().size()
158 == NUM_SLAVES_BASE;
159 }
160 });
161 }
162
163 @Test
164 public void testBasicStartUp() throws IOException {
165 RSGroupInfo defaultInfo = rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP);
166 assertEquals(4, defaultInfo.getServers().size());
167
168 int count = master.getAssignmentManager().getRegionStates().getRegionAssignments().size();
169
170 assertEquals(3, count);
171 }
172
173 @Test
174 public void testNamespaceCreateAndAssign() throws Exception {
175 LOG.info("testNamespaceCreateAndAssign");
176 String nsName = tablePrefix+"_foo";
177 final TableName tableName = TableName.valueOf(nsName, tablePrefix + "_testCreateAndAssign");
178 RSGroupInfo appInfo = addGroup(rsGroupAdmin, "appInfo", 1);
179 admin.createNamespace(NamespaceDescriptor.create(nsName)
180 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, "appInfo").build());
181 final HTableDescriptor desc = new HTableDescriptor(tableName);
182 desc.addFamily(new HColumnDescriptor("f"));
183 admin.createTable(desc);
184
185 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
186 @Override
187 public boolean evaluate() throws Exception {
188 return getTableRegionMap().get(desc.getTableName()) != null;
189 }
190 });
191 ServerName targetServer =
192 ServerName.parseServerName(appInfo.getServers().iterator().next().toString());
193 AdminProtos.AdminService.BlockingInterface rs = admin.getConnection().getAdmin(targetServer);
194
195 Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(rs).size());
196 }
197
198 @Test
199 public void testDefaultNamespaceCreateAndAssign() throws Exception {
200 LOG.info("testDefaultNamespaceCreateAndAssign");
201 final byte[] tableName = Bytes.toBytes(tablePrefix + "_testCreateAndAssign");
202 admin.modifyNamespace(NamespaceDescriptor.create("default")
203 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, "default").build());
204 final HTableDescriptor desc = new HTableDescriptor(tableName);
205 desc.addFamily(new HColumnDescriptor("f"));
206 admin.createTable(desc);
207
208 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
209 @Override
210 public boolean evaluate() throws Exception {
211 return getTableRegionMap().get(desc.getTableName()) != null;
212 }
213 });
214 }
215
216 @Test
217 public void testNamespaceConstraint() throws Exception {
218 String nsName = tablePrefix+"_foo";
219 String groupName = tablePrefix+"_foo";
220 LOG.info("testNamespaceConstraint");
221 rsGroupAdmin.addRSGroup(groupName);
222 admin.createNamespace(NamespaceDescriptor.create(nsName)
223 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, groupName)
224 .build());
225
226 try {
227 rsGroupAdmin.removeRSGroup(groupName);
228 fail("Expected a constraint exception");
229 } catch (IOException ex) {
230 }
231
232
233 admin.modifyNamespace(
234 NamespaceDescriptor.create(nsName)
235 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, groupName)
236 .build());
237 String anotherGroup = tablePrefix+"_anotherGroup";
238 rsGroupAdmin.addRSGroup(anotherGroup);
239
240 admin.deleteNamespace(nsName);
241 rsGroupAdmin.removeRSGroup(groupName);
242 try {
243 admin.createNamespace(NamespaceDescriptor.create(nsName)
244 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, "foo")
245 .build());
246 fail("Expected a constraint exception");
247 } catch (IOException ex) {
248 }
249 }
250
251 @Test
252 public void testGroupInfoMultiAccessing() throws Exception {
253 RSGroupInfoManager manager = RSGroupAdminEndpoint.getGroupInfoManager();
254 final RSGroupInfo defaultGroup = manager.getRSGroup("default");
255
256
257 Iterator<HostAndPort> it = defaultGroup.getServers().iterator();
258 manager.getRSGroup("default");
259 it.next();
260 }
261
262 @Test
263 public void testMisplacedRegions() throws Exception {
264 final TableName tableName = TableName.valueOf(tablePrefix+"_testMisplacedRegions");
265 LOG.info("testMisplacedRegions");
266
267 final RSGroupInfo RSGroupInfo = addGroup(rsGroupAdmin, "testMisplacedRegions", 1);
268
269 TEST_UTIL.createMultiRegionTable(tableName, new byte[]{'f'}, 15);
270 TEST_UTIL.waitUntilAllRegionsAssigned(tableName);
271
272 RSGroupAdminEndpoint.getGroupInfoManager()
273 .moveTables(Sets.newHashSet(tableName), RSGroupInfo.getName());
274
275 assertTrue(rsGroupAdmin.balanceRSGroup(RSGroupInfo.getName()));
276
277 TEST_UTIL.waitFor(60000, new Predicate<Exception>() {
278 @Override
279 public boolean evaluate() throws Exception {
280 ServerName serverName =
281 ServerName.valueOf(RSGroupInfo.getServers().iterator().next().toString(), 1);
282 return admin.getConnection().getAdmin()
283 .getOnlineRegions(serverName).size() == 15;
284 }
285 });
286 }
287 }