use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.
the class CompensationScopeInstance method handleException.
public void handleException(io.automatiko.engine.api.runtime.process.NodeInstance nodeInstance, String activityRef, Object dunno) {
assert activityRef != null : "It should not be possible for the compensation activity reference to be null here.";
CompensationScope compensationScope = (CompensationScope) getExceptionScope();
// broadcast/general compensation in reverse order
if (activityRef.startsWith(IMPLICIT_COMPENSATION_PREFIX)) {
activityRef = activityRef.substring(IMPLICIT_COMPENSATION_PREFIX.length());
assert activityRef.equals(compensationScope.getContextContainerId()) : "Compensation activity ref [" + activityRef + "] does not match" + " Compensation Scope container id [" + compensationScope.getContextContainerId() + "]";
Map<String, ExceptionHandler> handlers = compensationScope.getExceptionHandlers();
List<String> completedNodeIds = ((WorkflowProcessInstanceImpl) getProcessInstance()).getCompletedNodeIds();
ListIterator<String> iter = completedNodeIds.listIterator(completedNodeIds.size());
while (iter.hasPrevious()) {
String completedId = iter.previous();
ExceptionHandler handler = handlers.get(completedId);
if (handler != null) {
handleException(nodeInstance, handler, completedId, null);
}
}
} else {
// Specific compensation
ExceptionHandler handler = compensationScope.getExceptionHandler(activityRef);
if (handler == null) {
throw new IllegalArgumentException("Could not find CompensationHandler for " + activityRef);
}
handleException(nodeInstance, handler, activityRef, null);
}
// Cancel all node instances created for compensation
while (!compensationInstances.isEmpty()) {
NodeInstance generatedInstance = compensationInstances.pop();
((NodeInstanceContainer) generatedInstance.getNodeInstanceContainer()).removeNodeInstance(generatedInstance);
}
}
use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.
the class CompensationScopeInstance method handleException.
public void handleException(io.automatiko.engine.api.runtime.process.NodeInstance nodeInstance, ExceptionHandler handler, String compensationActivityRef, Object dunno) {
WorkflowProcessInstanceImpl processInstance = (WorkflowProcessInstanceImpl) getProcessInstance();
NodeInstanceContainer nodeInstanceContainer = (NodeInstanceContainer) getContextInstanceContainer();
if (handler instanceof CompensationHandler) {
CompensationHandler compensationHandler = (CompensationHandler) handler;
try {
Node handlerNode = compensationHandler.getnode();
if (handlerNode instanceof BoundaryEventNode) {
NodeInstance compensationHandlerNodeInstance = nodeInstanceContainer.getNodeInstance(handlerNode);
compensationInstances.add(compensationHandlerNodeInstance);
// The BoundaryEventNodeInstance.signalEvent() contains the necessary logic
// to check whether or not compensation may proceed (? : (not-active +
// completed))
EventNodeInstance eventNodeInstance = (EventNodeInstance) compensationHandlerNodeInstance;
eventNodeInstance.signalEvent("Compensation", compensationActivityRef);
} else if (handlerNode instanceof EventSubProcessNode) {
// Check that subprocess parent has completed.
List<String> completedIds = processInstance.getCompletedNodeIds();
if (completedIds.contains(((NodeImpl) handlerNode.getParentContainer()).getMetaData("UniqueId"))) {
NodeInstance subProcessNodeInstance = ((NodeInstanceContainer) nodeInstanceContainer).getNodeInstance((Node) handlerNode.getParentContainer());
compensationInstances.add(subProcessNodeInstance);
NodeInstance compensationHandlerNodeInstance = ((NodeInstanceContainer) subProcessNodeInstance).getNodeInstance(handlerNode);
compensationInstances.add(compensationHandlerNodeInstance);
EventSubProcessNodeInstance eventNodeInstance = (EventSubProcessNodeInstance) compensationHandlerNodeInstance;
eventNodeInstance.signalEvent("Compensation", compensationActivityRef);
}
}
assert handlerNode instanceof BoundaryEventNode || handlerNode instanceof EventSubProcessNode : "Unexpected compensation handler node type : " + handlerNode.getClass().getSimpleName();
} catch (Exception e) {
throwWorkflowRuntimeException(nodeInstanceContainer, processInstance, "Unable to execute compensation.", e);
}
} else {
Exception e = new IllegalArgumentException("Unsupported compensation handler: " + handler);
throwWorkflowRuntimeException(nodeInstanceContainer, processInstance, e.getMessage(), e);
}
}
use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.
the class DefaultExceptionScopeInstance method handleException.
public void handleException(io.automatiko.engine.api.runtime.process.NodeInstance nodeInstance, ExceptionHandler handler, String exception, Object params) {
if (handler instanceof ActionExceptionHandler) {
ActionExceptionHandler exceptionHandler = (ActionExceptionHandler) handler;
if (retryAvailable(nodeInstance, exceptionHandler)) {
Integer retryAttempts = ((NodeInstanceImpl) nodeInstance).getRetryAttempts();
if (retryAttempts == null) {
retryAttempts = 1;
} else {
retryAttempts = retryAttempts + 1;
}
long delay = calculateDelay(exceptionHandler.getRetryAfter().longValue(), retryAttempts, exceptionHandler.getRetryIncrement(), exceptionHandler.getRetryIncrementMultiplier());
DurationExpirationTime expirationTime = DurationExpirationTime.after(delay);
JobsService jobService = getProcessInstance().getProcessRuntime().getJobsService();
String jobId = jobService.scheduleProcessInstanceJob(ProcessInstanceJobDescription.of(nodeInstance.getNodeId(), "retry:" + nodeInstance.getId(), expirationTime, ((NodeInstanceImpl) nodeInstance).getProcessInstanceIdWithParent(), getProcessInstance().getRootProcessInstanceId(), getProcessInstance().getProcessId(), getProcessInstance().getProcess().getVersion(), getProcessInstance().getRootProcessId()));
((NodeInstanceImpl) nodeInstance).internalSetRetryJobId(jobId);
((NodeInstanceImpl) nodeInstance).internalSetRetryAttempts(retryAttempts);
((NodeInstanceImpl) nodeInstance).registerRetryEventListener();
if (nodeInstance instanceof WorkItemNodeInstance) {
((WorkItemImpl) ((WorkItemNodeInstance) nodeInstance).getWorkItem()).setState(WorkItem.RETRYING);
}
} else {
Action action = (Action) exceptionHandler.getAction().getMetaData("Action");
try {
ProcessInstance processInstance = getProcessInstance();
ProcessContext processContext = new ProcessContext(processInstance.getProcessRuntime());
ContextInstanceContainer contextInstanceContainer = getContextInstanceContainer();
if (contextInstanceContainer instanceof NodeInstance) {
processContext.setNodeInstance((NodeInstance) contextInstanceContainer);
} else {
processContext.setProcessInstance(processInstance);
}
String faultVariable = exceptionHandler.getFaultVariable();
if (faultVariable != null) {
processContext.setVariable(faultVariable, params);
}
action.execute(processContext);
} catch (Exception e) {
throw new RuntimeException("unable to execute Action", e);
}
}
} else {
throw new IllegalArgumentException("Unknown exception handler " + handler);
}
}
use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.
the class BoundaryEventNodeInstance method isAttachedToNodeActive.
private boolean isAttachedToNodeActive(Collection<NodeInstance> nodeInstances, String attachedTo, String type, Object event) {
if (nodeInstances != null && !nodeInstances.isEmpty()) {
for (NodeInstance nInstance : nodeInstances) {
String nodeUniqueId = (String) nInstance.getNode().getMetaData().get("UniqueId");
boolean isActivating = ((WorkflowProcessInstanceImpl) nInstance.getProcessInstance()).getActivatingNodeIds().contains(nodeUniqueId);
if (attachedTo.equals(nodeUniqueId) && !isActivating) {
// instance
if (type.startsWith("Timer-")) {
if (nInstance.getId().equals(event)) {
return true;
}
} else {
return true;
}
}
}
}
return false;
}
use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.
the class BoundaryEventNodeInstance method signalEvent.
@Override
public void signalEvent(String type, Object event) {
BoundaryEventNode boundaryNode = (BoundaryEventNode) getEventNode();
String attachedTo = boundaryNode.getAttachedToNodeId();
Collection<NodeInstance> nodeInstances = ((NodeInstanceContainer) getProcessInstance()).getNodeInstances(true);
if (type != null && type.startsWith("Compensation")) {
// if not active && completed, signal
if (!isAttachedToNodeActive(nodeInstances, attachedTo, type, event) && isAttachedToNodeCompleted(attachedTo)) {
super.signalEvent(type, event);
} else {
cancel();
}
} else {
if (isAttachedToNodeActive(nodeInstances, attachedTo, type, event)) {
super.signalEvent(type, event);
} else {
cancel();
}
}
}
Aggregations