Skip to content
Permalink
Browse files
support common input for operational input on Maintenance Management …
…API (#2055)

support common input for operational input on Maintenance Management API
  • Loading branch information
xyuanlu committed Apr 27, 2022
1 parent b129bd6 commit 25cd8ba19db14a9a282e03f605c6ca19b4cf16cf
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
@@ -78,6 +78,9 @@ public class MaintenanceManagementService {
private static final String CUSTOM_INSTANCE_CHECK_HTTP_REQUESTS_DURATION =
MetricRegistry.name(InstanceService.class, "custom_instance_check_http_requests_duration");
public static final String ALL_HEALTH_CHECK_NONBLOCK = "allHealthCheckNonBlock";
public static final String HELIX_INSTANCE_STOPPABLE_CHECK = "HelixInstanceStoppableCheck";
public static final String HELIX_CUSTOM_STOPPABLE_CHECK = "CustomInstanceStoppableCheck";
public static final String OPERATION_CONFIG_SHARED_INPUT = "OperationConfigSharedInput";

private final ConfigAccessor _configAccessor;
private final CustomRestClient _customRestClient;
@@ -361,13 +364,20 @@ private MaintenanceManagementInstanceInfo takeFreeSingleInstanceHelper(String cl
PerInstanceAccessor.PerInstanceProperties.continueOnFailures.name();
Map<String, Map<String, String>> operationConfigSet = new HashMap<>();

Map<String, String> commonOperationConfig =
(operationConfig == null || !operationConfig.containsKey(OPERATION_CONFIG_SHARED_INPUT))
? Collections.emptyMap()
: getMapFromJsonPayload(operationConfig.get(OPERATION_CONFIG_SHARED_INPUT));

// perform operation check
for (OperationInterface operationClass : operationAbstractClassList) {
String operationClassName = operationClass.getClass().getName();
Map<String, String> singleOperationConfig =
(operationConfig == null || !operationConfig.containsKey(operationClassName))
? Collections.emptyMap()
: getMapFromJsonPayload(operationConfig.get(operationClassName));
commonOperationConfig
.forEach(singleOperationConfig::putIfAbsent);
operationConfigSet.put(operationClassName, singleOperationConfig);
boolean continueOnFailures =
singleOperationConfig.containsKey(continueOnFailuresName) && getBooleanFromJsonPayload(
@@ -468,14 +478,15 @@ private Map<String, MaintenanceManagementInstanceInfo> batchInstanceHealthCheck(
// CostumeInstanceStoppableCheck. We should add finer grain check groups to choose from
// i.e. HELIX:INSTANCE_NOT_ENABLED, CUSTOM_PARTITION_HEALTH_FAILURE:PARTITION_INITIAL_STATE_FAIL etc.
for (String healthCheck : healthChecks) {
if (healthCheck.equals("HelixInstanceStoppableCheck")) {
if (healthCheck.equals(HELIX_INSTANCE_STOPPABLE_CHECK)) {
// this is helix own check
instancesForNext =
batchHelixInstanceStoppableCheck(clusterId, instancesForNext, finalStoppableChecks);
} else if (healthCheck.equals("CustomInstanceStoppableCheck")) {
} else if (healthCheck.equals(HELIX_CUSTOM_STOPPABLE_CHECK)) {
// custom check, includes custom Instance check and partition check.
instancesForNext = batchCustomInstanceStoppableCheck(clusterId, instancesForNext, finalStoppableChecks,
healthCheckConfig);
instancesForNext =
batchCustomInstanceStoppableCheck(clusterId, instancesForNext, finalStoppableChecks,
healthCheckConfig);
} else {
throw new UnsupportedOperationException(healthCheck + " is not supported yet!");
}
@@ -176,6 +176,7 @@ protected Map<String, Boolean> getInstanceHealthStatus(String clusterId,
Assert.assertEquals(actual.getFailedChecks().size(), expectedFailedChecksSize);
Assert.assertEquals(actual.getFailedChecks().get(0), expectedFailedCheck);
}

@Test
public void testCustomPartitionCheckWithSkipZKRead() throws IOException {
// Let ZK result is health, but http request is unhealthy.
@@ -256,7 +257,7 @@ public void testCustomPartitionCheckWithSkipZKRead() throws IOException {
Assert.assertEquals(instanceInfo2.getOperationResult(), "DummyTakeOperationResult");
}

/*
/*
* Tests stoppable check api when all checks query is enabled. After helix own check fails,
* the subsequent checks should be performed.
*/
@@ -294,6 +295,7 @@ protected Map<String, Boolean> getInstanceHealthStatus(String clusterId,
verify(_customRestClient, times(2))
.getPartitionStoppableCheck(anyString(), nullable(List.class), anyMap());
}

// TODO re-enable the test when partition health checks get decoupled
@Test(enabled = false)
public void testGetInstanceStoppableCheckWhenPartitionsCheckFail() throws IOException {
@@ -193,6 +193,24 @@ public void testTakeInstanceOperationCheckFailure() throws IOException {
}

@Test(dependsOnMethods = "testTakeInstanceOperationCheckFailure")
public void testTakeInstanceOperationCheckFailureCommonInput() throws IOException {
System.out.println("Start test :" + TestHelper.getTestMethodName());
String payload = "{ \"operation_list\" : [\"org.apache.helix.rest.server.TestOperationImpl\"],"
+ "\"operation_config\": { \"OperationConfigSharedInput\" :"
+ " {\"instance0\": true, \"instance2\": true, "
+ "\"instance3\": true, \"instance4\": true, \"instance5\": true, "
+ " \"value\" : \"i001\", \"list_value\" : [\"list1\"]}}} ";
Response response = new JerseyUriRequestBuilder("clusters/{}/instances/{}/takeInstance")
.format(STOPPABLE_CLUSTER, "instance0")
.post(this, Entity.entity(payload, MediaType.APPLICATION_JSON_TYPE));
String takeInstanceResult = response.readEntity(String.class);

Map<String, Object> actualMap = OBJECT_MAPPER.readValue(takeInstanceResult, Map.class);
Assert.assertFalse((boolean)actualMap.get("successful"));
System.out.println("End test :" + TestHelper.getTestMethodName());
}

@Test(dependsOnMethods = "testTakeInstanceOperationCheckFailureCommonInput")
public void testTakeInstanceOperationCheckFailureNonBlocking() throws IOException {
System.out.println("Start test :" + TestHelper.getTestMethodName());
String payload = "{ \"operation_list\" : [\"org.apache.helix.rest.server.TestOperationImpl\"],"

0 comments on commit 25cd8ba

Please sign in to comment.