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