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 static org.junit.Assert.assertTrue;
22  
23  import java.io.IOException;
24  import java.util.List;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.hadoop.conf.Configuration;
29  import org.apache.hadoop.fs.FileSystem;
30  import org.apache.hadoop.fs.Path;
31  import org.apache.hadoop.hbase.HBaseTestingUtility;
32  import org.apache.hadoop.hbase.HColumnDescriptor;
33  import org.apache.hadoop.hbase.HRegionInfo;
34  import org.apache.hadoop.hbase.HTableDescriptor;
35  import org.apache.hadoop.hbase.MediumTests;
36  import org.apache.hadoop.hbase.MiniHBaseCluster;
37  import org.apache.hadoop.hbase.Server;
38  import org.apache.hadoop.hbase.TableName;
39  import org.apache.hadoop.hbase.master.HMaster;
40  import org.apache.hadoop.hbase.master.MasterFileSystem;
41  import org.apache.hadoop.hbase.master.MasterServices;
42  import org.apache.hadoop.hbase.master.RegionState.State;
43  import org.apache.hadoop.hbase.master.RegionStates;
44  import org.apache.hadoop.hbase.util.Bytes;
45  import org.apache.hadoop.hbase.util.FSUtils;
46  import org.junit.After;
47  import org.junit.Before;
48  import org.junit.Test;
49  import org.junit.experimental.categories.Category;
50  
51  @Category(MediumTests.class)
52  public class TestCreateTableHandler {
53    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
54    private static final Log LOG = LogFactory.getLog(TestCreateTableHandler.class);
55    private static final byte[] FAMILYNAME = Bytes.toBytes("fam");
56    private static boolean throwException = false;
57    
58  
59    @Before
60    public void setUp() throws Exception {
61      TEST_UTIL.startMiniCluster(1);
62    }
63  
64    @After
65    public void tearDown() throws Exception {
66      TEST_UTIL.shutdownMiniCluster();
67      throwException = false;
68    }
69  
70    @Test (timeout=300000)
71    public void testCreateTableCalledTwiceAndFirstOneInProgress() throws Exception {
72      final byte[] tableName = Bytes.toBytes("testCreateTableCalledTwiceAndFirstOneInProgress");
73      final MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
74      final HMaster m = cluster.getMaster();
75      final HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
76      desc.addFamily(new HColumnDescriptor(FAMILYNAME));
77      final HRegionInfo[] hRegionInfos = new HRegionInfo[] { new HRegionInfo(desc.getTableName(), null,
78          null) };
79      CustomCreateTableHandler handler = new CustomCreateTableHandler(m, m.getMasterFileSystem(),
80          desc, cluster.getConfiguration(), hRegionInfos, m);
81      handler.prepare();
82      throwException = true;
83      handler.process();
84      throwException = false;
85      CustomCreateTableHandler handler1 = new CustomCreateTableHandler(m, m.getMasterFileSystem(),
86          desc, cluster.getConfiguration(), hRegionInfos, m);
87      handler1.prepare();
88      handler1.process();
89      for (int i = 0; i < 100; i++) {
90        if (!TEST_UTIL.getHBaseAdmin().isTableAvailable(tableName)) {
91          Thread.sleep(200);
92        }
93      }
94      assertTrue(TEST_UTIL.getHBaseAdmin().isTableEnabled(tableName));
95    }
96  
97    @Test (timeout=300000)
98    public void testCreateTableWithSplitRegion() throws Exception {
99      final byte[] tableName = Bytes.toBytes("testCreateTableWithSplitRegion");
100     final MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
101     final HMaster m = cluster.getMaster();
102     final HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
103     desc.addFamily(new HColumnDescriptor(FAMILYNAME));
104     byte[] splitPoint = Bytes.toBytes("split-point");
105     long ts = System.currentTimeMillis();
106     HRegionInfo d1 = new HRegionInfo(desc.getTableName(), null, splitPoint, false, ts);
107     HRegionInfo d2 = new HRegionInfo(desc.getTableName(), splitPoint, null, false, ts + 1);
108     HRegionInfo parent = new HRegionInfo(desc.getTableName(), null, null, true, ts + 2);
109     parent.setOffline(true);
110 
111     Path tempdir = m.getMasterFileSystem().getTempDir();
112     FileSystem fs = m.getMasterFileSystem().getFileSystem();
113     Path tempTableDir = FSUtils.getTableDir(tempdir, desc.getTableName());
114     fs.delete(tempTableDir, true); // Clean up temp table dir if exists
115 
116     final HRegionInfo[] hRegionInfos = new HRegionInfo[] {d1, d2, parent};
117     CreateTableHandler handler = new CreateTableHandler(m, m.getMasterFileSystem(),
118       desc, cluster.getConfiguration(), hRegionInfos, m);
119     handler.prepare();
120     handler.process();
121     for (int i = 0; i < 100; i++) {
122       if (!TEST_UTIL.getHBaseAdmin().isTableAvailable(tableName)) {
123         Thread.sleep(300);
124       }
125     }
126     assertTrue(TEST_UTIL.getHBaseAdmin().isTableEnabled(tableName));
127     assertTrue(TEST_UTIL.getHBaseAdmin().isTableAvailable(tableName));
128     assertTrue(TEST_UTIL.getHBaseAdmin().isTableAvailable(tableName, new byte[][] { splitPoint }));
129     RegionStates regionStates = m.getAssignmentManager().getRegionStates();
130     assertTrue("Parent should be in SPLIT state",
131       regionStates.isRegionInState(parent, State.SPLIT));
132   }
133 
134   @Test (timeout=60000)
135   public void testMasterRestartAfterEnablingNodeIsCreated() throws Exception {
136     byte[] tableName = Bytes.toBytes("testMasterRestartAfterEnablingNodeIsCreated");
137     final MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
138     final HMaster m = cluster.getMaster();
139     final HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
140     desc.addFamily(new HColumnDescriptor(FAMILYNAME));
141     final HRegionInfo[] hRegionInfos = new HRegionInfo[] { new HRegionInfo(desc.getTableName(), null,
142         null) };
143     CustomCreateTableHandler handler = new CustomCreateTableHandler(m, m.getMasterFileSystem(),
144         desc, cluster.getConfiguration(), hRegionInfos, m);
145     handler.prepare();
146     throwException = true;
147     handler.process();
148     abortAndStartNewMaster(cluster);
149     assertTrue(cluster.getLiveMasterThreads().size() == 1);
150   }
151 
152   private void abortAndStartNewMaster(final MiniHBaseCluster cluster) throws IOException {
153     cluster.abortMaster(0);
154     cluster.waitOnMaster(0);
155     LOG.info("Starting new master");
156     cluster.startMaster();
157     LOG.info("Waiting for master to become active.");
158     cluster.waitForActiveAndReadyMaster();
159   }
160 
161   private static class CustomCreateTableHandler extends CreateTableHandler {
162     public CustomCreateTableHandler(Server server, MasterFileSystem fileSystemManager,
163         HTableDescriptor hTableDescriptor, Configuration conf, HRegionInfo[] newRegions,
164         MasterServices masterServices) {
165       super(server, fileSystemManager, hTableDescriptor, conf, newRegions, masterServices);
166     }
167 
168     @Override
169     protected List<HRegionInfo> handleCreateHdfsRegions(Path tableRootDir,
170         TableName tableName) throws IOException {
171       if (throwException) {
172         throw new IOException("Test throws exceptions.");
173       }
174       return super.handleCreateHdfsRegions(tableRootDir, tableName);
175     }
176   }
177 }