use of io.serverlessworkflow.api.functions.FunctionDefinition in project kogito-runtimes by kiegroup.
the class CompositeContextNodeHandler method getActionNode.
private NodeFactory<?, ?> getActionNode(RuleFlowNodeContainerFactory<?, ?> embeddedSubProcess, FunctionRef functionRef, String inputVar, String outputVar, String collectVar, String... extraVariables) {
JsonNode functionArgs = functionRef.getArguments();
String actionName = functionRef.getRefName();
FunctionDefinition actionFunction = workflow.getFunctions().getFunctionDefs().stream().filter(wf -> wf.getName().equals(actionName)).findFirst().orElseThrow(() -> new IllegalArgumentException("cannot find function " + actionName));
ActionType actionType = ActionType.from(actionFunction);
String operation = actionType.getOperation(actionFunction);
switch(actionType) {
case SCRIPT:
return embeddedSubProcess.actionNode(parserContext.newId()).name(actionName).action(JavaDialect.ID, functionRef.getArguments().get(SCRIPT_TYPE_PARAM).asText());
case EXPRESSION:
return embeddedSubProcess.actionNode(parserContext.newId()).name(actionName).action(ExpressionActionSupplier.of(workflow, operation).withVarNames(inputVar, outputVar).withCollectVar(collectVar).withAddInputVars(extraVariables).build());
case SYSOUT:
return embeddedSubProcess.actionNode(parserContext.newId()).name(actionName).action(new SysoutActionSupplier(workflow.getExpressionLang(), functionRef.getArguments().get(SYSOUT_TYPE_PARAM).asText(), inputVar, extraVariables));
case SERVICE:
WorkItemNodeFactory<?> serviceFactory = addServiceParameters(embeddedSubProcess.workItemNode(parserContext.newId()).name(actionName).metaData(TaskDescriptor.KEY_WORKITEM_TYPE, SERVICE_TASK_TYPE).workName(SERVICE_TASK_TYPE).inMapping(inputVar, WORKITEM_PARAM).outMapping(WORKITEM_PARAM, outputVar), actionFunction, operation);
if (functionArgs == null || functionArgs.isEmpty()) {
serviceFactory.workParameter(WORKITEM_PARAM_TYPE, ServerlessWorkflowParser.JSON_NODE);
} else {
processArgs(serviceFactory, functionArgs, WORKITEM_PARAM, ObjectResolver.class);
}
return serviceFactory;
case REST:
WorkItemNodeFactory<?> workItemFactory = addRestParameters(embeddedSubProcess.workItemNode(parserContext.newId()).name(actionFunction.getName()).metaData(TaskDescriptor.KEY_WORKITEM_TYPE, RestWorkItemHandler.REST_TASK_TYPE).workName(RestWorkItemHandler.REST_TASK_TYPE).workParameter(RestWorkItemHandler.BODY_BUILDER, new RestBodyBuilderSupplier()).inMapping(inputVar, RestWorkItemHandler.CONTENT_DATA).outMapping(RestWorkItemHandler.RESULT, outputVar), actionFunction, operation);
if (functionArgs != null && !functionArgs.isEmpty()) {
processArgs(workItemFactory, functionArgs, RestWorkItemHandler.CONTENT_DATA, ObjectResolver.class);
}
return workItemFactory;
case OPENAPI:
return OpenApiTaskDescriptor.builderFor(ServerlessWorkflowUtils.getOpenApiURI(actionFunction), ServerlessWorkflowUtils.getOpenApiOperationId(actionFunction)).withExprLang(workflow.getExpressionLang()).withModelParameter(WORKITEM_PARAM).withArgs(functionsToMap(functionArgs), JsonNodeResolver.class, JsonNode.class).build(embeddedSubProcess.workItemNode(parserContext.newId())).name(functionRef.getRefName()).inMapping(inputVar, WORKITEM_PARAM).outMapping(WORKITEM_RESULT, outputVar);
default:
return emptyNode(embeddedSubProcess, actionName);
}
}
use of io.serverlessworkflow.api.functions.FunctionDefinition in project kogito-runtimes by kiegroup.
the class BuildExpressionsTest method testReplaceExpr.
@Test
void testReplaceExpr() {
Workflow flow = mock(Workflow.class);
FunctionDefinition functionDefinition = new FunctionDefinition();
functionDefinition.setType(Type.EXPRESSION);
functionDefinition.setOperation(".pepe");
functionDefinition.setName("pepe");
Functions functions = new Functions(Collections.singletonList(functionDefinition));
when(flow.getFunctions()).thenReturn(functions);
assertEquals("\"fn:pepe\"", ExpressionHandlerUtils.replaceExpr(flow, "\"fn:pepe\""));
assertEquals(".pepe", ExpressionHandlerUtils.replaceExpr(flow, "fn:pepe"));
assertEquals(".pepe", ExpressionHandlerUtils.replaceExpr(flow, "${fn:pepe}"));
assertThrows(IllegalArgumentException.class, () -> ExpressionHandlerUtils.replaceExpr(flow, "${fn:NoPepe}"));
}
use of io.serverlessworkflow.api.functions.FunctionDefinition 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.serverlessworkflow.api.functions.FunctionDefinition in project kogito-runtimes by kiegroup.
the class WorkflowUtilsTest method testResolveFunctionMetadata.
@Test
public void testResolveFunctionMetadata() {
FunctionDefinition function = new FunctionDefinition().withName("testfunction1").withMetadata(Collections.singletonMap("testprop1", "customtestprop1val"));
String testProp1Val = ServerlessWorkflowUtils.resolveFunctionMetadata(function, "testprop1", context);
assertThat(testProp1Val).isNotNull().isEqualTo("customtestprop1val");
String testProp2Val = ServerlessWorkflowUtils.resolveFunctionMetadata(function, "testprop2", context);
assertThat(testProp2Val).isNotNull().isEqualTo("testprop2val");
}
Aggregations