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);
}
}
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());
}
}
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);
}
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());
}
}
Aggregations