Search in sources :

Example 41 with Node

use of org.kie.api.definition.process.Node in project jbpm by kiegroup.

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 == null || !(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;
    }
    org.jbpm.process.core.Process process = (org.jbpm.process.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(activityRef, null);
    }
}
Also used : NodeImpl(org.jbpm.workflow.core.impl.NodeImpl) CompensationScopeInstance(org.jbpm.process.instance.context.exception.CompensationScopeInstance) Node(org.kie.api.definition.process.Node) Process(org.kie.api.definition.process.Process) RuleFlowProcess(org.jbpm.ruleflow.core.RuleFlowProcess) WorkflowRuntimeException(org.jbpm.workflow.instance.WorkflowRuntimeException) ContextContainer(org.jbpm.process.core.ContextContainer) CompensationScope(org.jbpm.process.core.context.exception.CompensationScope) NodeInstance(org.jbpm.workflow.instance.NodeInstance) CompositeNodeInstance(org.jbpm.workflow.instance.node.CompositeNodeInstance) CompositeContextNodeInstance(org.jbpm.workflow.instance.node.CompositeContextNodeInstance)

Example 42 with Node

use of org.kie.api.definition.process.Node in project jbpm by kiegroup.

the class NodeInstanceImpl method cancel.

public void cancel() {
    nodeInstanceContainer.removeNodeInstance(this);
    boolean hidden = false;
    Node node = getNode();
    if (node != null && node.getMetaData().get("hidden") != null) {
        hidden = true;
    }
    if (!hidden) {
        InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
        ((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireAfterNodeLeft(this, kruntime);
    }
}
Also used : InternalKnowledgeRuntime(org.drools.core.common.InternalKnowledgeRuntime) Node(org.kie.api.definition.process.Node)

Example 43 with Node

use of org.kie.api.definition.process.Node in project jbpm by kiegroup.

the class WorkflowProcessInstanceImpl method signalEvent.

@SuppressWarnings("unchecked")
public void signalEvent(String type, Object event) {
    logger.debug("Signal {} received with data {} in process instance {}", type, event, getId());
    synchronized (this) {
        if (getState() != ProcessInstance.STATE_ACTIVE) {
            return;
        }
        if ("timerTriggered".equals(type)) {
            TimerInstance timer = (TimerInstance) event;
            if (timer.getId() == slaTimerId) {
                handleSLAViolation();
                // no need to pass the event along as it was purely for SLA tracking
                return;
            }
        }
        if ("slaViolation".equals(type)) {
            handleSLAViolation();
            // no need to pass the event along as it was purely for SLA tracking
            return;
        }
        List<NodeInstance> currentView = new ArrayList<NodeInstance>(this.nodeInstances);
        try {
            this.activatingNodeIds = new ArrayList<String>();
            List<EventListener> listeners = eventListeners.get(type);
            if (listeners != null) {
                for (EventListener listener : listeners) {
                    listener.signalEvent(type, event);
                }
            }
            listeners = externalEventListeners.get(type);
            if (listeners != null) {
                for (EventListener listener : listeners) {
                    listener.signalEvent(type, event);
                }
            }
            for (Node node : getWorkflowProcess().getNodes()) {
                if (node instanceof EventNodeInterface) {
                    if (((EventNodeInterface) node).acceptsEvent(type, event, (e) -> resolveVariable(e))) {
                        if (node instanceof EventNode && ((EventNode) node).getFrom() == null) {
                            EventNodeInstance eventNodeInstance = (EventNodeInstance) getNodeInstance(node);
                            eventNodeInstance.signalEvent(type, event);
                        } else {
                            if (node instanceof EventSubProcessNode && ((resolveVariables(((EventSubProcessNode) node).getEvents()).contains(type)))) {
                                EventSubProcessNodeInstance eventNodeInstance = (EventSubProcessNodeInstance) getNodeInstance(node);
                                eventNodeInstance.signalEvent(type, event);
                            }
                            if (node instanceof DynamicNode && type.equals(((DynamicNode) node).getActivationEventName())) {
                                DynamicNodeInstance dynamicNodeInstance = (DynamicNodeInstance) getNodeInstance(node);
                                dynamicNodeInstance.signalEvent(type, event);
                            } else {
                                List<NodeInstance> nodeInstances = getNodeInstances(node.getId(), currentView);
                                if (nodeInstances != null && !nodeInstances.isEmpty()) {
                                    for (NodeInstance nodeInstance : nodeInstances) {
                                        ((EventNodeInstanceInterface) nodeInstance).signalEvent(type, event);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (((org.jbpm.workflow.core.WorkflowProcess) getWorkflowProcess()).isDynamic()) {
                for (Node node : getWorkflowProcess().getNodes()) {
                    if (type.equals(node.getName()) && node.getIncomingConnections().isEmpty()) {
                        NodeInstance nodeInstance = getNodeInstance(node);
                        if (event != null) {
                            Map<String, Object> dynamicParams = new HashMap<>();
                            if (event instanceof Map) {
                                dynamicParams.putAll((Map<String, Object>) event);
                            } else {
                                dynamicParams.put("Data", event);
                            }
                            ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).setDynamicParameters(dynamicParams);
                        }
                        ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).trigger(null, NodeImpl.CONNECTION_DEFAULT_TYPE);
                    }
                }
            }
        } finally {
            if (this.activatingNodeIds != null) {
                this.activatingNodeIds.clear();
                this.activatingNodeIds = null;
            }
        }
    }
}
Also used : DynamicNodeInstance(org.jbpm.workflow.instance.node.DynamicNodeInstance) TimerInstance(org.jbpm.process.instance.timer.TimerInstance) HashMap(java.util.HashMap) EventNodeInterface(org.jbpm.workflow.core.node.EventNodeInterface) EventSubProcessNode(org.jbpm.workflow.core.node.EventSubProcessNode) DynamicNode(org.jbpm.workflow.core.node.DynamicNode) AsyncEventNode(org.jbpm.workflow.core.node.AsyncEventNode) StateBasedNode(org.jbpm.workflow.core.node.StateBasedNode) EventSubProcessNode(org.jbpm.workflow.core.node.EventSubProcessNode) ActionNode(org.jbpm.workflow.core.node.ActionNode) EndNode(org.jbpm.workflow.core.node.EndNode) EventNode(org.jbpm.workflow.core.node.EventNode) Node(org.kie.api.definition.process.Node) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) EventSubProcessNodeInstance(org.jbpm.workflow.instance.node.EventSubProcessNodeInstance) AsyncEventNode(org.jbpm.workflow.core.node.AsyncEventNode) EventNode(org.jbpm.workflow.core.node.EventNode) EventNodeInstanceInterface(org.jbpm.workflow.instance.node.EventNodeInstanceInterface) DynamicNode(org.jbpm.workflow.core.node.DynamicNode) EventListener(org.kie.api.runtime.process.EventListener) EventSubProcessNodeInstance(org.jbpm.workflow.instance.node.EventSubProcessNodeInstance) DynamicNodeInstance(org.jbpm.workflow.instance.node.DynamicNodeInstance) EndNodeInstance(org.jbpm.workflow.instance.node.EndNodeInstance) NodeInstance(org.jbpm.workflow.instance.NodeInstance) EventNodeInstance(org.jbpm.workflow.instance.node.EventNodeInstance) CompositeNodeInstance(org.jbpm.workflow.instance.node.CompositeNodeInstance) EventNodeInstance(org.jbpm.workflow.instance.node.EventNodeInstance) WorkflowProcess(org.kie.api.definition.process.WorkflowProcess) Map(java.util.Map) HashMap(java.util.HashMap)

Example 44 with Node

use of org.kie.api.definition.process.Node in project jbpm by kiegroup.

the class WorkflowProcessInstanceUpgrader method getNodeId.

private static String getNodeId(Node[] nodes, String nodeName, boolean unique) {
    Stack<Node> nodeStack = new Stack<Node>();
    for (Node node : nodes) {
        nodeStack.push(node);
    }
    Node match = null;
    while (!nodeStack.isEmpty()) {
        Node topNode = nodeStack.pop();
        if (topNode.getName().compareTo(nodeName) == 0) {
            match = topNode;
            break;
        }
        if (topNode instanceof NodeContainer) {
            for (Node node : ((NodeContainer) topNode).getNodes()) {
                nodeStack.push(node);
            }
        }
    }
    if (match == null) {
        throw new IllegalArgumentException("No node with name " + nodeName);
    }
    String id = "";
    if (unique) {
        while (!(match.getNodeContainer() instanceof Process)) {
            id = ":" + match.getId() + id;
            match = (Node) match.getNodeContainer();
        }
    }
    id = match.getId() + id;
    return id;
}
Also used : Node(org.kie.api.definition.process.Node) NodeContainer(org.kie.api.definition.process.NodeContainer) Process(org.kie.api.definition.process.Process) WorkflowProcess(org.kie.api.definition.process.WorkflowProcess) RuleFlowProcess(org.jbpm.ruleflow.core.RuleFlowProcess) Stack(java.util.Stack)

Example 45 with Node

use of org.kie.api.definition.process.Node in project jbpm by kiegroup.

the class CompositeNode method removeIncomingConnection.

public void removeIncomingConnection(String type, Connection connection) {
    super.removeIncomingConnection(type, connection);
    CompositeNode.NodeAndType nodeAndType = internalGetLinkedIncomingNode(type);
    if (nodeAndType != null) {
        for (Connection inConnection : nodeAndType.getNode().getIncomingConnections(nodeAndType.getType())) {
            if (((CompositeNodeStart) inConnection.getFrom()).getInNodeId() == connection.getFrom().getId()) {
                Node compositeNodeStart = inConnection.getFrom();
                ((ConnectionImpl) inConnection).terminate();
                internalRemoveNode(compositeNodeStart);
                return;
            }
        }
        throw new IllegalArgumentException("Could not find internal incoming connection for node");
    }
}
Also used : Node(org.kie.api.definition.process.Node) Connection(org.kie.api.definition.process.Connection) ConnectionImpl(org.jbpm.workflow.core.impl.ConnectionImpl)

Aggregations

Node (org.kie.api.definition.process.Node)70 StartNode (org.jbpm.workflow.core.node.StartNode)27 EventNode (org.jbpm.workflow.core.node.EventNode)26 ActionNode (org.jbpm.workflow.core.node.ActionNode)25 EndNode (org.jbpm.workflow.core.node.EndNode)25 CompositeNode (org.jbpm.workflow.core.node.CompositeNode)22 ArrayList (java.util.ArrayList)20 EventSubProcessNode (org.jbpm.workflow.core.node.EventSubProcessNode)20 WorkItemNode (org.jbpm.workflow.core.node.WorkItemNode)19 FaultNode (org.jbpm.workflow.core.node.FaultNode)17 HumanTaskNode (org.jbpm.workflow.core.node.HumanTaskNode)17 StateBasedNode (org.jbpm.workflow.core.node.StateBasedNode)15 BoundaryEventNode (org.jbpm.workflow.core.node.BoundaryEventNode)13 NodeContainer (org.kie.api.definition.process.NodeContainer)13 DynamicNode (org.jbpm.workflow.core.node.DynamicNode)11 ForEachNode (org.jbpm.workflow.core.node.ForEachNode)11 StateNode (org.jbpm.workflow.core.node.StateNode)11 RuleSetNode (org.jbpm.workflow.core.node.RuleSetNode)10 SubProcessNode (org.jbpm.workflow.core.node.SubProcessNode)10 WorkflowProcessInstanceImpl (org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl)10