View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.master.handler;
20  
21  import java.io.IOException;
22  import java.util.concurrent.CountDownLatch;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.hbase.HBaseTestingUtility;
27  import org.apache.hadoop.hbase.HColumnDescriptor;
28  import org.apache.hadoop.hbase.HRegionInfo;
29  import org.apache.hadoop.hbase.HTableDescriptor;
30  import org.apache.hadoop.hbase.TableName;
31  import org.apache.hadoop.hbase.Waiter;
32  import org.apache.hadoop.hbase.client.HBaseAdmin;
33  import org.apache.hadoop.hbase.coprocessor.BaseMasterObserver;
34  import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
35  import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
36  import org.apache.hadoop.hbase.coprocessor.ObserverContext;
37  import org.apache.hadoop.hbase.testclassification.MediumTests;
38  import org.apache.hadoop.hbase.util.Bytes;
39  import org.junit.After;
40  import org.junit.Before;
41  import org.junit.Test;
42  import org.junit.experimental.categories.Category;
43  
44  @Category({ MediumTests.class })
45  public class TestEnableTableHandler {
46    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
47    private static final Log LOG = LogFactory.getLog(TestEnableTableHandler.class);
48    private static final byte[] FAMILYNAME = Bytes.toBytes("fam");
49  
50    @Before
51    public void setUp() throws Exception {
52      TEST_UTIL.getConfiguration().set("hbase.balancer.tablesOnMaster", "hbase:meta");
53      TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
54          MasterSyncObserver.class.getName());
55      TEST_UTIL.startMiniCluster(1, 2);
56    }
57  
58    @After
59    public void tearDown() throws Exception {
60      TEST_UTIL.shutdownMiniCluster();
61    }
62  
63    @Test(timeout = 300000)
64    public void testDisableTableAndRestart() throws Exception {
65      final TableName tableName = TableName.valueOf("testDisableTableAndRestart");
66      final HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
67      final HTableDescriptor desc = new HTableDescriptor(tableName);
68      desc.addFamily(new HColumnDescriptor(FAMILYNAME));
69      admin.createTable(desc);
70      admin.disableTable(tableName);
71      TEST_UTIL.waitTableDisabled(tableName.getName());
72  
73      TEST_UTIL.getHBaseCluster().shutdown();
74      TEST_UTIL.getHBaseCluster().waitUntilShutDown();
75  
76      TEST_UTIL.restartHBaseCluster(2);
77  
78      final HBaseAdmin newAdmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
79      newAdmin.enableTable(tableName);
80      TEST_UTIL.waitFor(10000, new Waiter.Predicate<Exception>() {
81        @Override
82        public boolean evaluate() throws Exception {
83          return newAdmin.isTableAvailable(tableName);
84        }
85      });
86    }
87  
88    public static class MasterSyncObserver extends BaseMasterObserver {
89      volatile CountDownLatch tableCreationLatch = null;
90      volatile CountDownLatch tableDeletionLatch = null;
91  
92      @Override
93      public void postCreateTableHandler(final ObserverContext<MasterCoprocessorEnvironment> ctx,
94          HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
95        // the AccessController test, some times calls only and directly the postCreateTableHandler()
96        if (tableCreationLatch != null) {
97          tableCreationLatch.countDown();
98        }
99      }
100 
101     @Override
102     public void postDeleteTableHandler(final ObserverContext<MasterCoprocessorEnvironment> ctx,
103         TableName tableName)
104         throws IOException {
105       // the AccessController test, some times calls only and directly the postDeleteTableHandler()
106       if (tableDeletionLatch != null) {
107         tableDeletionLatch.countDown();
108       }
109     }
110   }
111 
112   public static void createTable(HBaseTestingUtility testUtil, HTableDescriptor htd,
113       byte[][] splitKeys)
114       throws Exception {
115     createTable(testUtil, testUtil.getHBaseAdmin(), htd, splitKeys);
116   }
117 
118   public static void createTable(HBaseTestingUtility testUtil, HBaseAdmin admin,
119       HTableDescriptor htd, byte[][] splitKeys)
120       throws Exception {
121     // NOTE: We need a latch because admin is not sync,
122     // so the postOp coprocessor method may be called after the admin operation returned.
123     MasterSyncObserver observer = (MasterSyncObserver) testUtil.getHBaseCluster().getMaster()
124         .getCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
125     observer.tableCreationLatch = new CountDownLatch(1);
126     if (splitKeys != null) {
127       admin.createTable(htd, splitKeys);
128     } else {
129       admin.createTable(htd);
130     }
131     observer.tableCreationLatch.await();
132     observer.tableCreationLatch = null;
133     testUtil.waitUntilAllRegionsAssigned(htd.getTableName());
134   }
135 
136   public static void deleteTable(HBaseTestingUtility testUtil, TableName tableName)
137       throws Exception {
138     deleteTable(testUtil, testUtil.getHBaseAdmin(), tableName);
139   }
140 
141   public static void deleteTable(HBaseTestingUtility testUtil, HBaseAdmin admin,
142       TableName tableName)
143       throws Exception {
144     // NOTE: We need a latch because admin is not sync,
145     // so the postOp coprocessor method may be called after the admin operation returned.
146     MasterSyncObserver observer = (MasterSyncObserver) testUtil.getHBaseCluster().getMaster()
147         .getCoprocessorHost().findCoprocessor(MasterSyncObserver.class.getName());
148     observer.tableDeletionLatch = new CountDownLatch(1);
149     try {
150       admin.disableTable(tableName);
151     } catch (Exception e) {
152       LOG.debug("Table: " + tableName + " already disabled, so just deleting it.");
153     }
154     admin.deleteTable(tableName);
155     observer.tableDeletionLatch.await();
156     observer.tableDeletionLatch = null;
157   }
158 }