use of com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response in project cloudbreak by hortonworks.
the class SdxUpgradeRecoveryService method validateRecovery.
@Override
public SdxRecoverableResponse validateRecovery(SdxCluster sdxCluster, SdxRecoveryRequest request) {
MDCBuilder.buildMdcContext(sdxCluster);
try {
String initiatorUserCrn = ThreadBasedUserCrnProvider.getUserCrn();
if (Objects.nonNull(request) && request.getType() == SdxRecoveryType.RECOVER_WITH_DATA) {
String clusterRuntime = sdxCluster.getRuntime();
datalakeDRProto.DatalakeBackupInfo lastSuccessfulBackup = datalakeDrClient.getLastSuccessfulBackup(sdxCluster.getClusterName(), initiatorUserCrn, Optional.of(clusterRuntime));
if (Objects.isNull(lastSuccessfulBackup)) {
return new SdxRecoverableResponse("There is no successful backup taken yet for data lake cluster with runtime " + clusterRuntime + ".", RecoveryStatus.NON_RECOVERABLE);
}
}
RecoveryValidationV4Response response = ThreadBasedUserCrnProvider.doAsInternalActor(regionAwareInternalCrnGeneratorFactory.iam().getInternalCrnForServiceAsString(), () -> stackV4Endpoint.getClusterRecoverableByNameInternal(0L, sdxCluster.getClusterName(), initiatorUserCrn));
return new SdxRecoverableResponse(response.getReason(), response.getStatus());
} catch (WebApplicationException e) {
String exceptionMessage = exceptionMessageExtractor.getErrorMessage(e);
String message = String.format("Stack recovery validation failed on cluster: [%s]. Message: [%s]", sdxCluster.getClusterName(), exceptionMessage);
throw new CloudbreakApiException(message, e);
}
}
use of com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response in project cloudbreak by hortonworks.
the class SdxUpgradeRecoveryServiceTest method testValidateStatusSuccessfulShouldStartRecoveryFlow.
@Test
public void testValidateStatusSuccessfulShouldStartRecoveryFlow() {
when(regionAwareInternalCrnGenerator.getInternalCrnForServiceAsString()).thenReturn("crn");
when(regionAwareInternalCrnGeneratorFactory.iam()).thenReturn(regionAwareInternalCrnGenerator);
String reason = "Datalake upgrade recovery requested. Cluster will be terminated and re-launched with the original runtime.";
RecoveryValidationV4Response recoveryV4Response = new RecoveryValidationV4Response(reason, RecoveryStatus.RECOVERABLE);
when(stackV4Endpoint.getClusterRecoverableByNameInternal(WORKSPACE_ID, CLUSTER_NAME, USER_CRN)).thenReturn(recoveryV4Response);
when(sdxReactorFlowManager.triggerDatalakeRuntimeRecoveryFlow(cluster, SdxRecoveryType.RECOVER_WITHOUT_DATA)).thenReturn(new FlowIdentifier(FlowType.FLOW, "FLOW_ID"));
SdxRecoverableResponse sdxRecoverableResponse = ThreadBasedUserCrnProvider.doAs(USER_CRN, () -> underTest.validateRecovery(cluster));
assertEquals(reason, sdxRecoverableResponse.getReason());
SdxRecoveryResponse response = ThreadBasedUserCrnProvider.doAs(USER_CRN, () -> underTest.triggerRecovery(cluster, request));
assertEquals(new FlowIdentifier(FlowType.FLOW, "FLOW_ID"), response.getFlowIdentifier());
}
use of com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response in project cloudbreak by hortonworks.
the class SdxUpgradeRecoveryServiceTest method testNonRecoverableStatusShouldReturnNonRecoverable.
@Test
public void testNonRecoverableStatusShouldReturnNonRecoverable() {
when(regionAwareInternalCrnGenerator.getInternalCrnForServiceAsString()).thenReturn("crn");
when(regionAwareInternalCrnGeneratorFactory.iam()).thenReturn(regionAwareInternalCrnGenerator);
String errorMessage = "error message";
RecoveryValidationV4Response recoveryV4Response = new RecoveryValidationV4Response(errorMessage, RecoveryStatus.NON_RECOVERABLE);
when(stackV4Endpoint.getClusterRecoverableByNameInternal(WORKSPACE_ID, CLUSTER_NAME, USER_CRN)).thenReturn(recoveryV4Response);
SdxRecoverableResponse sdxRecoverableResponse = ThreadBasedUserCrnProvider.doAs(USER_CRN, () -> underTest.validateRecovery(cluster));
assertEquals(errorMessage, sdxRecoverableResponse.getReason());
}
use of com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response in project cloudbreak by hortonworks.
the class SdxUpgradeRecoveryServiceTest method testValidateWithDataAndSuccessfulBackupShouldStartRecoveryFlow.
@Test
public void testValidateWithDataAndSuccessfulBackupShouldStartRecoveryFlow() {
when(regionAwareInternalCrnGenerator.getInternalCrnForServiceAsString()).thenReturn("crn");
when(regionAwareInternalCrnGeneratorFactory.iam()).thenReturn(regionAwareInternalCrnGenerator);
String reason = "There is no successful backup taken yet for data lake cluster with runtime 7.2.2.";
RecoveryValidationV4Response recoveryV4Response = new RecoveryValidationV4Response(reason, RecoveryStatus.RECOVERABLE);
request.setType(SdxRecoveryType.RECOVER_WITH_DATA);
datalakeDRProto.DatalakeBackupInfo datalakeBackupInfo = datalakeDRProto.DatalakeBackupInfo.newBuilder().setRuntimeVersion(RUNTIME).setOverallState("SUCCESSFUL").build();
when(cluster.getRuntime()).thenReturn(RUNTIME);
when(stackV4Endpoint.getClusterRecoverableByNameInternal(WORKSPACE_ID, CLUSTER_NAME, USER_CRN)).thenReturn(recoveryV4Response);
when(datalakeDrClient.getLastSuccessfulBackup(CLUSTER_NAME, USER_CRN, Optional.of(RUNTIME))).thenReturn(datalakeBackupInfo);
when(sdxReactorFlowManager.triggerDatalakeRuntimeRecoveryFlow(cluster, SdxRecoveryType.RECOVER_WITH_DATA)).thenReturn(new FlowIdentifier(FlowType.FLOW, "FLOW_ID"));
SdxRecoverableResponse sdxRecoverableResponse = ThreadBasedUserCrnProvider.doAs(USER_CRN, () -> underTest.validateRecovery(cluster, request));
assertEquals(reason, sdxRecoverableResponse.getReason());
SdxRecoveryResponse response = ThreadBasedUserCrnProvider.doAs(USER_CRN, () -> underTest.triggerRecovery(cluster, request));
assertEquals(new FlowIdentifier(FlowType.FLOW, "FLOW_ID"), response.getFlowIdentifier());
}
use of com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response in project cloudbreak by hortonworks.
the class ClusterRecoveryService method validateStackStatus.
private RecoveryValidationV4Response validateStackStatus(Stack stack) {
List<StackStatus> statusList = stackStatusService.findAllStackStatusesById(stack.getId());
List<DetailedStackStatus> detailedStackStatusList = statusList.stream().map(StackStatus::getDetailedStackStatus).collect(Collectors.toList());
int lastRecoverySuccess = getLastRecoverySuccess(detailedStackStatusList);
int lastRecoveryFailure = getLastRecoveryFailure(detailedStackStatusList);
int lastUpgradeSuccess = getLastUpgradeSuccess(detailedStackStatusList);
int lastUpgradeFailure = getLastUpgradeFailure(detailedStackStatusList);
String logMessage = Stream.of(createLogEntry(lastUpgradeSuccess, DetailedStackStatus.CLUSTER_UPGRADE_FINISHED), createLogEntry(lastUpgradeFailure, DetailedStackStatus.CLUSTER_UPGRADE_FAILED), createLogEntry(lastRecoverySuccess, DetailedStackStatus.CLUSTER_RECOVERY_FINISHED), createLogEntry(lastRecoveryFailure, DetailedStackStatus.CLUSTER_RECOVERY_FAILED)).flatMap(Optional::stream).collect(Collectors.joining(". "));
LOGGER.debug(logMessage);
int maximumInt = IntStream.of(lastUpgradeFailure, lastRecoveryFailure, lastRecoverySuccess, lastUpgradeSuccess).max().getAsInt();
String reason;
RecoveryStatus status;
if (maximumInt == -1) {
reason = "There has been no failed upgrades for this cluster hence recovery is not permitted.";
status = NON_RECOVERABLE;
} else if (maximumInt == lastRecoveryFailure) {
reason = "Last cluster recovery has failed, recovery can be retried.";
status = RECOVERABLE;
} else if (maximumInt == lastUpgradeFailure) {
reason = "Last cluster upgrade has failed, recovery can be launched to restore the cluster to its pre-upgrade state.";
status = RECOVERABLE;
} else {
reason = "Cluster is not in a recoverable state now, neither uncorrected upgrade or recovery failures are present.";
status = NON_RECOVERABLE;
}
LOGGER.info(reason);
return new RecoveryValidationV4Response(reason, status);
}
Aggregations