use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class CallActivityHandler method writeNode.
public void writeNode(Node node, StringBuilder xmlDump, int metaDataType) {
SubProcessNode subProcessNode = (SubProcessNode) node;
writeNode("callActivity", subProcessNode, xmlDump, metaDataType);
if (subProcessNode.getProcessId() != null) {
xmlDump.append("calledElement=\"" + XmlBPMNProcessDumper.replaceIllegalCharsAttribute(subProcessNode.getProcessId()) + "\" ");
}
if (!subProcessNode.isWaitForCompletion()) {
xmlDump.append("tns:waitForCompletion=\"false\" ");
}
if (!subProcessNode.isIndependent()) {
xmlDump.append("tns:independent=\"false\" ");
}
xmlDump.append(">" + EOL);
writeExtensionElements(subProcessNode, xmlDump);
writeIO(subProcessNode, xmlDump);
endNode("callActivity", xmlDump);
}
use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class ServerlessWorkflowParser method buildActionsForState.
protected void buildActionsForState(Workflow workflow, List<Action> actions, NodeContainer embeddedSubProcess, ServerlessWorkflowFactory factory, AtomicLong ids, BiConsumer<Node, Node> firstLastNodeConsumer, BiConsumer<Node, Node> actionConsumer, boolean isParallel) {
Node firstNode = null;
Node lastNode = null;
Node prevNode = null;
for (Action action : actions) {
if (action.getFunctionRef() != null) {
// handle function based action
Optional<FunctionDefinition> functionDefinition = workflow.getFunctions().getFunctionDefs().stream().filter(functionDef -> functionDef.getName().equals(action.getFunctionRef().getRefName())).distinct().findFirst();
if (functionDefinition.get().getType() == FunctionDefinition.Type.EXPRESSION) {
ActionNode actionNode = factory.expressionActionStateNode(ids.getAndIncrement(), action.getName(), embeddedSubProcess, functionDefinition.get().getOperation(), action);
if (firstNode == null) {
firstNode = actionNode;
}
lastNode = actionNode;
} else if (functionDefinition.get().getType() == null || functionDefinition.get().getType() == FunctionDefinition.Type.REST) {
WorkItemNode serviceNode = factory.serviceNode(ids.getAndIncrement(), action, functionDefinition.get(), embeddedSubProcess);
if (firstNode == null) {
firstNode = serviceNode;
}
lastNode = serviceNode;
if (workflow.getTimeouts() != null && workflow.getTimeouts().getActionExecTimeout() != null) {
serviceNode.setMetaData("timeout", String.valueOf(DateTimeUtils.parseDuration(workflow.getTimeouts().getActionExecTimeout())));
}
if (action.getRetryableErrors() != null && !action.getRetryableErrors().isEmpty()) {
List<ErrorDefinition> defs = new ArrayList<>();
for (String errorRef : action.getRetryableErrors()) {
ErrorDefinition errorDef = workflow.getErrors().getErrorDefs().stream().filter(error -> error.getName().equals(errorRef)).findFirst().orElseThrow(() -> new IllegalStateException("Missing error definition for " + errorRef));
defs.add(errorDef);
}
RetryDefinition retry = null;
BoundaryEventNode errorNode = factory.errorBoundaryEventNode(ids.getAndIncrement(), defs, retry, embeddedSubProcess, serviceNode, workflow);
EndNode onErrorEnd = factory.endNode(ids.getAndIncrement(), action.getName() + "onErrorEnd", false, embeddedSubProcess);
factory.connect(errorNode.getId(), onErrorEnd.getId(), "connect_" + errorNode.getId() + "_" + onErrorEnd.getId(), embeddedSubProcess, false);
}
} else {
throw new UnsupportedOperationException(functionDefinition.get().getType() + " is not yet supported");
}
} else if (action.getSubFlowRef() != null) {
// handler sub workflow action definition
String workflowId = Objects.requireNonNull(action.getSubFlowRef().getWorkflowId(), "Workflow id for subworkflow is mandatory");
boolean independent = false;
if (action.getSubFlowRef().getOnParentComplete() != null && action.getSubFlowRef().getOnParentComplete().equals(OnParentComplete.CONTINUE)) {
independent = true;
}
boolean waitForCompletion = true;
if (action.getSubFlowRef().getInvoke().equals(Invoke.ASYNC)) {
waitForCompletion = false;
}
SubProcessNode callactivity = factory.callActivity(ids.getAndIncrement(), action.getName(), workflowId, waitForCompletion, embeddedSubProcess);
callactivity.setIndependent(independent);
callactivity.setProcessVersion(action.getSubFlowRef().getVersion());
if (firstNode == null) {
firstNode = callactivity;
}
lastNode = callactivity;
}
if (action.getSleep() != null && action.getSleep().getBefore() != null) {
TimerNode sleep = factory.timerNode(ids.getAndIncrement(), "sleep-before-" + action.getName(), action.getSleep().getBefore(), embeddedSubProcess);
factory.connect(sleep.getId(), firstNode.getId(), "connection_" + sleep.getId() + "_" + firstNode.getId(), embeddedSubProcess, false);
firstNode = sleep;
}
if (action.getSleep() != null && action.getSleep().getAfter() != null) {
TimerNode sleep = factory.timerNode(ids.getAndIncrement(), "sleep-after-" + action.getName(), action.getSleep().getAfter(), embeddedSubProcess);
factory.connect(lastNode.getId(), sleep.getId(), "connection_" + lastNode.getId() + "_" + sleep.getId(), embeddedSubProcess, false);
lastNode = sleep;
}
actionConsumer.accept(firstNode, lastNode);
if (isParallel && actions.size() > 1) {
// reset first node as all of action nodes will be first nodes
firstNode = null;
} else {
if (prevNode != null) {
factory.connect(prevNode.getId(), lastNode.getId(), "connect_" + prevNode.getId() + "_" + lastNode.getId(), embeddedSubProcess, false);
}
}
prevNode = lastNode;
}
firstLastNodeConsumer.accept(firstNode, lastNode);
}
use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class ServerlessProcess 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 LambdaSubProcessNodeVisitor method bind.
private BlockStmt bind(VariableScope variableScope, SubProcessNode subProcessNode, ModelMetaData subProcessModel) {
BlockStmt actionBody = new BlockStmt();
actionBody.addStatement(subProcessModel.newInstance("model"));
for (Map.Entry<String, String> e : subProcessNode.getInMappings().entrySet()) {
// check if given mapping is an expression
Matcher matcher = PatternConstants.PARAMETER_MATCHER.matcher(e.getValue());
if (matcher.find()) {
String expression = matcher.group(1);
String topLevelVariable = expression.split("\\.")[0];
Variable v = variableScope.findVariable(topLevelVariable);
if (actionBody.findFirst(VariableDeclarationExpr.class, vd -> vd.getVariable(0).getNameAsString().equals(v.getSanitizedName())).isEmpty()) {
actionBody.addStatement(makeAssignment(v));
}
actionBody.addStatement(subProcessModel.callSetter("model", e.getKey(), dotNotationToGetExpression(expression)));
} else {
Variable v = variableScope.findVariable(e.getValue());
if (v != null) {
if (actionBody.findFirst(VariableDeclarationExpr.class, vd -> vd.getVariable(0).getNameAsString().equals(v.getSanitizedName())).isEmpty()) {
actionBody.addStatement(makeAssignment(v));
}
actionBody.addStatement(subProcessModel.callSetter("model", e.getKey(), e.getValue()));
}
}
}
actionBody.addStatement(new ReturnStmt(new NameExpr("model")));
return actionBody;
}
use of io.automatiko.engine.workflow.process.core.node.SubProcessNode in project automatiko-engine by automatiko-io.
the class LambdaSubProcessNodeVisitor method visitNode.
@Override
public void visitNode(WorkflowProcess process, String factoryField, SubProcessNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
InputStream resourceAsStream = this.getClass().getResourceAsStream("/class-templates/SubProcessFactoryTemplate.java");
Optional<Expression> retValue = parse(resourceAsStream).findFirst(Expression.class);
String name = node.getName();
String subProcessId = node.getProcessId();
String subProcessVersion = ModelMetaData.version(node.getProcessVersion());
NodeValidator.of(getNodeKey(), name).notEmpty("subProcessId", subProcessId).validate();
body.addStatement(getAssignedFactoryMethod(factoryField, SubProcessNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId()))).addStatement(getNameMethod(node, "Call Activity")).addStatement(getFactoryMethod(getNodeId(node), METHOD_PROCESS_ID, new StringLiteralExpr(subProcessId))).addStatement(getFactoryMethod(getNodeId(node), METHOD_PROCESS_NAME, new StringLiteralExpr(getOrDefault(node.getProcessName(), "")))).addStatement(getFactoryMethod(getNodeId(node), METHOD_PROCESS_VERSION, new StringLiteralExpr(getOrDefault(node.getProcessVersion(), "")))).addStatement(getFactoryMethod(getNodeId(node), METHOD_WAIT_FOR_COMPLETION, new BooleanLiteralExpr(node.isWaitForCompletion()))).addStatement(getFactoryMethod(getNodeId(node), METHOD_INDEPENDENT, new BooleanLiteralExpr(node.isIndependent())));
Map<String, String> inputTypes = (Map<String, String>) node.getMetaData("BPMN.InputTypes");
String subProcessModelClassName = ProcessToExecModelGenerator.extractModelClassName(subProcessId, subProcessVersion);
ModelMetaData subProcessModel = new ModelMetaData(process.getType(), subProcessId, subProcessVersion, metadata.getPackageName(), subProcessModelClassName, WorkflowProcess.PRIVATE_VISIBILITY, VariableDeclarations.ofRawInfo(inputTypes), false, "Data model for " + name, "A complete data model for " + name);
retValue.ifPresent(retValueExpression -> {
retValueExpression.findAll(ClassOrInterfaceType.class).stream().filter(t -> t.getNameAsString().equals("$Type$")).forEach(t -> t.setName(subProcessModelClassName));
retValueExpression.findFirst(MethodDeclaration.class, m -> m.getNameAsString().equals("bind")).ifPresent(m -> m.setBody(bind(variableScope, node, subProcessModel)));
retValueExpression.findFirst(MethodDeclaration.class, m -> m.getNameAsString().equals("createInstance")).ifPresent(m -> m.setBody(createInstance(node, metadata)));
retValueExpression.findFirst(MethodDeclaration.class, m -> m.getNameAsString().equals("unbind")).ifPresent(m -> m.setBody(unbind(variableScope, node)));
retValueExpression.findFirst(MethodDeclaration.class, m -> m.getNameAsString().equals("abortInstance")).ifPresent(m -> m.setBody(abortInstance(node, metadata)));
});
if (retValue.isPresent()) {
body.addStatement(getFactoryMethod(getNodeId(node), getNodeKey(), retValue.get()));
} else {
body.addStatement(getFactoryMethod(getNodeId(node), getNodeKey()));
}
visitMetaData(node.getMetaData(), body, getNodeId(node));
body.addStatement(getDoneMethod(getNodeId(node)));
}
Aggregations