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.master.snapshot.SnapshotManager;
43 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
44 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
45 import org.apache.hadoop.hbase.testclassification.MediumTests;
46 import org.apache.hadoop.hbase.util.Bytes;
47 import org.junit.After;
48 import org.junit.AfterClass;
49 import org.junit.Assert;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 import org.junit.Test;
53 import org.junit.experimental.categories.Category;
54 import org.mockito.Mockito;
55 import org.mockito.invocation.InvocationOnMock;
56 import org.mockito.stubbing.Answer;
57
58 import javax.management.MBeanServer;
59 import javax.management.ObjectName;
60 import java.io.IOException;
61 import java.lang.management.ManagementFactory;
62 import java.util.Iterator;
63 import java.util.List;
64 import java.util.concurrent.atomic.AtomicReference;
65
66 import static org.junit.Assert.assertEquals;
67 import static org.junit.Assert.assertNotNull;
68 import static org.junit.Assert.assertTrue;
69 import static org.junit.Assert.fail;
70
71 @Category({MediumTests.class})
72 public class TestRSGroups extends TestRSGroupsBase {
73 protected static final Log LOG = LogFactory.getLog(TestRSGroups.class);
74 private static HMaster master;
75 private static boolean init = false;
76 private static RSGroupAdminEndpoint RSGroupAdminEndpoint;
77
78
79 @BeforeClass
80 public static void setUp() throws Exception {
81 TEST_UTIL = new HBaseTestingUtility();
82 conf = TEST_UTIL.getConfiguration();
83 conf.set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, RSGroupBasedLoadBalancer.class.getName());
84 conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, RSGroupAdminEndpoint.class.getName());
85 conf.setBoolean(HConstants.ZOOKEEPER_USEMULTI, true);
86 final int numSlaves = conf.getInt(NUM_SLAVES_BASE_KEY, DEFAULT_NUM_SLAVES_BASE);
87 TEST_UTIL.startMiniCluster(numSlaves);
88 conf.set(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, Integer.toString(numSlaves));
89 TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
90
91 admin = TEST_UTIL.getHBaseAdmin();
92 cluster = TEST_UTIL.getHBaseCluster();
93 master = ((MiniHBaseCluster)cluster).getMaster();
94
95
96 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
97 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
98 @Override
99 public boolean evaluate() throws Exception {
100 return master.isInitialized() &&
101 ((RSGroupBasedLoadBalancer) master.getLoadBalancer()).isOnline();
102 }
103 });
104 admin.setBalancerRunning(false,true);
105 rsGroupAdmin = new VerifyingRSGroupAdminClient(rsGroupAdmin.newClient(TEST_UTIL.getConnection()),
106 conf);
107 RSGroupAdminEndpoint =
108 master.getMasterCoprocessorHost().findCoprocessors(RSGroupAdminEndpoint.class).get(0);
109 }
110
111 @AfterClass
112 public static void tearDown() throws Exception {
113 TEST_UTIL.shutdownMiniCluster();
114 }
115
116 @Before
117 public void beforeMethod() throws Exception {
118 if(!init) {
119 init = true;
120 afterMethod();
121 }
122
123 }
124
125 @After
126 public void afterMethod() throws Exception {
127 deleteTableIfNecessary();
128 deleteNamespaceIfNecessary();
129 deleteGroups();
130
131 final int numSlaves = conf.getInt(NUM_SLAVES_BASE_KEY, DEFAULT_NUM_SLAVES_BASE);
132 int missing = numSlaves - getNumServers();
133 LOG.info("Restoring servers: "+missing);
134 for(int i=0; i<missing; i++) {
135 ((MiniHBaseCluster)cluster).startRegionServer();
136 }
137
138 rsGroupAdmin.addRSGroup("master");
139 ServerName masterServerName =
140 ((MiniHBaseCluster)cluster).getMaster().getServerName();
141
142 try {
143 rsGroupAdmin.moveServers(
144 Sets.newHashSet(masterServerName.getHostPort()),
145 "master");
146 } catch (Exception ex) {
147
148 }
149 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
150 TEST_UTIL.waitFor(waitTimeout, 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 == numSlaves;
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 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
186 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
187 @Override
188 public boolean evaluate() throws Exception {
189 return getTableRegionMap().get(desc.getTableName()) != null;
190 }
191 });
192 ServerName targetServer =
193 ServerName.parseServerName(appInfo.getServers().iterator().next().toString());
194 AdminProtos.AdminService.BlockingInterface rs = admin.getConnection().getAdmin(targetServer);
195
196 Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(rs).size());
197 }
198
199 @Test
200 public void testDefaultNamespaceCreateAndAssign() throws Exception {
201 LOG.info("testDefaultNamespaceCreateAndAssign");
202 final byte[] tableName = Bytes.toBytes(tablePrefix + "_testCreateAndAssign");
203 admin.modifyNamespace(NamespaceDescriptor.create("default")
204 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, "default").build());
205 final HTableDescriptor desc = new HTableDescriptor(tableName);
206 desc.addFamily(new HColumnDescriptor("f"));
207 admin.createTable(desc);
208
209 final long waitTimeout = conf.getLong(WAIT_TIMEOUT_KEY, DEFAULT_WAIT_TIMEOUT);
210 TEST_UTIL.waitFor(waitTimeout, new Waiter.Predicate<Exception>() {
211 @Override
212 public boolean evaluate() throws Exception {
213 return getTableRegionMap().get(desc.getTableName()) != null;
214 }
215 });
216 }
217
218 @Test
219 public void testNamespaceConstraint() throws Exception {
220 String nsName = tablePrefix+"_foo";
221 String groupName = tablePrefix+"_foo";
222 LOG.info("testNamespaceConstraint");
223 rsGroupAdmin.addRSGroup(groupName);
224 admin.createNamespace(NamespaceDescriptor.create(nsName)
225 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, groupName)
226 .build());
227
228 try {
229 rsGroupAdmin.removeRSGroup(groupName);
230 fail("Expected a constraint exception");
231 } catch (IOException ex) {
232 }
233
234
235 admin.modifyNamespace(
236 NamespaceDescriptor.create(nsName)
237 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, groupName)
238 .build());
239 String anotherGroup = tablePrefix+"_anotherGroup";
240 rsGroupAdmin.addRSGroup(anotherGroup);
241
242 admin.deleteNamespace(nsName);
243 rsGroupAdmin.removeRSGroup(groupName);
244 try {
245 admin.createNamespace(NamespaceDescriptor.create(nsName)
246 .addConfiguration(RSGroupInfo.NAMESPACEDESC_PROP_GROUP, "foo")
247 .build());
248 fail("Expected a constraint exception");
249 } catch (IOException ex) {
250 }
251 }
252
253 @Test
254 public void testGroupInfoMultiAccessing() throws Exception {
255 RSGroupInfoManager manager = RSGroupAdminEndpoint.getGroupInfoManager();
256 final RSGroupInfo defaultGroup = manager.getRSGroup("default");
257
258
259 Iterator<HostAndPort> it = defaultGroup.getServers().iterator();
260 manager.getRSGroup("default");
261 it.next();
262 }
263
264 @Test
265 public void testMisplacedRegions() throws Exception {
266 final TableName tableName = TableName.valueOf(tablePrefix+"_testMisplacedRegions");
267 LOG.info("testMisplacedRegions");
268
269 final RSGroupInfo RSGroupInfo = addGroup(rsGroupAdmin, "testMisplacedRegions", 1);
270
271 TEST_UTIL.createMultiRegionTable(tableName, new byte[]{'f'}, 15);
272 TEST_UTIL.waitUntilAllRegionsAssigned(tableName);
273
274 RSGroupAdminEndpoint.getGroupInfoManager()
275 .moveTables(Sets.newHashSet(tableName), RSGroupInfo.getName());
276
277 assertTrue(rsGroupAdmin.balanceRSGroup(RSGroupInfo.getName()));
278
279 TEST_UTIL.waitFor(60000, new Predicate<Exception>() {
280 @Override
281 public boolean evaluate() throws Exception {
282 ServerName serverName =
283 ServerName.valueOf(RSGroupInfo.getServers().iterator().next().toString(), 1);
284 return admin.getConnection().getAdmin()
285 .getOnlineRegions(serverName).size() == 15;
286 }
287 });
288 }
289
290 @Test
291 public void testCloneSnapshot() throws Exception {
292 byte[] FAMILY = Bytes.toBytes("test");
293 final TableName tableName = TableName.valueOf(tablePrefix + "_testCloneSnapshot");
294 String snapshotName = tableName.getNameAsString() + "_snap";
295 TableName clonedTableName = TableName.valueOf(tableName.getNameAsString() + "_clone");
296
297
298 TEST_UTIL.createTable(tableName, FAMILY);
299
300
301 admin.snapshot(snapshotName, tableName);
302
303
304 admin.cloneSnapshot(snapshotName, clonedTableName);
305 }
306
307 }