Search in sources :

Example 1 with RecoveryValidationV4Response

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);
    }
}
Also used : RecoveryValidationV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response) WebApplicationException(javax.ws.rs.WebApplicationException) SdxRecoverableResponse(com.sequenceiq.sdx.api.model.SdxRecoverableResponse) CloudbreakApiException(com.sequenceiq.cloudbreak.exception.CloudbreakApiException) com.cloudera.thunderhead.service.datalakedr.datalakeDRProto(com.cloudera.thunderhead.service.datalakedr.datalakeDRProto)

Example 2 with RecoveryValidationV4Response

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());
}
Also used : RecoveryValidationV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response) SdxRecoverableResponse(com.sequenceiq.sdx.api.model.SdxRecoverableResponse) FlowIdentifier(com.sequenceiq.flow.api.model.FlowIdentifier) SdxRecoveryResponse(com.sequenceiq.sdx.api.model.SdxRecoveryResponse) Test(org.junit.jupiter.api.Test)

Example 3 with RecoveryValidationV4Response

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());
}
Also used : RecoveryValidationV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response) SdxRecoverableResponse(com.sequenceiq.sdx.api.model.SdxRecoverableResponse) Test(org.junit.jupiter.api.Test)

Example 4 with RecoveryValidationV4Response

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());
}
Also used : RecoveryValidationV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response) SdxRecoverableResponse(com.sequenceiq.sdx.api.model.SdxRecoverableResponse) FlowIdentifier(com.sequenceiq.flow.api.model.FlowIdentifier) com.cloudera.thunderhead.service.datalakedr.datalakeDRProto(com.cloudera.thunderhead.service.datalakedr.datalakeDRProto) SdxRecoveryResponse(com.sequenceiq.sdx.api.model.SdxRecoveryResponse) Test(org.junit.jupiter.api.Test)

Example 5 with RecoveryValidationV4Response

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);
}
Also used : RecoveryValidationV4Response(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response) StackStatus(com.sequenceiq.cloudbreak.domain.stack.StackStatus) DetailedStackStatus(com.sequenceiq.cloudbreak.api.endpoint.v4.common.DetailedStackStatus) DetailedStackStatus(com.sequenceiq.cloudbreak.api.endpoint.v4.common.DetailedStackStatus) RecoveryStatus(com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryStatus)

Aggregations

RecoveryValidationV4Response (com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryValidationV4Response)8 SdxRecoverableResponse (com.sequenceiq.sdx.api.model.SdxRecoverableResponse)5 Test (org.junit.jupiter.api.Test)3 com.cloudera.thunderhead.service.datalakedr.datalakeDRProto (com.cloudera.thunderhead.service.datalakedr.datalakeDRProto)2 RecoveryStatus (com.sequenceiq.cloudbreak.api.endpoint.v4.stacks.response.recovery.RecoveryStatus)2 CloudbreakApiException (com.sequenceiq.cloudbreak.exception.CloudbreakApiException)2 FlowIdentifier (com.sequenceiq.flow.api.model.FlowIdentifier)2 SdxRecoveryResponse (com.sequenceiq.sdx.api.model.SdxRecoveryResponse)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 DetailedStackStatus (com.sequenceiq.cloudbreak.api.endpoint.v4.common.DetailedStackStatus)1 NameOrCrn (com.sequenceiq.cloudbreak.api.endpoint.v4.dto.NameOrCrn)1 StackStatus (com.sequenceiq.cloudbreak.domain.stack.StackStatus)1 Test (org.junit.Test)1