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());
}
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());
}
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());
}
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));
}
}
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());
}
Aggregations