This is an automated email from the ASF dual-hosted git repository.
fjtiradosarti pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git
The following commit(s) were added to refs/heads/main by this push:
new 8e67de3c0a Adding bifunction and trifunction support to fluent api
(#3853)
8e67de3c0a is described below
commit 8e67de3c0a93054e5b006f3d7ab7ceedf3f42dab
Author: Francisco Javier Tirado Sarti
<[email protected]>
AuthorDate: Thu Feb 27 13:56:22 2025 +0100
Adding bifunction and trifunction support to fluent api (#3853)
---
.../org/jbpm/workflow/core/impl/NodeIoHelper.java | 3 +-
.../instance/node/WorkItemNodeInstance.java | 3 +-
.../process/workitems/impl/KogitoWorkItemImpl.java | 4 +-
.../workflow/functions/FunctionDefinitionEx.java | 29 ++++++++++--
...{FunctionDefinitionEx.java => TriFunction.java} | 26 ++---------
.../executor/StaticFunctionWorkItemHandler.java | 51 +++++++++++++++++-----
.../workflow/executor/StaticJavaRegister.java | 2 +-
.../StaticFluentWorkflowApplicationTest.java | 28 ++++++++++++
.../serverless/workflow/fluent/ActionBuilder.java | 12 +++++
.../workflow/fluent/FunctionBuilder.java | 12 ++++-
.../workflow/WorkflowWorkItemHandler.java | 4 +-
11 files changed, 130 insertions(+), 44 deletions(-)
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeIoHelper.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeIoHelper.java
index 5eaa8f0d98..0465f2658f 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeIoHelper.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeIoHelper.java
@@ -21,6 +21,7 @@ package org.jbpm.workflow.core.impl;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@@ -145,7 +146,7 @@ public class NodeIoHelper {
Function<String, Object> targetResolver) {
NodeIoHelper ioHelper = new NodeIoHelper(nodeInstanceImpl);
- Map<String, Object> inputSet = new HashMap<>();
+ Map<String, Object> inputSet = new LinkedHashMap<>();
// for inputs resolve it is supposed to create object by default
constructor (that is the reason is null
ioHelper.processInputs(dataInputAssociation, sourceResolver,
targetResolver, (target, value) -> inputSet.put(target, value));
return inputSet;
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java
index be1ff4ddfa..e16e47b64d 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java
@@ -24,6 +24,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -231,7 +232,7 @@ public class WorkItemNodeInstance extends
StateBasedNodeInstance implements Even
workItem.setStartDate(new Date());
workItem.setState(ACTIVE);
- Map<String, Object> resolvedParameters = new HashMap<>();
+ Map<String, Object> resolvedParameters = new LinkedHashMap<>();
Collection<String> metaParameters = work.getMetaParameters();
diff --git
a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImpl.java
b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImpl.java
index af06146384..5177ad7bdc 100755
---
a/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImpl.java
+++
b/jbpm/process-workitems/src/main/java/org/kie/kogito/process/workitems/impl/KogitoWorkItemImpl.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -39,7 +40,7 @@ public class KogitoWorkItemImpl implements
InternalKogitoWorkItem, Serializable
private String id;
private String name;
private int state = 0;
- private Map<String, Object> parameters = new ProxyMap(new HashMap<>());
+ private Map<String, Object> parameters = new ProxyMap(new
LinkedHashMap<>());
private Map<String, Object> results = new HashMap<>();
private String processInstanceId;
private String deploymentId;
@@ -325,7 +326,6 @@ public class KogitoWorkItemImpl implements
InternalKogitoWorkItem, Serializable
@Override
public void putAll(Map<? extends String, ? extends Object> m) {
map.putAll(m);
-
}
@Override
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/FunctionDefinitionEx.java
b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/FunctionDefinitionEx.java
index e06fa51af7..27481e204c 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/FunctionDefinitionEx.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/FunctionDefinitionEx.java
@@ -18,25 +18,46 @@
*/
package org.kie.kogito.serverless.workflow.functions;
+import java.util.function.BiFunction;
import java.util.function.Function;
import io.serverlessworkflow.api.functions.FunctionDefinition;
-public class FunctionDefinitionEx<T, V> extends FunctionDefinition {
+public class FunctionDefinitionEx extends FunctionDefinition {
private static final long serialVersionUID = 1L;
- private transient Function<T, V> function;
+ private transient Function function;
+ private transient BiFunction bifunction;
+ private transient TriFunction trifunction;
public FunctionDefinitionEx(String name) {
super(name);
}
- public FunctionDefinition withFunction(Function<T, V> function) {
+ public FunctionDefinition withFunction(Function function) {
this.function = function;
return this;
}
- public Function<T, V> getFunction() {
+ public FunctionDefinition withBiFunction(BiFunction function) {
+ this.bifunction = function;
+ return this;
+ }
+
+ public FunctionDefinition withTriFunction(TriFunction function) {
+ this.trifunction = function;
+ return this;
+ }
+
+ public Function getFunction() {
return function;
}
+
+ public BiFunction getBiFunction() {
+ return bifunction;
+ }
+
+ public TriFunction getTriFunction() {
+ return trifunction;
+ }
}
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/FunctionDefinitionEx.java
b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/TriFunction.java
similarity index 60%
copy from
kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/FunctionDefinitionEx.java
copy to
kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/TriFunction.java
index e06fa51af7..4627750caf 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/FunctionDefinitionEx.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/functions/TriFunction.java
@@ -18,25 +18,7 @@
*/
package org.kie.kogito.serverless.workflow.functions;
-import java.util.function.Function;
-
-import io.serverlessworkflow.api.functions.FunctionDefinition;
-
-public class FunctionDefinitionEx<T, V> extends FunctionDefinition {
-
- private static final long serialVersionUID = 1L;
- private transient Function<T, V> function;
-
- public FunctionDefinitionEx(String name) {
- super(name);
- }
-
- public FunctionDefinition withFunction(Function<T, V> function) {
- this.function = function;
- return this;
- }
-
- public Function<T, V> getFunction() {
- return function;
- }
-}
+@FunctionalInterface
+public interface TriFunction<T, U, V, R> {
+ R apply(T arg1, U arg2, V arg3);
+}
\ No newline at end of file
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticFunctionWorkItemHandler.java
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticFunctionWorkItemHandler.java
index acaa404100..39bb94bb02 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticFunctionWorkItemHandler.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticFunctionWorkItemHandler.java
@@ -18,42 +18,73 @@
*/
package org.kie.kogito.serverless.workflow.executor;
+import java.util.Iterator;
import java.util.Map;
+import java.util.function.BiFunction;
import java.util.function.Function;
import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
import org.kie.kogito.jackson.utils.JsonObjectUtils;
import org.kie.kogito.serverless.workflow.SWFConstants;
import org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler;
+import org.kie.kogito.serverless.workflow.functions.FunctionDefinitionEx;
+import org.kie.kogito.serverless.workflow.functions.TriFunction;
import com.fasterxml.jackson.databind.JsonNode;
import static org.kie.kogito.serverless.workflow.SWFConstants.CONTENT_DATA;
-public class StaticFunctionWorkItemHandler<V, T> extends
WorkflowWorkItemHandler {
+public class StaticFunctionWorkItemHandler extends WorkflowWorkItemHandler {
- private final String name;
- private final Function<V, T> function;
+ private final FunctionDefinitionEx functionDef;
- public StaticFunctionWorkItemHandler(String name, Function<V, T> function)
{
- this.name = name;
- this.function = function;
+ public StaticFunctionWorkItemHandler(FunctionDefinitionEx functionDef) {
+ this.functionDef = functionDef;
}
@Override
public String getName() {
- return name;
+ return functionDef.getName();
}
@Override
protected Object internalExecute(KogitoWorkItem workItem, Map<String,
Object> parameters) {
+ if (functionDef.getFunction() != null) {
+ return internalExecute(functionDef.getFunction(), workItem,
parameters);
+ } else if (functionDef.getBiFunction() != null) {
+ return internalExecute(functionDef.getBiFunction(), parameters);
+ } else if (functionDef.getTriFunction() != null) {
+ return internalExecute(functionDef.getTriFunction(), parameters);
+ }
+ throw new IllegalStateException("No function set");
+ }
+
+ private Object internalExecute(TriFunction triFunction, Map<String,
Object> parameters) {
+ checkParamsSize(parameters, 3);
+ Iterator<Object> iter = parameters.values().iterator();
+ return triFunction.apply(iter.next(), iter.next(), iter.next());
+ }
+
+ private Object internalExecute(BiFunction biFunction, Map<String, Object>
parameters) {
+ checkParamsSize(parameters, 2);
+ Iterator<Object> iter = parameters.values().iterator();
+ return biFunction.apply(iter.next(), iter.next());
+ }
+
+ private void checkParamsSize(Map<String, Object> parameters, int size) {
+ if (parameters.size() != size) {
+ throw new IllegalArgumentException("Wrong number of arguments. The
function expects " + size);
+ }
+ }
+
+ private Object internalExecute(Function function, KogitoWorkItem workItem,
Map<String, Object> parameters) {
int size = parameters.size();
if (size == 0) {
- return function.apply((V) JsonObjectUtils.toJavaValue((JsonNode)
workItem.getParameter(SWFConstants.MODEL_WORKFLOW_VAR)));
+ return function.apply(JsonObjectUtils.toJavaValue((JsonNode)
workItem.getParameter(SWFConstants.MODEL_WORKFLOW_VAR)));
} else if (size == 1 && parameters.containsKey(CONTENT_DATA)) {
- return function.apply((V) parameters.get(CONTENT_DATA));
+ return function.apply(parameters.get(CONTENT_DATA));
} else {
- return function.apply((V) parameters);
+ return function.apply(parameters);
}
}
}
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticJavaRegister.java
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticJavaRegister.java
index 17bea35b1b..36d3f71a0e 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticJavaRegister.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/main/java/org/kie/kogito/serverless/workflow/executor/StaticJavaRegister.java
@@ -28,7 +28,7 @@ public class StaticJavaRegister implements
StaticWorkflowRegister {
public void register(StaticWorkflowApplication application, Workflow
workflow) {
if (workflow.getFunctions() != null &&
workflow.getFunctions().getFunctionDefs() != null) {
workflow.getFunctions().getFunctionDefs().stream().filter(FunctionDefinitionEx.class::isInstance).map(FunctionDefinitionEx.class::cast)
- .forEach(function -> application.registerHandler(new
StaticFunctionWorkItemHandler<>(function.getName(), function.getFunction())));
+ .forEach(function -> application.registerHandler(new
StaticFunctionWorkItemHandler(function)));
}
}
}
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticFluentWorkflowApplicationTest.java
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticFluentWorkflowApplicationTest.java
index dfc9d750d3..bd3255d6ae 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticFluentWorkflowApplicationTest.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-executor-core/src/test/java/org/kie/kogito/serverless/workflow/executor/StaticFluentWorkflowApplicationTest.java
@@ -194,6 +194,10 @@ public class StaticFluentWorkflowApplicationTest {
return one * two;
}
+ private double quadratic(int one, int two, int three) {
+ return Math.sqrt(one * one + two * two - three * three);
+ }
+
@Test
void testJava() {
final String DOUBLE = "double";
@@ -211,6 +215,30 @@ public class StaticFluentWorkflowApplicationTest {
}
}
+ @Test
+ void testJavaTwoParams() {
+ try (StaticWorkflowApplication application =
StaticWorkflowApplication.create()) {
+ Workflow workflow = workflow("Javatest")
+ .start(operation().action(call(java("multiply",
this::multiply), ".input1", ".input2")))
+ .end().build();
+ Process<JsonNodeModel> process = application.process(workflow);
+ JsonNode result = application.execute(process, Map.of("input1", 4,
"input2", 8)).getWorkflowdata();
+ assertThat(result.get("response").asInt()).isEqualTo(32);
+ }
+ }
+
+ @Test
+ void testJavaThreeParams() {
+ try (StaticWorkflowApplication application =
StaticWorkflowApplication.create()) {
+ Workflow workflow = workflow("Javatest")
+ .start(operation().action(call(java("quadratic",
this::quadratic), ".input1", ".input2", ".input3")))
+ .end().build();
+ Process<JsonNodeModel> process = application.process(workflow);
+ JsonNode result = application.execute(process, Map.of("input1", 3,
"input2", 4, "input3", 5)).getWorkflowdata();
+ assertThat(result.get("response").asInt()).isEqualTo(0);
+ }
+ }
+
@Test
void testInterpolation() {
interpolation("\"My name is \\(.name) and my surname is
\\(.surname)\"");
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/ActionBuilder.java
b/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/ActionBuilder.java
index 26be06f4f7..90a69f04f4 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/ActionBuilder.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/ActionBuilder.java
@@ -22,6 +22,7 @@ import java.time.Duration;
import java.util.Optional;
import org.kie.kogito.jackson.utils.JsonObjectUtils;
+import org.kie.kogito.jackson.utils.ObjectMapperFactory;
import org.kie.kogito.process.Process;
import org.kie.kogito.serverless.workflow.SWFConstants;
import org.kie.kogito.serverless.workflow.actions.WorkflowLogLevel;
@@ -98,6 +99,17 @@ public class ActionBuilder {
return call(functionBuilder, JsonObjectUtils.fromValue(args));
}
+ public static ActionBuilder call(FunctionBuilder functionBuilder, Object
first, Object second, Object... extras) {
+ ObjectNode node = ObjectMapperFactory.get().createObjectNode();
+ node.set("arg1", JsonObjectUtils.fromValue(first));
+ node.set("arg2", JsonObjectUtils.fromValue(second));
+ int i = 3;
+ for (Object extra : extras) {
+ node.set("arg" + i++, JsonObjectUtils.fromValue(extra));
+ }
+ return call(functionBuilder, node);
+ }
+
public static ActionBuilder call(String functionName, JsonNode args) {
return new ActionBuilder(new Action().withFunctionRef(new
FunctionRef().withRefName(functionName).withArguments(args)));
}
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/FunctionBuilder.java
b/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/FunctionBuilder.java
index 1abe1d2fca..5cebe9c905 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/FunctionBuilder.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/FunctionBuilder.java
@@ -21,11 +21,13 @@ package org.kie.kogito.serverless.workflow.fluent;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import java.util.function.BiFunction;
import java.util.function.Function;
import org.kie.kogito.serverless.workflow.SWFConstants;
import org.kie.kogito.serverless.workflow.actions.WorkflowLogLevel;
import org.kie.kogito.serverless.workflow.functions.FunctionDefinitionEx;
+import org.kie.kogito.serverless.workflow.functions.TriFunction;
import org.kie.kogito.serverless.workflow.parser.types.ServiceTypeHandler;
import io.serverlessworkflow.api.functions.FunctionDefinition;
@@ -64,7 +66,15 @@ public class FunctionBuilder {
}
public static <T, V> FunctionBuilder java(String funcName, Function<T, V>
function) {
- return new FunctionBuilder(new FunctionDefinitionEx<T,
V>(funcName).withFunction(function).withType(Type.CUSTOM).withOperation("java"));
+ return new FunctionBuilder(new
FunctionDefinitionEx(funcName).withFunction(function).withType(Type.CUSTOM).withOperation("java"));
+ }
+
+ public static <T, U, R> FunctionBuilder java(String funcName,
BiFunction<T, U, R> function) {
+ return new FunctionBuilder(new
FunctionDefinitionEx(funcName).withBiFunction(function).withType(Type.CUSTOM).withOperation("java"));
+ }
+
+ public static <T, U, V, R> FunctionBuilder java(String funcName,
TriFunction<T, U, V, R> function) {
+ return new FunctionBuilder(new
FunctionDefinitionEx(funcName).withTriFunction(function).withType(Type.CUSTOM).withOperation("java"));
}
public static FunctionBuilder java(String funcName, String className,
String methodName) {
diff --git
a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/WorkflowWorkItemHandler.java
b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/WorkflowWorkItemHandler.java
index 289f319895..b397eb7e53 100644
---
a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/WorkflowWorkItemHandler.java
+++
b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/WorkflowWorkItemHandler.java
@@ -19,7 +19,7 @@
package org.kie.kogito.serverless.workflow;
import java.util.Collections;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
@@ -38,7 +38,7 @@ public abstract class WorkflowWorkItemHandler extends
DefaultKogitoWorkItemHandl
@Override
public Optional<WorkItemTransition>
activateWorkItemHandler(KogitoWorkItemManager manager, KogitoWorkItemHandler
handler, KogitoWorkItem workItem, WorkItemTransition transition) {
- Map<String, Object> parameters = new
HashMap<>(workItem.getParameters());
+ Map<String, Object> parameters = new
LinkedHashMap<>(workItem.getParameters());
parameters.remove(SWFConstants.MODEL_WORKFLOW_VAR);
logger.debug("Workflow workitem {} will be invoked with parameters
{}", workItem.getName(), parameters);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]