use of io.automatiko.engine.workflow.process.core.node.StartNode in project automatiko-engine by automatiko-io.
the class DmnDecisionInProcessTest method createProcess.
private ExecutableProcess createProcess(String namespace, String modelName, String decisionName) {
DMNRuntime dmnRuntime = DmnRuntimeProvider.fromClassPath("PersonDecisions.dmn");
DmnDecisionModel dmnDecisionModel = new DmnDecisionModel(dmnRuntime, namespace, modelName);
ExecutableProcess process = new ExecutableProcess();
process.setId("process");
process.setName("Process");
List<Variable> variables = new ArrayList<Variable>();
Variable variable1 = new Variable();
variable1.setName("person");
variable1.setType(new ObjectDataType(Person.class));
variables.add(variable1);
Variable variable2 = new Variable();
variable2.setName("isAdult");
variable2.setType(new BooleanDataType());
variables.add(variable2);
process.getVariableScope().setVariables(variables);
StartNode startNode = new StartNode();
startNode.setName("Start");
startNode.setId(1);
RuleSetNode ruleSetNode = new RuleSetNode();
ruleSetNode.setName("RuleSetNode");
ruleSetNode.setId(2);
ruleSetNode.setRuleType(RuleSetNode.RuleType.decision(namespace, modelName, null));
ruleSetNode.setLanguage(RuleSetNode.DMN_LANG);
ruleSetNode.setDecisionModel(() -> dmnDecisionModel);
ruleSetNode.addInMapping("Person", "person");
ruleSetNode.addOutMapping("isAdult", "isAdult");
EndNode endNode = new EndNode();
endNode.setName("End");
endNode.setId(3);
connect(startNode, ruleSetNode);
connect(ruleSetNode, endNode);
process.addNode(startNode);
process.addNode(ruleSetNode);
process.addNode(endNode);
return process;
}
use of io.automatiko.engine.workflow.process.core.node.StartNode in project automatiko-engine by automatiko-io.
the class LightProcessRuntime method initStartTimers.
public void initStartTimers() {
Collection<Process> processes = runtimeContext.getProcesses();
for (Process process : processes) {
ExecutableProcess p = (ExecutableProcess) process;
List<StartNode> startNodes = p.getTimerStart();
if (startNodes != null && !startNodes.isEmpty()) {
for (StartNode startNode : startNodes) {
if (startNode != null && startNode.getTimer() != null) {
jobService.scheduleProcessJob(ProcessJobDescription.of(createTimerInstance(startNode.getTimer()), p.getId(), p.getVersion()));
}
}
}
}
}
use of io.automatiko.engine.workflow.process.core.node.StartNode in project automatiko-engine by automatiko-io.
the class LightProcessRuntime method initProcessEventListener.
private void initProcessEventListener(Process process) {
if (process instanceof ExecutableProcess) {
for (Node node : ((ExecutableProcess) process).getNodes()) {
if (node instanceof StartNode) {
StartNode startNode = (StartNode) node;
if (startNode != null) {
List<Trigger> triggers = startNode.getTriggers();
if (triggers != null) {
for (Trigger trigger : triggers) {
if (trigger instanceof EventTrigger) {
final List<EventFilter> filters = ((EventTrigger) trigger).getEventFilters();
String type = null;
for (EventFilter filter : filters) {
if (filter instanceof EventTypeFilter) {
type = ((EventTypeFilter) filter).getType();
}
}
StartProcessEventListener listener = new StartProcessEventListener(process.getId(), filters, trigger.getInMappings(), startNode.getEventTransformer());
signalManager.addEventListener(type, listener);
((ExecutableProcess) process).getRuntimeMetaData().put("StartProcessEventType", type);
((ExecutableProcess) process).getRuntimeMetaData().put("StartProcessEventListener", listener);
}
}
}
}
}
}
}
}
use of io.automatiko.engine.workflow.process.core.node.StartNode in project automatiko-engine by automatiko-io.
the class ServerlessWorkflowParser method parse.
public Process parse(Reader workflowFile) {
AtomicLong ids = new AtomicLong(0);
Workflow workflow = Workflow.fromSource(toString(workflowFile));
ServerlessWorkflowFactory factory = new ServerlessWorkflowFactory();
if (!"jq".equalsIgnoreCase(workflow.getExpressionLang())) {
throw new IllegalArgumentException("Not supported expression language, only 'jq' is supported");
}
WorkflowProcess process = factory.createProcess(workflow);
State start = WorkflowUtils.getStartingState(workflow);
Node startNode;
if (start.getType().equals(DefaultState.Type.EVENT)) {
List<Node> nodes = new ArrayList<>();
EventState eventState = (EventState) start;
for (OnEvents onEvent : eventState.getOnEvents()) {
if (eventState.isExclusive()) {
// use event based gateway
Join join = factory.joinNode(ids.getAndIncrement(), "join_" + eventState.getName(), Join.TYPE_XOR, process);
for (String eventRef : onEvent.getEventRefs()) {
EventDefinition event = WorkflowUtils.getDefinedConsumedEvents(workflow).stream().filter(e -> e.getName().equals(eventRef)).findFirst().get();
StartNode startMessageNode = factory.messageStartNode(ids.getAndIncrement(), event, onEvent, process);
factory.connect(startMessageNode.getId(), join.getId(), "connection_" + startMessageNode.getId() + "_" + join.getId(), process, false);
}
buildActionsForState(workflow, onEvent.getActions(), process, factory, ids, (first, last) -> {
factory.connect(join.getId(), first.getId(), join.getId() + "_" + first.getId(), process, false);
nodes.add(last);
}, (first, last) -> {
}, false);
} else {
// use parallel gateway
Join parallelJoin = factory.joinNode(ids.getAndIncrement(), "join_" + eventState.getName(), Join.TYPE_AND, process);
for (String eventRef : onEvent.getEventRefs()) {
EventDefinition event = WorkflowUtils.getDefinedConsumedEvents(workflow).stream().filter(e -> e.getName().equals(eventRef)).findFirst().get();
StartNode startMessageNode = factory.messageStartNode(ids.getAndIncrement(), event, onEvent, process);
factory.connect(startMessageNode.getId(), parallelJoin.getId(), "connection_" + startMessageNode.getId() + "_" + parallelJoin.getId(), process, false);
}
buildActionsForState(workflow, onEvent.getActions(), process, factory, ids, (first, last) -> {
factory.connect(parallelJoin.getId(), first.getId(), parallelJoin.getId() + "_" + first.getId(), process, false);
nodes.add(last);
}, (first, last) -> {
}, false);
}
}
// start node becomes the last node after message event handling so other parts are connected to it
startNode = nodes.get(0);
if (eventState.getStateDataFilter() != null && eventState.getStateDataFilter().getOutput() != null) {
ActionNode stateDataFilterActionNode = factory.stateDataFilterActionNode(ids.getAndIncrement(), "", process, eventState.getStateDataFilter().getOutput());
factory.connect(startNode.getId(), stateDataFilterActionNode.getId(), "connection_" + startNode.getId() + "_" + stateDataFilterActionNode.getId(), process, false);
startNode = stateDataFilterActionNode;
}
if (eventState.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), eventState.getName() + "-end", eventState.getEnd().isTerminate(), process);
if (eventState.getEnd().getProduceEvents() != null && !eventState.getEnd().getProduceEvents().isEmpty()) {
produceEvents(eventState.getEnd().getProduceEvents(), factory, workflow, ids, process, startNode.getId(), endNode.getId());
} else {
factory.connect(startNode.getId(), endNode.getId(), "connection_" + startNode.getId() + "_" + endNode.getId(), process, false);
}
}
} else {
startNode = factory.startNode(ids.getAndIncrement(), start.getName() + "-start", process);
}
// map of state names to node ids for connecting purpose
Map<String, Long> mappedNodes = new LinkedHashMap<>();
Node currentNode = null;
// process all states and create proper node representation for each state
for (State state : workflow.getStates()) {
if (state.getType().equals(Type.INJECT)) {
ActionNode actionNode = factory.injectStateNode(ids.getAndIncrement(), state.getName(), process, ((InjectState) state).getData().toString());
mappedNodes.put(state.getName(), actionNode.getId());
if (state.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), state.getName() + "-end", state.getEnd().isTerminate(), process);
if (state.getEnd().getProduceEvents() != null && !state.getEnd().getProduceEvents().isEmpty()) {
produceEvents(state.getEnd().getProduceEvents(), factory, workflow, ids, process, actionNode.getId(), endNode.getId());
} else {
factory.connect(actionNode.getId(), endNode.getId(), "connection_" + actionNode.getId() + "_" + endNode.getId(), process, false);
}
}
setUniqueId(actionNode, state);
currentNode = actionNode;
} else if (state.getType().equals(DefaultState.Type.OPERATION)) {
OperationState operationState = (OperationState) state;
CompositeContextNode embeddedSubProcess = factory.subProcessNode(ids.getAndIncrement(), state.getName(), process);
currentNode = embeddedSubProcess;
setUniqueId(embeddedSubProcess, state);
// handle state data inputs
Assignment inputAssignment = new Assignment("jq", "", "");
inputAssignment.setMetaData("Action", new InputJqAssignmentAction(state.getStateDataFilter() == null ? null : factory.unwrapExpression(state.getStateDataFilter().getInput())));
embeddedSubProcess.addInAssociation(new DataAssociation(Collections.emptyList(), "", Arrays.asList(inputAssignment), null));
// handle state data outputs
Assignment outputAssignment = new Assignment("jq", "", "");
outputAssignment.setMetaData("Action", new OutputJqAssignmentAction(state.getStateDataFilter() == null ? null : factory.unwrapExpression(state.getStateDataFilter().getOutput())));
embeddedSubProcess.addOutAssociation(new DataAssociation(Collections.emptyList(), "", Arrays.asList(outputAssignment), null));
mappedNodes.put(state.getName(), embeddedSubProcess.getId());
StartNode embeddedStartNode = factory.startNode(ids.getAndIncrement(), "EmbeddedStart", embeddedSubProcess);
EndNode embeddedEndNode = factory.endNode(ids.getAndIncrement(), "EmbeddedEnd", false, embeddedSubProcess);
if (operationState.getActions() == null || operationState.getActions().isEmpty()) {
factory.connect(embeddedStartNode.getId(), embeddedEndNode.getId(), embeddedStartNode.getId() + "_" + embeddedEndNode.getId(), embeddedSubProcess, false);
if (state.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), state.getName() + "-end", state.getEnd().isTerminate(), process);
if (state.getEnd().getProduceEvents() != null && !state.getEnd().getProduceEvents().isEmpty()) {
produceEvents(state.getEnd().getProduceEvents(), factory, workflow, ids, process, embeddedSubProcess.getId(), endNode.getId());
} else {
factory.connect(embeddedSubProcess.getId(), endNode.getId(), "connection_" + embeddedSubProcess.getId() + "_" + endNode.getId(), process, false);
}
}
// ensure that start node is connected
if (state.equals(start) && currentNode != null) {
factory.connect(startNode.getId(), currentNode.getId(), "connection_" + startNode.getId() + "_" + currentNode.getId(), process, false);
}
continue;
}
if (operationState.getActionMode() == null || operationState.getActionMode() == ActionMode.SEQUENTIAL) {
buildActionsForState(workflow, operationState.getActions(), embeddedSubProcess, factory, ids, (first, last) -> {
factory.connect(embeddedStartNode.getId(), first.getId(), embeddedStartNode.getId() + "_" + first.getId(), embeddedSubProcess, false);
factory.connect(last.getId(), embeddedEndNode.getId(), last.getId() + "_" + embeddedEndNode.getId(), embeddedSubProcess, false);
}, (first, last) -> {
}, false);
} else {
Split split = factory.splitNode(ids.getAndIncrement(), "parallel-split-" + state.getName(), Split.TYPE_AND, embeddedSubProcess);
Join join = factory.joinNode(ids.getAndIncrement(), "parallel-join-" + state.getName(), Join.TYPE_AND, embeddedSubProcess);
factory.connect(embeddedStartNode.getId(), split.getId(), embeddedStartNode.getId() + "_" + split.getId(), embeddedSubProcess, false);
factory.connect(join.getId(), embeddedEndNode.getId(), join.getId() + "_" + embeddedEndNode.getId(), embeddedSubProcess, false);
buildActionsForState(workflow, operationState.getActions(), embeddedSubProcess, factory, ids, (first, last) -> {
}, (first, last) -> {
factory.connect(split.getId(), first.getId(), split.getId() + "_" + first.getId(), embeddedSubProcess, false);
factory.connect(last.getId(), join.getId(), last.getId() + "_" + join.getId(), embeddedSubProcess, false);
}, true);
}
if (state.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), state.getName() + "-end", state.getEnd().isTerminate(), process);
if (state.getEnd().getProduceEvents() != null && !state.getEnd().getProduceEvents().isEmpty()) {
produceEvents(state.getEnd().getProduceEvents(), factory, workflow, ids, process, embeddedSubProcess.getId(), endNode.getId());
} else {
factory.connect(embeddedSubProcess.getId(), endNode.getId(), "connection_" + embeddedSubProcess.getId() + "_" + endNode.getId(), process, false);
}
}
} else if (state.getType().equals(DefaultState.Type.EVENT)) {
EventState eventState = (EventState) state;
if (eventState.equals(start)) {
// event state that is start node is already handled
continue;
}
for (OnEvents onEvent : eventState.getOnEvents()) {
CompositeContextNode embeddedSubProcess = factory.subProcessNode(ids.getAndIncrement(), state.getName(), process);
setUniqueId(embeddedSubProcess, state);
currentNode = embeddedSubProcess;
// handle state data inputs
Assignment inputAssignment = new Assignment("jq", "", "");
inputAssignment.setMetaData("Action", new InputJqAssignmentAction(state.getStateDataFilter() == null ? null : factory.unwrapExpression(state.getStateDataFilter().getInput())));
embeddedSubProcess.addInAssociation(new DataAssociation(Collections.emptyList(), "", Arrays.asList(inputAssignment), null));
// handle state data outputs
Assignment outputAssignment = new Assignment("jq", "", "");
outputAssignment.setMetaData("Action", new OutputJqAssignmentAction(state.getStateDataFilter() == null ? null : factory.unwrapExpression(state.getStateDataFilter().getOutput())));
embeddedSubProcess.addOutAssociation(new DataAssociation(Collections.emptyList(), "", Arrays.asList(outputAssignment), null));
mappedNodes.put(state.getName(), embeddedSubProcess.getId());
StartNode embeddedStartNode = factory.startNode(ids.getAndIncrement(), "EmbeddedStart", embeddedSubProcess);
EndNode embeddedEndNode = factory.endNode(ids.getAndIncrement(), "EmbeddedEnd", false, embeddedSubProcess);
if (eventState.isExclusive()) {
// use event based gateway
Split eventSplit = factory.eventBasedSplit(ids.getAndIncrement(), "split_" + state.getName(), embeddedSubProcess);
Join join = factory.joinNode(ids.getAndIncrement(), "join_" + state.getName(), Join.TYPE_XOR, embeddedSubProcess);
factory.connect(embeddedStartNode.getId(), eventSplit.getId(), "connection_" + embeddedStartNode.getId() + "_" + eventSplit.getId(), embeddedSubProcess, false);
for (String eventRef : onEvent.getEventRefs()) {
EventDefinition event = WorkflowUtils.getDefinedConsumedEvents(workflow).stream().filter(e -> e.getName().equals(eventRef)).findFirst().get();
EventNode eventNode = factory.consumeEventNode(ids.getAndIncrement(), event, onEvent.getEventDataFilter(), embeddedSubProcess);
factory.connect(eventSplit.getId(), eventNode.getId(), "connection_" + eventSplit.getId() + "_" + eventNode.getId(), embeddedSubProcess, false);
factory.connect(eventNode.getId(), join.getId(), "connection_" + eventNode.getId() + "_" + join.getId(), embeddedSubProcess, false);
}
buildActionsForState(workflow, onEvent.getActions(), embeddedSubProcess, factory, ids, (first, last) -> {
factory.connect(join.getId(), first.getId(), join.getId() + "_" + first.getId(), embeddedSubProcess, false);
factory.connect(last.getId(), embeddedEndNode.getId(), last.getId() + "_" + embeddedEndNode.getId(), embeddedSubProcess, false);
}, (first, last) -> {
}, false);
} else {
// use parallel gateway
Split parallelSplit = factory.splitNode(ids.getAndIncrement(), "split_" + state.getName(), Split.TYPE_AND, embeddedSubProcess);
Join parallelJoin = factory.joinNode(ids.getAndIncrement(), "join_" + state.getName(), Join.TYPE_AND, embeddedSubProcess);
factory.connect(embeddedStartNode.getId(), parallelSplit.getId(), "connection_" + embeddedStartNode.getId() + "_" + parallelSplit.getId(), embeddedSubProcess, false);
for (String eventRef : onEvent.getEventRefs()) {
EventDefinition event = WorkflowUtils.getDefinedConsumedEvents(workflow).stream().filter(e -> e.getName().equals(eventRef)).findFirst().get();
EventNode eventNode = factory.consumeEventNode(ids.getAndIncrement(), event, onEvent.getEventDataFilter(), embeddedSubProcess);
factory.connect(parallelSplit.getId(), eventNode.getId(), "connection_" + parallelSplit.getId() + "_" + eventNode.getId(), embeddedSubProcess, false);
factory.connect(eventNode.getId(), parallelJoin.getId(), "connection_" + eventNode.getId() + "_" + parallelJoin.getId(), embeddedSubProcess, false);
}
buildActionsForState(workflow, onEvent.getActions(), embeddedSubProcess, factory, ids, (first, last) -> {
factory.connect(parallelJoin.getId(), first.getId(), parallelJoin.getId() + "_" + first.getId(), embeddedSubProcess, false);
factory.connect(last.getId(), embeddedEndNode.getId(), last.getId() + "_" + embeddedEndNode.getId(), embeddedSubProcess, false);
}, (first, last) -> {
}, false);
}
if (state.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), state.getName() + "-end", state.getEnd().isTerminate(), process);
if (state.getEnd().getProduceEvents() != null && !state.getEnd().getProduceEvents().isEmpty()) {
produceEvents(state.getEnd().getProduceEvents(), factory, workflow, ids, process, embeddedSubProcess.getId(), endNode.getId());
} else {
factory.connect(embeddedSubProcess.getId(), endNode.getId(), "connection_" + embeddedSubProcess.getId() + "_" + endNode.getId(), process, false);
}
}
}
} else if (state.getType().equals(DefaultState.Type.CALLBACK)) {
CallbackState callcackState = (CallbackState) state;
CompositeContextNode embeddedSubProcess = factory.subProcessNode(ids.getAndIncrement(), state.getName(), process);
currentNode = embeddedSubProcess;
setUniqueId(embeddedSubProcess, state);
// handle state data inputs
Assignment inputAssignment = new Assignment("jq", "", "");
inputAssignment.setMetaData("Action", new InputJqAssignmentAction(state.getStateDataFilter() == null ? null : factory.unwrapExpression(state.getStateDataFilter().getInput())));
embeddedSubProcess.addInAssociation(new DataAssociation(Collections.emptyList(), "", Arrays.asList(inputAssignment), null));
// handle state data outputs
Assignment outputAssignment = new Assignment("jq", "", "");
outputAssignment.setMetaData("Action", new OutputJqAssignmentAction(state.getStateDataFilter() == null ? null : factory.unwrapExpression(state.getStateDataFilter().getOutput())));
embeddedSubProcess.addOutAssociation(new DataAssociation(Collections.emptyList(), "", Arrays.asList(outputAssignment), null));
mappedNodes.put(state.getName(), embeddedSubProcess.getId());
StartNode embeddedStartNode = factory.startNode(ids.getAndIncrement(), "EmbeddedStart", embeddedSubProcess);
EndNode embeddedEndNode = factory.endNode(ids.getAndIncrement(), "EmbeddedEnd", false, embeddedSubProcess);
EventDefinition event = WorkflowUtils.getDefinedConsumedEvents(workflow).stream().filter(e -> e.getName().equals(callcackState.getEventRef())).findFirst().get();
EventNode eventNode = factory.consumeEventNode(ids.getAndIncrement(), event, callcackState.getEventDataFilter(), embeddedSubProcess);
buildActionsForState(workflow, Collections.singletonList(callcackState.getAction()), embeddedSubProcess, factory, ids, (first, last) -> {
factory.connect(embeddedStartNode.getId(), first.getId(), embeddedStartNode.getId() + "_" + first.getId(), embeddedSubProcess, false);
factory.connect(last.getId(), eventNode.getId(), last.getId() + "_" + eventNode.getId(), embeddedSubProcess, false);
}, (first, last) -> {
}, false);
factory.connect(eventNode.getId(), embeddedEndNode.getId(), "connection_" + eventNode.getId() + "_" + embeddedEndNode.getId(), embeddedSubProcess, false);
if (state.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), state.getName() + "-end", state.getEnd().isTerminate(), process);
if (state.getEnd().getProduceEvents() != null && !state.getEnd().getProduceEvents().isEmpty()) {
produceEvents(state.getEnd().getProduceEvents(), factory, workflow, ids, process, embeddedSubProcess.getId(), endNode.getId());
} else {
factory.connect(embeddedSubProcess.getId(), endNode.getId(), "connection_" + embeddedSubProcess.getId() + "_" + endNode.getId(), process, false);
}
}
} else if (state.getType().equals(Type.SLEEP)) {
TimerNode sleep = factory.timerNode(ids.getAndIncrement(), "sleep-" + state.getName(), ((SleepState) state).getDuration(), process);
mappedNodes.put(state.getName(), sleep.getId());
setUniqueId(sleep, state);
if (state.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), state.getName() + "-end", state.getEnd().isTerminate(), process);
if (state.getEnd().getProduceEvents() != null && !state.getEnd().getProduceEvents().isEmpty()) {
produceEvents(state.getEnd().getProduceEvents(), factory, workflow, ids, process, sleep.getId(), endNode.getId());
} else {
factory.connect(sleep.getId(), endNode.getId(), "connection_" + sleep.getId() + "_" + endNode.getId(), process, false);
}
}
currentNode = sleep;
} else if (state.getType().equals(DefaultState.Type.PARALLEL)) {
ParallelState parallelState = (ParallelState) state;
CompositeContextNode embeddedSubProcess = factory.subProcessNode(ids.getAndIncrement(), state.getName(), process);
setUniqueId(embeddedSubProcess, state);
currentNode = embeddedSubProcess;
// handle state data inputs
Assignment inputAssignment = new Assignment("jq", "", "");
inputAssignment.setMetaData("Action", new InputJqAssignmentAction(state.getStateDataFilter() == null ? null : factory.unwrapExpression(state.getStateDataFilter().getInput())));
embeddedSubProcess.addInAssociation(new DataAssociation(Collections.emptyList(), "", Arrays.asList(inputAssignment), null));
// handle state data outputs
Assignment outputAssignment = new Assignment("jq", "", "");
outputAssignment.setMetaData("Action", new OutputJqAssignmentAction(state.getStateDataFilter() == null ? null : factory.unwrapExpression(state.getStateDataFilter().getOutput())));
embeddedSubProcess.addOutAssociation(new DataAssociation(Collections.emptyList(), "", Arrays.asList(outputAssignment), null));
mappedNodes.put(state.getName(), embeddedSubProcess.getId());
StartNode embeddedStartNode = factory.startNode(ids.getAndIncrement(), "EmbeddedStart", embeddedSubProcess);
EndNode embeddedEndNode = factory.endNode(ids.getAndIncrement(), "EmbeddedEnd", false, embeddedSubProcess);
Split parallelSplit = factory.splitNode(ids.getAndIncrement(), "split_" + state.getName(), Split.TYPE_AND, embeddedSubProcess);
Join parallelJoin;
if (parallelState.getCompletionType().equals(CompletionType.AT_LEAST)) {
parallelJoin = factory.joinNode(ids.getAndIncrement(), "join_" + state.getName(), Join.TYPE_N_OF_M, embeddedSubProcess);
parallelJoin.setN(parallelState.getNumCompleted());
} else {
parallelJoin = factory.joinNode(ids.getAndIncrement(), "join_" + state.getName(), Join.TYPE_AND, embeddedSubProcess);
}
factory.connect(embeddedStartNode.getId(), parallelSplit.getId(), "connection_" + embeddedStartNode.getId() + "_" + parallelSplit.getId(), embeddedSubProcess, false);
for (Branch branch : parallelState.getBranches()) {
buildActionsForState(workflow, branch.getActions(), embeddedSubProcess, factory, ids, (first, last) -> {
factory.connect(parallelSplit.getId(), first.getId(), parallelSplit.getId() + "_" + first.getId(), embeddedSubProcess, false);
factory.connect(last.getId(), parallelJoin.getId(), last.getId() + "_" + parallelJoin.getId(), embeddedSubProcess, false);
}, (first, last) -> {
}, true);
}
factory.connect(parallelJoin.getId(), embeddedEndNode.getId(), "connection_" + parallelJoin.getId() + "_" + embeddedEndNode.getId(), embeddedSubProcess, false);
if (state.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), state.getName() + "-end", state.getEnd().isTerminate(), process);
if (state.getEnd().getProduceEvents() != null && !state.getEnd().getProduceEvents().isEmpty()) {
produceEvents(state.getEnd().getProduceEvents(), factory, workflow, ids, process, embeddedSubProcess.getId(), endNode.getId());
} else {
factory.connect(embeddedSubProcess.getId(), endNode.getId(), "connection_" + embeddedSubProcess.getId() + "_" + endNode.getId(), process, false);
}
}
} else if (state.getType().equals(DefaultState.Type.FOREACH)) {
}
// ensure that start node is connected
if (state.equals(start) && currentNode != null) {
factory.connect(startNode.getId(), currentNode.getId(), "connection_" + startNode.getId() + "_" + currentNode.getId(), process, false);
}
}
for (State state : workflow.getStates()) {
if (state.getType().equals(Type.SWITCH)) {
// switch state must be processed at the end as it needs to reference other nodes by id
SwitchState switchState = (SwitchState) state;
if (switchState.getDataConditions() != null && !switchState.getDataConditions().isEmpty()) {
Split splitNode = factory.splitNode(ids.getAndIncrement(), "split_" + state.getName(), Split.TYPE_XOR, process);
currentNode = splitNode;
setUniqueId(splitNode, state);
mappedNodes.put(state.getName(), splitNode.getId());
int priority = 1;
for (DataCondition condition : switchState.getDataConditions()) {
boolean isDefaultConstraint = false;
if (switchState.getDefaultCondition() != null && switchState.getDefaultCondition().getTransition() != null && condition.getTransition() != null && condition.getTransition().getNextState().equals(switchState.getDefaultCondition().getTransition().getNextState())) {
isDefaultConstraint = true;
}
if (switchState.getDefaultCondition() != null && switchState.getDefaultCondition().getEnd() != null && condition.getEnd() != null) {
isDefaultConstraint = true;
}
Connection outgoingConnection = null;
long target = 0;
if (condition.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), "end_" + switchState.getName(), false, process);
target = endNode.getId();
outgoingConnection = factory.connect(splitNode.getId(), endNode.getId(), "connection_" + splitNode.getId() + "_" + endNode.getId(), process, false);
} else if (condition.getTransition() != null && condition.getTransition().getNextState() != null) {
long source = splitNode.getId();
target = mappedNodes.get(condition.getTransition().getNextState());
outgoingConnection = factory.connect(source, target, "connection_" + source + "_" + target, process, false);
}
ReturnValueConstraintEvaluator returnValueConstraint = new ReturnValueConstraintEvaluator();
returnValueConstraint.setDialect("jq");
returnValueConstraint.setName(splitNode.getId() + "_" + target);
returnValueConstraint.setPriority(priority);
returnValueConstraint.setDefault(isDefaultConstraint);
returnValueConstraint.setType("DROOLS_DEFAULT");
returnValueConstraint.setConstraint(factory.unwrapExpression(condition.getCondition()));
returnValueConstraint.setEvaluator(new JqReturnValueEvaluator(factory.unwrapExpression(condition.getCondition())));
splitNode.setConstraint(outgoingConnection, returnValueConstraint);
}
} else if (switchState.getEventConditions() != null && !switchState.getEventConditions().isEmpty()) {
Split splitNode = factory.eventBasedSplit(ids.getAndIncrement(), "split_" + state.getName(), process);
currentNode = splitNode;
setUniqueId(splitNode, state);
mappedNodes.put(state.getName(), splitNode.getId());
for (EventCondition eventCondition : switchState.getEventConditions()) {
EventDefinition event = WorkflowUtils.getDefinedConsumedEvents(workflow).stream().filter(e -> e.getName().equals(eventCondition.getEventRef())).findFirst().get();
EventNode eventNode = factory.consumeEventNode(ids.getAndIncrement(), event, eventCondition.getEventDataFilter(), process);
factory.connect(splitNode.getId(), eventNode.getId(), "connection_" + splitNode.getId() + "_" + eventNode.getId(), process, false);
long target = 0;
if (eventCondition.getEnd() != null) {
EndNode endNode = factory.endNode(ids.getAndIncrement(), "end_" + switchState.getName(), false, process);
target = endNode.getId();
factory.connect(splitNode.getId(), endNode.getId(), "connection_" + splitNode.getId() + "_" + endNode.getId(), process, false);
} else if (eventCondition.getTransition() != null && eventCondition.getTransition().getNextState() != null) {
target = mappedNodes.get(eventCondition.getTransition().getNextState());
factory.connect(eventNode.getId(), target, "connection_" + eventNode.getId() + "_" + target, process, false);
}
}
if (switchState.getTimeouts() != null && switchState.getTimeouts().getEventTimeout() != null) {
TimerNode timer = factory.timerNode(ids.getAndIncrement(), "event-switch-timeout", switchState.getTimeouts().getEventTimeout(), process);
factory.connect(splitNode.getId(), timer.getId(), "connection_" + splitNode.getId() + "_" + timer.getId(), process, false);
EndNode endNode = factory.endNode(ids.getAndIncrement(), "end_" + switchState.getName(), false, process);
factory.connect(timer.getId(), endNode.getId(), "connection_" + timer.getId() + "_" + endNode.getId(), process, false);
}
}
// ensure that start node is connected
if (state.equals(start) && currentNode != null) {
factory.connect(startNode.getId(), currentNode.getId(), "connection_" + startNode.getId() + "_" + currentNode.getId(), process, false);
}
}
}
// next connect all nodes
for (State state : workflow.getStates()) {
if (!mappedNodes.containsKey(state.getName())) {
continue;
}
long source = mappedNodes.get(state.getName());
if (state.getTransition() != null && state.getTransition().getNextState() != null) {
long target = mappedNodes.get(state.getTransition().getNextState());
if (state.getTransition().getProduceEvents() != null && !state.getTransition().getProduceEvents().isEmpty()) {
produceEvents(state.getTransition().getProduceEvents(), factory, workflow, ids, process, source, target);
} else {
factory.connect(source, target, "connection_" + source + "_" + target, process, false);
}
}
}
// attach error handling
for (State state : workflow.getStates()) {
if (!mappedNodes.containsKey(state.getName())) {
continue;
}
long source = mappedNodes.get(state.getName());
if (process.getNode(source) instanceof CompositeContextNode) {
addErrorHandlingToState(workflow, state, factory, ids, process, (CompositeContextNode) process.getNode(source));
}
}
factory.validate((ExecutableProcess) process);
if (workflow.getTimeouts() != null && workflow.getTimeouts().getWorkflowExecTimeout() != null) {
factory.addExecutionTimeout(ids.getAndIncrement(), workflow.getTimeouts().getWorkflowExecTimeout(), (ExecutableProcess) process);
}
process.setMetaData("SW-Workflow", workflow);
return process;
}
use of io.automatiko.engine.workflow.process.core.node.StartNode in project automatiko-engine by automatiko-io.
the class ServiceTaskDescriptor method collectHandledErrorCodes.
private Set<String> collectHandledErrorCodes() {
Set<String> errorCodes = new HashSet<>();
NodeContainer container = workItemNode.getParentContainer();
String thisNodeId = (String) workItemNode.getMetaData("UniqueId");
for (Node node : container.getNodes()) {
if (node instanceof BoundaryEventNode) {
String errorCode = (String) node.getMetaData().get("ErrorEvent");
if (errorCode != null && ((BoundaryEventNode) node).getAttachedToNodeId().equals(thisNodeId)) {
errorCodes.add(errorCode);
}
}
}
// next collect event subprocess node with error start event from this level and to all parents
String replaceRegExp = "Error-|Escalation-";
for (Node node : container.getNodes()) {
if (node instanceof EventSubProcessNode) {
EventSubProcessNode eventSubProcessNode = (EventSubProcessNode) node;
Node[] nodes = eventSubProcessNode.getNodes();
for (Node subNode : nodes) {
// avoids cyclomatic complexity
if (subNode == null || !(subNode instanceof StartNode)) {
continue;
}
List<Trigger> triggers = ((StartNode) subNode).getTriggers();
if (triggers == null) {
continue;
}
for (Trigger trigger : triggers) {
if (trigger instanceof EventTrigger) {
final List<EventFilter> filters = ((EventTrigger) trigger).getEventFilters();
for (EventFilter filter : filters) {
if (filter instanceof EventTypeFilter) {
eventSubProcessNode.addEvent((EventTypeFilter) filter);
String type = ((EventTypeFilter) filter).getType();
if (type.startsWith("Error-")) {
String trimmedType = type.replaceFirst(replaceRegExp, "");
for (String error : trimmedType.split(",")) {
errorCodes.add(error);
}
}
}
}
}
}
}
}
}
return errorCodes;
}
Aggregations