001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import org.apache.hadoop.hbase.AsyncMetaTableAccessor; 021import org.apache.hadoop.hbase.HBaseClassTestRule; 022import org.apache.hadoop.hbase.HConstants; 023import org.apache.hadoop.hbase.HRegionLocation; 024import org.apache.hadoop.hbase.TableName; 025import org.apache.hadoop.hbase.testclassification.ClientTests; 026import org.apache.hadoop.hbase.testclassification.LargeTests; 027import org.apache.hadoop.hbase.util.Bytes; 028import org.apache.hadoop.hbase.util.Threads; 029import org.junit.ClassRule; 030import org.junit.Ignore; 031import org.junit.Test; 032import org.junit.experimental.categories.Category; 033import org.junit.runner.RunWith; 034import org.junit.runners.Parameterized; 035 036import java.util.ArrayList; 037import java.util.List; 038import java.util.Optional; 039 040import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME; 041import static org.junit.Assert.assertEquals; 042import static org.junit.Assert.assertFalse; 043import static org.junit.Assert.assertTrue; 044 045/** 046 * Class to test asynchronous region admin operations. 047 * @see TestAsyncRegionAdminApi This test and it used to be joined it was taking longer than our 048 * ten minute timeout so they were split. 049 */ 050@RunWith(Parameterized.class) 051@Category({ LargeTests.class, ClientTests.class }) 052public class TestAsyncRegionAdminApi2 extends TestAsyncAdminBase { 053 054 @ClassRule 055 public static final HBaseClassTestRule CLASS_RULE = 056 HBaseClassTestRule.forClass(TestAsyncRegionAdminApi2.class); 057 058 @Test 059 public void testGetRegionLocation() throws Exception { 060 RawAsyncHBaseAdmin rawAdmin = (RawAsyncHBaseAdmin) ASYNC_CONN.getAdmin(); 061 TEST_UTIL.createMultiRegionTable(tableName, HConstants.CATALOG_FAMILY); 062 AsyncTableRegionLocator locator = ASYNC_CONN.getRegionLocator(tableName); 063 HRegionLocation regionLocation = locator.getRegionLocation(Bytes.toBytes("mmm")).get(); 064 RegionInfo region = regionLocation.getRegion(); 065 byte[] regionName = regionLocation.getRegion().getRegionName(); 066 HRegionLocation location = rawAdmin.getRegionLocation(regionName).get(); 067 assertTrue(Bytes.equals(regionName, location.getRegion().getRegionName())); 068 location = rawAdmin.getRegionLocation(region.getEncodedNameAsBytes()).get(); 069 assertTrue(Bytes.equals(regionName, location.getRegion().getRegionName())); 070 } 071 072 @Test 073 public void testSplitSwitch() throws Exception { 074 createTableWithDefaultConf(tableName); 075 byte[][] families = {FAMILY}; 076 final int rows = 10000; 077 TestAsyncRegionAdminApi.loadData(tableName, families, rows); 078 079 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME); 080 List<HRegionLocation> regionLocations = 081 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)).get(); 082 int originalCount = regionLocations.size(); 083 084 initSplitMergeSwitch(); 085 assertTrue(admin.splitSwitch(false).get()); 086 try { 087 admin.split(tableName, Bytes.toBytes(rows / 2)).join(); 088 } catch (Exception e) { 089 //Expected 090 } 091 int count = admin.getRegions(tableName).get().size(); 092 assertTrue(originalCount == count); 093 094 assertFalse(admin.splitSwitch(true).get()); 095 admin.split(tableName).join(); 096 while ((count = admin.getRegions(tableName).get().size()) == originalCount) { 097 Threads.sleep(100); 098 } 099 assertTrue(originalCount < count); 100 } 101 102 @Test 103 @Ignore 104 // It was ignored in TestSplitOrMergeStatus, too 105 public void testMergeSwitch() throws Exception { 106 createTableWithDefaultConf(tableName); 107 byte[][] families = {FAMILY}; 108 TestAsyncRegionAdminApi.loadData(tableName, families, 1000); 109 110 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME); 111 List<HRegionLocation> regionLocations = 112 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)).get(); 113 int originalCount = regionLocations.size(); 114 115 initSplitMergeSwitch(); 116 admin.split(tableName).join(); 117 int postSplitCount = originalCount; 118 while ((postSplitCount = admin.getRegions(tableName).get().size()) == originalCount) { 119 Threads.sleep(100); 120 } 121 assertTrue("originalCount=" + originalCount + ", postSplitCount=" + postSplitCount, 122 originalCount != postSplitCount); 123 124 // Merge switch is off so merge should NOT succeed. 125 assertTrue(admin.mergeSwitch(false).get()); 126 List<RegionInfo> regions = admin.getRegions(tableName).get(); 127 assertTrue(regions.size() > 1); 128 admin.mergeRegions(regions.get(0).getRegionName(), regions.get(1).getRegionName(), true).join(); 129 int count = admin.getRegions(tableName).get().size(); 130 assertTrue("postSplitCount=" + postSplitCount + ", count=" + count, postSplitCount == count); 131 132 // Merge switch is on so merge should succeed. 133 assertFalse(admin.mergeSwitch(true).get()); 134 admin.mergeRegions(regions.get(0).getRegionName(), regions.get(1).getRegionName(), true).join(); 135 count = admin.getRegions(tableName).get().size(); 136 assertTrue((postSplitCount / 2) == count); 137 } 138 139 private void initSplitMergeSwitch() throws Exception { 140 if (!admin.isSplitEnabled().get()) { 141 admin.splitSwitch(true).get(); 142 } 143 if (!admin.isMergeEnabled().get()) { 144 admin.mergeSwitch(true).get(); 145 } 146 assertTrue(admin.isSplitEnabled().get()); 147 assertTrue(admin.isMergeEnabled().get()); 148 } 149 150 @Test 151 public void testMergeRegions() throws Exception { 152 byte[][] splitRows = new byte[][]{Bytes.toBytes("3"), Bytes.toBytes("6")}; 153 createTableWithDefaultConf(tableName, splitRows); 154 155 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME); 156 List<HRegionLocation> regionLocations = 157 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)).get(); 158 RegionInfo regionA; 159 RegionInfo regionB; 160 161 // merge with full name 162 assertEquals(3, regionLocations.size()); 163 regionA = regionLocations.get(0).getRegion(); 164 regionB = regionLocations.get(1).getRegion(); 165 admin.mergeRegions(regionA.getRegionName(), regionB.getRegionName(), false).get(); 166 167 regionLocations = 168 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)).get(); 169 assertEquals(2, regionLocations.size()); 170 // merge with encoded name 171 regionA = regionLocations.get(0).getRegion(); 172 regionB = regionLocations.get(1).getRegion(); 173 admin.mergeRegions(regionA.getRegionName(), regionB.getRegionName(), false).get(); 174 175 regionLocations = 176 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)).get(); 177 assertEquals(1, regionLocations.size()); 178 } 179 180 @Test 181 public void testSplitTable() throws Exception { 182 initSplitMergeSwitch(); 183 splitTest(TableName.valueOf("testSplitTable"), 3000, false, null); 184 splitTest(TableName.valueOf("testSplitTableWithSplitPoint"), 3000, false, Bytes.toBytes("3")); 185 splitTest(TableName.valueOf("testSplitTableRegion"), 3000, true, null); 186 splitTest(TableName.valueOf("testSplitTableRegionWithSplitPoint2"), 3000, true, Bytes.toBytes("3")); 187 } 188 189 private void 190 splitTest(TableName tableName, int rowCount, boolean isSplitRegion, byte[] splitPoint) 191 throws Exception { 192 // create table 193 createTableWithDefaultConf(tableName); 194 195 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME); 196 List<HRegionLocation> regionLocations = 197 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)).get(); 198 assertEquals(1, regionLocations.size()); 199 200 AsyncTable<?> table = ASYNC_CONN.getTable(tableName); 201 List<Put> puts = new ArrayList<>(); 202 for (int i = 0; i < rowCount; i++) { 203 Put put = new Put(Bytes.toBytes(i)); 204 put.addColumn(FAMILY, null, Bytes.toBytes("value" + i)); 205 puts.add(put); 206 } 207 table.putAll(puts).join(); 208 209 if (isSplitRegion) { 210 if (splitPoint == null) { 211 admin.splitRegion(regionLocations.get(0).getRegion().getRegionName()).get(); 212 } else { 213 admin.splitRegion(regionLocations.get(0).getRegion().getRegionName(), splitPoint).get(); 214 } 215 } else { 216 if (splitPoint == null) { 217 admin.split(tableName).get(); 218 } else { 219 admin.split(tableName, splitPoint).get(); 220 } 221 } 222 223 int count = 0; 224 for (int i = 0; i < 45; i++) { 225 try { 226 regionLocations = 227 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, Optional.of(tableName)) 228 .get(); 229 count = regionLocations.size(); 230 if (count >= 2) { 231 break; 232 } 233 Thread.sleep(1000L); 234 } catch (Exception e) { 235 LOG.error(e.toString(), e); 236 } 237 } 238 assertEquals(2, count); 239 } 240} 241