Search in sources :

Example 1 with RolledbackResourcesException

use of com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException in project cloudbreak by hortonworks.

the class AzureUpscaleService method upscale.

public List<CloudResourceStatus> upscale(AuthenticatedContext ac, CloudStack stack, List<CloudResource> resources, AzureStackView azureStackView, AzureClient client, AdjustmentTypeWithThreshold adjustmentTypeWithThreshold) throws QuotaExceededException {
    CloudContext cloudContext = ac.getCloudContext();
    String stackName = azureUtils.getStackName(cloudContext);
    String resourceGroupName = azureResourceGroupMetadataProvider.getResourceGroupName(cloudContext, stack);
    List<CloudResource> newInstances = new ArrayList<>();
    List<CloudResource> templateResources = new ArrayList<>();
    List<CloudResource> osDiskResources = new ArrayList<>();
    DateTime preDeploymentTime = DateTime.now();
    filterExistingInstances(azureStackView);
    try {
        List<Group> scaledGroups = cloudResourceHelper.getScaledGroups(stack);
        CloudResource armTemplate = getArmTemplate(resources, stackName);
        Deployment templateDeployment = azureTemplateDeploymentService.getTemplateDeployment(client, stack, ac, azureStackView, AzureInstanceTemplateOperation.UPSCALE);
        LOGGER.info("Created template deployment for upscale: {}", templateDeployment.exportTemplate().template());
        templateResources.addAll(azureCloudResourceService.getDeploymentCloudResources(templateDeployment));
        newInstances.addAll(azureCloudResourceService.getInstanceCloudResources(stackName, templateResources, scaledGroups, resourceGroupName));
        if (!newInstances.isEmpty()) {
            osDiskResources.addAll(azureCloudResourceService.getAttachedOsDiskResources(newInstances, resourceGroupName, client));
        } else {
            LOGGER.warn("Skipping OS disk collection as there was no VM instance found amongst cloud resources for {}!", stackName);
        }
        azureCloudResourceService.saveCloudResources(resourceNotifier, cloudContext, ListUtils.union(templateResources, osDiskResources));
        List<CloudResource> reattachableVolumeSets = getReattachableVolumeSets(resources, newInstances);
        List<CloudResource> networkResources = azureCloudResourceService.getNetworkResources(resources);
        azureComputeResourceService.buildComputeResourcesForUpscale(ac, stack, scaledGroups, newInstances, reattachableVolumeSets, networkResources, adjustmentTypeWithThreshold);
        List<CloudResourceStatus> successfulInstances = newInstances.stream().map(cloudResource -> new CloudResourceStatus(cloudResource, ResourceStatus.CREATED, cloudResource.getParameter(CloudResource.PRIVATE_ID, Long.class))).collect(Collectors.toList());
        return ListUtils.union(Collections.singletonList(new CloudResourceStatus(armTemplate, ResourceStatus.IN_PROGRESS)), successfulInstances);
    } catch (Retry.ActionFailedException e) {
        LOGGER.error("Retry.ActionFailedException happened", e);
        rollbackResources(ac, client, stack, cloudContext, resources, preDeploymentTime);
        throw azureUtils.convertToCloudConnectorException(e.getCause(), "Stack upscale");
    } catch (CloudException e) {
        LOGGER.error("CloudException happened", e);
        rollbackResources(ac, client, stack, cloudContext, resources, preDeploymentTime);
        checkIfQuotaLimitIssued(e);
        throw azureUtils.convertToCloudConnectorException(e, "Stack upscale");
    } catch (RolledbackResourcesException e) {
        LOGGER.error("RolledbackResourcesException happened", e);
        rollbackResources(ac, client, stack, cloudContext, resources, preDeploymentTime);
        throw new CloudConnectorException(String.format("Could not upscale Azure infrastructure, infrastructure was rolled back with resources: %s, %s", stackName, e.getMessage()), e);
    } catch (Exception e) {
        LOGGER.error("Exception happened", e);
        rollbackResources(ac, client, stack, cloudContext, resources, preDeploymentTime);
        throw new CloudConnectorException(String.format("Could not upscale Azure infrastructure, infrastructure was rolled back: %s, %s", stackName, e.getMessage()), e);
    }
}
Also used : AzureClient(com.sequenceiq.cloudbreak.cloud.azure.client.AzureClient) CloudContext(com.sequenceiq.cloudbreak.cloud.context.CloudContext) CloudError(com.microsoft.azure.CloudError) RolledbackResourcesException(com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException) LoggerFactory(org.slf4j.LoggerFactory) CloudInstance(com.sequenceiq.cloudbreak.cloud.model.CloudInstance) AzureComputeResourceService(com.sequenceiq.cloudbreak.cloud.azure.connector.resource.AzureComputeResourceService) ArrayList(java.util.ArrayList) ResourceNotifier(com.sequenceiq.cloudbreak.cloud.notification.ResourceNotifier) Inject(javax.inject.Inject) CloudConnectorException(com.sequenceiq.cloudbreak.cloud.exception.CloudConnectorException) Matcher(java.util.regex.Matcher) AzureStackView(com.sequenceiq.cloudbreak.cloud.azure.view.AzureStackView) AuthenticatedContext(com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext) ListUtils(org.apache.commons.collections4.ListUtils) AzureInstanceView(com.sequenceiq.cloudbreak.cloud.azure.view.AzureInstanceView) AzureUtils(com.sequenceiq.cloudbreak.cloud.azure.AzureUtils) CommonStatus(com.sequenceiq.common.api.type.CommonStatus) ResourceStatus(com.sequenceiq.cloudbreak.cloud.model.ResourceStatus) CloudResourceHelper(com.sequenceiq.cloudbreak.cloud.transform.CloudResourceHelper) ResourceType(com.sequenceiq.common.api.type.ResourceType) Deployment(com.microsoft.azure.management.resources.Deployment) Logger(org.slf4j.Logger) AzureResourceGroupMetadataProvider(com.sequenceiq.cloudbreak.cloud.azure.AzureResourceGroupMetadataProvider) CloudResource(com.sequenceiq.cloudbreak.cloud.model.CloudResource) AdjustmentTypeWithThreshold(com.sequenceiq.common.api.adjustment.AdjustmentTypeWithThreshold) CloudResourceStatus(com.sequenceiq.cloudbreak.cloud.model.CloudResourceStatus) DateTime(org.joda.time.DateTime) Retry(com.sequenceiq.cloudbreak.service.Retry) Collectors(java.util.stream.Collectors) QuotaExceededException(com.sequenceiq.cloudbreak.cloud.exception.QuotaExceededException) AzureCloudResourceService(com.sequenceiq.cloudbreak.cloud.azure.AzureCloudResourceService) CloudStack(com.sequenceiq.cloudbreak.cloud.model.CloudStack) AzureTerminationHelperService(com.sequenceiq.cloudbreak.cloud.azure.AzureTerminationHelperService) List(java.util.List) Component(org.springframework.stereotype.Component) AzureTemplateDeploymentService(com.sequenceiq.cloudbreak.cloud.azure.template.AzureTemplateDeploymentService) Group(com.sequenceiq.cloudbreak.cloud.model.Group) CloudException(com.microsoft.azure.CloudException) Pattern(java.util.regex.Pattern) AzureInstanceTemplateOperation(com.sequenceiq.cloudbreak.cloud.azure.AzureInstanceTemplateOperation) Collections(java.util.Collections) Group(com.sequenceiq.cloudbreak.cloud.model.Group) CloudConnectorException(com.sequenceiq.cloudbreak.cloud.exception.CloudConnectorException) CloudContext(com.sequenceiq.cloudbreak.cloud.context.CloudContext) ArrayList(java.util.ArrayList) Deployment(com.microsoft.azure.management.resources.Deployment) CloudException(com.microsoft.azure.CloudException) RolledbackResourcesException(com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException) DateTime(org.joda.time.DateTime) RolledbackResourcesException(com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException) CloudConnectorException(com.sequenceiq.cloudbreak.cloud.exception.CloudConnectorException) QuotaExceededException(com.sequenceiq.cloudbreak.cloud.exception.QuotaExceededException) CloudException(com.microsoft.azure.CloudException) CloudResourceStatus(com.sequenceiq.cloudbreak.cloud.model.CloudResourceStatus) CloudResource(com.sequenceiq.cloudbreak.cloud.model.CloudResource) Retry(com.sequenceiq.cloudbreak.service.Retry)

Example 2 with RolledbackResourcesException

use of com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException in project cloudbreak by hortonworks.

the class CloudFailureHandlerTest method rollbackOnExactDoesNotReachThreshold.

@Test
void rollbackOnExactDoesNotReachThreshold() throws Exception {
    ScaleContext scaleContext = new ScaleContext(true, AdjustmentType.EXACT, 4L);
    Group group = mock(Group.class);
    List<CloudResourceStatus> failuresList = new ArrayList<>();
    CloudResource instance2 = newResource("instance-2", ResourceType.AWS_INSTANCE, CommonStatus.FAILED);
    failuresList.add(new CloudResourceStatus(instance2, ResourceStatus.FAILED, "failed instance", 2L));
    CloudResource instance3 = newResource("instance-3", ResourceType.AWS_INSTANCE, CommonStatus.FAILED);
    failuresList.add(new CloudResourceStatus(instance3, ResourceStatus.FAILED, "failed instance", 3L));
    CloudResource instance4 = newResource("instance-4", ResourceType.AWS_INSTANCE, CommonStatus.FAILED);
    failuresList.add(new CloudResourceStatus(instance4, ResourceStatus.FAILED, "failed instance", 4L));
    AuthenticatedContext auth = new AuthenticatedContext(mock(CloudContext.class), mock(CloudCredential.class));
    ResourceBuilderContext resourceBuilderContext = mock(ResourceBuilderContext.class);
    List<CloudResourceStatus> resourceStatuses = new ArrayList<>(failuresList);
    CloudResource volume2 = newResource("vol-2", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume2, ResourceStatus.CREATED, 2L));
    CloudResource volume4 = newResource("vol-4", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume4, ResourceStatus.CREATED, 4L));
    CloudResource instance1 = newResource("instance-1", ResourceType.AWS_INSTANCE, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(instance1, ResourceStatus.CREATED, 1L));
    CloudResource volume1 = newResource("vol-1", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume1, ResourceStatus.CREATED, 1L));
    CloudResource instance5 = newResource("instance-5", ResourceType.AWS_INSTANCE, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(instance5, ResourceStatus.CREATED, 5L));
    CloudResource volume5 = newResource("vol-5", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume5, ResourceStatus.CREATED, 5L));
    CloudResource instance6 = newResource("instance-6", ResourceType.AWS_INSTANCE, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(instance6, ResourceStatus.CREATED, 6L));
    CloudResource volume6 = newResource("vol-6", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume6, ResourceStatus.CREATED, 6L));
    ResourceBuilders resourceBuilders = mock(ResourceBuilders.class);
    ArrayList<ComputeResourceBuilder<ResourceBuilderContext>> computeResourceBuilders = new ArrayList<>();
    ComputeResourceBuilder instanceResourceBuilder = mock(ComputeResourceBuilder.class);
    when(instanceResourceBuilder.resourceType()).thenReturn(ResourceType.AWS_INSTANCE);
    computeResourceBuilders.add(instanceResourceBuilder);
    ComputeResourceBuilder volumeResourceBuilder = mock(ComputeResourceBuilder.class);
    when(volumeResourceBuilder.resourceType()).thenReturn(ResourceType.AWS_VOLUMESET);
    computeResourceBuilders.add(volumeResourceBuilder);
    when(resourceBuilders.compute(any())).thenReturn(computeResourceBuilders);
    ArgumentCaptor<ResourceDeletionCallable> callableArgumentCaptor = ArgumentCaptor.forClass(ResourceDeletionCallable.class);
    when(resourceBuilderExecutor.submit(callableArgumentCaptor.capture())).thenAnswer(invocation -> ((Callable) invocation.getArgument(0)).call());
    RolledbackResourcesException rolledbackResourcesException = assertThrows(RolledbackResourcesException.class, () -> cloudFailureHandler.rollbackIfNecessary(new CloudFailureContext(auth, scaleContext, resourceBuilderContext), failuresList, resourceStatuses, group, resourceBuilders, 6));
    assertEquals("Resources are rolled back because successful node count was lower than threshold. 3 nodes are failed. Error reason: failed instance", rolledbackResourcesException.getMessage());
    verifyDeleteAll(instanceResourceBuilder, resourceBuilderContext, auth, instance1, instance5, instance6);
    verifyDeleteAll(volumeResourceBuilder, resourceBuilderContext, auth, volume1, volume2, volume4, volume5, volume6);
    verify(resourceBuilderExecutor, times(11)).submit(any(Callable.class));
}
Also used : Group(com.sequenceiq.cloudbreak.cloud.model.Group) CloudCredential(com.sequenceiq.cloudbreak.cloud.model.CloudCredential) ScaleContext(com.sequenceiq.cloudbreak.cloud.template.compute.CloudFailureHandler.ScaleContext) CloudContext(com.sequenceiq.cloudbreak.cloud.context.CloudContext) ArrayList(java.util.ArrayList) AuthenticatedContext(com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext) RolledbackResourcesException(com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException) Callable(java.util.concurrent.Callable) ComputeResourceBuilder(com.sequenceiq.cloudbreak.cloud.template.ComputeResourceBuilder) CloudResourceStatus(com.sequenceiq.cloudbreak.cloud.model.CloudResourceStatus) ResourceBuilders(com.sequenceiq.cloudbreak.cloud.template.init.ResourceBuilders) ResourceBuilderContext(com.sequenceiq.cloudbreak.cloud.template.context.ResourceBuilderContext) CloudResource(com.sequenceiq.cloudbreak.cloud.model.CloudResource) Test(org.junit.jupiter.api.Test)

Example 3 with RolledbackResourcesException

use of com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException in project cloudbreak by hortonworks.

the class CloudFailureHandlerTest method rollbackOnPercentageDoesNotReachThreshold.

@Test
void rollbackOnPercentageDoesNotReachThreshold() throws Exception {
    ScaleContext scaleContext = new ScaleContext(true, AdjustmentType.PERCENTAGE, 60L);
    Group group = mock(Group.class);
    ArrayList<CloudResourceStatus> failuresList = new ArrayList<>();
    CloudResource instance2 = newResource("instance-2", ResourceType.AWS_INSTANCE, CommonStatus.FAILED);
    failuresList.add(new CloudResourceStatus(instance2, ResourceStatus.FAILED, "failed instance", 2L));
    CloudResource instance3 = newResource("instance-3", ResourceType.AWS_INSTANCE, CommonStatus.FAILED);
    failuresList.add(new CloudResourceStatus(instance3, ResourceStatus.FAILED, "failed instance", 3L));
    CloudResource instance4 = newResource("instance-4", ResourceType.AWS_INSTANCE, CommonStatus.FAILED);
    failuresList.add(new CloudResourceStatus(instance4, ResourceStatus.FAILED, "failed instance", 4L));
    AuthenticatedContext auth = new AuthenticatedContext(mock(CloudContext.class), mock(CloudCredential.class));
    ResourceBuilderContext resourceBuilderContext = mock(ResourceBuilderContext.class);
    ArrayList<CloudResourceStatus> resourceStatuses = new ArrayList<>(failuresList);
    CloudResource volume2 = newResource("vol-2", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume2, ResourceStatus.CREATED, 2L));
    CloudResource volume4 = newResource("vol-4", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume4, ResourceStatus.CREATED, 4L));
    CloudResource instance1 = newResource("instance-1", ResourceType.AWS_INSTANCE, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(instance1, ResourceStatus.CREATED, 1L));
    CloudResource volume1 = newResource("vol-1", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume1, ResourceStatus.CREATED, 1L));
    CloudResource instance5 = newResource("instance-5", ResourceType.AWS_INSTANCE, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(instance5, ResourceStatus.CREATED, 5L));
    CloudResource volume5 = newResource("vol-5", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume5, ResourceStatus.CREATED, 5L));
    CloudResource instance6 = newResource("instance-6", ResourceType.AWS_INSTANCE, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(instance6, ResourceStatus.CREATED, 6L));
    CloudResource volume6 = newResource("vol-6", ResourceType.AWS_VOLUMESET, CommonStatus.CREATED);
    resourceStatuses.add(new CloudResourceStatus(volume6, ResourceStatus.CREATED, 6L));
    ResourceBuilders resourceBuilders = mock(ResourceBuilders.class);
    ArrayList<ComputeResourceBuilder<ResourceBuilderContext>> computeResourceBuilders = new ArrayList<>();
    ComputeResourceBuilder instanceResourceBuilder = mock(ComputeResourceBuilder.class);
    when(instanceResourceBuilder.resourceType()).thenReturn(ResourceType.AWS_INSTANCE);
    computeResourceBuilders.add(instanceResourceBuilder);
    ComputeResourceBuilder volumeResourceBuilder = mock(ComputeResourceBuilder.class);
    when(volumeResourceBuilder.resourceType()).thenReturn(ResourceType.AWS_VOLUMESET);
    computeResourceBuilders.add(volumeResourceBuilder);
    when(resourceBuilders.compute(any())).thenReturn(computeResourceBuilders);
    ArgumentCaptor<ResourceDeletionCallable> callableArgumentCaptor = ArgumentCaptor.forClass(ResourceDeletionCallable.class);
    when(resourceBuilderExecutor.submit(callableArgumentCaptor.capture())).thenAnswer(invocation -> ((Callable) invocation.getArgument(0)).call());
    RolledbackResourcesException rolledbackResourcesException = assertThrows(RolledbackResourcesException.class, () -> cloudFailureHandler.rollbackIfNecessary(new CloudFailureContext(auth, scaleContext, resourceBuilderContext), failuresList, resourceStatuses, group, resourceBuilders, 6));
    assertEquals("Resources are rolled back because successful node count was lower than threshold. 3 nodes are failed. Error reason: failed instance", rolledbackResourcesException.getMessage());
    verifyDeleteAll(instanceResourceBuilder, resourceBuilderContext, auth, instance1, instance5, instance6);
    verifyDeleteAll(volumeResourceBuilder, resourceBuilderContext, auth, volume1, volume2, volume4, volume5, volume6);
    verify(resourceBuilderExecutor, times(11)).submit(any(Callable.class));
}
Also used : Group(com.sequenceiq.cloudbreak.cloud.model.Group) CloudCredential(com.sequenceiq.cloudbreak.cloud.model.CloudCredential) ScaleContext(com.sequenceiq.cloudbreak.cloud.template.compute.CloudFailureHandler.ScaleContext) CloudContext(com.sequenceiq.cloudbreak.cloud.context.CloudContext) ArrayList(java.util.ArrayList) AuthenticatedContext(com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext) RolledbackResourcesException(com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException) Callable(java.util.concurrent.Callable) ComputeResourceBuilder(com.sequenceiq.cloudbreak.cloud.template.ComputeResourceBuilder) CloudResourceStatus(com.sequenceiq.cloudbreak.cloud.model.CloudResourceStatus) ResourceBuilders(com.sequenceiq.cloudbreak.cloud.template.init.ResourceBuilders) ResourceBuilderContext(com.sequenceiq.cloudbreak.cloud.template.context.ResourceBuilderContext) CloudResource(com.sequenceiq.cloudbreak.cloud.model.CloudResource) Test(org.junit.jupiter.api.Test)

Aggregations

AuthenticatedContext (com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext)3 CloudContext (com.sequenceiq.cloudbreak.cloud.context.CloudContext)3 RolledbackResourcesException (com.sequenceiq.cloudbreak.cloud.exception.RolledbackResourcesException)3 CloudResource (com.sequenceiq.cloudbreak.cloud.model.CloudResource)3 CloudResourceStatus (com.sequenceiq.cloudbreak.cloud.model.CloudResourceStatus)3 Group (com.sequenceiq.cloudbreak.cloud.model.Group)3 ArrayList (java.util.ArrayList)3 CloudCredential (com.sequenceiq.cloudbreak.cloud.model.CloudCredential)2 ComputeResourceBuilder (com.sequenceiq.cloudbreak.cloud.template.ComputeResourceBuilder)2 ScaleContext (com.sequenceiq.cloudbreak.cloud.template.compute.CloudFailureHandler.ScaleContext)2 ResourceBuilderContext (com.sequenceiq.cloudbreak.cloud.template.context.ResourceBuilderContext)2 ResourceBuilders (com.sequenceiq.cloudbreak.cloud.template.init.ResourceBuilders)2 Callable (java.util.concurrent.Callable)2 Test (org.junit.jupiter.api.Test)2 CloudError (com.microsoft.azure.CloudError)1 CloudException (com.microsoft.azure.CloudException)1 Deployment (com.microsoft.azure.management.resources.Deployment)1 AzureCloudResourceService (com.sequenceiq.cloudbreak.cloud.azure.AzureCloudResourceService)1 AzureInstanceTemplateOperation (com.sequenceiq.cloudbreak.cloud.azure.AzureInstanceTemplateOperation)1 AzureResourceGroupMetadataProvider (com.sequenceiq.cloudbreak.cloud.azure.AzureResourceGroupMetadataProvider)1