use of edu.harvard.iq.dataverse.workflow.step.WorkflowStep in project dataverse by IQSS.
the class WorkflowServiceBean method executeSteps.
/**
* Execute the passed workflow, starting from {@code initialStepIdx}.
* @param wf The workflow to run.
* @param ctxt Execution context to run the workflow in.
* @param initialStepIdx 0-based index of the first step to run.
*/
private void executeSteps(Workflow wf, WorkflowContext ctxt, int initialStepIdx) {
final List<WorkflowStepData> steps = wf.getSteps();
for (int stepIdx = initialStepIdx; stepIdx < steps.size(); stepIdx++) {
WorkflowStepData wsd = steps.get(stepIdx);
WorkflowStep step = createStep(wsd);
WorkflowStepResult res = runStep(step, ctxt);
try {
if (res == WorkflowStepResult.OK) {
logger.log(Level.INFO, "Workflow {0} step {1}: OK", new Object[] { ctxt.getInvocationId(), stepIdx });
} else if (res instanceof Failure) {
logger.log(Level.WARNING, "Workflow {0} failed: {1}", new Object[] { ctxt.getInvocationId(), ((Failure) res).getReason() });
rollback(wf, ctxt, (Failure) res, stepIdx - 1);
return;
} else if (res instanceof Pending) {
pauseAndAwait(wf, ctxt, (Pending) res, stepIdx);
return;
}
} catch (Exception e) {
logger.log(Level.WARNING, "Workflow {0} step {1}: Uncought exception:", new Object[] { ctxt.getInvocationId(), e.getMessage() });
logger.log(Level.WARNING, "Trace:", e);
rollback(wf, ctxt, (Failure) res, stepIdx - 1);
return;
}
}
workflowCompleted(wf, ctxt);
}
use of edu.harvard.iq.dataverse.workflow.step.WorkflowStep in project dataverse by IQSS.
the class WorkflowServiceBean method rollback.
@Asynchronous
private void rollback(Workflow wf, WorkflowContext ctxt, Failure failure, int lastCompletedStepIdx) {
ctxt = refresh(ctxt);
final List<WorkflowStepData> steps = wf.getSteps();
for (int stepIdx = lastCompletedStepIdx; stepIdx >= 0; --stepIdx) {
WorkflowStepData wsd = steps.get(stepIdx);
WorkflowStep step = createStep(wsd);
try {
logger.log(Level.INFO, "Workflow {0} step {1}: Rollback", new Object[] { ctxt.getInvocationId(), stepIdx });
rollbackStep(step, ctxt, failure);
} catch (Exception e) {
logger.log(Level.WARNING, "Workflow " + ctxt.getInvocationId() + " step " + stepIdx + ": Rollback error: " + e.getMessage(), e);
}
}
logger.log(Level.INFO, "Removing workflow lock");
try {
engine.submit(new RemoveLockCommand(ctxt.getRequest(), ctxt.getDataset(), DatasetLock.Reason.Workflow));
// Corner case - delete locks generated within this same transaction.
Query deleteQuery = em.createQuery("DELETE from DatasetLock l WHERE l.dataset.id=:id AND l.reason=:reason");
deleteQuery.setParameter("id", ctxt.getDataset().getId());
deleteQuery.setParameter("reason", DatasetLock.Reason.Workflow);
deleteQuery.executeUpdate();
} catch (CommandException ex) {
logger.log(Level.SEVERE, "Error restoring dataset locks state after rollback: " + ex.getMessage(), ex);
}
}
use of edu.harvard.iq.dataverse.workflow.step.WorkflowStep in project dataverse by IQSS.
the class WorkflowServiceBean method doResume.
private void doResume(PendingWorkflowInvocation pending, String body) {
Workflow wf = pending.getWorkflow();
List<WorkflowStepData> stepsLeft = wf.getSteps().subList(pending.getPendingStepIdx(), wf.getSteps().size());
WorkflowStep pendingStep = createStep(stepsLeft.get(0));
final WorkflowContext ctxt = pending.reCreateContext(roleAssignees);
WorkflowStepResult res = pendingStep.resume(ctxt, pending.getLocalData(), body);
if (res instanceof Failure) {
rollback(wf, ctxt, (Failure) res, pending.getPendingStepIdx() - 1);
} else if (res instanceof Pending) {
pauseAndAwait(wf, ctxt, (Pending) res, pending.getPendingStepIdx());
} else {
executeSteps(wf, ctxt, pending.getPendingStepIdx() + 1);
}
}
Aggregations