Search in sources :

Example 1 with Step

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

the class WorkflowService method loadWorkflow.

/**
 * This method sets up the workflow from ZK and DB data using the supplied ZK workflow path.
 * The state for each of the Steps is loaded from ZK.
 * This is called from updateStepStatus().
 *
 * @param zkWorkflowPath -- zookeeper path of the Workflow
 * @return Workflow -- returns fully reconstructed workflow
 * @throws WorkflowNotFound exception if cannot load workflow
 */
private Workflow loadWorkflow(String zkWorkflowPath) throws WorkflowException {
    try {
        Workflow workflow = (Workflow) _dataManager.getData(zkWorkflowPath, false);
        // The stepMap and stepStatusMap can be large; they are saved
        // separately in ZK and reconstructed from the database.
        workflow._stepMap = new HashMap<String, Step>();
        workflow._stepStatusMap = new HashMap<String, StepStatus>();
        workflow._service = this;
        // Load all the step states.
        List<String> children = _dataManager.getChildren(zkWorkflowPath);
        for (String child : children) {
            String childPath = zkWorkflowPath + "/" + child;
            Object stepObj = _dataManager.getData(childPath, false);
            if (stepObj == null || false == (stepObj instanceof Step)) {
                continue;
            }
            Step step = (Step) stepObj;
            restoreStepDataFromDB(step);
            workflow.getStepMap().put(step.stepId, step);
            if (step.stepGroup != null) {
                if (workflow.getStepGroupMap().get(step.stepGroup) == null) {
                    workflow.getStepGroupMap().put(step.stepGroup, new HashSet<String>());
                }
                workflow.getStepGroupMap().get(step.stepGroup).add(step.stepId);
            }
            StepStatus status = step.status;
            workflow._stepStatusMap.put(step.stepId, status);
            _log.debug(String.format("Loaded step %s state %s for workflow %s", step.stepId, step.status.state, workflow._orchTaskId));
        }
        return workflow;
    } catch (Exception ex) {
        _log.error("Unable to load workflow: " + zkWorkflowPath, ex);
        throw WorkflowException.exceptions.workflowNotFound(zkWorkflowPath);
    }
}
Also used : DataObject(com.emc.storageos.db.client.model.DataObject) Step(com.emc.storageos.workflow.Workflow.Step) StepStatus(com.emc.storageos.workflow.Workflow.StepStatus) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException)

Example 2 with Step

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

the class WorkflowService method resumePreviousRollback.

/**
 * Resume the error/cancelled steps in a previous rollback if possible.
 * Returns true if rollback restarted; false if there was no previous rollback.
 *
 * @param workflow
 *            URI
 * @return true iff a previous rollback was restarted
 */
private boolean resumePreviousRollback(Workflow workflow) {
    // If haven't initiated rollback, then return false.
    if (workflow.isRollbackState() == false) {
        return false;
    }
    Map<String, Step> stepMap = workflow.getStepMap();
    // Determine what steps need to be re-executed.
    for (Step step : stepMap.values()) {
        // Do not consider non-rollback steps
        if (!step.isRollbackStep()) {
            continue;
        }
        // by setting it to CREATE. We should not have any non-terminal states.
        if (step.status.state == StepState.ERROR || step.status.state == StepState.CANCELLED) {
            step.status.updateState(StepState.CREATED, null, "");
        }
    }
    // Now queue all the steps to be restarted.
    for (Step step : stepMap.values()) {
        if (step.isRollbackStep() && step.status.state == StepState.CREATED) {
            _log.info(String.format("Retrying previous rollback step %s : %s", step.stepId, step.description));
            queueWorkflowStep(workflow, step);
        }
    }
    return true;
}
Also used : Step(com.emc.storageos.workflow.Workflow.Step)

Example 3 with Step

use of com.emc.storageos.workflow.Workflow.Step 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 4 with Step

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

the class WorkflowService method executePlan.

/**
 * Execute the workflow. It is saved here and control is passed to WorkflowExecutor.
 *
 * @param workflow
 */
public void executePlan(Workflow workflow) throws WorkflowException {
    InterProcessLock lock = null;
    try {
        if (!workflow.getStepMap().isEmpty()) {
            _log.info("Executing workflow plan: " + workflow.getWorkflowURI() + " " + workflow.getOrchTaskId());
            workflow.setWorkflowState(WorkflowState.RUNNING);
            // Mark steps that should be suspended in the workflow for later.
            suspendStepsMatchingProperty(workflow);
            // Make sure parent/child relationship is refreshed in case child workflow was created
            // before parent was executed
            workflow._nested = associateToParentWorkflow(workflow);
            persistWorkflow(workflow);
            for (Step step : workflow.getStepMap().values()) {
                persistWorkflowStep(workflow, step);
            }
            // Check suspended state and modify states
            if (checkSuspendedSteps(workflow)) {
                _log.info("Workflow is suspended: " + workflow.getWorkflowURI());
                // release any workflow locks
                for (Step step : workflow.getStepMap().values()) {
                    if (step.status.state == StepState.SUSPENDED_NO_ERROR) {
                        completerStepSuspendedNoError(step.stepId);
                    }
                }
            } else {
                /**
                 * Lock the workflow.
                 */
                lock = lockWorkflow(workflow);
                /**
                 * Queue any steps that have not been queued.
                 */
                for (Step step : workflow.getStepMap().values()) {
                    if (step.status.state == StepState.CREATED) {
                        queueWorkflowStep(workflow, step);
                    }
                }
            }
        } else {
            _log.info("Workflow executed with no steps: " + workflow.getWorkflowURI());
            // release any workflow locks
            releaseAllWorkflowLocks(workflow);
            // If no steps are to process, then just exit properly
            if (workflow._taskCompleter != null) {
                workflow._taskCompleter.ready(_dbClient);
            }
        }
    } finally {
        unlockWorkflow(workflow, lock);
    }
}
Also used : InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) Step(com.emc.storageos.workflow.Workflow.Step)

Example 5 with Step

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

the class WorkflowService method checkSuspendedSteps.

/**
 * Checks the workflow for any steps marked for suspension and marked them for suspension and cancels remaining
 * steps.
 *
 * @param workflow
 *            -- The Workflow to be checked.
 * @return
 *         -- true if the entire workflow is suspended, false if there's something worth queueing
 */
private boolean checkSuspendedSteps(Workflow workflow) {
    boolean again;
    String fromStepId = "None";
    Set<String> suspendedSteps = new HashSet<String>();
    do {
        // only loop again if made change
        again = false;
        for (Step step : workflow.getStepMap().values()) {
            if (step.status.state == StepState.SUSPENDED_NO_ERROR || step.status.state == StepState.CANCELLED) {
                continue;
            }
            try {
                try {
                    if (!isBlocked(workflow, step) && isStepMarkedForSuspend(workflow, step)) {
                        again = true;
                        changeStepToSuspendedNoErrorState(workflow, suspendedSteps, step);
                        fromStepId = step.stepId;
                    }
                } catch (CancelledException ex) {
                    again = true;
                    // If we got a CancelledException, this step needs to be cancelled.
                    step.status.updateState(StepState.CANCELLED, null, "Cancelled by step: " + fromStepId);
                    _log.info(String.format("Step %s has been cancelled by step %s", step.stepId, fromStepId));
                    persistWorkflowStep(workflow, step);
                }
            } catch (Exception ex) {
                _log.error("Exception" + ex.getMessage());
            }
        }
    } while (again == true);
    for (Step step : workflow.getStepMap().values()) {
        if (step.status.state == StepState.CREATED || step.status.state == StepState.BLOCKED || step.status.state == StepState.QUEUED) {
            // There's a reason to go into the queueing loop to attempt to dispatch steps
            return false;
        }
    }
    // Don't bother dispatching steps. Call the completer for the workflow as suspended.
    return true;
}
Also used : Step(com.emc.storageos.workflow.Workflow.Step) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException) HashSet(java.util.HashSet)

Aggregations

Step (com.emc.storageos.workflow.Workflow.Step)12 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)5 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)5 LockRetryException (com.emc.storageos.locking.LockRetryException)5 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)5 ControllerException (com.emc.storageos.volumecontroller.ControllerException)5 StepStatus (com.emc.storageos.workflow.Workflow.StepStatus)4 HashSet (java.util.HashSet)4 DataObject (com.emc.storageos.db.client.model.DataObject)2 InterProcessLock (org.apache.curator.framework.recipes.locks.InterProcessLock)2 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)1 WorkflowStepData (com.emc.storageos.db.client.model.WorkflowStepData)1 StepState (com.emc.storageos.workflow.Workflow.StepState)1 URI (java.net.URI)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Set (java.util.Set)1 Stat (org.apache.zookeeper.data.Stat)1