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