/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.workflow; import java.io.Serializable; import java.util.Map; import com.emc.storageos.svcs.errorhandling.model.ServiceCoded; import com.emc.storageos.workflow.Workflow.StepState; import com.emc.storageos.workflow.Workflow.StepStatus; /** * A nested rollback handler for rollback of entire Workflows. It calls the original handler * as needed and handles the completion of the parent Workflow. */ class NestedWorkflowRollbackHandler implements Workflow.WorkflowRollbackHandler, Serializable { static final Integer NUMBER_OF_ADDED_ARGS = 2; // number of arguments added for our handler // There may be a nested (i.e. previous) handler that our handler needs to call. If so, // it will be placed in the args here. static int indexOfNestedHandler(Object[] args) { return (args.length - 2); // next to last argument in list } // The parentStepId will be in the args at this position. We will need to fire a workflow // step completer on the parent step id. static int indexOfParentStepId(Object[] args) { return (args.length - 1); // the very last argument } @Override public void initiatingRollback(Workflow workflow, Object[] args) { Workflow.WorkflowRollbackHandler originalHandler = (Workflow.WorkflowRollbackHandler) args[indexOfNestedHandler(args)]; if (originalHandler != null) { originalHandler.initiatingRollback(workflow, args); } } @Override public void rollbackComplete(Workflow workflow, Object[] args) { Workflow.WorkflowRollbackHandler originalHandler = (Workflow.WorkflowRollbackHandler) args[indexOfNestedHandler(args)]; if (originalHandler != null) { originalHandler.initiatingRollback(workflow, args); } Map<String, StepStatus> stepToStepStatus = workflow.getStepStatusMap(); boolean rollbackError = false; StringBuilder builder = new StringBuilder(); for (StepStatus stepStatus : stepToStepStatus.values()) { if (stepStatus.description.startsWith("Rollback ") && stepStatus.state == StepState.ERROR) { if (builder.length() > 0) { builder.append("\n"); } builder.append(stepStatus.message); rollbackError = true; } } String parentStepId = (String) args[indexOfParentStepId(args)]; if (rollbackError) { ServiceCoded coded = WorkflowException.exceptions.innerWorkflowRollbackError(workflow.getWorkflowURI().toString(), builder.toString()); WorkflowStepCompleter.stepFailed(parentStepId, coded); } else { WorkflowStepCompleter.stepSucceded(parentStepId); } } }