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