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.master.assignment; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertNull; 024import static org.junit.Assert.assertTrue; 025 026import java.io.IOException; 027import java.util.List; 028import java.util.concurrent.atomic.AtomicBoolean; 029import org.apache.hadoop.hbase.Cell; 030import org.apache.hadoop.hbase.HBaseClassTestRule; 031import org.apache.hadoop.hbase.HBaseTestingUtility; 032import org.apache.hadoop.hbase.HConstants; 033import org.apache.hadoop.hbase.MetaTableAccessor; 034import org.apache.hadoop.hbase.ServerName; 035import org.apache.hadoop.hbase.TableName; 036import org.apache.hadoop.hbase.TableNameTestRule; 037import org.apache.hadoop.hbase.client.Get; 038import org.apache.hadoop.hbase.client.Put; 039import org.apache.hadoop.hbase.client.RegionInfo; 040import org.apache.hadoop.hbase.client.RegionInfoBuilder; 041import org.apache.hadoop.hbase.client.Result; 042import org.apache.hadoop.hbase.client.Table; 043import org.apache.hadoop.hbase.master.RegionState; 044import org.apache.hadoop.hbase.regionserver.HRegion; 045import org.apache.hadoop.hbase.testclassification.MasterTests; 046import org.apache.hadoop.hbase.testclassification.MediumTests; 047import org.apache.hadoop.hbase.util.Bytes; 048import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 049import org.junit.AfterClass; 050import org.junit.BeforeClass; 051import org.junit.ClassRule; 052import org.junit.Rule; 053import org.junit.Test; 054import org.junit.experimental.categories.Category; 055 056import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 057 058 059@Category({ MasterTests.class, MediumTests.class }) 060public class TestRegionStateStore { 061 062 @ClassRule 063 public static final HBaseClassTestRule CLASS_RULE = 064 HBaseClassTestRule.forClass(TestRegionStateStore.class); 065 066 private static HBaseTestingUtility UTIL = new HBaseTestingUtility(); 067 068 @Rule 069 public final TableNameTestRule name = new TableNameTestRule(); 070 071 @BeforeClass 072 public static void beforeClass() throws Exception { 073 UTIL.startMiniCluster(); 074 } 075 076 @AfterClass 077 public static void tearDown() throws Exception { 078 UTIL.shutdownMiniCluster(); 079 } 080 081 @Test 082 public void testVisitMetaForRegionExistingRegion() throws Exception { 083 final TableName tableName = name.getTableName(); 084 UTIL.createTable(tableName, "cf"); 085 final List<HRegion> regions = UTIL.getHBaseCluster().getRegions(tableName); 086 final String encodedName = regions.get(0).getRegionInfo().getEncodedName(); 087 final RegionStateStore regionStateStore = UTIL.getHBaseCluster().getMaster(). 088 getAssignmentManager().getRegionStateStore(); 089 final AtomicBoolean visitorCalled = new AtomicBoolean(false); 090 regionStateStore.visitMetaForRegion(encodedName, new RegionStateStore.RegionStateVisitor() { 091 @Override 092 public void visitRegionState(Result result, RegionInfo regionInfo, RegionState.State state, 093 ServerName regionLocation, ServerName lastHost, long openSeqNum) { 094 assertEquals(encodedName, regionInfo.getEncodedName()); 095 visitorCalled.set(true); 096 } 097 }); 098 assertTrue("Visitor has not been called.", visitorCalled.get()); 099 } 100 101 @Test 102 public void testVisitMetaForBadRegionState() throws Exception { 103 final TableName tableName = name.getTableName(); 104 UTIL.createTable(tableName, "cf"); 105 final List<HRegion> regions = UTIL.getHBaseCluster().getRegions(tableName); 106 final String encodedName = regions.get(0).getRegionInfo().getEncodedName(); 107 final RegionStateStore regionStateStore = UTIL.getHBaseCluster().getMaster(). 108 getAssignmentManager().getRegionStateStore(); 109 110 // add the BAD_STATE which does not exist in enum RegionState.State 111 Put put = new Put(regions.get(0).getRegionInfo().getRegionName(), 112 EnvironmentEdgeManager.currentTime()); 113 put.addColumn(HConstants.CATALOG_FAMILY, HConstants.STATE_QUALIFIER, 114 Bytes.toBytes("BAD_STATE")); 115 116 try (Table table = UTIL.getConnection().getTable(TableName.META_TABLE_NAME)) { 117 table.put(put); 118 } 119 120 final AtomicBoolean visitorCalled = new AtomicBoolean(false); 121 regionStateStore.visitMetaForRegion(encodedName, new RegionStateStore.RegionStateVisitor() { 122 @Override 123 public void visitRegionState(Result result, RegionInfo regionInfo, 124 RegionState.State state, ServerName regionLocation, 125 ServerName lastHost, long openSeqNum) { 126 assertEquals(encodedName, regionInfo.getEncodedName()); 127 assertNull(state); 128 visitorCalled.set(true); 129 } 130 }); 131 assertTrue("Visitor has not been called.", visitorCalled.get()); 132 } 133 134 @Test 135 public void testVisitMetaForRegionNonExistingRegion() throws Exception { 136 final String encodedName = "fakeencodedregionname"; 137 final RegionStateStore regionStateStore = UTIL.getHBaseCluster().getMaster(). 138 getAssignmentManager().getRegionStateStore(); 139 final AtomicBoolean visitorCalled = new AtomicBoolean(false); 140 regionStateStore.visitMetaForRegion(encodedName, new RegionStateStore.RegionStateVisitor() { 141 @Override 142 public void visitRegionState(Result result, RegionInfo regionInfo, RegionState.State state, 143 ServerName regionLocation, ServerName lastHost, long openSeqNum) { 144 visitorCalled.set(true); 145 } 146 }); 147 assertFalse("Visitor has been called, but it shouldn't.", visitorCalled.get()); 148 } 149 150 @Test 151 public void testMetaLocationForRegionReplicasIsRemovedAtTableDeletion() throws IOException { 152 long regionId = System.currentTimeMillis(); 153 TableName tableName = name.getTableName(); 154 RegionInfo primary = RegionInfoBuilder.newBuilder(tableName) 155 .setStartKey(HConstants.EMPTY_START_ROW).setEndKey(HConstants.EMPTY_END_ROW).setSplit(false) 156 .setRegionId(regionId).setReplicaId(0).build(); 157 158 try (Table meta = MetaTableAccessor.getMetaHTable(UTIL.getConnection())) { 159 List<RegionInfo> regionInfos = Lists.newArrayList(primary); 160 MetaTableAccessor.addRegionsToMeta(UTIL.getConnection(), regionInfos, 3); 161 final RegionStateStore regionStateStore = 162 UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionStateStore(); 163 regionStateStore.removeRegionReplicas(tableName, 3, 1); 164 Get get = new Get(primary.getRegionName()); 165 Result result = meta.get(get); 166 for (int replicaId = 0; replicaId < 3; replicaId++) { 167 Cell serverCell = result.getColumnLatestCell(HConstants.CATALOG_FAMILY, 168 MetaTableAccessor.getServerColumn(replicaId)); 169 Cell startCodeCell = result.getColumnLatestCell(HConstants.CATALOG_FAMILY, 170 MetaTableAccessor.getStartCodeColumn(replicaId)); 171 Cell stateCell = result.getColumnLatestCell(HConstants.CATALOG_FAMILY, 172 MetaTableAccessor.getRegionStateColumn(replicaId)); 173 Cell snCell = result.getColumnLatestCell(HConstants.CATALOG_FAMILY, 174 MetaTableAccessor.getServerNameColumn(replicaId)); 175 if (replicaId == 0) { 176 assertNotNull(stateCell); 177 } else { 178 assertNull(serverCell); 179 assertNull(startCodeCell); 180 assertNull(stateCell); 181 assertNull(snCell); 182 } 183 } 184 } 185 } 186}