Search in sources :

Example 1 with KogitoNodeInstance

use of org.kie.kogito.internal.process.runtime.KogitoNodeInstance in project kogito-runtimes by kiegroup.

the class SplitInstance method executeStrategy.

protected void executeStrategy(Split split, String type) {
    // TODO make different strategies for each type
    switch(split.getType()) {
        case Split.TYPE_AND:
            triggerCompleted(Node.CONNECTION_DEFAULT_TYPE, true);
            break;
        case Split.TYPE_XOR:
            List<Connection> outgoing = split.getDefaultOutgoingConnections();
            int priority = Integer.MAX_VALUE;
            Connection selected = null;
            for (final Iterator<Connection> iterator = outgoing.iterator(); iterator.hasNext(); ) {
                final Connection connection = (Connection) iterator.next();
                ConstraintEvaluator constraint = (ConstraintEvaluator) split.getConstraint(connection);
                if (constraint != null && constraint.getPriority() < priority && !constraint.isDefault()) {
                    try {
                        if (constraint.evaluate(this, connection, constraint)) {
                            selected = connection;
                            priority = constraint.getPriority();
                        }
                    } catch (RuntimeException e) {
                        throw new RuntimeException("Exception when trying to evaluate constraint " + constraint.getName() + " in split " + split.getName(), e);
                    }
                }
            }
            ((NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
            if (selected == null) {
                for (final Iterator<Connection> iterator = outgoing.iterator(); iterator.hasNext(); ) {
                    final Connection connection = (Connection) iterator.next();
                    if (split.isDefault(connection)) {
                        selected = connection;
                        break;
                    }
                }
            }
            if (selected == null) {
                throw new IllegalArgumentException("XOR split could not find at least one valid outgoing connection for split " + getSplit().getName());
            }
            if (!hasLoop(selected.getTo(), split)) {
                setLevel(1);
                ((NodeInstanceContainer) getNodeInstanceContainer()).setCurrentLevel(1);
            }
            triggerConnection(selected);
            break;
        case Split.TYPE_OR:
            ((NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
            outgoing = split.getDefaultOutgoingConnections();
            boolean found = false;
            List<NodeInstanceTrigger> nodeInstances = new ArrayList<NodeInstanceTrigger>();
            List<Connection> outgoingCopy = new ArrayList<Connection>(outgoing);
            while (!outgoingCopy.isEmpty()) {
                priority = Integer.MAX_VALUE;
                Connection selectedConnection = null;
                ConstraintEvaluator selectedConstraint = null;
                for (final Iterator<Connection> iterator = outgoingCopy.iterator(); iterator.hasNext(); ) {
                    final Connection connection = (Connection) iterator.next();
                    ConstraintEvaluator constraint = (ConstraintEvaluator) split.getConstraint(connection);
                    if (constraint != null && constraint.getPriority() < priority && !constraint.isDefault()) {
                        priority = constraint.getPriority();
                        selectedConnection = connection;
                        selectedConstraint = constraint;
                    }
                }
                if (selectedConstraint == null) {
                    break;
                }
                if (selectedConstraint.evaluate(this, selectedConnection, selectedConstraint)) {
                    nodeInstances.add(new NodeInstanceTrigger(followConnection(selectedConnection), selectedConnection.getToType()));
                    found = true;
                }
                outgoingCopy.remove(selectedConnection);
            }
            for (NodeInstanceTrigger nodeInstance : nodeInstances) {
                // stop if this process instance has been aborted / completed
                if (getProcessInstance().getState() != ProcessInstance.STATE_ACTIVE) {
                    return;
                }
                triggerNodeInstance(nodeInstance.getNodeInstance(), nodeInstance.getToType());
            }
            if (!found) {
                for (final Iterator<Connection> iterator = outgoing.iterator(); iterator.hasNext(); ) {
                    final Connection connection = (Connection) iterator.next();
                    ConstraintEvaluator constraint = (ConstraintEvaluator) split.getConstraint(connection);
                    if (constraint != null && constraint.isDefault() || split.isDefault(connection)) {
                        triggerConnection(connection);
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                throw new IllegalArgumentException("OR split could not find at least one valid outgoing connection for split " + getSplit().getName());
            }
            break;
        case Split.TYPE_XAND:
            ((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
            org.kie.api.definition.process.Node node = getNode();
            List<Connection> connections = null;
            if (node != null) {
                connections = node.getOutgoingConnections(type);
            }
            if (connections == null || connections.isEmpty()) {
                ((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer()).nodeInstanceCompleted(this, type);
            } else {
                ExclusiveGroupInstance groupInstance = new ExclusiveGroupInstance();
                org.kie.api.runtime.process.NodeInstanceContainer parent = getNodeInstanceContainer();
                if (parent instanceof ContextInstanceContainer) {
                    ((ContextInstanceContainer) parent).addContextInstance(ExclusiveGroup.EXCLUSIVE_GROUP, groupInstance);
                } else {
                    throw new IllegalArgumentException("An Exclusive AND is only possible if the parent is a context instance container");
                }
                Map<org.jbpm.workflow.instance.NodeInstance, String> nodeInstancesMap = new HashMap<org.jbpm.workflow.instance.NodeInstance, String>();
                for (Connection connection : connections) {
                    nodeInstancesMap.put(followConnection(connection), connection.getToType());
                }
                for (KogitoNodeInstance nodeInstance : nodeInstancesMap.keySet()) {
                    groupInstance.addNodeInstance(nodeInstance);
                }
                for (Map.Entry<org.jbpm.workflow.instance.NodeInstance, String> entry : nodeInstancesMap.entrySet()) {
                    // stop if this process instance has been aborted / completed
                    if (getProcessInstance().getState() != ProcessInstance.STATE_ACTIVE) {
                        return;
                    }
                    boolean hidden = false;
                    if (getNode().getMetaData().get("hidden") != null) {
                        hidden = true;
                    }
                    InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
                    if (!hidden) {
                        ((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireBeforeNodeLeft(this, kruntime);
                    }
                    ((org.jbpm.workflow.instance.NodeInstance) entry.getKey()).trigger(this, entry.getValue());
                    if (!hidden) {
                        ((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireAfterNodeLeft(this, kruntime);
                    }
                }
            }
            break;
        default:
            throw new IllegalArgumentException("Illegal split type " + split.getType());
    }
}
Also used : NodeInstanceContainer(org.jbpm.workflow.instance.NodeInstanceContainer) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ConstraintEvaluator(org.jbpm.process.instance.impl.ConstraintEvaluator) InternalKnowledgeRuntime(org.drools.core.common.InternalKnowledgeRuntime) WorkflowRuntimeException(org.jbpm.workflow.instance.WorkflowRuntimeException) ContextInstanceContainer(org.jbpm.process.instance.ContextInstanceContainer) ExclusiveGroupInstance(org.jbpm.process.instance.context.exclusive.ExclusiveGroupInstance) Connection(org.kie.api.definition.process.Connection) KogitoNodeInstance(org.kie.kogito.internal.process.runtime.KogitoNodeInstance) KogitoNodeInstance(org.kie.kogito.internal.process.runtime.KogitoNodeInstance) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with KogitoNodeInstance

use of org.kie.kogito.internal.process.runtime.KogitoNodeInstance in project kogito-runtimes by kiegroup.

the class StateBasedNodeInstance method internalTrigger.

@Override
public void internalTrigger(KogitoNodeInstance from, String type) {
    super.internalTrigger(from, type);
    // if node instance was cancelled, abort
    if (getNodeInstanceContainer().getNodeInstance(getStringId()) == null) {
        return;
    }
    // activate timers
    Map<Timer, DroolsAction> timers = getEventBasedNode().getTimers();
    if (timers != null) {
        addTimerListener();
        timerInstances = new ArrayList<>(timers.size());
        JobsService jobService = ((KogitoProcessRuntime.Provider) getProcessInstance().getKnowledgeRuntime().getProcessRuntime()).getKogitoProcessRuntime().getJobsService();
        for (Timer timer : timers.keySet()) {
            ProcessInstanceJobDescription jobDescription = ProcessInstanceJobDescription.of(new TimerJobId(timer.getId()), createTimerInstance(timer), getProcessInstance().getStringId(), getProcessInstance().getRootProcessInstanceId(), getProcessInstance().getProcessId(), getProcessInstance().getRootProcessId(), Optional.ofNullable(from).map(KogitoNodeInstance::getStringId).orElse(null));
            timerInstances.add(jobService.scheduleProcessInstanceJob(jobDescription));
        }
    }
    if (getEventBasedNode().getBoundaryEvents() != null) {
        for (String name : getEventBasedNode().getBoundaryEvents()) {
            boolean isActive = ((InternalAgenda) getProcessInstance().getKnowledgeRuntime().getAgenda()).isRuleActiveInRuleFlowGroup("DROOLS_SYSTEM", name, getProcessInstance().getId());
            if (isActive) {
                getProcessInstance().getKnowledgeRuntime().signalEvent(name, null);
            } else {
                addActivationListener();
            }
        }
    }
    ((WorkflowProcessInstanceImpl) getProcessInstance()).addActivatingNodeId((String) getNode().getMetaData().get("UniqueId"));
}
Also used : DroolsAction(org.jbpm.workflow.core.DroolsAction) KogitoProcessRuntime(org.kie.kogito.internal.process.runtime.KogitoProcessRuntime) WorkflowProcessInstanceImpl(org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl) InternalAgenda(org.drools.core.common.InternalAgenda) Timer(org.jbpm.process.core.timer.Timer) KogitoNodeInstance(org.kie.kogito.internal.process.runtime.KogitoNodeInstance) JobsService(org.kie.kogito.jobs.JobsService) ProcessInstanceJobDescription(org.kie.kogito.jobs.ProcessInstanceJobDescription) TimerJobId(org.kie.kogito.jobs.TimerJobId)

Example 3 with KogitoNodeInstance

use of org.kie.kogito.internal.process.runtime.KogitoNodeInstance in project kogito-runtimes by kiegroup.

the class CompositeNodeInstance method internalTrigger.

@Override
public void internalTrigger(KogitoNodeInstance from, String type) {
    super.internalTrigger(from, type);
    // if node instance was cancelled, abort
    if (getNodeInstanceContainer().getNodeInstance(getStringId()) == null) {
        return;
    }
    CompositeNode.NodeAndType nodeAndType = getCompositeNode().internalGetLinkedIncomingNode(type);
    if (nodeAndType != null) {
        List<Connection> connections = nodeAndType.getNode().getIncomingConnections(nodeAndType.getType());
        for (Connection connection : connections) {
            if ((connection.getFrom() instanceof CompositeNode.CompositeNodeStart) && (from == null || ((CompositeNode.CompositeNodeStart) connection.getFrom()).getInNode().getId() == from.getNodeId())) {
                NodeInstance nodeInstance = getNodeInstance(connection.getFrom());
                nodeInstance.trigger(null, nodeAndType.getType());
                return;
            }
        }
    } else {
        // try to search for start nodes
        boolean found = false;
        for (org.kie.api.definition.process.Node node : getCompositeNode().getNodes()) {
            if (node instanceof StartNode) {
                StartNode startNode = (StartNode) node;
                if (startNode.getTriggers() == null || startNode.getTriggers().isEmpty()) {
                    NodeInstance nodeInstance = getNodeInstance(startNode);
                    nodeInstance.trigger(null, null);
                    found = true;
                }
            }
        }
        if (found) {
            return;
        }
    }
    if (isLinkedIncomingNodeRequired()) {
        throw new IllegalArgumentException("Could not find start for composite node: " + type);
    }
}
Also used : StartNode(org.jbpm.workflow.core.node.StartNode) Connection(org.kie.api.definition.process.Connection) CompositeNode(org.jbpm.workflow.core.node.CompositeNode) NodeInstance(org.jbpm.workflow.instance.NodeInstance) KogitoNodeInstance(org.kie.kogito.internal.process.runtime.KogitoNodeInstance)

Example 4 with KogitoNodeInstance

use of org.kie.kogito.internal.process.runtime.KogitoNodeInstance in project kogito-runtimes by kiegroup.

the class EndNodeInstance method internalTrigger.

@Override
public void internalTrigger(KogitoNodeInstance from, String type) {
    super.internalTrigger(from, type);
    if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
        throw new IllegalArgumentException("An EndNode only accepts default incoming connections!");
    }
    leaveTime = new Date();
    boolean hidden = false;
    if (getNode().getMetaData().get(HIDDEN) != null) {
        hidden = true;
    }
    InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
    if (!hidden) {
        ((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireBeforeNodeLeft(this, kruntime);
    }
    ((NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
    if (getEndNode().isTerminate()) {
        if (getNodeInstanceContainer() instanceof CompositeNodeInstance) {
            if (getEndNode().getScope() == PROCESS_SCOPE) {
                getProcessInstance().setState(KogitoProcessInstance.STATE_COMPLETED);
            } else {
                while (!getNodeInstanceContainer().getNodeInstances().isEmpty()) {
                    ((org.jbpm.workflow.instance.NodeInstance) getNodeInstanceContainer().getNodeInstances().iterator().next()).cancel();
                }
                ((NodeInstanceContainer) getNodeInstanceContainer()).nodeInstanceCompleted(this, null);
            }
        } else {
            ((NodeInstanceContainer) getNodeInstanceContainer()).setState(KogitoProcessInstance.STATE_COMPLETED);
        }
    } else {
        ((NodeInstanceContainer) getNodeInstanceContainer()).nodeInstanceCompleted(this, null);
    }
    if (!hidden) {
        ((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireAfterNodeLeft(this, kruntime);
    }
}
Also used : InternalKnowledgeRuntime(org.drools.core.common.InternalKnowledgeRuntime) NodeInstanceContainer(org.jbpm.workflow.instance.NodeInstanceContainer) KogitoNodeInstance(org.kie.kogito.internal.process.runtime.KogitoNodeInstance) Date(java.util.Date)

Example 5 with KogitoNodeInstance

use of org.kie.kogito.internal.process.runtime.KogitoNodeInstance in project kogito-runtimes by kiegroup.

the class FaultNodeInstance method internalTrigger.

public void internalTrigger(KogitoNodeInstance from, String type) {
    if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
        throw new IllegalArgumentException("A FaultNode only accepts default incoming connections!");
    }
    triggerTime = new Date();
    String faultName = getFaultName();
    ExceptionScopeInstance exceptionScopeInstance = getExceptionScopeInstance(faultName);
    NodeInstanceContainer nodeInstanceContainer = (NodeInstanceContainer) getNodeInstanceContainer();
    nodeInstanceContainer.removeNodeInstance(this);
    boolean exceptionHandled = false;
    if (getFaultNode().isTerminateParent()) {
        // handle exception before canceling nodes to allow boundary event to catch the events
        if (exceptionScopeInstance != null) {
            exceptionHandled = true;
            handleException(faultName, exceptionScopeInstance);
        }
        if (nodeInstanceContainer instanceof CompositeNodeInstance) {
            ((CompositeNodeInstance) nodeInstanceContainer).cancel();
        } else if (nodeInstanceContainer instanceof WorkflowProcessInstance) {
            Collection<NodeInstance> nodeInstances = ((WorkflowProcessInstance) nodeInstanceContainer).getNodeInstances();
            for (NodeInstance nodeInstance : nodeInstances) {
                ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).cancel();
            }
        }
    }
    if (exceptionScopeInstance != null) {
        if (!exceptionHandled) {
            handleException(faultName, exceptionScopeInstance);
        }
        boolean hidden = false;
        if (getNode().getMetaData().get("hidden") != null) {
            hidden = true;
        }
        if (!hidden) {
            InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
            ((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireBeforeNodeLeft(this, kruntime);
        }
        ((NodeInstanceContainer) getNodeInstanceContainer()).nodeInstanceCompleted(this, null);
        if (!hidden) {
            InternalKnowledgeRuntime kruntime = getProcessInstance().getKnowledgeRuntime();
            ((InternalProcessRuntime) kruntime.getProcessRuntime()).getProcessEventSupport().fireAfterNodeLeft(this, kruntime);
        }
    } else {
        ((ProcessInstance) getProcessInstance()).setState(ProcessInstance.STATE_ABORTED, faultName, getFaultData());
    }
}
Also used : NodeInstanceContainer(org.jbpm.workflow.instance.NodeInstanceContainer) Date(java.util.Date) InternalKnowledgeRuntime(org.drools.core.common.InternalKnowledgeRuntime) Collection(java.util.Collection) ProcessInstance(org.jbpm.process.instance.ProcessInstance) WorkflowProcessInstance(org.kie.api.runtime.process.WorkflowProcessInstance) NodeInstance(org.kie.api.runtime.process.NodeInstance) KogitoNodeInstance(org.kie.kogito.internal.process.runtime.KogitoNodeInstance) WorkflowProcessInstance(org.kie.api.runtime.process.WorkflowProcessInstance) ExceptionScopeInstance(org.jbpm.process.instance.context.exception.ExceptionScopeInstance)

Aggregations

KogitoNodeInstance (org.kie.kogito.internal.process.runtime.KogitoNodeInstance)33 KogitoWorkItem (org.kie.kogito.internal.process.runtime.KogitoWorkItem)15 KogitoProcessInstance (org.kie.kogito.internal.process.runtime.KogitoProcessInstance)14 Map (java.util.Map)12 SLAViolatedEvent (org.kie.api.event.process.SLAViolatedEvent)12 KogitoProcessEventListener (org.kie.kogito.internal.process.event.KogitoProcessEventListener)12 List (java.util.List)11 HumanTaskWorkItem (org.kie.kogito.process.workitem.HumanTaskWorkItem)9 WorkUnit (org.kie.kogito.uow.WorkUnit)9 AbstractEventSupport (org.drools.core.event.AbstractEventSupport)8 MessageEventImpl (org.drools.core.event.MessageEventImpl)8 ProcessCompletedEventImpl (org.drools.core.event.ProcessCompletedEventImpl)8 ProcessStartedEventImpl (org.drools.core.event.ProcessStartedEventImpl)8 SLAViolatedEventImpl (org.drools.core.event.SLAViolatedEventImpl)8 SignalEventImpl (org.drools.core.event.SignalEventImpl)8 Date (java.util.Date)7 ExclusiveGroupInstance (org.jbpm.process.instance.context.exclusive.ExclusiveGroupInstance)6 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)5 MessageEvent (org.kie.api.event.process.MessageEvent)5