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.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertNotNull; 022 023import java.io.IOException; 024import java.util.Set; 025import org.apache.hadoop.hbase.HBaseTestingUtil; 026import org.apache.hadoop.hbase.ServerName; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.Waiter; 029import org.apache.hadoop.hbase.Waiter.ExplainingPredicate; 030import org.apache.hadoop.hbase.client.Put; 031import org.apache.hadoop.hbase.client.RegionInfo; 032import org.apache.hadoop.hbase.client.Table; 033import org.apache.hadoop.hbase.master.HMaster; 034import org.apache.hadoop.hbase.master.RegionState.State; 035import org.apache.hadoop.hbase.master.procedure.ProcedureSyncWait; 036import org.apache.hadoop.hbase.util.Bytes; 037import org.apache.hadoop.hbase.util.Threads; 038import org.apache.yetus.audience.InterfaceAudience; 039import org.apache.yetus.audience.InterfaceStability; 040import org.slf4j.Logger; 041import org.slf4j.LoggerFactory; 042 043@InterfaceAudience.Private 044@InterfaceStability.Evolving 045public final class AssignmentTestingUtil { 046 private static final Logger LOG = LoggerFactory.getLogger(AssignmentTestingUtil.class); 047 048 private AssignmentTestingUtil() { 049 } 050 051 public static void waitForRegionToBeInTransition(final HBaseTestingUtil util, 052 final RegionInfo hri) { 053 while (!isRegionInTransition(hri, getMaster(util).getAssignmentManager())) { 054 Threads.sleep(10); 055 } 056 } 057 058 public static boolean isRegionInTransition(RegionInfo hri, AssignmentManager am) { 059 return am.getRegionsInTransition().stream() 060 .anyMatch(rsn -> rsn.getRegionInfo().getEncodedName().equals(hri.getEncodedName())); 061 } 062 063 public static void waitForRsToBeDead(final HBaseTestingUtil util, final ServerName serverName) 064 throws Exception { 065 util.waitFor(60000, new ExplainingPredicate<Exception>() { 066 @Override 067 public boolean evaluate() { 068 return getMaster(util).getServerManager().isServerDead(serverName); 069 } 070 071 @Override 072 public String explainFailure() { 073 return "Server " + serverName + " is not dead"; 074 } 075 }); 076 } 077 078 public static void stopRs(final HBaseTestingUtil util, final ServerName serverName) 079 throws Exception { 080 LOG.info("STOP REGION SERVER " + serverName); 081 util.getMiniHBaseCluster().stopRegionServer(serverName); 082 waitForRsToBeDead(util, serverName); 083 } 084 085 public static void killRs(final HBaseTestingUtil util, final ServerName serverName) 086 throws Exception { 087 LOG.info("KILL REGION SERVER " + serverName); 088 util.getMiniHBaseCluster().killRegionServer(serverName); 089 waitForRsToBeDead(util, serverName); 090 } 091 092 public static void crashRs(final HBaseTestingUtil util, final ServerName serverName, 093 final boolean kill) throws Exception { 094 if (kill) { 095 killRs(util, serverName); 096 } else { 097 stopRs(util, serverName); 098 } 099 } 100 101 public static ServerName crashRsWithRegion(final HBaseTestingUtil util, final RegionInfo hri, 102 final boolean kill) throws Exception { 103 ServerName serverName = getServerHoldingRegion(util, hri); 104 crashRs(util, serverName, kill); 105 return serverName; 106 } 107 108 public static ServerName getServerHoldingRegion(final HBaseTestingUtil util, final RegionInfo hri) 109 throws Exception { 110 ServerName serverName = 111 util.getMiniHBaseCluster().getServerHoldingRegion(hri.getTable(), hri.getRegionName()); 112 ServerName amServerName = 113 getMaster(util).getAssignmentManager().getRegionStates().getRegionServerOfRegion(hri); 114 115 // Make sure AM and MiniCluster agrees on the Server holding the region 116 // and that the server is online. 117 assertEquals(amServerName, serverName); 118 assertEquals(true, getMaster(util).getServerManager().isServerOnline(serverName)); 119 return serverName; 120 } 121 122 public static boolean isServerHoldingMeta(final HBaseTestingUtil util, 123 final ServerName serverName) throws Exception { 124 for (RegionInfo hri : getMetaRegions(util)) { 125 if (serverName.equals(getServerHoldingRegion(util, hri))) { 126 return true; 127 } 128 } 129 return false; 130 } 131 132 public static Set<RegionInfo> getMetaRegions(final HBaseTestingUtil util) { 133 return getMaster(util).getAssignmentManager().getMetaRegionSet(); 134 } 135 136 private static HMaster getMaster(final HBaseTestingUtil util) { 137 return util.getMiniHBaseCluster().getMaster(); 138 } 139 140 public static boolean waitForAssignment(AssignmentManager am, RegionInfo regionInfo) 141 throws IOException { 142 // This method can be called before the regionInfo has made it into the regionStateMap 143 // so wait around here a while. 144 Waiter.waitFor(am.getConfiguration(), 10000, 145 () -> am.getRegionStates().getRegionStateNode(regionInfo) != null); 146 RegionStateNode regionNode = am.getRegionStates().getRegionStateNode(regionInfo); 147 // Wait until the region has already been open, or we have a TRSP along with it. 148 Waiter.waitFor(am.getConfiguration(), 30000, 149 () -> regionNode.isInState(State.OPEN) || regionNode.isTransitionScheduled()); 150 TransitRegionStateProcedure proc = regionNode.getProcedure(); 151 regionNode.lock(); 152 try { 153 if (regionNode.isInState(State.OPEN)) { 154 return true; 155 } 156 proc = regionNode.getProcedure(); 157 } finally { 158 regionNode.unlock(); 159 } 160 assertNotNull(proc); 161 ProcedureSyncWait.waitForProcedureToCompleteIOE(am.getMaster().getMasterProcedureExecutor(), 162 proc, 5L * 60 * 1000); 163 return true; 164 } 165 166 public static void insertData(final HBaseTestingUtil UTIL, final TableName tableName, 167 int rowCount, int startRowNum, String... cfs) throws IOException { 168 insertData(UTIL, tableName, rowCount, startRowNum, false, cfs); 169 } 170 171 public static void insertData(final HBaseTestingUtil UTIL, final TableName tableName, 172 int rowCount, int startRowNum, boolean flushOnce, String... cfs) throws IOException { 173 Table t = UTIL.getConnection().getTable(tableName); 174 Put p; 175 for (int i = 0; i < rowCount / 2; i++) { 176 p = new Put(Bytes.toBytes("" + (startRowNum + i))); 177 for (String cf : cfs) { 178 p.addColumn(Bytes.toBytes(cf), Bytes.toBytes("q"), Bytes.toBytes(i)); 179 } 180 t.put(p); 181 p = new Put(Bytes.toBytes("" + (startRowNum + rowCount - i - 1))); 182 for (String cf : cfs) { 183 p.addColumn(Bytes.toBytes(cf), Bytes.toBytes("q"), Bytes.toBytes(i)); 184 } 185 t.put(p); 186 if (i % 5 == 0 && !flushOnce) { 187 UTIL.getAdmin().flush(tableName); 188 } 189 } 190 if (flushOnce) { 191 UTIL.getAdmin().flush(tableName); 192 } 193 } 194}