Search in sources :

Example 1 with StopStartDownscaleStopInstancesRequest

use of com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest in project cloudbreak by hortonworks.

the class StopStartDownscaleActionsTest method testStopInstancesActionAllDecommissioned.

@Test
void testStopInstancesActionAllDecommissioned() throws Exception {
    AbstractStopStartDownscaleActions<StopStartDownscaleDecommissionViaCMResult> action = (AbstractStopStartDownscaleActions<StopStartDownscaleDecommissionViaCMResult>) underTest.stopInstancesAction();
    initActionPrivateFields(action);
    List<InstanceMetaData> instancesActionableStarted = generateInstances(10, 100, InstanceStatus.SERVICES_HEALTHY, INSTANCE_GROUP_NAME_ACTIONABLE);
    List<InstanceMetaData> instancesActionableNotStarted = generateInstances(5, 200, InstanceStatus.STOPPED, INSTANCE_GROUP_NAME_ACTIONABLE);
    List<InstanceMetaData> instancesRandomStarted = generateInstances(8, 300, InstanceStatus.SERVICES_HEALTHY, INSTANCE_GROUP_NAME_RANDOM);
    List<InstanceMetaData> instancesRandomNotStarted = generateInstances(3, 400, InstanceStatus.STOPPED, INSTANCE_GROUP_NAME_RANDOM);
    List<InstanceMetaData> expectedToBeStopped = instancesActionableStarted.stream().limit(5).collect(Collectors.toList());
    Set<Long> instanceIdsToRemove = expectedToBeStopped.stream().map(InstanceMetaData::getId).collect(Collectors.toUnmodifiableSet());
    Set<String> decommissionedHostsFqdns = expectedToBeStopped.stream().map(InstanceMetaData::getDiscoveryFQDN).collect(Collectors.toUnmodifiableSet());
    StopStartDownscaleContext stopStartDownscaleContext = createContext(instanceIdsToRemove);
    StopStartDownscaleDecommissionViaCMRequest r = new StopStartDownscaleDecommissionViaCMRequest(1L, INSTANCE_GROUP_NAME_ACTIONABLE, instanceIdsToRemove);
    StopStartDownscaleDecommissionViaCMResult payload = new StopStartDownscaleDecommissionViaCMResult(r, decommissionedHostsFqdns, Collections.emptyList());
    mockStackEtc(instancesActionableStarted, instancesActionableNotStarted, instancesRandomStarted, instancesRandomNotStarted);
    List<CloudInstance> expectedCloudInstances = mockInstanceMetadataToCloudInstanceConverter(expectedToBeStopped);
    when(reactorEventFactory.createEvent(anyMap(), isNotNull())).thenReturn(event);
    new AbstractActionTestSupport<>(action).doExecute(stopStartDownscaleContext, payload, Collections.emptyMap());
    verify(instanceMetaDataToCloudInstanceConverter).convert(eq(expectedToBeStopped), anyString(), any(StackAuthentication.class));
    verify(stopStartDownscaleFlowService).clusterDownscalingStoppingInstances(eq(STACK_ID), eq(INSTANCE_GROUP_NAME_ACTIONABLE), eq(decommissionedHostsFqdns));
    verifyNoMoreInteractions(stopStartDownscaleFlowService);
    ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class);
    verify(reactorEventFactory).createEvent(anyMap(), argumentCaptor.capture());
    verify(eventBus).notify("STOPSTARTDOWNSCALESTOPINSTANCESREQUEST", event);
    assertThat(argumentCaptor.getValue()).isInstanceOf(StopStartDownscaleStopInstancesRequest.class);
    StopStartDownscaleStopInstancesRequest req = (StopStartDownscaleStopInstancesRequest) argumentCaptor.getValue();
    Assert.assertEquals(expectedCloudInstances, req.getCloudInstancesToStop());
}
Also used : StopStartDownscaleDecommissionViaCMResult(com.sequenceiq.cloudbreak.reactor.api.event.orchestration.StopStartDownscaleDecommissionViaCMResult) StackAuthentication(com.sequenceiq.cloudbreak.domain.StackAuthentication) StopStartDownscaleStopInstancesRequest(com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest) CloudInstance(com.sequenceiq.cloudbreak.cloud.model.CloudInstance) StopStartDownscaleDecommissionViaCMRequest(com.sequenceiq.cloudbreak.reactor.api.event.cluster.StopStartDownscaleDecommissionViaCMRequest) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) AbstractStopStartDownscaleActions(com.sequenceiq.cloudbreak.core.flow2.cluster.stopstartds.StopStartDownscaleActions.AbstractStopStartDownscaleActions) InstanceMetaData(com.sequenceiq.cloudbreak.domain.stack.instance.InstanceMetaData) Test(org.junit.jupiter.api.Test)

Example 2 with StopStartDownscaleStopInstancesRequest

use of com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest in project cloudbreak by hortonworks.

the class StopStartDownscaleStopInstancesHandlerTest method testExpectedResultInernal.

private void testExpectedResultInernal(List<CloudInstance> cloudInstancesToStop, List<CloudVmInstanceStatus> cloudConnectoReturnList, boolean expectedCloudInteractions) {
    StopStartDownscaleStopInstancesRequest request = new StopStartDownscaleStopInstancesRequest(cloudContext, cloudCredential, cloudStack, cloudInstancesToStop);
    lenient().when(instanceConnector.stopWithLimitedRetry(any(AuthenticatedContext.class), eq(null), eq(cloudInstancesToStop), any(Long.class))).thenReturn(cloudConnectoReturnList);
    Event event = new Event(request);
    underTest.accept(event);
    ArgumentCaptor<Event> resultCaptor = ArgumentCaptor.forClass(Event.class);
    verify(eventBus).notify(any(Object.class), resultCaptor.capture());
    if (expectedCloudInteractions) {
        verify(instanceConnector).stopWithLimitedRetry(any(AuthenticatedContext.class), eq(null), eq(cloudInstancesToStop), eq(EXPECTED_STOP_POLL_TIMEBOUND_MS));
    }
    verifyNoMoreInteractions(instanceConnector);
    assertEquals(1, resultCaptor.getAllValues().size());
    Event resultEvent = resultCaptor.getValue();
    assertEquals(StopStartDownscaleStopInstancesResult.class, resultEvent.getData().getClass());
    StopStartDownscaleStopInstancesResult result = (StopStartDownscaleStopInstancesResult) resultEvent.getData();
    assertEquals(cloudConnectoReturnList, result.getAffectedInstanceStatuses());
}
Also used : StopStartDownscaleStopInstancesRequest(com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest) Event(reactor.bus.Event) StopStartDownscaleStopInstancesResult(com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesResult) AuthenticatedContext(com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext)

Example 3 with StopStartDownscaleStopInstancesRequest

use of com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest in project cloudbreak by hortonworks.

the class StopStartDownscaleStopInstancesHandlerTest method testFailureFromCloudProviderWhenStoppingInstances.

@Test
void testFailureFromCloudProviderWhenStoppingInstances() {
    List<CloudInstance> cloudInstancesToStop = generateCloudInstances(5);
    when(instanceConnector.stopWithLimitedRetry(any(AuthenticatedContext.class), eq(null), eq(cloudInstancesToStop), any(Long.class))).thenThrow(new RuntimeException("CloudProviderStopError"));
    StopStartDownscaleStopInstancesRequest request = new StopStartDownscaleStopInstancesRequest(cloudContext, cloudCredential, cloudStack, cloudInstancesToStop);
    Event event = new Event(request);
    underTest.accept(event);
    ArgumentCaptor<Event> resultCaptor = ArgumentCaptor.forClass(Event.class);
    verify(eventBus).notify(any(Object.class), resultCaptor.capture());
    assertEquals(1, resultCaptor.getAllValues().size());
    Event resultEvent = resultCaptor.getValue();
    assertEquals(StopStartDownscaleStopInstancesResult.class, resultEvent.getData().getClass());
    StopStartDownscaleStopInstancesResult result = (StopStartDownscaleStopInstancesResult) resultEvent.getData();
    assertEquals(0, result.getAffectedInstanceStatuses().size());
    assertEquals("CloudProviderStopError", result.getErrorDetails().getMessage());
    assertEquals("STOPSTARTDOWNSCALESTOPINSTANCESRESULT_ERROR", result.selector());
    assertEquals(EventStatus.FAILED, result.getStatus());
}
Also used : StopStartDownscaleStopInstancesRequest(com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest) CloudInstance(com.sequenceiq.cloudbreak.cloud.model.CloudInstance) Event(reactor.bus.Event) StopStartDownscaleStopInstancesResult(com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesResult) AuthenticatedContext(com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext) Test(org.junit.jupiter.api.Test)

Example 4 with StopStartDownscaleStopInstancesRequest

use of com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest in project cloudbreak by hortonworks.

the class StopStartDownscaleStopInstancesHandler method accept.

@Override
public void accept(Event<StopStartDownscaleStopInstancesRequest> event) {
    StopStartDownscaleStopInstancesRequest request = event.getData();
    LOGGER.info("StopStartDownscaleStopInstancesHandler: {}", event.getData().getResourceId());
    CloudContext cloudContext = request.getCloudContext();
    try {
        CloudConnector<?> connector = cloudPlatformConnectors.get(cloudContext.getPlatformVariant());
        AuthenticatedContext ac = getAuthenticatedContext(request, cloudContext, connector);
        List<CloudInstance> cloudInstancesToStop = request.getCloudInstancesToStop();
        List<CloudVmInstanceStatus> cloudVmInstanceStatusList = Collections.emptyList();
        if (cloudInstancesToStop.size() > 0) {
            LOGGER.info("Attempting to stop instances with a timebound of {}ms. count={}, instances=[{}]", STOP_POLL_TIMEBOUND_MS, cloudInstancesToStop.size(), cloudInstancesToStop.stream().map(CloudInstance::getInstanceId).collect(Collectors.toList()));
            // TODO CB-15132: CB-15342 In case of a failure in this step, the nodes stay in a DECOMMISSIONED state,
            // even if the services are started via CM. The StackStatusChckerJob appears to ignore a bunch of CM states.
            // TODO CB-15132: What happens if the cloud provider does not know about an instance for which a STOP was requested. How does the API
            // behave.
            cloudVmInstanceStatusList = connector.instances().stopWithLimitedRetry(ac, null, cloudInstancesToStop, STOP_POLL_TIMEBOUND_MS);
        } else {
            LOGGER.info("No cloud VM instances to stop. Succeeding flow step with no action taken");
        }
        LOGGER.trace("CloudVMInstanceStatusesPostStop={}", cloudVmInstanceStatusList);
        // TODO CB-15132: If we fail to STOP all instances - one potential path for error handling would be to allow a subsequent upscale operation
        // to consider nodes which are in DECOMMISSIONED state, but RUNNING - as candidates for UPSCALE.
        StopStartDownscaleStopInstancesResult result = new StopStartDownscaleStopInstancesResult(request.getResourceId(), request, cloudVmInstanceStatusList);
        eventBus.notify(result.selector(), new Event<>(event.getHeaders(), result));
    } catch (Exception e) {
        // TODO CB-15132: Try propagating specific information in the error, so that a later step can potentially attempt
        // to recover from this, or proceed with a reduced set of nodes.
        String message = "Failed while attempting to stop some instances";
        LOGGER.error(message, e);
        StopStartDownscaleStopInstancesResult result = new StopStartDownscaleStopInstancesResult(message, e, request.getResourceId(), request);
        eventBus.notify(result.selector(), new Event<>(event.getHeaders(), result));
    }
}
Also used : StopStartDownscaleStopInstancesRequest(com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest) CloudContext(com.sequenceiq.cloudbreak.cloud.context.CloudContext) CloudVmInstanceStatus(com.sequenceiq.cloudbreak.cloud.model.CloudVmInstanceStatus) CloudInstance(com.sequenceiq.cloudbreak.cloud.model.CloudInstance) StopStartDownscaleStopInstancesResult(com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesResult) AuthenticatedContext(com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext) Event(reactor.bus.Event)

Example 5 with StopStartDownscaleStopInstancesRequest

use of com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest in project cloudbreak by hortonworks.

the class StopStartDownscaleActionsTest method testStopInstancesActionNotAllDecommissioned.

@Test
void testStopInstancesActionNotAllDecommissioned() throws Exception {
    AbstractStopStartDownscaleActions<StopStartDownscaleDecommissionViaCMResult> action = (AbstractStopStartDownscaleActions<StopStartDownscaleDecommissionViaCMResult>) underTest.stopInstancesAction();
    initActionPrivateFields(action);
    List<InstanceMetaData> instancesActionableStarted = generateInstances(10, 100, InstanceStatus.SERVICES_HEALTHY, INSTANCE_GROUP_NAME_ACTIONABLE);
    List<InstanceMetaData> instancesActionableNotStarted = generateInstances(5, 200, InstanceStatus.STOPPED, INSTANCE_GROUP_NAME_ACTIONABLE);
    List<InstanceMetaData> instancesRandomStarted = generateInstances(8, 300, InstanceStatus.SERVICES_HEALTHY, INSTANCE_GROUP_NAME_RANDOM);
    List<InstanceMetaData> instancesRandomNotStarted = generateInstances(3, 400, InstanceStatus.STOPPED, INSTANCE_GROUP_NAME_RANDOM);
    Set<Long> instanceIdsToRemove = instancesActionableStarted.stream().limit(6).map(InstanceMetaData::getId).collect(Collectors.toUnmodifiableSet());
    List<InstanceMetaData> expectedToBeStopped = instancesActionableStarted.stream().limit(4).collect(Collectors.toList());
    Set<String> decommissionedHostsFqdns = expectedToBeStopped.stream().map(InstanceMetaData::getDiscoveryFQDN).collect(Collectors.toUnmodifiableSet());
    List<InstanceMetaData> notDecommissioned = instancesActionableStarted.subList(4, 6);
    List<String> notDecommissionedFqdns = notDecommissioned.stream().map(InstanceMetaData::getDiscoveryFQDN).collect(Collectors.toUnmodifiableList());
    StopStartDownscaleContext stopStartDownscaleContext = createContext(instanceIdsToRemove);
    StopStartDownscaleDecommissionViaCMRequest r = new StopStartDownscaleDecommissionViaCMRequest(1L, INSTANCE_GROUP_NAME_ACTIONABLE, instanceIdsToRemove);
    StopStartDownscaleDecommissionViaCMResult payload = new StopStartDownscaleDecommissionViaCMResult(r, decommissionedHostsFqdns, notDecommissionedFqdns);
    mockStackEtc(instancesActionableStarted, instancesActionableNotStarted, instancesRandomStarted, instancesRandomNotStarted);
    List<CloudInstance> expectedCloudInstances = mockInstanceMetadataToCloudInstanceConverter(expectedToBeStopped);
    when(reactorEventFactory.createEvent(anyMap(), isNotNull())).thenReturn(event);
    new AbstractActionTestSupport<>(action).doExecute(stopStartDownscaleContext, payload, Collections.emptyMap());
    verify(instanceMetaDataToCloudInstanceConverter).convert(eq(expectedToBeStopped), anyString(), any(StackAuthentication.class));
    verify(stopStartDownscaleFlowService).logCouldNotDecommission(eq(STACK_ID), eq(notDecommissionedFqdns));
    verify(stopStartDownscaleFlowService).clusterDownscalingStoppingInstances(eq(STACK_ID), eq(INSTANCE_GROUP_NAME_ACTIONABLE), eq(decommissionedHostsFqdns));
    verifyNoMoreInteractions(stopStartDownscaleFlowService);
    ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class);
    verify(reactorEventFactory).createEvent(anyMap(), argumentCaptor.capture());
    verify(eventBus).notify("STOPSTARTDOWNSCALESTOPINSTANCESREQUEST", event);
    assertThat(argumentCaptor.getValue()).isInstanceOf(StopStartDownscaleStopInstancesRequest.class);
    StopStartDownscaleStopInstancesRequest req = (StopStartDownscaleStopInstancesRequest) argumentCaptor.getValue();
    Assert.assertEquals(expectedCloudInstances, req.getCloudInstancesToStop());
}
Also used : StopStartDownscaleDecommissionViaCMResult(com.sequenceiq.cloudbreak.reactor.api.event.orchestration.StopStartDownscaleDecommissionViaCMResult) StackAuthentication(com.sequenceiq.cloudbreak.domain.StackAuthentication) StopStartDownscaleStopInstancesRequest(com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest) CloudInstance(com.sequenceiq.cloudbreak.cloud.model.CloudInstance) StopStartDownscaleDecommissionViaCMRequest(com.sequenceiq.cloudbreak.reactor.api.event.cluster.StopStartDownscaleDecommissionViaCMRequest) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) AbstractStopStartDownscaleActions(com.sequenceiq.cloudbreak.core.flow2.cluster.stopstartds.StopStartDownscaleActions.AbstractStopStartDownscaleActions) InstanceMetaData(com.sequenceiq.cloudbreak.domain.stack.instance.InstanceMetaData) Test(org.junit.jupiter.api.Test)

Aggregations

StopStartDownscaleStopInstancesRequest (com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesRequest)7 CloudInstance (com.sequenceiq.cloudbreak.cloud.model.CloudInstance)6 StopStartDownscaleStopInstancesResult (com.sequenceiq.cloudbreak.cloud.event.instance.StopStartDownscaleStopInstancesResult)4 InstanceMetaData (com.sequenceiq.cloudbreak.domain.stack.instance.InstanceMetaData)4 StopStartDownscaleDecommissionViaCMRequest (com.sequenceiq.cloudbreak.reactor.api.event.cluster.StopStartDownscaleDecommissionViaCMRequest)4 StopStartDownscaleDecommissionViaCMResult (com.sequenceiq.cloudbreak.reactor.api.event.orchestration.StopStartDownscaleDecommissionViaCMResult)4 Test (org.junit.jupiter.api.Test)4 AuthenticatedContext (com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext)3 AbstractStopStartDownscaleActions (com.sequenceiq.cloudbreak.core.flow2.cluster.stopstartds.StopStartDownscaleActions.AbstractStopStartDownscaleActions)3 StackAuthentication (com.sequenceiq.cloudbreak.domain.StackAuthentication)3 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)3 Event (reactor.bus.Event)3 CloudContext (com.sequenceiq.cloudbreak.cloud.context.CloudContext)2 CloudVmInstanceStatus (com.sequenceiq.cloudbreak.cloud.model.CloudVmInstanceStatus)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Crn (com.sequenceiq.cloudbreak.auth.crn.Crn)1 AvailabilityZone.availabilityZone (com.sequenceiq.cloudbreak.cloud.model.AvailabilityZone.availabilityZone)1 CloudCredential (com.sequenceiq.cloudbreak.cloud.model.CloudCredential)1 CloudStack (com.sequenceiq.cloudbreak.cloud.model.CloudStack)1 InstanceStatus (com.sequenceiq.cloudbreak.cloud.model.InstanceStatus)1