/** * Create one TransitRegionStateProcedure to assign a region w/o specifying a target server. * This method is specified for HBCK2 */ public TransitRegionStateProcedure createOneAssignProcedure(RegionInfo hri, boolean override) { RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(hri); return createAssignProcedure(regionNode, null, override); }
/** * @param assignments Map of assignments from which we produce an array of AssignProcedures. * @return Assignments made from the passed in <code>assignments</code> */ private TransitRegionStateProcedure[] createAssignProcedures( Map<ServerName, List<RegionInfo>> assignments) { return assignments.entrySet().stream() .flatMap(e -> e.getValue().stream().map(hri -> regionStates.getOrCreateRegionStateNode(hri)) .map(regionNode -> createAssignProcedure(regionNode, e.getKey(), false))) .sorted(AssignmentManager::compare).toArray(TransitRegionStateProcedure[]::new); }
/** * Create an array of TransitRegionStateProcedure w/o specifying a target server. * <p/> * If no target server, at assign time, we will try to use the former location of the region if * one exists. This is how we 'retain' the old location across a server restart. * <p/> * Should only be called when you can make sure that no one can touch these regions other than * you. For example, when you are creating table. */ public TransitRegionStateProcedure[] createAssignProcedures(List<RegionInfo> hris) { return hris.stream().map(hri -> regionStates.getOrCreateRegionStateNode(hri)) .map(regionNode -> createAssignProcedure(regionNode, null, false)) .sorted(AssignmentManager::compare).toArray(TransitRegionStateProcedure[]::new); }
private AssignProcedure createAndSubmitAssign(TableName tableName, int regionId) { RegionInfo hri = createRegionInfo(tableName, regionId); AssignProcedure proc = am.createAssignProcedure(hri); master.getMasterProcedureExecutor().submitProcedure(proc); return proc; }
@Test public void testAssignWithRandExec() throws Exception { final TableName tableName = TableName.valueOf("testAssignWithRandExec"); final RegionInfo hri = createRegionInfo(tableName, 1); rsDispatcher.setMockRsExecutor(new RandRsExecutor()); // Loop a bunch of times so we hit various combos of exceptions. for (int i = 0; i < 10; i++) { LOG.info("ROUND=" + i); AssignProcedure proc = am.createAssignProcedure(hri); waitOnFuture(submitProcedure(proc)); } }
@Test public void testAssignAndCrashBeforeResponse() throws Exception { final TableName tableName = TableName.valueOf("testAssignAndCrashBeforeResponse"); final RegionInfo hri = createRegionInfo(tableName, 1); rsDispatcher.setMockRsExecutor(new HangThenRSCrashExecutor()); AssignProcedure proc = am.createAssignProcedure(hri); waitOnFuture(submitProcedure(proc)); }
private void testFailedOpen(final TableName tableName, final MockRSExecutor executor) throws Exception { final RegionInfo hri = createRegionInfo(tableName, 1); // Test Assign operation failure rsDispatcher.setMockRsExecutor(executor); try { waitOnFuture(submitProcedure(am.createAssignProcedure(hri))); fail("unexpected assign completion"); } catch (RetriesExhaustedException e) { // expected exception LOG.info("REGION STATE " + am.getRegionStates().getRegionStateNode(hri)); LOG.info("expected exception from assign operation: " + e.getMessage(), e); assertEquals(true, am.getRegionStates().getRegionState(hri).isFailedOpen()); } }
waitOnFuture(submitProcedure(am.createAssignProcedure(hri))); fail("unexpected assign completion"); } catch (RetriesExhaustedException e) { waitOnFuture(submitProcedure(am.createAssignProcedure(hri)));
@Test public void testUnassignAndCrashBeforeResponse() throws Exception { final TableName tableName = TableName.valueOf("testAssignAndCrashBeforeResponse"); final RegionInfo hri = createRegionInfo(tableName, 1); rsDispatcher.setMockRsExecutor(new HangOnCloseThenRSCrashExecutor()); for (int i = 0; i < HangOnCloseThenRSCrashExecutor.TYPES_OF_FAILURE; i++) { AssignProcedure assign = am.createAssignProcedure(hri); waitOnFuture(submitProcedure(assign)); UnassignProcedure unassign = am.createUnassignProcedure(hri, am.getRegionStates().getRegionServerOfRegion(hri), false); waitOnFuture(submitProcedure(unassign)); } }
@Test public void testAssignAnAssignedRegion() throws Exception { final TableName tableName = TableName.valueOf("testAssignAnAssignedRegion"); final RegionInfo hri = createRegionInfo(tableName, 1); // collect AM metrics before test collectAssignmentManagerMetrics(); rsDispatcher.setMockRsExecutor(new GoodRsExecutor()); final Future<byte[]> futureA = submitProcedure(am.createAssignProcedure(hri)); // wait first assign waitOnFuture(futureA); am.getRegionStates().isRegionInState(hri, State.OPEN); // Second should be a noop. We should recognize region is already OPEN internally // and skip out doing nothing. // wait second assign final Future<byte[]> futureB = submitProcedure(am.createAssignProcedure(hri)); waitOnFuture(futureB); am.getRegionStates().isRegionInState(hri, State.OPEN); // TODO: What else can we do to ensure just a noop. // TODO: Though second assign is noop, it's considered success, can noop be handled in a // better way? assertEquals(assignSubmittedCount + 2, assignProcMetrics.getSubmittedCounter().getCount()); assertEquals(assignFailedCount, assignProcMetrics.getFailedCounter().getCount()); }
final AssignProcedure ap = am.createAssignProcedure(RegionInfoBuilder.FIRST_META_REGIONINFO); scheduler.schedule(() -> master.getMasterProcedureExecutor().submitProcedure(ap), 10, TimeUnit.SECONDS); AssignProcedure riap = am.createAssignProcedure(ri); master.getMasterProcedureExecutor().submitProcedure(riap);
@Ignore @Test // Disabled for now. Since HBASE-18551, this mock is insufficient. public void testSocketTimeout() throws Exception { final TableName tableName = TableName.valueOf(this.name.getMethodName()); final RegionInfo hri = createRegionInfo(tableName, 1); // collect AM metrics before test collectAssignmentManagerMetrics(); rsDispatcher.setMockRsExecutor(new SocketTimeoutRsExecutor(20, 3)); waitOnFuture(submitProcedure(am.createAssignProcedure(hri))); rsDispatcher.setMockRsExecutor(new SocketTimeoutRsExecutor(20, 1)); // exception.expect(ServerCrashException.class); waitOnFuture(submitProcedure(am.createUnassignProcedure(hri, null, false))); assertEquals(assignSubmittedCount + 1, assignProcMetrics.getSubmittedCounter().getCount()); assertEquals(assignFailedCount, assignProcMetrics.getFailedCounter().getCount()); assertEquals(unassignSubmittedCount + 1, unassignProcMetrics.getSubmittedCounter().getCount()); assertEquals(unassignFailedCount + 1, unassignProcMetrics.getFailedCounter().getCount()); }
@Test public void testUnassignAnUnassignedRegion() throws Exception { final TableName tableName = TableName.valueOf("testUnassignAnUnassignedRegion"); final RegionInfo hri = createRegionInfo(tableName, 1); // collect AM metrics before test collectAssignmentManagerMetrics(); rsDispatcher.setMockRsExecutor(new GoodRsExecutor()); // assign the region first waitOnFuture(submitProcedure(am.createAssignProcedure(hri))); final Future<byte[]> futureA = submitProcedure(am.createUnassignProcedure(hri, null, false)); // Wait first unassign. waitOnFuture(futureA); am.getRegionStates().isRegionInState(hri, State.CLOSED); // Second should be a noop. We should recognize region is already CLOSED internally // and skip out doing nothing. final Future<byte[]> futureB = submitProcedure(am.createUnassignProcedure(hri, ServerName.valueOf("example.org,1234,1"), false)); waitOnFuture(futureB); // Ensure we are still CLOSED. am.getRegionStates().isRegionInState(hri, State.CLOSED); // TODO: What else can we do to ensure just a noop. assertEquals(assignSubmittedCount + 1, assignProcMetrics.getSubmittedCounter().getCount()); assertEquals(assignFailedCount, assignProcMetrics.getFailedCounter().getCount()); // TODO: Though second unassign is noop, it's considered success, can noop be handled in a // better way? assertEquals(unassignSubmittedCount + 2, unassignProcMetrics.getSubmittedCounter().getCount()); assertEquals(unassignFailedCount, unassignProcMetrics.getFailedCounter().getCount()); }