Search in sources :

Example 1 with ContextInstanceContainer

use of io.automatiko.engine.workflow.base.instance.ContextInstanceContainer 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);
    }
}
Also used : NodeInstanceImpl(io.automatiko.engine.workflow.process.instance.impl.NodeInstanceImpl) Action(io.automatiko.engine.workflow.base.instance.impl.Action) WorkItemNodeInstance(io.automatiko.engine.workflow.process.instance.node.WorkItemNodeInstance) ActionExceptionHandler(io.automatiko.engine.workflow.base.core.context.exception.ActionExceptionHandler) ProcessContext(io.automatiko.engine.workflow.base.core.context.ProcessContext) JobsService(io.automatiko.engine.api.jobs.JobsService) WorkItemImpl(io.automatiko.engine.workflow.base.instance.impl.workitem.WorkItemImpl) ProcessInstance(io.automatiko.engine.workflow.base.instance.ProcessInstance) ContextInstanceContainer(io.automatiko.engine.workflow.base.instance.ContextInstanceContainer) DurationExpirationTime(io.automatiko.engine.api.jobs.DurationExpirationTime) WorkItemNodeInstance(io.automatiko.engine.workflow.process.instance.node.WorkItemNodeInstance) NodeInstance(io.automatiko.engine.workflow.process.instance.NodeInstance)

Example 2 with ContextInstanceContainer

use of io.automatiko.engine.workflow.base.instance.ContextInstanceContainer in project automatiko-engine by automatiko-io.

the class SplitInstance method executeStrategy.

protected void executeStrategy(Split split, String type) {
    // TODO make different strategies for each type
    String uniqueId = (String) getNode().getMetaData().get(UNIQUE_ID);
    if (uniqueId == null) {
        uniqueId = ((NodeImpl) getNode()).getUniqueId();
    }
    switch(split.getType()) {
        case Split.TYPE_AND:
            triggerCompleted(io.automatiko.engine.workflow.process.core.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);
            ((WorkflowProcessInstanceImpl) getProcessInstance()).addCompletedNodeId(uniqueId);
            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() == STATE_COMPLETED || getProcessInstance().getState() == STATE_ABORTED) {
                    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());
            }
            ((WorkflowProcessInstanceImpl) getProcessInstance()).addCompletedNodeId(uniqueId);
            break;
        case Split.TYPE_XAND:
            ((io.automatiko.engine.workflow.process.instance.NodeInstanceContainer) getNodeInstanceContainer()).removeNodeInstance(this);
            Node node = getNode();
            List<Connection> connections = null;
            if (node != null) {
                connections = node.getOutgoingConnections(type);
            }
            if (connections == null || connections.isEmpty()) {
                ((io.automatiko.engine.workflow.process.instance.NodeInstanceContainer) getNodeInstanceContainer()).nodeInstanceCompleted(this, type);
            } else {
                ExclusiveGroupInstance groupInstance = new ExclusiveGroupInstance();
                io.automatiko.engine.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<io.automatiko.engine.workflow.process.instance.NodeInstance, String> nodeInstancesMap = new HashMap<io.automatiko.engine.workflow.process.instance.NodeInstance, String>();
                for (Connection connection : connections) {
                    nodeInstancesMap.put(followConnection(connection), connection.getToType());
                }
                for (NodeInstance nodeInstance : nodeInstancesMap.keySet()) {
                    groupInstance.addNodeInstance(nodeInstance);
                }
                for (Map.Entry<io.automatiko.engine.workflow.process.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;
                    }
                    InternalProcessRuntime runtime = getProcessInstance().getProcessRuntime();
                    if (!hidden) {
                        runtime.getProcessEventSupport().fireBeforeNodeLeft(this, runtime);
                    }
                    ((io.automatiko.engine.workflow.process.instance.NodeInstance) entry.getKey()).trigger(this, entry.getValue());
                    if (!hidden) {
                        runtime.getProcessEventSupport().fireAfterNodeLeft(this, runtime);
                    }
                }
            }
            ((WorkflowProcessInstanceImpl) getProcessInstance()).addCompletedNodeId(uniqueId);
            break;
        default:
            throw new IllegalArgumentException("Illegal split type " + split.getType());
    }
}
Also used : NodeInstanceContainer(io.automatiko.engine.workflow.process.instance.NodeInstanceContainer) HashMap(java.util.HashMap) Node(io.automatiko.engine.api.definition.process.Node) WorkflowProcessInstanceImpl(io.automatiko.engine.workflow.process.instance.impl.WorkflowProcessInstanceImpl) ArrayList(java.util.ArrayList) ConstraintEvaluator(io.automatiko.engine.workflow.base.instance.impl.ConstraintEvaluator) WorkflowRuntimeException(io.automatiko.engine.workflow.process.instance.WorkflowRuntimeException) ContextInstanceContainer(io.automatiko.engine.workflow.base.instance.ContextInstanceContainer) ExclusiveGroupInstance(io.automatiko.engine.workflow.base.instance.context.exclusive.ExclusiveGroupInstance) Connection(io.automatiko.engine.api.definition.process.Connection) InternalProcessRuntime(io.automatiko.engine.workflow.base.instance.InternalProcessRuntime) NodeInstance(io.automatiko.engine.api.runtime.process.NodeInstance) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with ContextInstanceContainer

use of io.automatiko.engine.workflow.base.instance.ContextInstanceContainer in project automatiko-engine by automatiko-io.

the class NodeInstanceImpl method resolveContextInstance.

public ContextInstance resolveContextInstance(String contextId, Object param) {
    Context context = resolveContext(contextId, param);
    if (context == null) {
        return null;
    }
    ContextInstanceContainer contextInstanceContainer = getContextInstanceContainer(context.getContextContainer());
    if (contextInstanceContainer == null) {
        throw new IllegalArgumentException("Could not find context instance container for context");
    }
    return contextInstanceContainer.getContextInstance(context);
}
Also used : Context(io.automatiko.engine.workflow.base.core.Context) ProcessContext(io.automatiko.engine.workflow.base.core.context.ProcessContext) ContextInstanceContainer(io.automatiko.engine.workflow.base.instance.ContextInstanceContainer)

Example 4 with ContextInstanceContainer

use of io.automatiko.engine.workflow.base.instance.ContextInstanceContainer in project automatiko-engine by automatiko-io.

the class WorkflowReuseContextInstanceFactory method getContextInstance.

public ContextInstance getContextInstance(Context context, ContextInstanceContainer contextInstanceContainer, ProcessInstance processInstance) {
    ContextInstance result = contextInstanceContainer.getContextInstance(context.getType(), context.getId());
    if (result != null) {
        return result;
    }
    try {
        AbstractContextInstance contextInstance = (AbstractContextInstance) cls.newInstance();
        contextInstance.setContextId(context.getId());
        contextInstance.setContextInstanceContainer(contextInstanceContainer);
        contextInstance.setProcessInstance(processInstance);
        contextInstanceContainer.addContextInstance(context.getType(), contextInstance);
        NodeInstanceContainer nodeInstanceContainer = null;
        if (contextInstanceContainer instanceof NodeInstanceContainer) {
            nodeInstanceContainer = (NodeInstanceContainer) contextInstanceContainer;
        } else if (contextInstanceContainer instanceof ContextInstance) {
            ContextInstanceContainer parent = ((ContextInstance) contextInstanceContainer).getContextInstanceContainer();
            while (parent != null) {
                if (parent instanceof NodeInstanceContainer) {
                    nodeInstanceContainer = (NodeInstanceContainer) parent;
                } else if (contextInstanceContainer instanceof ContextInstance) {
                    parent = ((ContextInstance) contextInstanceContainer).getContextInstanceContainer();
                } else {
                    parent = null;
                }
            }
        }
        ((WorkflowContextInstance) contextInstance).setNodeInstanceContainer(nodeInstanceContainer);
        return contextInstance;
    } catch (Exception e) {
        throw new RuntimeException("Unable to instantiate context '" + this.cls.getName() + "': " + e.getMessage());
    }
}
Also used : AbstractContextInstance(io.automatiko.engine.workflow.base.instance.context.AbstractContextInstance) NodeInstanceContainer(io.automatiko.engine.workflow.process.instance.NodeInstanceContainer) ContextInstance(io.automatiko.engine.workflow.base.instance.ContextInstance) AbstractContextInstance(io.automatiko.engine.workflow.base.instance.context.AbstractContextInstance) ContextInstanceContainer(io.automatiko.engine.workflow.base.instance.ContextInstanceContainer)

Aggregations

ContextInstanceContainer (io.automatiko.engine.workflow.base.instance.ContextInstanceContainer)4 ProcessContext (io.automatiko.engine.workflow.base.core.context.ProcessContext)2 NodeInstanceContainer (io.automatiko.engine.workflow.process.instance.NodeInstanceContainer)2 Connection (io.automatiko.engine.api.definition.process.Connection)1 Node (io.automatiko.engine.api.definition.process.Node)1 DurationExpirationTime (io.automatiko.engine.api.jobs.DurationExpirationTime)1 JobsService (io.automatiko.engine.api.jobs.JobsService)1 NodeInstance (io.automatiko.engine.api.runtime.process.NodeInstance)1 Context (io.automatiko.engine.workflow.base.core.Context)1 ActionExceptionHandler (io.automatiko.engine.workflow.base.core.context.exception.ActionExceptionHandler)1 ContextInstance (io.automatiko.engine.workflow.base.instance.ContextInstance)1 InternalProcessRuntime (io.automatiko.engine.workflow.base.instance.InternalProcessRuntime)1 ProcessInstance (io.automatiko.engine.workflow.base.instance.ProcessInstance)1 AbstractContextInstance (io.automatiko.engine.workflow.base.instance.context.AbstractContextInstance)1 ExclusiveGroupInstance (io.automatiko.engine.workflow.base.instance.context.exclusive.ExclusiveGroupInstance)1 Action (io.automatiko.engine.workflow.base.instance.impl.Action)1 ConstraintEvaluator (io.automatiko.engine.workflow.base.instance.impl.ConstraintEvaluator)1 WorkItemImpl (io.automatiko.engine.workflow.base.instance.impl.workitem.WorkItemImpl)1 NodeInstance (io.automatiko.engine.workflow.process.instance.NodeInstance)1 WorkflowRuntimeException (io.automatiko.engine.workflow.process.instance.WorkflowRuntimeException)1