use of io.automatiko.engine.api.definition.process.Node in project automatiko-engine by automatiko-io.
the class CompensationEventListener method signalEvent.
/**
* When signaling compensation, you can do that in 1 of 2 ways: 1.
* signalEvent("Compensation", <node-with-compensation-handler-id>) This is
* specific compensation, that only possibly triggers the compensation handler
* attached to the node referred to by the <node-with-compensation-handler-id>.
* 2. signalEvent("Compensation", "implicit:" +
* <node-container-containing-compensation-scope-id> ) This is implicit or
* general compensation, in which you trigger all visible compensation handlers
* (in the proper order, etc.) in the (sub-)process referred to by the
* <node-container-containing-compensation-scope-id>.
*/
public void signalEvent(String compensationType, Object activityRefStr) {
if (!(activityRefStr instanceof String)) {
throw new WorkflowRuntimeException(null, getProcessInstance(), "Compensation can only be triggered with String events, not an event of type " + (activityRefStr == null ? "null" : activityRefStr.getClass().getSimpleName()));
}
// 1. parse the activity ref (is it general or specific compensation?)
String activityRef = (String) activityRefStr;
String toCompensateNodeId = activityRef;
boolean generalCompensation = false;
if (activityRef.startsWith(IMPLICIT_COMPENSATION_PREFIX)) {
toCompensateNodeId = activityRef.substring(IMPLICIT_COMPENSATION_PREFIX.length());
generalCompensation = true;
}
io.automatiko.engine.workflow.base.core.Process process = (io.automatiko.engine.workflow.base.core.Process) instance.getProcess();
// 2. for specific compensation: find the node that will be compensated
// for general compensation: find the compensation scope container that contains
// all the visible compensation handlers
Node toCompensateNode = null;
ContextContainer compensationScopeContainer = null;
if (generalCompensation) {
if (toCompensateNodeId.equals(instance.getProcessId())) {
compensationScopeContainer = process;
} else {
compensationScopeContainer = (ContextContainer) findNode(toCompensateNodeId);
}
} else {
toCompensateNode = findNode(toCompensateNodeId);
}
// c. handle the exception (which also cleans up the generated node instances)
if (toCompensateNode != null || compensationScopeContainer != null) {
CompensationScope compensationScope = null;
if (compensationScopeContainer != null) {
compensationScope = (CompensationScope) compensationScopeContainer.getDefaultContext(COMPENSATION_SCOPE);
} else {
compensationScope = (CompensationScope) ((NodeImpl) toCompensateNode).resolveContext(COMPENSATION_SCOPE, toCompensateNodeId);
}
assert compensationScope != null : "Compensation scope for node [" + toCompensateNodeId + "] could not be found!";
CompensationScopeInstance scopeInstance;
if (compensationScope.getContextContainerId().equals(process.getId())) {
// process level compensation
scopeInstance = (CompensationScopeInstance) instance.getContextInstance(compensationScope);
} else {
// nested compensation
Stack<NodeInstance> generatedInstances;
if (toCompensateNode == null) {
// logic is the same if it's specific or general
generatedInstances = createNodeInstanceContainers((Node) compensationScopeContainer, true);
} else {
generatedInstances = createNodeInstanceContainers(toCompensateNode, false);
}
NodeInstance nodeInstanceContainer = generatedInstances.peek();
scopeInstance = ((CompensationScopeInstance) ((ContextInstanceContainer) nodeInstanceContainer).getContextInstance(compensationScope));
scopeInstance.addCompensationInstances(generatedInstances);
}
scopeInstance.handleException(null, activityRef, null);
}
}
use of io.automatiko.engine.api.definition.process.Node in project automatiko-engine by automatiko-io.
the class ExecutableProcessFactory method linkBoundaryEvents.
protected void linkBoundaryEvents(NodeContainer nodeContainer) {
for (Node node : nodeContainer.getNodes()) {
if (node instanceof CompositeNode) {
CompositeNode compositeNode = (CompositeNode) node;
linkBoundaryEvents(compositeNode.getNodeContainer());
}
if (node instanceof EventNode) {
final String attachedTo = (String) node.getMetaData().get(ATTACHED_TO);
if (attachedTo != null) {
Node attachedNode = findNodeByIdOrUniqueIdInMetadata(nodeContainer, attachedTo, "Could not find node to attach to: " + attachedTo);
for (EventFilter filter : ((EventNode) node).getEventFilters()) {
String type = ((EventTypeFilter) filter).getType();
if (type.startsWith("Timer-")) {
linkBoundaryTimerEvent(node, attachedTo, attachedNode);
} else if (node.getMetaData().get(SIGNAL_NAME) != null || type.startsWith("Message-")) {
linkBoundarySignalEvent(node, attachedTo);
} else if (type.startsWith("Error-")) {
linkBoundaryErrorEvent(nodeContainer, node, attachedTo, attachedNode);
} else if (type.startsWith("Condition-") || type.startsWith("RuleFlowStateEvent-")) {
linkBoundaryConditionEvent(nodeContainer, node, attachedTo, attachedNode);
} else if (type.startsWith("Compensation")) {
addCompensationScope(getExecutableProcess(), node, nodeContainer, attachedTo);
}
}
}
}
}
}
Aggregations