Search in sources :

Example 1 with NodeInstance

use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.

the class CompensationScopeInstance method handleException.

public void handleException(io.automatiko.engine.api.runtime.process.NodeInstance nodeInstance, String activityRef, Object dunno) {
    assert activityRef != null : "It should not be possible for the compensation activity reference to be null here.";
    CompensationScope compensationScope = (CompensationScope) getExceptionScope();
    // broadcast/general compensation in reverse order
    if (activityRef.startsWith(IMPLICIT_COMPENSATION_PREFIX)) {
        activityRef = activityRef.substring(IMPLICIT_COMPENSATION_PREFIX.length());
        assert activityRef.equals(compensationScope.getContextContainerId()) : "Compensation activity ref [" + activityRef + "] does not match" + " Compensation Scope container id [" + compensationScope.getContextContainerId() + "]";
        Map<String, ExceptionHandler> handlers = compensationScope.getExceptionHandlers();
        List<String> completedNodeIds = ((WorkflowProcessInstanceImpl) getProcessInstance()).getCompletedNodeIds();
        ListIterator<String> iter = completedNodeIds.listIterator(completedNodeIds.size());
        while (iter.hasPrevious()) {
            String completedId = iter.previous();
            ExceptionHandler handler = handlers.get(completedId);
            if (handler != null) {
                handleException(nodeInstance, handler, completedId, null);
            }
        }
    } else {
        // Specific compensation
        ExceptionHandler handler = compensationScope.getExceptionHandler(activityRef);
        if (handler == null) {
            throw new IllegalArgumentException("Could not find CompensationHandler for " + activityRef);
        }
        handleException(nodeInstance, handler, activityRef, null);
    }
    // Cancel all node instances created for compensation
    while (!compensationInstances.isEmpty()) {
        NodeInstance generatedInstance = compensationInstances.pop();
        ((NodeInstanceContainer) generatedInstance.getNodeInstanceContainer()).removeNodeInstance(generatedInstance);
    }
}
Also used : ExceptionHandler(io.automatiko.engine.workflow.base.core.context.exception.ExceptionHandler) NodeInstanceContainer(io.automatiko.engine.workflow.process.instance.NodeInstanceContainer) WorkflowProcessInstanceImpl(io.automatiko.engine.workflow.process.instance.impl.WorkflowProcessInstanceImpl) CompensationScope(io.automatiko.engine.workflow.base.core.context.exception.CompensationScope) EventNodeInstance(io.automatiko.engine.workflow.process.instance.node.EventNodeInstance) NodeInstance(io.automatiko.engine.workflow.process.instance.NodeInstance) EventSubProcessNodeInstance(io.automatiko.engine.workflow.process.instance.node.EventSubProcessNodeInstance)

Example 2 with NodeInstance

use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.

the class CompensationScopeInstance method handleException.

public void handleException(io.automatiko.engine.api.runtime.process.NodeInstance nodeInstance, ExceptionHandler handler, String compensationActivityRef, Object dunno) {
    WorkflowProcessInstanceImpl processInstance = (WorkflowProcessInstanceImpl) getProcessInstance();
    NodeInstanceContainer nodeInstanceContainer = (NodeInstanceContainer) getContextInstanceContainer();
    if (handler instanceof CompensationHandler) {
        CompensationHandler compensationHandler = (CompensationHandler) handler;
        try {
            Node handlerNode = compensationHandler.getnode();
            if (handlerNode instanceof BoundaryEventNode) {
                NodeInstance compensationHandlerNodeInstance = nodeInstanceContainer.getNodeInstance(handlerNode);
                compensationInstances.add(compensationHandlerNodeInstance);
                // The BoundaryEventNodeInstance.signalEvent() contains the necessary logic
                // to check whether or not compensation may proceed (? : (not-active +
                // completed))
                EventNodeInstance eventNodeInstance = (EventNodeInstance) compensationHandlerNodeInstance;
                eventNodeInstance.signalEvent("Compensation", compensationActivityRef);
            } else if (handlerNode instanceof EventSubProcessNode) {
                // Check that subprocess parent has completed.
                List<String> completedIds = processInstance.getCompletedNodeIds();
                if (completedIds.contains(((NodeImpl) handlerNode.getParentContainer()).getMetaData("UniqueId"))) {
                    NodeInstance subProcessNodeInstance = ((NodeInstanceContainer) nodeInstanceContainer).getNodeInstance((Node) handlerNode.getParentContainer());
                    compensationInstances.add(subProcessNodeInstance);
                    NodeInstance compensationHandlerNodeInstance = ((NodeInstanceContainer) subProcessNodeInstance).getNodeInstance(handlerNode);
                    compensationInstances.add(compensationHandlerNodeInstance);
                    EventSubProcessNodeInstance eventNodeInstance = (EventSubProcessNodeInstance) compensationHandlerNodeInstance;
                    eventNodeInstance.signalEvent("Compensation", compensationActivityRef);
                }
            }
            assert handlerNode instanceof BoundaryEventNode || handlerNode instanceof EventSubProcessNode : "Unexpected compensation handler node type : " + handlerNode.getClass().getSimpleName();
        } catch (Exception e) {
            throwWorkflowRuntimeException(nodeInstanceContainer, processInstance, "Unable to execute compensation.", e);
        }
    } else {
        Exception e = new IllegalArgumentException("Unsupported compensation handler: " + handler);
        throwWorkflowRuntimeException(nodeInstanceContainer, processInstance, e.getMessage(), e);
    }
}
Also used : NodeInstanceContainer(io.automatiko.engine.workflow.process.instance.NodeInstanceContainer) NodeImpl(io.automatiko.engine.workflow.process.core.impl.NodeImpl) EventSubProcessNode(io.automatiko.engine.workflow.process.core.node.EventSubProcessNode) Node(io.automatiko.engine.api.definition.process.Node) EventSubProcessNode(io.automatiko.engine.workflow.process.core.node.EventSubProcessNode) BoundaryEventNode(io.automatiko.engine.workflow.process.core.node.BoundaryEventNode) WorkflowProcessInstanceImpl(io.automatiko.engine.workflow.process.instance.impl.WorkflowProcessInstanceImpl) CompensationHandler(io.automatiko.engine.workflow.base.core.context.exception.CompensationHandler) BoundaryEventNode(io.automatiko.engine.workflow.process.core.node.BoundaryEventNode) WorkflowRuntimeException(io.automatiko.engine.workflow.process.instance.WorkflowRuntimeException) EventSubProcessNodeInstance(io.automatiko.engine.workflow.process.instance.node.EventSubProcessNodeInstance) List(java.util.List) EventNodeInstance(io.automatiko.engine.workflow.process.instance.node.EventNodeInstance) NodeInstance(io.automatiko.engine.workflow.process.instance.NodeInstance) EventSubProcessNodeInstance(io.automatiko.engine.workflow.process.instance.node.EventSubProcessNodeInstance) EventNodeInstance(io.automatiko.engine.workflow.process.instance.node.EventNodeInstance)

Example 3 with NodeInstance

use of io.automatiko.engine.workflow.process.instance.NodeInstance 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 4 with NodeInstance

use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.

the class BoundaryEventNodeInstance method isAttachedToNodeActive.

private boolean isAttachedToNodeActive(Collection<NodeInstance> nodeInstances, String attachedTo, String type, Object event) {
    if (nodeInstances != null && !nodeInstances.isEmpty()) {
        for (NodeInstance nInstance : nodeInstances) {
            String nodeUniqueId = (String) nInstance.getNode().getMetaData().get("UniqueId");
            boolean isActivating = ((WorkflowProcessInstanceImpl) nInstance.getProcessInstance()).getActivatingNodeIds().contains(nodeUniqueId);
            if (attachedTo.equals(nodeUniqueId) && !isActivating) {
                // instance
                if (type.startsWith("Timer-")) {
                    if (nInstance.getId().equals(event)) {
                        return true;
                    }
                } else {
                    return true;
                }
            }
        }
    }
    return false;
}
Also used : NodeInstance(io.automatiko.engine.workflow.process.instance.NodeInstance)

Example 5 with NodeInstance

use of io.automatiko.engine.workflow.process.instance.NodeInstance in project automatiko-engine by automatiko-io.

the class BoundaryEventNodeInstance method signalEvent.

@Override
public void signalEvent(String type, Object event) {
    BoundaryEventNode boundaryNode = (BoundaryEventNode) getEventNode();
    String attachedTo = boundaryNode.getAttachedToNodeId();
    Collection<NodeInstance> nodeInstances = ((NodeInstanceContainer) getProcessInstance()).getNodeInstances(true);
    if (type != null && type.startsWith("Compensation")) {
        // if not active && completed, signal
        if (!isAttachedToNodeActive(nodeInstances, attachedTo, type, event) && isAttachedToNodeCompleted(attachedTo)) {
            super.signalEvent(type, event);
        } else {
            cancel();
        }
    } else {
        if (isAttachedToNodeActive(nodeInstances, attachedTo, type, event)) {
            super.signalEvent(type, event);
        } else {
            cancel();
        }
    }
}
Also used : NodeInstanceContainer(io.automatiko.engine.workflow.process.instance.NodeInstanceContainer) BoundaryEventNode(io.automatiko.engine.workflow.process.core.node.BoundaryEventNode) NodeInstance(io.automatiko.engine.workflow.process.instance.NodeInstance)

Aggregations

NodeInstance (io.automatiko.engine.workflow.process.instance.NodeInstance)22 EventSubProcessNodeInstance (io.automatiko.engine.workflow.process.instance.node.EventSubProcessNodeInstance)10 WorkflowProcessInstanceImpl (io.automatiko.engine.workflow.process.instance.impl.WorkflowProcessInstanceImpl)6 CompositeContextNodeInstance (io.automatiko.engine.workflow.process.instance.node.CompositeContextNodeInstance)6 EventNodeInstance (io.automatiko.engine.workflow.process.instance.node.EventNodeInstance)6 Node (io.automatiko.engine.api.definition.process.Node)5 EventSubProcessNode (io.automatiko.engine.workflow.process.core.node.EventSubProcessNode)5 NodeInstanceContainer (io.automatiko.engine.workflow.process.instance.NodeInstanceContainer)5 CompositeNodeInstance (io.automatiko.engine.workflow.process.instance.node.CompositeNodeInstance)5 HashMap (java.util.HashMap)5 ExpressionEvaluator (io.automatiko.engine.api.expression.ExpressionEvaluator)4 VariableScopeInstance (io.automatiko.engine.workflow.base.instance.context.variable.VariableScopeInstance)4 HumanTaskNodeInstance (io.automatiko.engine.workflow.process.instance.node.HumanTaskNodeInstance)4 LambdaSubProcessNodeInstance (io.automatiko.engine.workflow.process.instance.node.LambdaSubProcessNodeInstance)4 WorkItemNodeInstance (io.automatiko.engine.workflow.process.instance.node.WorkItemNodeInstance)4 Map (java.util.Map)4 ContextContainer (io.automatiko.engine.workflow.base.core.ContextContainer)3 EndNodeInstance (io.automatiko.engine.workflow.process.instance.node.EndNodeInstance)3 FaultNodeInstance (io.automatiko.engine.workflow.process.instance.node.FaultNodeInstance)3 StartNodeInstance (io.automatiko.engine.workflow.process.instance.node.StartNodeInstance)3