Search in sources :

Example 6 with NodeImpl

use of io.automatiko.engine.workflow.process.core.impl.NodeImpl in project automatiko-engine by automatiko-io.

the class CompositeNode method addIncomingConnection.

public void addIncomingConnection(String type, Connection connection) {
    if (connection.getFrom().getParentContainer() == this) {
        linkOutgoingConnections(connection.getFrom().getId(), connection.getFromType(), io.automatiko.engine.workflow.process.core.Node.CONNECTION_DEFAULT_TYPE);
    } else {
        super.addIncomingConnection(type, connection);
        CompositeNode.NodeAndType inNode = internalGetLinkedIncomingNode(type);
        if (inNode != null) {
            CompositeNodeStart start = new CompositeNodeStart(this, connection.getFrom(), type);
            internalAddNode(start);
            NodeImpl node = (NodeImpl) inNode.getNode();
            if (node != null) {
                new ConnectionImpl(start, io.automatiko.engine.workflow.process.core.Node.CONNECTION_DEFAULT_TYPE, inNode.getNode(), inNode.getType());
            }
        }
    }
}
Also used : NodeImpl(io.automatiko.engine.workflow.process.core.impl.NodeImpl) ConnectionImpl(io.automatiko.engine.workflow.process.core.impl.ConnectionImpl)

Example 7 with NodeImpl

use of io.automatiko.engine.workflow.process.core.impl.NodeImpl in project automatiko-engine by automatiko-io.

the class ProcessHandler method assignLanes.

private void assignLanes(NodeContainer nodeContainer, Map<String, String> laneMapping) {
    for (Node node : nodeContainer.getNodes()) {
        String lane = null;
        String uniqueId = (String) node.getMetaData().get("UniqueId");
        if (uniqueId != null) {
            lane = laneMapping.get(uniqueId);
        } else {
            lane = laneMapping.get(XmlBPMNProcessDumper.getUniqueNodeId(node));
        }
        if (lane != null) {
            ((NodeImpl) node).setMetaData("Lane", lane);
            if (node instanceof HumanTaskNode) {
                ((HumanTaskNode) node).setSwimlane(lane);
            }
        }
        if (node instanceof NodeContainer) {
            assignLanes((NodeContainer) node, laneMapping);
        }
    }
}
Also used : NodeImpl(io.automatiko.engine.workflow.process.core.impl.NodeImpl) ExtendedNodeImpl(io.automatiko.engine.workflow.process.core.impl.ExtendedNodeImpl) StateBasedNode(io.automatiko.engine.workflow.process.core.node.StateBasedNode) CompositeContextNode(io.automatiko.engine.workflow.process.core.node.CompositeContextNode) ActionNode(io.automatiko.engine.workflow.process.core.node.ActionNode) FaultNode(io.automatiko.engine.workflow.process.core.node.FaultNode) EventSubProcessNode(io.automatiko.engine.workflow.process.core.node.EventSubProcessNode) StateNode(io.automatiko.engine.workflow.process.core.node.StateNode) WorkItemNode(io.automatiko.engine.workflow.process.core.node.WorkItemNode) SubProcessNode(io.automatiko.engine.workflow.process.core.node.SubProcessNode) RuleSetNode(io.automatiko.engine.workflow.process.core.node.RuleSetNode) CompositeNode(io.automatiko.engine.workflow.process.core.node.CompositeNode) Node(io.automatiko.engine.api.definition.process.Node) HumanTaskNode(io.automatiko.engine.workflow.process.core.node.HumanTaskNode) BoundaryEventNode(io.automatiko.engine.workflow.process.core.node.BoundaryEventNode) StartNode(io.automatiko.engine.workflow.process.core.node.StartNode) EndNode(io.automatiko.engine.workflow.process.core.node.EndNode) EventNode(io.automatiko.engine.workflow.process.core.node.EventNode) NodeContainer(io.automatiko.engine.api.definition.process.NodeContainer) HumanTaskNode(io.automatiko.engine.workflow.process.core.node.HumanTaskNode)

Example 8 with NodeImpl

use of io.automatiko.engine.workflow.process.core.impl.NodeImpl in project automatiko-engine by automatiko-io.

the class ProcessHandler method handleIntermediateOrEndThrowCompensationEvent.

protected void handleIntermediateOrEndThrowCompensationEvent(ExtendedNodeImpl throwEventNode) {
    if (throwEventNode.getMetaData("compensation-activityRef") != null) {
        String activityRef = (String) throwEventNode.getMetaData().remove("compensation-activityRef");
        NodeContainer nodeParent = (NodeContainer) throwEventNode.getParentContainer();
        if (nodeParent instanceof EventSubProcessNode) {
            boolean compensationEventSubProcess = false;
            List<Trigger> startTriggers = ((EventSubProcessNode) nodeParent).findStartNode().getTriggers();
            CESP_CHECK: for (Trigger trigger : startTriggers) {
                if (trigger instanceof EventTrigger) {
                    for (EventFilter filter : ((EventTrigger) trigger).getEventFilters()) {
                        if (((EventTypeFilter) filter).getType().equals("Compensation")) {
                            compensationEventSubProcess = true;
                            break CESP_CHECK;
                        }
                    }
                }
            }
            if (compensationEventSubProcess) {
                // BPMN2 spec, p. 252, p. 248: intermediate and end compensation event
                // visibility scope
                nodeParent = (NodeContainer) ((NodeImpl) nodeParent).getParentContainer();
            }
        }
        String parentId;
        if (nodeParent instanceof ExecutableProcess) {
            parentId = ((ExecutableProcess) nodeParent).getId();
        } else {
            parentId = (String) ((NodeImpl) nodeParent).getMetaData("UniqueId");
        }
        String compensationEvent;
        if (activityRef.length() == 0) {
            // general/implicit compensation
            compensationEvent = CompensationScope.IMPLICIT_COMPENSATION_PREFIX + parentId;
        } else {
            // specific compensation
            compensationEvent = activityRef;
        }
        throwEventNode.setMetaData("CompensationEvent", compensationEvent);
        ConsequenceAction compensationAction = new ConsequenceAction("java", "");
        compensationAction.setMetaData("Action", new ProcessInstanceCompensationAction(compensationEvent));
        if (throwEventNode instanceof ActionNode) {
            ((ActionNode) throwEventNode).setAction(compensationAction);
        } else if (throwEventNode instanceof EndNode) {
            List<ProcessAction> actions = new ArrayList<ProcessAction>();
            actions.add(compensationAction);
            ((EndNode) throwEventNode).setActions(EndNode.EVENT_NODE_ENTER, actions);
        }
        throwEventNode.setMetaData("TriggerType", "Compensation");
    }
}
Also used : ProcessAction(io.automatiko.engine.workflow.process.core.ProcessAction) NodeImpl(io.automatiko.engine.workflow.process.core.impl.NodeImpl) ExtendedNodeImpl(io.automatiko.engine.workflow.process.core.impl.ExtendedNodeImpl) EventSubProcessNode(io.automatiko.engine.workflow.process.core.node.EventSubProcessNode) ConsequenceAction(io.automatiko.engine.workflow.process.core.impl.ConsequenceAction) ActionNode(io.automatiko.engine.workflow.process.core.node.ActionNode) NodeContainer(io.automatiko.engine.api.definition.process.NodeContainer) EventFilter(io.automatiko.engine.workflow.base.core.event.EventFilter) ProcessInstanceCompensationAction(io.automatiko.engine.workflow.base.instance.impl.actions.ProcessInstanceCompensationAction) EventTypeFilter(io.automatiko.engine.workflow.base.core.event.EventTypeFilter) Trigger(io.automatiko.engine.workflow.process.core.node.Trigger) ConstraintTrigger(io.automatiko.engine.workflow.process.core.node.ConstraintTrigger) EventTrigger(io.automatiko.engine.workflow.process.core.node.EventTrigger) EndNode(io.automatiko.engine.workflow.process.core.node.EndNode) ExecutableProcess(io.automatiko.engine.workflow.process.executable.core.ExecutableProcess) List(java.util.List) ArrayList(java.util.ArrayList) EventTrigger(io.automatiko.engine.workflow.process.core.node.EventTrigger)

Example 9 with NodeImpl

use of io.automatiko.engine.workflow.process.core.impl.NodeImpl in project automatiko-engine by automatiko-io.

the class ProcessHandler method linkAssociations.

public static void linkAssociations(Definitions definitions, NodeContainer nodeContainer, List<Association> associations) {
    if (associations != null) {
        for (Association association : associations) {
            String sourceRef = association.getSourceRef();
            Object source = null;
            try {
                source = findNodeOrDataStoreByUniqueId(definitions, nodeContainer, sourceRef, "Could not find source [" + sourceRef + "] for association " + association.getId() + "]");
            } catch (IllegalArgumentException e) {
            // source not found
            }
            String targetRef = association.getTargetRef();
            Object target = null;
            try {
                target = findNodeOrDataStoreByUniqueId(definitions, nodeContainer, targetRef, "Could not find target [" + targetRef + "] for association [" + association.getId() + "]");
            } catch (IllegalArgumentException e) {
            // target not found
            }
            if (source == null || target == null) {
            // TODO: ignoring this association for now
            } else if (target instanceof DataStore || source instanceof DataStore) {
            // TODO: ignoring data store associations for now
            } else if (source instanceof EventNode) {
                EventNode sourceNode = (EventNode) source;
                Node targetNode = (Node) target;
                checkBoundaryEventCompensationHandler(association, sourceNode, targetNode);
                // make sure IsForCompensation is set to true on target
                NodeImpl targetNodeImpl = (NodeImpl) target;
                String isForCompensation = "isForCompensation";
                Object compensationObject = targetNodeImpl.getMetaData(isForCompensation);
                if (compensationObject == null) {
                    targetNodeImpl.setMetaData(isForCompensation, true);
                    logger.warn("Setting {} attribute to true for node {}", isForCompensation, targetRef);
                } else if (!Boolean.parseBoolean(compensationObject.toString())) {
                    throw new IllegalArgumentException(isForCompensation + " attribute [" + compensationObject + "] should be true for Compensation Activity [" + targetRef + "]");
                }
                // put Compensation Handler in CompensationHandlerNode
                NodeContainer sourceParent = sourceNode.getParentContainer();
                NodeContainer targetParent = targetNode.getParentContainer();
                if (!sourceParent.equals(targetParent)) {
                    throw new IllegalArgumentException("Compensation Associations may not cross (sub-)process boundaries,");
                }
                // connect boundary event to compensation activity
                ConnectionImpl connection = new ConnectionImpl(sourceNode, NodeImpl.CONNECTION_DEFAULT_TYPE, targetNode, NodeImpl.CONNECTION_DEFAULT_TYPE);
                connection.setMetaData("UniqueId", association.getId());
                connection.setMetaData("hidden", true);
                connection.setMetaData("association", true);
            // Compensation use cases:
            // - boundary event --associated-> activity
            // - implicit sub process compensation handler + recursive?
            /**
             * BPMN2 spec, p.442: "A Compensation Event Sub-process becomes enabled when its
             * parent Activity transitions into state Completed. At that time, a snapshot of
             * the data associated with the parent Acitivity is taken and kept for later
             * usage by the Compensation Event Sub-Process."
             */
            }
        }
    }
}
Also used : BoundaryEventNode(io.automatiko.engine.workflow.process.core.node.BoundaryEventNode) EventNode(io.automatiko.engine.workflow.process.core.node.EventNode) DataAssociation(io.automatiko.engine.workflow.process.core.node.DataAssociation) Association(io.automatiko.engine.workflow.bpmn2.core.Association) NodeImpl(io.automatiko.engine.workflow.process.core.impl.NodeImpl) ExtendedNodeImpl(io.automatiko.engine.workflow.process.core.impl.ExtendedNodeImpl) DataStore(io.automatiko.engine.workflow.bpmn2.core.DataStore) StateBasedNode(io.automatiko.engine.workflow.process.core.node.StateBasedNode) CompositeContextNode(io.automatiko.engine.workflow.process.core.node.CompositeContextNode) ActionNode(io.automatiko.engine.workflow.process.core.node.ActionNode) FaultNode(io.automatiko.engine.workflow.process.core.node.FaultNode) EventSubProcessNode(io.automatiko.engine.workflow.process.core.node.EventSubProcessNode) StateNode(io.automatiko.engine.workflow.process.core.node.StateNode) WorkItemNode(io.automatiko.engine.workflow.process.core.node.WorkItemNode) SubProcessNode(io.automatiko.engine.workflow.process.core.node.SubProcessNode) RuleSetNode(io.automatiko.engine.workflow.process.core.node.RuleSetNode) CompositeNode(io.automatiko.engine.workflow.process.core.node.CompositeNode) Node(io.automatiko.engine.api.definition.process.Node) HumanTaskNode(io.automatiko.engine.workflow.process.core.node.HumanTaskNode) BoundaryEventNode(io.automatiko.engine.workflow.process.core.node.BoundaryEventNode) StartNode(io.automatiko.engine.workflow.process.core.node.StartNode) EndNode(io.automatiko.engine.workflow.process.core.node.EndNode) EventNode(io.automatiko.engine.workflow.process.core.node.EventNode) ConnectionImpl(io.automatiko.engine.workflow.process.core.impl.ConnectionImpl) NodeContainer(io.automatiko.engine.api.definition.process.NodeContainer)

Example 10 with NodeImpl

use of io.automatiko.engine.workflow.process.core.impl.NodeImpl 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);
    }
}
Also used : NodeImpl(io.automatiko.engine.workflow.process.core.impl.NodeImpl) CompensationScopeInstance(io.automatiko.engine.workflow.base.instance.context.exception.CompensationScopeInstance) Node(io.automatiko.engine.api.definition.process.Node) ExecutableProcess(io.automatiko.engine.workflow.process.executable.core.ExecutableProcess) WorkflowRuntimeException(io.automatiko.engine.workflow.process.instance.WorkflowRuntimeException) ContextContainer(io.automatiko.engine.workflow.base.core.ContextContainer) CompensationScope(io.automatiko.engine.workflow.base.core.context.exception.CompensationScope) NodeInstance(io.automatiko.engine.workflow.process.instance.NodeInstance) CompositeNodeInstance(io.automatiko.engine.workflow.process.instance.node.CompositeNodeInstance)

Aggregations

NodeImpl (io.automatiko.engine.workflow.process.core.impl.NodeImpl)10 Node (io.automatiko.engine.api.definition.process.Node)6 EventSubProcessNode (io.automatiko.engine.workflow.process.core.node.EventSubProcessNode)6 ConnectionImpl (io.automatiko.engine.workflow.process.core.impl.ConnectionImpl)5 ExtendedNodeImpl (io.automatiko.engine.workflow.process.core.impl.ExtendedNodeImpl)5 ActionNode (io.automatiko.engine.workflow.process.core.node.ActionNode)5 BoundaryEventNode (io.automatiko.engine.workflow.process.core.node.BoundaryEventNode)5 EndNode (io.automatiko.engine.workflow.process.core.node.EndNode)5 CompositeContextNode (io.automatiko.engine.workflow.process.core.node.CompositeContextNode)4 CompositeNode (io.automatiko.engine.workflow.process.core.node.CompositeNode)4 EventNode (io.automatiko.engine.workflow.process.core.node.EventNode)4 FaultNode (io.automatiko.engine.workflow.process.core.node.FaultNode)4 HumanTaskNode (io.automatiko.engine.workflow.process.core.node.HumanTaskNode)4 RuleSetNode (io.automatiko.engine.workflow.process.core.node.RuleSetNode)4 StartNode (io.automatiko.engine.workflow.process.core.node.StartNode)4 StateBasedNode (io.automatiko.engine.workflow.process.core.node.StateBasedNode)4 StateNode (io.automatiko.engine.workflow.process.core.node.StateNode)4 SubProcessNode (io.automatiko.engine.workflow.process.core.node.SubProcessNode)4 WorkItemNode (io.automatiko.engine.workflow.process.core.node.WorkItemNode)4 NodeContainer (io.automatiko.engine.api.definition.process.NodeContainer)3