use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class SvgBpmnProcessImageGenerator method buildNodeContainer.
/*
* Build methods
*/
protected void buildNodeContainer(int x, int y, NodeContainer nodeContainer, SVGGraphics2D g2) {
try {
for (Node node : nodeContainer.getNodes()) {
if (node instanceof StartNode) {
buildStartEvent(x, y, (StartNode) node, g2);
} else if (node instanceof EndNode) {
buildEndEvent(x, y, (EndNode) node, g2);
} else if (node instanceof FaultNode) {
buildErrorEndEvent(x, y, (FaultNode) node, g2);
} else if (node instanceof BoundaryEventNode) {
buildBoundaryEvent(x, y, node, g2);
} else if (node instanceof EventNode || node instanceof StateNode) {
buildIntermediateEvent(x, y, node, g2);
} else if (node instanceof HumanTaskNode) {
buildHumanTaskNode(x, y, (HumanTaskNode) node, g2);
} else if (node instanceof ActionNode) {
buildScriptTaskNode(x, y, (ActionNode) node, g2);
} else if (node instanceof WorkItemNode) {
buildServiceTaskNode(x, y, (WorkItemNode) node, g2);
} else if (node instanceof Split || node instanceof Join) {
buildGateway(x, y, node, g2);
} else if (node instanceof ForEachNode) {
buildNodeContainer(x(node), y(node), ((ForEachNode) node).getCompositeNode(), g2);
} else if (node instanceof CompositeNode) {
buildSubprocessNode(x, y, (CompositeNode) node, g2);
int sx = x(node);
int sy = y(node);
buildNodeContainer(sx, sy, (CompositeNode) node, g2);
} else if (node instanceof RuleSetNode) {
buildBusinessRuleTaskNode(x, y, (RuleSetNode) node, g2);
} else if (node instanceof TimerNode) {
buildTimerEvent(x, y, (TimerNode) node, g2);
} else if (node instanceof SubProcessNode) {
buildCallActivity(x, y, (SubProcessNode) node, g2);
}
buildSequenceFlow(x, y, node, g2);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class ProcessHandler method checkBoundaryEventCompensationHandler.
/**
* This logic belongs in {@link ExecutableProcessValidator} -- except that
* {@link Association}s are a jbpm-bpmn2 class, and
* {@link ExecutableProcessValidator} is a jbpm-flow class..
* </p>
* Maybe we should have a BPMNProcessValidator class?
*
* @param association The association to check.
* @param source The source of the association.
* @param target The target of the association.
*/
private static void checkBoundaryEventCompensationHandler(Association association, Node source, Node target) {
// - event node is boundary event node
if (!(source instanceof BoundaryEventNode)) {
throw new IllegalArgumentException("(Compensation) activities may only be associated with Boundary Event Nodes (not with" + source.getClass().getSimpleName() + " nodes [node " + ((String) source.getMetaData().get("UniqueId")) + "].");
}
BoundaryEventNode eventNode = (BoundaryEventNode) source;
// - event node has compensationEvent
List<EventFilter> eventFilters = eventNode.getEventFilters();
boolean compensationCheckPassed = false;
if (eventFilters != null) {
for (EventFilter filter : eventFilters) {
if (filter instanceof EventTypeFilter) {
String type = ((EventTypeFilter) filter).getType();
if (type != null && type.equals("Compensation")) {
compensationCheckPassed = true;
}
}
}
}
if (!compensationCheckPassed) {
throw new IllegalArgumentException("An Event [" + ((String) eventNode.getMetaData("UniqueId")) + "] linked from an association [" + association.getId() + "] must be a (Boundary) Compensation Event.");
}
// - boundary event node is attached to the correct type of node?
/**
* Tasks: business: RuleSetNode manual: WorkItemNode receive: WorkItemNode
* script: ActionNode send: WorkItemNode service: WorkItemNode task:
* WorkItemNode user: HumanTaskNode
*/
String attachedToId = eventNode.getAttachedToNodeId();
Node attachedToNode = null;
for (Node node : eventNode.getParentContainer().getNodes()) {
if (attachedToId.equals(node.getMetaData().get("UniqueId"))) {
attachedToNode = node;
break;
}
}
if (attachedToNode == null) {
throw new IllegalArgumentException("Boundary Event [" + ((String) eventNode.getMetaData("UniqueId")) + "] is not attached to a node [" + attachedToId + "] that can be found.");
}
if (!(attachedToNode instanceof RuleSetNode || attachedToNode instanceof WorkItemNode || attachedToNode instanceof ActionNode || attachedToNode instanceof HumanTaskNode || attachedToNode instanceof CompositeNode || attachedToNode instanceof SubProcessNode)) {
throw new IllegalArgumentException("Compensation Boundary Event [" + ((String) eventNode.getMetaData("UniqueId")) + "] must be attached to a task or sub-process.");
}
// - associated node is a task or subProcess
compensationCheckPassed = false;
if (target instanceof WorkItemNode || target instanceof HumanTaskNode || target instanceof CompositeContextNode || target instanceof SubProcessNode) {
compensationCheckPassed = true;
} else if (target instanceof ActionNode) {
Object nodeTypeObj = ((ActionNode) target).getMetaData("NodeType");
if (nodeTypeObj != null && nodeTypeObj.equals("ScriptTask")) {
compensationCheckPassed = true;
}
}
if (!compensationCheckPassed) {
throw new IllegalArgumentException("An Activity [" + ((String) ((NodeImpl) target).getMetaData("UniqueId")) + "] associated with a Boundary Compensation Event must be a Task or a (non-Event) Sub-Process");
}
// - associated node does not have outgoingConnections of it's own
compensationCheckPassed = true;
NodeImpl targetNode = (NodeImpl) target;
Map<String, List<io.automatiko.engine.api.definition.process.Connection>> connectionsMap = targetNode.getOutgoingConnections();
ConnectionImpl outgoingConnection = null;
for (String connectionType : connectionsMap.keySet()) {
List<io.automatiko.engine.api.definition.process.Connection> connections = connectionsMap.get(connectionType);
if (connections != null && !connections.isEmpty()) {
for (io.automatiko.engine.api.definition.process.Connection connection : connections) {
Object hiddenObj = connection.getMetaData().get("hidden");
if (hiddenObj != null && ((Boolean) hiddenObj)) {
continue;
}
outgoingConnection = (ConnectionImpl) connection;
compensationCheckPassed = false;
break;
}
}
}
if (!compensationCheckPassed) {
throw new IllegalArgumentException("A Compensation Activity [" + ((String) targetNode.getMetaData("UniqueId")) + "] may not have any outgoing connection [" + (String) outgoingConnection.getMetaData("UniqueId") + "]");
}
}
use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class SubProcessTest method testNonExistentSubProcess.
@Test
public void testNonExistentSubProcess() {
String nonExistentSubProcessName = "nonexistent.process";
ExecutableProcess process = new ExecutableProcess();
process.setId("org.company.core.process.process");
process.setName("Process");
StartNode startNode = new StartNode();
startNode.setName("Start");
startNode.setId(1);
SubProcessNode subProcessNode = new SubProcessNode();
subProcessNode.setName("SubProcessNode");
subProcessNode.setId(2);
subProcessNode.setProcessId(nonExistentSubProcessName);
EndNode endNode = new EndNode();
endNode.setName("End");
endNode.setId(3);
connect(startNode, subProcessNode);
connect(subProcessNode, endNode);
process.addNode(startNode);
process.addNode(subProcessNode);
process.addNode(endNode);
InternalProcessRuntime ksession = createProcessRuntime(process);
ProcessInstance pi = ksession.startProcess("org.company.core.process.process");
assertEquals(ProcessInstance.STATE_ERROR, pi.getState());
}
use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class BpmnProcess method registerListeners.
@Override
protected void registerListeners() {
super.registerListeners();
List<SubProcessNode> subprocessNodes = new ArrayList<SubProcessNode>();
collectSubprocessNodes(subprocessNodes, (NodeContainer) process());
for (SubProcessNode sp : subprocessNodes) {
services.getSignalManager().addEventListener(sp.getProcessId(), completionEventListener);
}
}
use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class ServerlessWorkflowFactory method callActivity.
public SubProcessNode callActivity(long id, String name, String calledId, boolean waitForCompletion, NodeContainer nodeContainer) {
SubProcessNode subProcessNode = new SubProcessNode();
subProcessNode.setId(id);
subProcessNode.setName(name);
subProcessNode.setProcessId(calledId);
subProcessNode.setWaitForCompletion(waitForCompletion);
subProcessNode.setIndependent(true);
VariableScope variableScope = new VariableScope();
subProcessNode.addContext(variableScope);
subProcessNode.setDefaultContext(variableScope);
Map<String, String> inputOtuputTypes = new HashMap<>();
inputOtuputTypes.put(DEFAULT_WORKFLOW_VAR, JSON_NODE);
subProcessNode.setMetaData("BPMN.InputTypes", inputOtuputTypes);
subProcessNode.setMetaData("BPMN.OutputTypes", inputOtuputTypes);
// parent and sub processes have process var "workflowdata"
subProcessNode.addInMapping(DEFAULT_WORKFLOW_VAR, DEFAULT_WORKFLOW_VAR);
subProcessNode.addOutMapping(DEFAULT_WORKFLOW_VAR, DEFAULT_WORKFLOW_VAR);
nodeContainer.addNode(subProcessNode);
return subProcessNode;
}
Aggregations