1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master.handler;
20
21 import java.io.IOException;
22 import java.util.concurrent.CountDownLatch;
23 import java.util.List;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.hbase.HConstants;
28 import org.apache.hadoop.hbase.MetaTableAccessor;
29 import org.apache.hadoop.hbase.HBaseTestingUtility;
30 import org.apache.hadoop.hbase.HColumnDescriptor;
31 import org.apache.hadoop.hbase.HRegionInfo;
32 import org.apache.hadoop.hbase.HTableDescriptor;
33 import org.apache.hadoop.hbase.MiniHBaseCluster;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.client.Delete;
36 import org.apache.hadoop.hbase.client.HBaseAdmin;
37 import org.apache.hadoop.hbase.client.Result;
38 import org.apache.hadoop.hbase.client.ResultScanner;
39 import org.apache.hadoop.hbase.client.Table;
40 import org.apache.hadoop.hbase.coprocessor.BaseMasterObserver;
41 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
42 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
43 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
44 import org.apache.hadoop.hbase.master.HMaster;
45 import org.apache.hadoop.hbase.testclassification.MediumTests;
46 import org.apache.hadoop.hbase.util.Bytes;
47 import org.apache.hadoop.hbase.util.JVMClusterUtil;
48 import org.junit.After;
49 import org.junit.Before;
50 import org.junit.Test;
51 import org.junit.experimental.categories.Category;
52
53 import static org.junit.Assert.assertEquals;
54 import static org.junit.Assert.assertTrue;
55 import static org.junit.Assert.fail;
56
57 @Category({ MediumTests.class })
58 public class TestEnableTableHandler {
59 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
60 private static final Log LOG = LogFactory.getLog(TestEnableTableHandler.class);
61 private static final byte[] FAMILYNAME = Bytes.toBytes("fam");
62
63 @Before
64 public void setUp() throws Exception {
65 TEST_UTIL.getConfiguration().set("hbase.balancer.tablesOnMaster", "hbase:meta");
66 TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
67 MasterSyncObserver.class.getName());
68 TEST_UTIL.startMiniCluster(1);
69 }
70
71 @After
72 public void tearDown() throws Exception {
73 TEST_UTIL.shutdownMiniCluster();
74 }
75
76 @Test(timeout = 300000)
77 public void testEnableTableWithNoRegionServers() throws Exception {
78 final TableName tableName = TableName.valueOf("testEnableTableWithNoRegionServers");
79 final MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
80 final HMaster m = cluster.getMaster();
81 final HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
82 final HTableDescriptor desc = new HTableDescriptor(tableName);
83 desc.addFamily(new HColumnDescriptor(FAMILYNAME));
84 admin.createTable(desc);
85 admin.disableTable(tableName);
86 TEST_UTIL.waitTableDisabled(tableName.getName());
87
88 admin.enableTable(tableName);
89 TEST_UTIL.waitTableEnabled(tableName);
90
91
92 admin.disableTable(tableName);
93
94 TEST_UTIL.waitUntilNoRegionsInTransition(60000);
95
96 JVMClusterUtil.RegionServerThread rs = cluster.getRegionServerThreads().get(0);
97 rs.getRegionServer().stop("stop");
98 cluster.waitForRegionServerToStop(rs.getRegionServer().getServerName(), 10000);
99
100 TEST_UTIL.waitUntilAllRegionsAssigned(TableName.META_TABLE_NAME);
101
102 admin.enableTable(tableName);
103 assertTrue(admin.isTableEnabled(tableName));
104
105 JVMClusterUtil.RegionServerThread rs2 = cluster.startRegionServer();
106 m.getAssignmentManager().assign(admin.getTableRegions(tableName));
107 TEST_UTIL.waitUntilAllRegionsAssigned(tableName);
108 List<HRegionInfo> onlineRegions = admin.getOnlineRegions(
109 rs2.getRegionServer().getServerName());
110 assertEquals(2, onlineRegions.size());
111 assertEquals(tableName, onlineRegions.get(1).getTable());
112 }
113
114
115 @Test(timeout = 300000)
116 public void testDisableTableAndRestart() throws Exception {
117 final TableName tableName = TableName.valueOf("testDisableTableAndRestart");
118 final MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
119 final HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
120 final HTableDescriptor desc = new HTableDescriptor(tableName);
121 desc.addFamily(new HColumnDescriptor(FAMILYNAME));
122 admin.createTable(desc);
123 admin.disableTable(tableName);
124 TEST_UTIL.waitTableDisabled(tableName.getName());
125
126 TEST_UTIL.getHBaseCluster().shutdown();
127 TEST_UTIL.getHBaseCluster().waitUntilShutDown();
128
129 TEST_UTIL.restartHBaseCluster(2);
130
131 admin.enableTable(tableName);
132 TEST_UTIL.waitTableEnabled(tableName);
133 }
134
135
136
137
138
139
140
141
142 @Test(timeout=60000)
143 public void testDeleteForSureClearsAllTableRowsFromMeta()
144 throws IOException, InterruptedException {
145 final TableName tableName = TableName.valueOf("testDeleteForSureClearsAllTableRowsFromMeta");
146 final HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
147 final HTableDescriptor desc = new HTableDescriptor(tableName);
148 desc.addFamily(new HColumnDescriptor(FAMILYNAME));
149 try {
150 createTable(TEST_UTIL, desc, HBaseTestingUtility.KEYS_FOR_HBA_CREATE_TABLE);
151 } catch (Exception e) {
152 e.printStackTrace();
153 fail("Got an exception while creating " + tableName);
154 }
155
156
157 try (Table metaTable = TEST_UTIL.getConnection().getTable(TableName.META_TABLE_NAME)) {
158 try (ResultScanner scanner =
159 metaTable.getScanner(MetaTableAccessor.getScanForTableName(tableName))) {
160 for (Result result : scanner) {
161
162 Delete d = new Delete(result.getRow());
163 d.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
164 LOG.info("Mangled: " + d);
165 metaTable.delete(d);
166 break;
167 }
168 }
169 admin.disableTable(tableName);
170 TEST_UTIL.waitTableDisabled(tableName.getName());
171
172 try {
173 deleteTable(TEST_UTIL, tableName);
174 } catch (Exception e) {
175 e.printStackTrace();
176 fail("Got an exception while deleting " + tableName);
177 }
178 int rowCount = 0;
179 try (ResultScanner scanner =
180 metaTable.getScanner(MetaTableAccessor.getScanForTableName(tableName))) {
181 for (Result result : scanner) {
182 LOG.info("Found when none expected: " + result);
183 rowCount++;
184 }
185 }
186 assertEquals(0, rowCount);
187 }
188 }
189
190 public static class MasterSyncObserver extends BaseMasterObserver {
191 volatile CountDownLatch tableCreationLatch = null;
192 volatile CountDownLatch tableDeletionLatch = null;
193
194 @Override
195 public void postCreateTableHandler(final ObserverContext<MasterCoprocessorEnvironment> ctx,
196 HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
197
198 if (tableCreationLatch != null) {
199 tableCreationLatch.countDown();
200 }
201 }
202
203 @Override
204 public void postDeleteTableHandler(final ObserverContext<MasterCoprocessorEnvironment> ctx,
205 TableName tableName)
206 throws IOException {
207
208 if (tableDeletionLatch != null) {
209 tableDeletionLatch.countDown();
210 }
211 }
212 }
213
214 public static void createTable(HBaseTestingUtility testUtil, HTableDescriptor htd,
215 byte [][] splitKeys)
216 throws Exception {
217 createTable(testUtil, testUtil.getHBaseAdmin(), htd, splitKeys);
218 }
219
220 public static void createTable(HBaseTestingUtility testUtil, HBaseAdmin admin,
221 HTableDescriptor htd, byte [][] splitKeys)
222 throws Exception {
223
224
225 MasterSyncObserver observer = (MasterSyncObserver)testUtil.getHBaseCluster().getMaster()
226 .getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
227 observer.tableCreationLatch = new CountDownLatch(1);
228 if (splitKeys != null) {
229 admin.createTable(htd, splitKeys);
230 } else {
231 admin.createTable(htd);
232 }
233 observer.tableCreationLatch.await();
234 observer.tableCreationLatch = null;
235 testUtil.waitUntilAllRegionsAssigned(htd.getTableName());
236 }
237
238 public static void deleteTable(HBaseTestingUtility testUtil, TableName tableName)
239 throws Exception {
240 deleteTable(testUtil, testUtil.getHBaseAdmin(), tableName);
241 }
242
243 public static void deleteTable(HBaseTestingUtility testUtil, HBaseAdmin admin,
244 TableName tableName)
245 throws Exception {
246
247
248 MasterSyncObserver observer = (MasterSyncObserver)testUtil.getHBaseCluster().getMaster()
249 .getMasterCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
250 observer.tableDeletionLatch = new CountDownLatch(1);
251 try {
252 admin.disableTable(tableName);
253 } catch (Exception e) {
254 LOG.debug("Table: " + tableName + " already disabled, so just deleting it.");
255 }
256 admin.deleteTable(tableName);
257 observer.tableDeletionLatch.await();
258 observer.tableDeletionLatch = null;
259 }
260 }