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