2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.client
;
20 import static org
.apache
.hadoop
.hbase
.TableName
.META_TABLE_NAME
;
21 import static org
.hamcrest
.CoreMatchers
.instanceOf
;
22 import static org
.junit
.Assert
.assertEquals
;
23 import static org
.junit
.Assert
.assertFalse
;
24 import static org
.junit
.Assert
.assertThat
;
25 import static org
.junit
.Assert
.assertTrue
;
26 import static org
.junit
.Assert
.fail
;
28 import java
.util
.ArrayList
;
29 import java
.util
.Collections
;
30 import java
.util
.List
;
31 import java
.util
.concurrent
.ExecutionException
;
32 import java
.util
.stream
.Collectors
;
33 import org
.apache
.hadoop
.hbase
.AsyncMetaTableAccessor
;
34 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
35 import org
.apache
.hadoop
.hbase
.HConstants
;
36 import org
.apache
.hadoop
.hbase
.HRegionLocation
;
37 import org
.apache
.hadoop
.hbase
.TableName
;
38 import org
.apache
.hadoop
.hbase
.testclassification
.ClientTests
;
39 import org
.apache
.hadoop
.hbase
.testclassification
.LargeTests
;
40 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
41 import org
.apache
.hadoop
.hbase
.util
.Threads
;
42 import org
.junit
.ClassRule
;
43 import org
.junit
.Ignore
;
44 import org
.junit
.Test
;
45 import org
.junit
.experimental
.categories
.Category
;
46 import org
.junit
.runner
.RunWith
;
47 import org
.junit
.runners
.Parameterized
;
50 * Class to test asynchronous region admin operations.
51 * @see TestAsyncRegionAdminApi This test and it used to be joined it was taking longer than our
52 * ten minute timeout so they were split.
54 @RunWith(Parameterized
.class)
55 @Category({ LargeTests
.class, ClientTests
.class })
56 public class TestAsyncRegionAdminApi2
extends TestAsyncAdminBase
{
59 public static final HBaseClassTestRule CLASS_RULE
=
60 HBaseClassTestRule
.forClass(TestAsyncRegionAdminApi2
.class);
63 public void testGetRegionLocation() throws Exception
{
64 RawAsyncHBaseAdmin rawAdmin
= (RawAsyncHBaseAdmin
) ASYNC_CONN
.getAdmin();
65 TEST_UTIL
.createMultiRegionTable(tableName
, HConstants
.CATALOG_FAMILY
);
66 AsyncTableRegionLocator locator
= ASYNC_CONN
.getRegionLocator(tableName
);
67 HRegionLocation regionLocation
= locator
.getRegionLocation(Bytes
.toBytes("mmm")).get();
68 RegionInfo region
= regionLocation
.getRegion();
69 byte[] regionName
= regionLocation
.getRegion().getRegionName();
70 HRegionLocation location
= rawAdmin
.getRegionLocation(regionName
).get();
71 assertTrue(Bytes
.equals(regionName
, location
.getRegion().getRegionName()));
72 location
= rawAdmin
.getRegionLocation(region
.getEncodedNameAsBytes()).get();
73 assertTrue(Bytes
.equals(regionName
, location
.getRegion().getRegionName()));
77 public void testSplitSwitch() throws Exception
{
78 createTableWithDefaultConf(tableName
);
79 byte[][] families
= {FAMILY
};
80 final int rows
= 10000;
81 TestAsyncRegionAdminApi
.loadData(tableName
, families
, rows
);
83 AsyncTable
<AdvancedScanResultConsumer
> metaTable
= ASYNC_CONN
.getTable(META_TABLE_NAME
);
84 List
<HRegionLocation
> regionLocations
=
85 AsyncMetaTableAccessor
.getTableHRegionLocations(metaTable
, tableName
).get();
86 int originalCount
= regionLocations
.size();
88 initSplitMergeSwitch();
89 assertTrue(admin
.splitSwitch(false).get());
91 admin
.split(tableName
, Bytes
.toBytes(rows
/ 2)).join();
92 } catch (Exception e
) {
95 int count
= admin
.getRegions(tableName
).get().size();
96 assertTrue(originalCount
== count
);
98 assertFalse(admin
.splitSwitch(true).get());
99 admin
.split(tableName
).join();
100 while ((count
= admin
.getRegions(tableName
).get().size()) == originalCount
) {
103 assertTrue(originalCount
< count
);
108 // It was ignored in TestSplitOrMergeStatus, too
109 public void testMergeSwitch() throws Exception
{
110 createTableWithDefaultConf(tableName
);
111 byte[][] families
= {FAMILY
};
112 TestAsyncRegionAdminApi
.loadData(tableName
, families
, 1000);
114 AsyncTable
<AdvancedScanResultConsumer
> metaTable
= ASYNC_CONN
.getTable(META_TABLE_NAME
);
115 List
<HRegionLocation
> regionLocations
=
116 AsyncMetaTableAccessor
.getTableHRegionLocations(metaTable
, tableName
).get();
117 int originalCount
= regionLocations
.size();
119 initSplitMergeSwitch();
120 admin
.split(tableName
).join();
121 int postSplitCount
= originalCount
;
122 while ((postSplitCount
= admin
.getRegions(tableName
).get().size()) == originalCount
) {
125 assertTrue("originalCount=" + originalCount
+ ", postSplitCount=" + postSplitCount
,
126 originalCount
!= postSplitCount
);
128 // Merge switch is off so merge should NOT succeed.
129 assertTrue(admin
.mergeSwitch(false).get());
130 List
<RegionInfo
> regions
= admin
.getRegions(tableName
).get();
131 assertTrue(regions
.size() > 1);
132 admin
.mergeRegions(regions
.get(0).getRegionName(), regions
.get(1).getRegionName(), true).join();
133 int count
= admin
.getRegions(tableName
).get().size();
134 assertTrue("postSplitCount=" + postSplitCount
+ ", count=" + count
, postSplitCount
== count
);
136 // Merge switch is on so merge should succeed.
137 assertFalse(admin
.mergeSwitch(true).get());
138 admin
.mergeRegions(regions
.get(0).getRegionName(), regions
.get(1).getRegionName(), true).join();
139 count
= admin
.getRegions(tableName
).get().size();
140 assertTrue((postSplitCount
/ 2) == count
);
143 private void initSplitMergeSwitch() throws Exception
{
144 if (!admin
.isSplitEnabled().get()) {
145 admin
.splitSwitch(true).get();
147 if (!admin
.isMergeEnabled().get()) {
148 admin
.mergeSwitch(true).get();
150 assertTrue(admin
.isSplitEnabled().get());
151 assertTrue(admin
.isMergeEnabled().get());
155 public void testMergeRegions() throws Exception
{
156 byte[][] splitRows
= new byte[][]{Bytes
.toBytes("3"), Bytes
.toBytes("6")};
157 createTableWithDefaultConf(tableName
, splitRows
);
159 AsyncTable
<AdvancedScanResultConsumer
> metaTable
= ASYNC_CONN
.getTable(META_TABLE_NAME
);
160 List
<HRegionLocation
> regionLocations
= AsyncMetaTableAccessor
161 .getTableHRegionLocations(metaTable
, tableName
).get();
165 // merge with full name
166 assertEquals(3, regionLocations
.size());
167 regionA
= regionLocations
.get(0).getRegion();
168 regionB
= regionLocations
.get(1).getRegion();
169 admin
.mergeRegions(regionA
.getRegionName(), regionB
.getRegionName(), false).get();
171 regionLocations
= AsyncMetaTableAccessor
172 .getTableHRegionLocations(metaTable
, tableName
).get();
173 assertEquals(2, regionLocations
.size());
174 // merge with encoded name
175 regionA
= regionLocations
.get(0).getRegion();
176 regionB
= regionLocations
.get(1).getRegion();
177 admin
.mergeRegions(regionA
.getRegionName(), regionB
.getRegionName(), false).get();
179 regionLocations
= AsyncMetaTableAccessor
180 .getTableHRegionLocations(metaTable
, tableName
).get();
181 assertEquals(1, regionLocations
.size());
185 public void testMergeRegionsInvalidRegionCount() throws Exception
{
186 byte[][] splitRows
= new byte[][] { Bytes
.toBytes("3"), Bytes
.toBytes("6") };
187 createTableWithDefaultConf(tableName
, splitRows
);
188 List
<RegionInfo
> regions
= admin
.getRegions(tableName
).join();
191 admin
.mergeRegions(Collections
.emptyList(), false).get();
193 } catch (ExecutionException e
) {
195 assertThat(e
.getCause(), instanceOf(IllegalArgumentException
.class));
199 admin
.mergeRegions(regions
.stream().limit(1).map(RegionInfo
::getEncodedNameAsBytes
)
200 .collect(Collectors
.toList()), false).get();
202 } catch (ExecutionException e
) {
204 assertThat(e
.getCause(), instanceOf(IllegalArgumentException
.class));
209 public void testSplitTable() throws Exception
{
210 initSplitMergeSwitch();
211 splitTest(TableName
.valueOf("testSplitTable"), 3000, false, null);
212 splitTest(TableName
.valueOf("testSplitTableWithSplitPoint"), 3000, false, Bytes
.toBytes("3"));
213 splitTest(TableName
.valueOf("testSplitTableRegion"), 3000, true, null);
214 splitTest(TableName
.valueOf("testSplitTableRegionWithSplitPoint2"), 3000, true, Bytes
.toBytes("3"));
218 splitTest(TableName tableName
, int rowCount
, boolean isSplitRegion
, byte[] splitPoint
)
221 createTableWithDefaultConf(tableName
);
223 AsyncTable
<AdvancedScanResultConsumer
> metaTable
= ASYNC_CONN
.getTable(META_TABLE_NAME
);
224 List
<HRegionLocation
> regionLocations
= AsyncMetaTableAccessor
225 .getTableHRegionLocations(metaTable
, tableName
).get();
226 assertEquals(1, regionLocations
.size());
228 AsyncTable
<?
> table
= ASYNC_CONN
.getTable(tableName
);
229 List
<Put
> puts
= new ArrayList
<>();
230 for (int i
= 0; i
< rowCount
; i
++) {
231 Put put
= new Put(Bytes
.toBytes(i
));
232 put
.addColumn(FAMILY
, null, Bytes
.toBytes("value" + i
));
235 table
.putAll(puts
).join();
238 if (splitPoint
== null) {
239 admin
.splitRegion(regionLocations
.get(0).getRegion().getRegionName()).get();
241 admin
.splitRegion(regionLocations
.get(0).getRegion().getRegionName(), splitPoint
).get();
244 if (splitPoint
== null) {
245 admin
.split(tableName
).get();
247 admin
.split(tableName
, splitPoint
).get();
252 for (int i
= 0; i
< 45; i
++) {
254 regionLocations
= AsyncMetaTableAccessor
255 .getTableHRegionLocations(metaTable
, tableName
).get();
256 count
= regionLocations
.size();
261 } catch (Exception e
) {
262 LOG
.error(e
.toString(), e
);
265 assertEquals(2, count
);