Search in sources :

Example 1 with StepState

use of com.emc.storageos.workflow.Workflow.StepState in project coprhd-controller by CoprHD.

the class WorkflowService method queueResumeSteps.

/**
 * Queue steps to resume workflow.
 *
 * @param workflow
 */
private void queueResumeSteps(Workflow workflow, Map<String, com.emc.storageos.db.client.model.Workflow> childWFMap) {
    // Clear any error steps. Mark back to CREATED.
    for (String stepId : workflow.getStepMap().keySet()) {
        StepState state = workflow.getStepStatus(stepId).state;
        switch(state) {
            case ERROR:
                // resumeWorkflow will resume the appropriate child workflows.
                if (childWFMap.containsKey(stepId)) {
                    Workflow child = loadWorkflowFromUri(childWFMap.get(stepId).getId());
                    if (child.getWorkflowState() == WorkflowState.SUSPENDED_ERROR || child.getWorkflowState() == WorkflowState.SUSPENDED_NO_ERROR) {
                        workflow.getStepStatus(stepId).updateState(StepState.EXECUTING, null, "");
                        break;
                    }
                }
                workflow.getStepStatus(stepId).updateState(StepState.CREATED, null, "");
                break;
            case BLOCKED:
            case CREATED:
            case SUSPENDED_NO_ERROR:
            case SUSPENDED_ERROR:
            case CANCELLED:
            case EXECUTING:
                workflow.getStepStatus(stepId).updateState(StepState.CREATED, null, "");
                break;
            case QUEUED:
            case SUCCESS:
                break;
        }
    }
    // Queue the newly recreated steps
    for (String stepId : workflow.getStepMap().keySet()) {
        Step step = workflow.getStepMap().get(stepId);
        if (step.status.state == StepState.CREATED) {
            queueWorkflowStep(workflow, step);
            persistWorkflowStep(workflow, step);
        }
    }
    workflow.setWorkflowState(WorkflowState.RUNNING);
    persistWorkflow(workflow);
    logWorkflow(workflow, true);
}
Also used : StepState(com.emc.storageos.workflow.Workflow.StepState) Step(com.emc.storageos.workflow.Workflow.Step)

Example 2 with StepState

use of com.emc.storageos.workflow.Workflow.StepState in project coprhd-controller by CoprHD.

the class WorkflowService method rollbackInnerWorkflow.

/**
 * Rolls back a workflow that is assumed to be a child of the given stepId.
 * Updates the step status to EXECUTING if workflow is successfully initiated,
 * and aranges for a rollback completer to mark the step as SUCCESS when
 * the rollback completes.
 * NOTE: The current state of the child workflow must be SUCCESS in order
 * for rollback to be invoked.
 *
 * @param workflow
 *            -- the Inner workflow
 * @param stepId
 *            -- assumed to be a stepId of the outer workflow
 */
private void rollbackInnerWorkflow(Workflow workflow, String stepId) {
    URI uri = workflow.getWorkflowURI();
    _log.info(String.format("Rollback requested workflow: %s", uri));
    // Get the workflow state.
    String[] message = new String[1];
    message[0] = "";
    StepState state = Workflow.getOverallState(workflow.getStepStatusMap(), message);
    // Update the rollback handlers. We do this in order to be able to fire a completer at the end of the workflow.
    Object[] args;
    if (workflow._rollbackHandler != null) {
        // Nested rollback handler, add our arguments to the end.
        // Our rollback handler will call the nested handler.
        args = new Object[workflow._rollbackHandlerArgs.length + NestedWorkflowRollbackHandler.NUMBER_OF_ADDED_ARGS];
        for (int i = 0; i < workflow._rollbackHandlerArgs.length; i++) {
            // copy original arguments
            args[i] = workflow._rollbackHandlerArgs[i];
        }
        // append our new arguments, to the original original rollback handler
        args[NestedWorkflowRollbackHandler.indexOfNestedHandler(args)] = workflow._rollbackHandler;
        // append stepId for completion
        args[NestedWorkflowRollbackHandler.indexOfParentStepId(args)] = stepId;
    } else {
        // No nested rollback handler.
        args = new Object[NestedWorkflowRollbackHandler.NUMBER_OF_ADDED_ARGS];
        args[NestedWorkflowRollbackHandler.indexOfNestedHandler(args)] = null;
        args[NestedWorkflowRollbackHandler.indexOfParentStepId(args)] = stepId;
    }
    workflow._rollbackHandler = new NestedWorkflowRollbackHandler();
    workflow._rollbackHandlerArgs = args;
    // Determine if the workflow already attempted a rollback.
    // If so, attempt to restart the rollback's error and cancelled steps.
    boolean rollBackCompleted = determineIfRollbackCompleted(workflow);
    if (rollBackCompleted) {
        _log.info(String.format("Rollback already completed workflow %s", workflow.getWorkflowURI()));
        WorkflowStepCompleter.stepSucceded(stepId);
        return;
    }
    // See if can restart the previous rollback.
    InterProcessLock workflowLock = null;
    try {
        workflowLock = lockWorkflow(workflow);
        boolean rollBackStarted = resumePreviousRollback(workflow);
        if (rollBackStarted) {
            _log.info(String.format("Previous rollback resumed; errored/cancelled rollback steps queued; workflow %s", workflow.getWorkflowURI()));
        } else {
            // Otherwise, attempt to initiate a new rollback.
            if (workflow._rollbackHandler != null) {
                workflow._rollbackHandler.initiatingRollback(workflow, workflow._rollbackHandlerArgs);
            }
            rollBackStarted = initiateRollback(workflow);
            if (rollBackStarted) {
                _log.info(String.format("New rollback initiated workflow %s", workflow.getWorkflowURI()));
            }
        }
        if (rollBackStarted) {
            // Return now, wait until the rollback completions fire the completer.
            persistWorkflow(workflow);
            logWorkflow(workflow, true);
            WorkflowStepCompleter.stepExecuting(stepId);
        } else {
            ServiceCoded coded = WorkflowException.exceptions.workflowRollbackNotInitiated(uri.toString());
            WorkflowStepCompleter.stepFailed(stepId, coded);
        }
    } finally {
        unlockWorkflow(workflow, workflowLock);
    }
}
Also used : StepState(com.emc.storageos.workflow.Workflow.StepState) ServiceCoded(com.emc.storageos.svcs.errorhandling.model.ServiceCoded) DataObject(com.emc.storageos.db.client.model.DataObject) InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) URI(java.net.URI) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint)

Example 3 with StepState

use of com.emc.storageos.workflow.Workflow.StepState in project coprhd-controller by CoprHD.

the class WorkflowService method queueWorkflowStep.

/**
 * Queue the step on the Dispatcher to execute.
 *
 * @param workflow
 *            -- The Workflow containing this step
 * @param step
 *            -- Step step to be queued for execution
 */
public void queueWorkflowStep(Workflow workflow, Step step) throws WorkflowException {
    synchronized (workflow) {
        // default is to go into QUEUED state
        StepState state = StepState.QUEUED;
        try {
            if (isBlocked(workflow, step)) {
                // We are blocked waiting on a prerequisite step
                state = StepState.BLOCKED;
            } else if (isStepMarkedForSuspend(workflow, step)) {
                state = StepState.SUSPENDED_NO_ERROR;
                step.suspendStep = false;
            }
        } catch (CancelledException cancelEx) {
            state = StepState.CANCELLED;
        }
        // Persist the Workflow and the Steps in Zookeeper
        workflow.getStepStatus(step.stepId).updateState(state, null, "");
        persistWorkflowStep(workflow, step);
        _log.info(String.format("%s step: %s queued state %s", step.description, step.stepId, state));
        // If step is suspended, call the update status to initiate other steps to be cancelled
        if (state == StepState.SUSPENDED_NO_ERROR) {
            // A suspended step doesn't actually run, so call the update status here.
            completerStepSuspendedNoError(step.stepId);
        }
        // If step is ready to run, send it to the Dispatcher.
        if (state == StepState.QUEUED) {
            dispatchStep(step, workflow._nested);
        }
    }
}
Also used : StepState(com.emc.storageos.workflow.Workflow.StepState)

Example 4 with StepState

use of com.emc.storageos.workflow.Workflow.StepState in project coprhd-controller by CoprHD.

the class WorkflowService method isBlocked.

/**
 * Determine if a workflow step is blocked. A step is blocked if it has a waitFor clause
 * pointing to a step or step group that is not in the SUCCESS state.
 * If a pre-requisite step has errored or been cancelled, a CancelledException is thrown.
 *
 * @param workflow
 *            Workflow containing the Step
 * @param step
 *            Step checked.
 * @return true if the step is blocked waiting on a pre-requiste step to complete, false if runnable now.
 * @throws CancelledException
 *             if a prerequisite step has had an error or has been cancelled
 *             or if this step (or all steps) should be cancelled because of suspend request.
 */
boolean isBlocked(Workflow workflow, Step step) throws WorkflowException, CancelledException {
    // The step cannot be blocked if waitFor is null (which means not specified)
    if (step.waitFor == null) {
        return false;
    }
    Map<String, StepStatus> statusMap = new HashMap<String, StepStatus>();
    try {
        StepStatus status = workflow.getStepStatus(step.waitFor);
        statusMap.put(step.waitFor, status);
    } catch (WorkflowException ex1) {
        try {
            statusMap = workflow.getStepGroupStatus(step.waitFor);
        } catch (WorkflowException ex2) {
            throw new WorkflowException(String.format("Workflow step %s waitFor %s invalid, must be stepId or stepGroup name", step.stepId, step.waitFor));
        }
    }
    String[] errorMessage = new String[1];
    StepState state = Workflow.getOverallState(statusMap, errorMessage);
    switch(state) {
        case SUSPENDED_NO_ERROR:
        case SUSPENDED_ERROR:
        case CANCELLED:
            throw new CancelledException();
        case ERROR:
            if ((workflow.getRollbackContOnError()) && (workflow.isRollbackState())) {
                _log.info("Allowing rollback to continue despite failure in previous rollback step.");
                return false;
            }
            throw new CancelledException();
        case SUCCESS:
            return false;
        case CREATED:
        case BLOCKED:
        case QUEUED:
        case EXECUTING:
        default:
            return true;
    }
}
Also used : StepState(com.emc.storageos.workflow.Workflow.StepState) HashMap(java.util.HashMap) StepStatus(com.emc.storageos.workflow.Workflow.StepStatus)

Aggregations

StepState (com.emc.storageos.workflow.Workflow.StepState)4 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)1 DataObject (com.emc.storageos.db.client.model.DataObject)1 ServiceCoded (com.emc.storageos.svcs.errorhandling.model.ServiceCoded)1 Step (com.emc.storageos.workflow.Workflow.Step)1 StepStatus (com.emc.storageos.workflow.Workflow.StepStatus)1 URI (java.net.URI)1 HashMap (java.util.HashMap)1 InterProcessLock (org.apache.curator.framework.recipes.locks.InterProcessLock)1