package com.sequenceiq.cloudbreak.core.flow2.stack.downscale; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.statemachine.action.Action; import com.sequenceiq.cloudbreak.cloud.event.Selectable; import com.sequenceiq.cloudbreak.cloud.event.resource.DownscaleStackCollectResourcesRequest; import com.sequenceiq.cloudbreak.cloud.event.resource.DownscaleStackCollectResourcesResult; import com.sequenceiq.cloudbreak.cloud.event.resource.DownscaleStackRequest; import com.sequenceiq.cloudbreak.cloud.event.resource.DownscaleStackResult; import com.sequenceiq.cloudbreak.cloud.model.CloudInstance; import com.sequenceiq.cloudbreak.cloud.model.CloudResource; import com.sequenceiq.cloudbreak.converter.spi.InstanceMetaDataToCloudInstanceConverter; import com.sequenceiq.cloudbreak.converter.spi.ResourceToCloudResourceConverter; import com.sequenceiq.cloudbreak.core.flow2.event.StackDownscaleTriggerEvent; import com.sequenceiq.cloudbreak.core.flow2.stack.AbstractStackFailureAction; import com.sequenceiq.cloudbreak.core.flow2.stack.StackFailureContext; import com.sequenceiq.cloudbreak.domain.InstanceGroup; import com.sequenceiq.cloudbreak.domain.InstanceMetaData; import com.sequenceiq.cloudbreak.domain.Stack; import com.sequenceiq.cloudbreak.reactor.api.event.StackEvent; import com.sequenceiq.cloudbreak.reactor.api.event.StackFailureEvent; @Configuration public class StackDownscaleActions { private static final Logger LOGGER = LoggerFactory.getLogger(StackDownscaleActions.class); private static final String RESOURCES = "RESOURCES"; private static final String INSTANCES = "INSTANCES"; @Inject private InstanceMetaDataToCloudInstanceConverter metadataConverter; @Inject private ResourceToCloudResourceConverter cloudResourceConverter; @Inject private StackDownscaleService stackDownscaleService; @Bean(name = "DOWNSCALE_COLLECT_RESOURCES_STATE") public Action stackDownscaleCollectResourcesAction() { return new AbstractStackDownscaleAction<StackDownscaleTriggerEvent>(StackDownscaleTriggerEvent.class) { @Override protected void doExecute(StackScalingFlowContext context, StackDownscaleTriggerEvent payload, Map<Object, Object> variables) throws Exception { stackDownscaleService.startStackDownscale(context, payload); Stack stack = context.getStack(); LOGGER.debug("Assembling downscale stack event for stack: {}", stack); List<CloudResource> resources = cloudResourceConverter.convert(stack.getResources()); variables.put(RESOURCES, resources); List<CloudInstance> instances = new ArrayList<>(); InstanceGroup group = stack.getInstanceGroupByInstanceGroupName(context.getInstanceGroupName()); for (InstanceMetaData metaData : group.getAllInstanceMetaData()) { if (context.getInstanceIds().contains(metaData.getInstanceId())) { CloudInstance cloudInstance = metadataConverter.convert(metaData); instances.add(cloudInstance); } } variables.put(INSTANCES, instances); DownscaleStackCollectResourcesRequest request = new DownscaleStackCollectResourcesRequest(context.getCloudContext(), context.getCloudCredential(), context.getCloudStack(), resources, instances); sendEvent(context.getFlowId(), request); } }; } @Bean(name = "DOWNSCALE_STATE") public Action stackDownscaleAction() { return new AbstractStackDownscaleAction<DownscaleStackCollectResourcesResult>(DownscaleStackCollectResourcesResult.class) { @Override protected void doExecute(StackScalingFlowContext context, DownscaleStackCollectResourcesResult payload, Map<Object, Object> variables) throws Exception { DownscaleStackRequest request = new DownscaleStackRequest(context.getCloudContext(), context.getCloudCredential(), context.getCloudStack(), (List<CloudResource>) variables.get(RESOURCES), (List<CloudInstance>) variables.get(INSTANCES), payload.getResourcesToScale()); sendEvent(context.getFlowId(), request); } }; } @Bean(name = "DOWNSCALE_FINISHED_STATE") public Action stackDownscaleFinishedAction() { return new AbstractStackDownscaleAction<DownscaleStackResult>(DownscaleStackResult.class) { @Override protected void doExecute(StackScalingFlowContext context, DownscaleStackResult payload, Map<Object, Object> variables) throws Exception { stackDownscaleService.finishStackDownscale(context, getInstanceGroupName(variables), getInstanceIds(variables)); sendEvent(context); } @Override protected Selectable createRequest(StackScalingFlowContext context) { return new StackEvent(StackDownscaleEvent.DOWNSCALE_FINALIZED_EVENT.event(), context.getStack().getId()); } }; } @Bean(name = "DOWNSCALE_FAILED_STATE") public Action stackDownscaleFailedAction() { return new AbstractStackFailureAction<StackDownscaleState, StackDownscaleEvent>() { @Override protected void doExecute(StackFailureContext context, StackFailureEvent payload, Map<Object, Object> variables) throws Exception { stackDownscaleService.handleStackDownscaleError(payload.getException()); sendEvent(context); } @Override protected Selectable createRequest(StackFailureContext context) { return new StackEvent(StackDownscaleEvent.DOWNSCALE_FAIL_HANDLED_EVENT.event(), context.getStack().getId()); } }; } }