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