in helix-rest/src/main/java/org/apache/helix/rest/clusterMaintenanceService/MaintenanceManagementService.java [393:475]
private MaintenanceManagementInstanceInfo takeFreeSingleInstanceHelper(String clusterId,
String instanceName, List<String> healthChecks, Map<String, String> healthCheckConfig,
List<String> operations, Map<String, String> operationConfig, boolean performOperation,
boolean isTakeInstance) {
if (operations == null) {
operations = new ArrayList<>();
}
if (healthChecks == null) {
healthChecks = new ArrayList<>();
}
try {
MaintenanceManagementInstanceInfo instanceInfo;
instanceInfo =
batchInstanceHealthCheck(clusterId, ImmutableList.of(instanceName), healthChecks,
healthCheckConfig).getOrDefault(instanceName, new MaintenanceManagementInstanceInfo(
MaintenanceManagementInstanceInfo.OperationalStatus.SUCCESS));
if (!instanceInfo.isSuccessful()) {
return instanceInfo;
}
List<OperationInterface> operationAbstractClassList = getAllOperationClasses(operations);
_dataAccessor.populateCache(OperationInterface.PROPERTY_TYPE_LIST);
RestSnapShot sp = _dataAccessor.getRestSnapShot();
String continueOnFailuresName =
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(
singleOperationConfig.get(continueOnFailuresName));
MaintenanceManagementInstanceInfo checkResult = isTakeInstance ? operationClass
.operationCheckForTakeSingleInstance(instanceName, singleOperationConfig, sp)
: operationClass
.operationCheckForFreeSingleInstance(instanceName, singleOperationConfig, sp);
instanceInfo.mergeResult(checkResult, continueOnFailures);
}
// operation execution
if (performOperation && instanceInfo.isSuccessful()) {
for (OperationInterface operationClass : operationAbstractClassList) {
Map<String, String> singleOperationConfig =
operationConfigSet.get(operationClass.getClass().getName());
boolean continueOnFailures =
singleOperationConfig.containsKey(continueOnFailuresName) && Boolean
.parseBoolean(singleOperationConfig.get(continueOnFailuresName));
MaintenanceManagementInstanceInfo newResult = isTakeInstance ? operationClass
.operationExecForTakeSingleInstance(instanceName, singleOperationConfig, sp)
: operationClass
.operationExecForFreeSingleInstance(instanceName, singleOperationConfig, sp);
instanceInfo.mergeResult(newResult, continueOnFailures);
if (!instanceInfo.isSuccessful()) {
LOG.warn("Operation failed for {}, skip all following operations.",
operationClass.getClass().getName());
break;
}
}
}
return instanceInfo;
} catch (Exception ex) {
return new MaintenanceManagementInstanceInfo(
MaintenanceManagementInstanceInfo.OperationalStatus.FAILURE,
Collections.singletonList(ex.getMessage()));
}
}