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;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.io.IOException;
25  import java.util.List;
26  import java.util.NavigableSet;
27  import java.util.TreeSet;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.apache.hadoop.conf.Configuration;
32  import org.apache.hadoop.hbase.*;
33  import org.apache.hadoop.hbase.client.HBaseAdmin;
34  import org.apache.hadoop.hbase.client.HTable;
35  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
36  import org.apache.hadoop.hbase.util.Bytes;
37  import org.apache.hadoop.hbase.util.JVMClusterUtil.MasterThread;
38  import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
39  import org.apache.hadoop.hbase.zookeeper.ZKAssign;
40  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
41  import org.apache.zookeeper.KeeperException;
42  import org.junit.Test;
43  import org.junit.experimental.categories.Category;
44  
45  @Category(LargeTests.class)
46  public class TestMasterRestartAfterDisablingTable {
47  
48    private static final Log LOG = LogFactory.getLog(TestMasterRestartAfterDisablingTable.class);
49  
50    @Test
51    public void testForCheckingIfEnableAndDisableWorksFineAfterSwitch()
52        throws Exception {
53      final int NUM_MASTERS = 2;
54      final int NUM_RS = 1;
55      final int NUM_REGIONS_TO_CREATE = 4;
56  
57      // Start the cluster
58      log("Starting cluster");
59      Configuration conf = HBaseConfiguration.create();
60      conf.setInt("hbase.master.assignment.timeoutmonitor.period", 2000);
61      conf.setInt("hbase.master.assignment.timeoutmonitor.timeout", 5000);
62      HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(conf);
63      TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS);
64      MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
65      log("Waiting for active/ready master");
66      cluster.waitForActiveAndReadyMaster();
67      ZooKeeperWatcher zkw = new ZooKeeperWatcher(conf, "testmasterRestart", null);
68      HMaster master = cluster.getMaster();
69  
70      // Create a table with regions
71      byte[] table = Bytes.toBytes("tableRestart");
72      byte[] family = Bytes.toBytes("family");
73      log("Creating table with " + NUM_REGIONS_TO_CREATE + " regions");
74      HTable ht = TEST_UTIL.createTable(table, family);
75      int numRegions = TEST_UTIL.createMultiRegions(conf, ht, family,
76          NUM_REGIONS_TO_CREATE);
77      numRegions += 1; // catalogs
78      log("Waiting for no more RIT\n");
79      blockUntilNoRIT(zkw, master);
80      log("Disabling table\n");
81      TEST_UTIL.getHBaseAdmin().disableTable(table);
82  
83      NavigableSet<String> regions = getAllOnlineRegions(cluster);
84      assertEquals(
85          "The number of regions for the table tableRestart should be 0 and only"
86              + "the catalog and namespace tables should be present.", 2, regions.size());
87  
88      List<MasterThread> masterThreads = cluster.getMasterThreads();
89      MasterThread activeMaster = null;
90      if (masterThreads.get(0).getMaster().isActiveMaster()) {
91        activeMaster = masterThreads.get(0);
92      } else {
93        activeMaster = masterThreads.get(1);
94      }
95      activeMaster.getMaster().stop(
96          "stopping the active master so that the backup can become active");
97      cluster.hbaseCluster.waitOnMaster(activeMaster);
98      cluster.waitForActiveAndReadyMaster();
99  
100     assertTrue("The table should not be in enabled state", cluster.getMaster()
101         .getAssignmentManager().getZKTable().isDisablingOrDisabledTable(
102             TableName.valueOf("tableRestart")));
103     log("Enabling table\n");
104     // Need a new Admin, the previous one is on the old master
105     HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
106     admin.enableTable(table);
107     admin.close();
108     log("Waiting for no more RIT\n");
109     blockUntilNoRIT(zkw, master);
110     log("Verifying there are " + numRegions + " assigned on cluster\n");
111     regions = getAllOnlineRegions(cluster);
112     assertEquals(
113         "The assigned regions were not onlined after master switch except for the catalog and namespace tables.",
114         6, regions.size());
115     assertTrue("The table should be in enabled state", cluster.getMaster()
116         .getAssignmentManager().getZKTable()
117         .isEnabledTable(TableName.valueOf("tableRestart")));
118     ht.close();
119     TEST_UTIL.shutdownMiniCluster();
120   }
121 
122   private void log(String msg) {
123     LOG.debug("\n\nTRR: " + msg + "\n");
124   }
125 
126   private void blockUntilNoRIT(ZooKeeperWatcher zkw, HMaster master)
127       throws KeeperException, InterruptedException {
128     ZKAssign.blockUntilNoRIT(zkw);
129     master.assignmentManager.waitUntilNoRegionsInTransition(60000);
130   }
131 
132   private NavigableSet<String> getAllOnlineRegions(MiniHBaseCluster cluster)
133       throws IOException {
134     NavigableSet<String> online = new TreeSet<String>();
135     for (RegionServerThread rst : cluster.getLiveRegionServerThreads()) {
136       for (HRegionInfo region : ProtobufUtil.getOnlineRegions(rst.getRegionServer())) {
137         online.add(region.getRegionNameAsString());
138       }
139     }
140     return online;
141   }
142 
143 }
144