diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/Step.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/Step.java index 71a4dc18..6fbaf248 100644 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/Step.java +++ b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/Step.java @@ -47,8 +47,11 @@ protected SELF self() { // --------------------------------------------------------------------------- /** Queue a {@code when(predicate)} to be applied on the concrete builder. */ - public SELF when(Predicate predicate) { - postConfigurers.add(b -> ((ConditionalTaskBuilder) b).when(predicate)); + public SELF when(SerializablePredicate predicate) { + postConfigurers.add( + b -> + ((ConditionalTaskBuilder) b) + .when(predicate, ReflectionUtils.inferInputType(predicate))); return self(); } @@ -115,13 +118,16 @@ public SELF then(FlowDirectiveEnum directive) { * } * * @param the task result type - * @param the export type (what gets forwarded to the next step) + * @param the export type (what gets forwarded to the next step) * @param function the transformation function * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(Function) */ - public SELF exportAs(Function function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function)); + public SELF exportAs(SerializableFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .exportAs(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -132,13 +138,13 @@ public SELF exportAs(Function function) { *

This variant allows you to explicitly specify the input type class for better type safety. * * @param the task result type - * @param the export type (what gets forwarded to the next step) + * @param the export type (what gets forwarded to the next step) * @param function the transformation function * @param taskResultClass the class of the task result type * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(Function, Class) */ - public SELF exportAs(Function function, Class taskResultClass) { + public SELF exportAs(Function function, Class taskResultClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function, taskResultClass)); return self(); } @@ -150,13 +156,16 @@ public SELF exportAs(Function function, Class taskResultClass) { * metadata when shaping the export. * * @param the task result type - * @param the export type (what gets forwarded to the next step) + * @param the export type (what gets forwarded to the next step) * @param function the filter function with workflow and task context * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(JavaFilterFunction) */ - public SELF exportAs(JavaFilterFunction function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function)); + public SELF exportAs(JavaFilterFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .exportAs(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -165,14 +174,14 @@ public SELF exportAs(JavaFilterFunction function) { * with explicit input type. * * @param the task result type - * @param the export type (what gets forwarded to the next step) + * @param the export type (what gets forwarded to the next step) * @param function the filter function with workflow and task context * @param taskResultClass the class of the task result type * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(JavaFilterFunction, * Class) */ - public SELF exportAs(JavaFilterFunction function, Class taskResultClass) { + public SELF exportAs(JavaFilterFunction function, Class taskResultClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function, taskResultClass)); return self(); } @@ -184,14 +193,17 @@ public SELF exportAs(JavaFilterFunction function, Class taskResu * when shaping the export. * * @param the task result type - * @param the export type (what gets forwarded to the next step) + * @param the export type (what gets forwarded to the next step) * @param function the context function with workflow context * @return this step for method chaining * @see * io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(JavaContextFunction) */ - public SELF exportAs(JavaContextFunction function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function)); + public SELF exportAs(JavaContextFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .exportAs(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -200,7 +212,7 @@ public SELF exportAs(JavaContextFunction function) { * explicit input type. * * @param the task result type - * @param the export type (what gets forwarded to the next step) + * @param the export type (what gets forwarded to the next step) * @param function the context function with workflow context * @param taskResultClass the class of the task result type * @return this step for method chaining @@ -208,7 +220,7 @@ public SELF exportAs(JavaContextFunction function) { * io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(JavaContextFunction, * Class) */ - public SELF exportAs(JavaContextFunction function, Class taskResultClass) { + public SELF exportAs(JavaContextFunction function, Class taskResultClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function, taskResultClass)); return self(); } @@ -255,13 +267,16 @@ public SELF exportAs(String jqExpression) { * } * * @param the task result type - * @param the output type (what gets written to workflow data) + * @param the output type (what gets written to workflow data) * @param function the transformation function * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#outputAs(Function) */ - public SELF outputAs(Function function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function)); + public SELF outputAs(SerializableFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .outputAs(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -272,13 +287,13 @@ public SELF outputAs(Function function) { *

This variant allows you to explicitly specify the input type class for better type safety. * * @param the task result type - * @param the output type (what gets written to workflow data) + * @param the output type (what gets written to workflow data) * @param function the transformation function * @param taskResultClass the class of the task result type * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#outputAs(Function, Class) */ - public SELF outputAs(Function function, Class taskResultClass) { + public SELF outputAs(Function function, Class taskResultClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function, taskResultClass)); return self(); } @@ -308,13 +323,16 @@ public SELF outputAs(Function function, Class taskResultClass) { * } * * @param the task result type - * @param the output type (what gets written to workflow data) + * @param the output type (what gets written to workflow data) * @param function the filter function with workflow and task context * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#outputAs(JavaFilterFunction) */ - public SELF outputAs(JavaFilterFunction function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function)); + public SELF outputAs(JavaFilterFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .outputAs(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -323,14 +341,14 @@ public SELF outputAs(JavaFilterFunction function) { * function with explicit input type. * * @param the task result type - * @param the output type (what gets written to workflow data) + * @param the output type (what gets written to workflow data) * @param function the filter function with workflow and task context * @param taskResultClass the class of the task result type * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#outputAs(JavaFilterFunction, * Class) */ - public SELF outputAs(JavaFilterFunction function, Class taskResultClass) { + public SELF outputAs(JavaFilterFunction function, Class taskResultClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function, taskResultClass)); return self(); } @@ -342,13 +360,16 @@ public SELF outputAs(JavaFilterFunction function, Class taskResu * when shaping the committed output. * * @param the task result type - * @param the output type (what gets written to workflow data) + * @param the output type (what gets written to workflow data) * @param function the context function with workflow context * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#outputAs(JavaContextFunction) */ - public SELF outputAs(JavaContextFunction function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function)); + public SELF outputAs(JavaContextFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .outputAs(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -357,14 +378,14 @@ public SELF outputAs(JavaContextFunction function) { * with explicit input type. * * @param the task result type - * @param the output type (what gets written to workflow data) + * @param the output type (what gets written to workflow data) * @param function the context function with workflow context * @param taskResultClass the class of the task result type * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#outputAs(JavaContextFunction, * Class) */ - public SELF outputAs(JavaContextFunction function, Class taskResultClass) { + public SELF outputAs(JavaContextFunction function, Class taskResultClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function, taskResultClass)); return self(); } @@ -410,13 +431,16 @@ public SELF outputAs(String jqExpression) { * } * * @param the input type (workflow data or task input) - * @param the result type (what the task will see as input) + * @param the result type (what the task will see as input) * @param function the transformation function * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#inputFrom(Function) */ - public SELF inputFrom(Function function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function)); + public SELF inputFrom(SerializableFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .inputFrom(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -434,13 +458,13 @@ public SELF inputFrom(Function function) { * } * * @param the input type (workflow data or task input) - * @param the result type (what the task will see as input) + * @param the result type (what the task will see as input) * @param function the transformation function * @param inputClass the class of the input type * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#inputFrom(Function, Class) */ - public SELF inputFrom(Function function, Class inputClass) { + public SELF inputFrom(Function function, Class inputClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function, inputClass)); return self(); } @@ -466,13 +490,16 @@ public SELF inputFrom(Function function, Class inputClass) { * } * * @param the input type (workflow data or task input) - * @param the result type (what the task will see as input) + * @param the result type (what the task will see as input) * @param function the filter function with workflow and task context * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#inputFrom(JavaFilterFunction) */ - public SELF inputFrom(JavaFilterFunction function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function)); + public SELF inputFrom(JavaFilterFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .inputFrom(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -483,14 +510,14 @@ public SELF inputFrom(JavaFilterFunction function) { * type specification. * * @param the input type (workflow data or task input) - * @param the result type (what the task will see as input) + * @param the result type (what the task will see as input) * @param function the filter function with workflow and task context * @param inputClass the class of the input type * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#inputFrom(JavaFilterFunction, * Class) */ - public SELF inputFrom(JavaFilterFunction function, Class inputClass) { + public SELF inputFrom(JavaFilterFunction function, Class inputClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function, inputClass)); return self(); } @@ -502,13 +529,16 @@ public SELF inputFrom(JavaFilterFunction function, Class inputCl * you to inspect workflow metadata and current data. * * @param the input type (workflow data or task input) - * @param the result type (what the task will see as input) + * @param the result type (what the task will see as input) * @param function the context function with workflow context * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#inputFrom(JavaContextFunction) */ - public SELF inputFrom(JavaContextFunction function) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function)); + public SELF inputFrom(JavaContextFunction function) { + postConfigurers.add( + b -> + ((FuncTaskTransformations) b) + .inputFrom(function, ReflectionUtils.inferInputType(function))); return self(); } @@ -519,14 +549,14 @@ public SELF inputFrom(JavaContextFunction function) { * type specification. * * @param the input type (workflow data or task input) - * @param the result type (what the task will see as input) + * @param the result type (what the task will see as input) * @param function the context function with workflow context * @param inputClass the class of the input type * @return this step for method chaining * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#inputFrom(JavaContextFunction, * Class) */ - public SELF inputFrom(JavaContextFunction function, Class inputClass) { + public SELF inputFrom(JavaContextFunction function, Class inputClass) { postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function, inputClass)); return self(); } diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java index 4d307ce2..5a294790 100644 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java +++ b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java @@ -21,7 +21,9 @@ import io.serverlessworkflow.api.types.Workflow; import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; +import io.serverlessworkflow.impl.TaskContextData; import io.serverlessworkflow.impl.WorkflowApplication; +import io.serverlessworkflow.impl.WorkflowContextData; import io.serverlessworkflow.impl.WorkflowDefinition; import io.serverlessworkflow.impl.WorkflowModel; import org.assertj.core.api.SoftAssertions; @@ -42,17 +44,15 @@ void test_input_with_inputFrom() { (Long input) -> { softly.assertThat(input).isEqualTo(10L); return input + 5; - }, - Long.class), + }), function("returnEnriched", (Long enrichedValue) -> enrichedValue, Long.class) .inputFrom( - (object, workflowContext) -> { + (Long object, WorkflowContextData workflowContext) -> { softly.assertThat(object).isEqualTo(15L); Long input = input(workflowContext, Long.class); softly.assertThat(input).isEqualTo(10L); return object + input; - }, - Long.class)) + })) .build(); try (WorkflowApplication app = WorkflowApplication.builder().build()) { @@ -118,12 +118,13 @@ void test_output_with_exportAs() { }, Long.class) .exportAs( - (object, workflowContext, taskContextData) -> { + (Long object, + WorkflowContextData workflowContext, + TaskContextData taskContextData) -> { Long taskOutput = output(taskContextData, Long.class); softly.assertThat(taskOutput).isEqualTo(15L); return taskOutput * 2; - }, - Object.class)) + })) .build(); try (WorkflowApplication app = WorkflowApplication.builder().build()) {