From 92e9d52a38142a6d12293b7c625705e3c1a1ee67 Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Mon, 20 Jul 2026 16:09:46 -0400 Subject: [PATCH] Remove experimental module (moved to quarkus-flow) The experimental/ module has been migrated to quarkus-flow as io.quarkiverse.flow.dsl. See quarkiverse/quarkus-flow#722. Signed-off-by: Ricardo Zanini --- experimental/fluent/func/pom.xml | 49 - .../fluent/func/FuncCallGrpcTaskBuilder.java | 40 - .../fluent/func/FuncCallHttpTaskBuilder.java | 38 - .../func/FuncCallOpenAPITaskBuilder.java | 41 - .../fluent/func/FuncCallTaskBuilder.java | 111 - .../fluent/func/FuncDoTaskBuilder.java | 136 - .../func/FuncEmitEventPropertiesBuilder.java | 56 - .../fluent/func/FuncEmitTaskBuilder.java | 39 - .../fluent/func/FuncEventFilterBuilder.java | 32 - .../FuncEventFilterPropertiesBuilder.java | 71 - .../fluent/func/FuncForTaskBuilder.java | 133 - .../fluent/func/FuncForkTaskBuilder.java | 72 - .../fluent/func/FuncListenTaskBuilder.java | 49 - .../fluent/func/FuncListenToBuilder.java | 88 - .../fluent/func/FuncRaiseTaskBuilder.java | 34 - .../fluent/func/FuncSetTaskBuilder.java | 30 - .../fluent/func/FuncSwitchTaskBuilder.java | 128 - .../fluent/func/FuncTaskItemListBuilder.java | 253 -- .../fluent/func/FuncTryTaskBuilder.java | 86 - .../fluent/func/FuncWorkflowBuilder.java | 60 - .../configurers/FuncCallGrpcConfigurer.java | 22 - .../configurers/FuncCallHttpConfigurer.java | 22 - .../FuncCallOpenAPIConfigurer.java | 22 - .../func/configurers/FuncEmitConfigurer.java | 22 - .../configurers/FuncListenConfigurer.java | 22 - .../func/configurers/FuncTaskConfigurer.java | 21 - .../configurers/SwitchCaseConfigurer.java | 23 - .../fluent/func/dsl/BaseFuncListenSpec.java | 63 - .../fluent/func/dsl/CommonFuncOps.java | 63 - .../fluent/func/dsl/ConsumeStep.java | 57 - .../fluent/func/dsl/CtxBiFunction.java | 29 - .../fluent/func/dsl/EmitStep.java | 51 - .../fluent/func/dsl/FuncCallGrpcStep.java | 93 - .../fluent/func/dsl/FuncCallHttpStep.java | 57 - .../fluent/func/dsl/FuncCallOpenAPIStep.java | 108 - .../fluent/func/dsl/FuncCallStep.java | 100 - .../fluent/func/dsl/FuncDSL.java | 2714 ----------------- .../fluent/func/dsl/FuncEmitSpec.java | 93 - .../fluent/func/dsl/FuncEventFilterSpec.java | 366 --- .../fluent/func/dsl/FuncListenSpec.java | 37 - .../fluent/func/dsl/ListenStep.java | 51 - .../fluent/func/dsl/Step.java | 625 ---- .../fluent/func/dsl/SwitchCaseSpec.java | 52 - .../fluent/func/spi/CallFnFluent.java | 28 - .../fluent/func/spi/CallGrpcFluent.java | 28 - .../func/spi/ConditionalTaskBuilder.java | 39 - .../spi/ConditionalTaskBuilderHelper.java | 28 - .../fluent/func/spi/FuncDoFluent.java | 66 - .../func/spi/FuncTaskTransformations.java | 72 - .../fluent/func/spi/FuncTransformations.java | 126 - .../fluent/func/FuncDSLConsumeTest.java | 52 - .../fluent/func/FuncDSLOAuth2Test.java | 131 - .../fluent/func/FuncDSLScheduleTest.java | 149 - .../fluent/func/FuncDSLTaskNameTest.java | 293 -- .../fluent/func/FuncDSLTest.java | 671 ---- .../fluent/func/FuncDSLUniqueIdTest.java | 154 - .../fluent/func/FuncDSLWaitTest.java | 198 -- .../fluent/func/FuncEventFilterSpecTest.java | 141 - .../func/FuncTaskItemDefaultNamingTest.java | 106 - experimental/fluent/jackson/pom.xml | 36 - .../jackson/FuncExportAsDeserializer.java | 33 - .../jackson/FuncExportAsMixIn.java | 24 - .../jackson/FuncExportAsSerializer.java | 34 - .../jackson/FuncInputFromDeserializer.java | 33 - .../jackson/FuncInputFromMixIn.java | 24 - .../jackson/FuncInputFromSerializer.java | 34 - .../jackson/FuncJacksonModule.java | 104 - .../jackson/FuncOutputAsDeserializer.java | 33 - .../jackson/FuncOutputAsMixIn.java | 24 - .../jackson/FuncOutputAsSerializer.java | 34 - .../FunctionArgumentsDeserializer.java | 37 - .../jackson/FunctionArgumentsSerializer.java | 31 - .../jackson/FunctionDeserializer.java | 42 - .../SerializableFunctionSerializer.java | 38 - .../jackson/SerializationUtils.java | 145 - .../jackson/SerializedLambdaDeserializer.java | 82 - .../jackson/SerializedLambdaWriter.java | 45 - .../jackson/TaskMetadataDeserializer.java | 36 - .../jackson/TaskMetadataSerializer.java | 30 - .../reflect-config.json | 197 -- .../com.fasterxml.jackson.databind.Module | 1 - experimental/fluent/pom.xml | 65 - experimental/lambda-fluent/pom.xml | 30 - experimental/lambda/pom.xml | 64 - .../func/AbstractJavaCallExecutor.java | 93 - .../executors/func/DataTypeConverter.java | 25 - .../func/DataTypeConverterRegistry.java | 75 - .../func/JavaCallFunctionBuilder.java | 93 - .../func/JavaConsumerCallExecutor.java | 43 - .../func/JavaContextFunctionCallExecutor.java | 39 - .../func/JavaFilterFunctionCallExecutor.java | 39 - .../func/JavaForExecutorBuilder.java | 108 - .../impl/executors/func/JavaFuncUtils.java | 64 - .../func/JavaFunctionCallExecutor.java | 37 - .../func/JavaListenExecutorBuilder.java | 41 - .../func/JavaLoopFunctionCallExecutor.java | 44 - .../JavaLoopFunctionIndexCallExecutor.java | 50 - .../func/JavaSwitchExecutorBuilder.java | 41 - .../func/JavaTaskExecutorFactory.java | 39 - .../func/JavaExpressionFactory.java | 199 -- ...orkflow.impl.executors.CallableTaskBuilder | 2 - ...orkflow.impl.executors.TaskExecutorFactory | 1 - ...orkflow.impl.expressions.ExpressionFactory | 1 - .../func/CallJavaContextFunctionTest.java | 74 - .../impl/executors/func/CallTest.java | 241 -- .../executors/func/EventFilteringTest.java | 161 - .../executors/func/FluentDSLCallTest.java | 154 - .../func/ForTaskFunctionRegressionTest.java | 72 - ...cDSLDataFlowTransformationHelpersTest.java | 204 -- .../func/FuncDSLReflectionsTest.java | 186 -- .../impl/executors/func/JavaFunctions.java | 59 - .../func/ListenUntilCurrentTest.java | 219 -- .../func/ListenUntilValidationTest.java | 81 - .../impl/executors/func/ModelTest.java | 252 -- .../workflow/impl/executors/func/Person.java | 18 - .../executors/func/StringBuilder2String.java | 36 - .../func/WorkflowNumberConversionTest.java | 215 -- .../impl/executors/func/WorkflowThenTest.java | 101 - ...flow.impl.executors.func.DataTypeConverter | 1 - experimental/model/pom.xml | 28 - .../impl/model/func/JavaModel.java | 122 - .../impl/model/func/JavaModelCollection.java | 173 -- .../func/JavaModelCollectionMarshaller.java | 45 - .../impl/model/func/JavaModelFactory.java | 90 - .../impl/model/func/JavaModelMarshaller.java | 43 - .../func/SerializableObjectMarshaller.java | 63 - ...rverlessworkflow.impl.WorkflowModelFactory | 1 - ...low.impl.marshaller.CustomObjectMarshaller | 3 - .../impl/model/func/Address.java | 20 - .../func/JavaModelSerializationTest.java | 55 - .../impl/model/func/Person.java | 20 - experimental/pom.xml | 59 - experimental/test/pom.xml | 116 - .../fluent/test/ForEachFuncTest.java | 120 - .../fluent/test/ForkFuncTest.java | 77 - .../fluent/test/FuncCallAsyncTest.java | 93 - .../fluent/test/FuncDSLSerializationTest.java | 107 - .../fluent/test/FuncDoTaskTest.java | 84 - .../fluent/test/FuncEventFilterTest.java | 274 -- .../fluent/test/FuncHttpTest.java | 268 -- .../fluent/test/FuncOAuth2HttpTest.java | 261 -- .../fluent/test/FuncOpenAPITest.java | 112 - .../fluent/test/FuncTryCatchTest.java | 648 ---- .../fluent/test/LaggedInMemoryEvents.java | 37 - .../fluent/test/TestSerializationUtils.java | 48 - .../test/src/test/resources/logback.xml | 13 - experimental/types/pom.xml | 20 - .../api/types/func/CallJava.java | 129 - .../api/types/func/ContextFunction.java | 23 - .../api/types/func/ContextPredicate.java | 23 - .../api/types/func/EventDataFunction.java | 54 - .../api/types/func/EventDataPredicate.java | 56 - .../types/func/EventPropertiesPredicate.java | 62 - .../api/types/func/FilterFunction.java | 24 - .../api/types/func/FilterPredicate.java | 24 - .../api/types/func/FilterSerializable.java | 19 - .../types/func/FuncCloudEventPredicate.java | 53 - .../func/FuncCloudEventPredicateFactory.java | 32 - .../api/types/func/FunctionObject.java | 24 - .../api/types/func/InstanceIdFunction.java | 27 - .../api/types/func/LoopFunction.java | 21 - .../api/types/func/LoopFunctionIndex.java | 21 - .../api/types/func/LoopPredicate.java | 21 - .../api/types/func/LoopPredicateIndex.java | 21 - .../types/func/LoopPredicateIndexContext.java | 23 - .../types/func/LoopPredicateIndexFilter.java | 24 - .../api/types/func/SerializableConsumer.java | 21 - .../api/types/func/SerializableFunction.java | 28 - .../api/types/func/SerializablePredicate.java | 21 - .../api/types/func/TypedContextFunction.java | 19 - .../api/types/func/TypedContextPredicate.java | 19 - .../api/types/func/TypedFilterFunction.java | 19 - .../api/types/func/TypedFilterPredicate.java | 19 - .../api/types/func/TypedFunction.java | 21 - .../api/types/func/TypedPredicate.java | 21 - .../api/types/func/UniqueIdBiFunction.java | 30 - .../api/types/utils/ForTaskFunction.java | 196 -- .../types/utils/MapSetTaskConfiguration.java | 32 - .../api/types/utils/ReflectionUtils.java | 160 - .../api/types/utils/TaskMetadataKeys.java | 18 - .../api/types/utils/TaskPredicate.java | 90 - .../api/types/utils/TypesUtils.java | 39 - ...low.impl.events.CloudEventPredicateFactory | 1 - pom.xml | 1 - 184 files changed, 17341 deletions(-) delete mode 100644 experimental/fluent/func/pom.xml delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallGrpcTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallHttpTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallOpenAPITaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncDoTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitEventPropertiesBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEventFilterBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEventFilterPropertiesBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncForTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncForkTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncListenTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncListenToBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncRaiseTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSetTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSwitchTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTaskItemListBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTryTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncWorkflowBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallGrpcConfigurer.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallHttpConfigurer.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallOpenAPIConfigurer.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncEmitConfigurer.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncListenConfigurer.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncTaskConfigurer.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/SwitchCaseConfigurer.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/BaseFuncListenSpec.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CommonFuncOps.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ConsumeStep.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CtxBiFunction.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/EmitStep.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallGrpcStep.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallHttpStep.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallOpenAPIStep.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallStep.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEmitSpec.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEventFilterSpec.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncListenSpec.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ListenStep.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/Step.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/SwitchCaseSpec.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/CallFnFluent.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/CallGrpcFluent.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/ConditionalTaskBuilder.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/ConditionalTaskBuilderHelper.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncDoFluent.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTaskTransformations.java delete mode 100644 experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTransformations.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLConsumeTest.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLOAuth2Test.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLScheduleTest.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTaskNameTest.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTest.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLUniqueIdTest.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLWaitTest.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncEventFilterSpecTest.java delete mode 100644 experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncTaskItemDefaultNamingTest.java delete mode 100644 experimental/fluent/jackson/pom.xml delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsDeserializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsMixIn.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsSerializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromDeserializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromMixIn.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromSerializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncJacksonModule.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsDeserializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsMixIn.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsSerializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionArgumentsDeserializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionArgumentsSerializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionDeserializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializableFunctionSerializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializationUtils.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializedLambdaDeserializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializedLambdaWriter.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/TaskMetadataDeserializer.java delete mode 100644 experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/TaskMetadataSerializer.java delete mode 100644 experimental/fluent/jackson/src/main/resources/META-INF/native-image/io.serverlessworkflow/serverlessworkflow-experimental-fluent-serialization-jackson/reflect-config.json delete mode 100644 experimental/fluent/jackson/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module delete mode 100644 experimental/fluent/pom.xml delete mode 100644 experimental/lambda-fluent/pom.xml delete mode 100644 experimental/lambda/pom.xml delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/AbstractJavaCallExecutor.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/DataTypeConverter.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/DataTypeConverterRegistry.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaCallFunctionBuilder.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaConsumerCallExecutor.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaContextFunctionCallExecutor.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFilterFunctionCallExecutor.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaForExecutorBuilder.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFuncUtils.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFunctionCallExecutor.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaListenExecutorBuilder.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaLoopFunctionCallExecutor.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaLoopFunctionIndexCallExecutor.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaSwitchExecutorBuilder.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaTaskExecutorFactory.java delete mode 100644 experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java delete mode 100644 experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.executors.CallableTaskBuilder delete mode 100644 experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.executors.TaskExecutorFactory delete mode 100644 experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.expressions.ExpressionFactory delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallJavaContextFunctionTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/EventFilteringTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FluentDSLCallTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ForTaskFunctionRegressionTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLReflectionsTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/JavaFunctions.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ListenUntilCurrentTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ListenUntilValidationTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ModelTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/Person.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/StringBuilder2String.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/WorkflowNumberConversionTest.java delete mode 100644 experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/WorkflowThenTest.java delete mode 100644 experimental/lambda/src/test/resources/META-INF/services/io.serverlessworkflow.impl.executors.func.DataTypeConverter delete mode 100644 experimental/model/pom.xml delete mode 100644 experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModel.java delete mode 100644 experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelCollection.java delete mode 100644 experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelCollectionMarshaller.java delete mode 100644 experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelFactory.java delete mode 100644 experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelMarshaller.java delete mode 100644 experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/SerializableObjectMarshaller.java delete mode 100644 experimental/model/src/main/resources/META-INF/services/io.serverlessworkflow.impl.WorkflowModelFactory delete mode 100644 experimental/model/src/main/resources/META-INF/services/io.serverlessworkflow.impl.marshaller.CustomObjectMarshaller delete mode 100644 experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/Address.java delete mode 100644 experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/JavaModelSerializationTest.java delete mode 100644 experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/Person.java delete mode 100644 experimental/pom.xml delete mode 100644 experimental/test/pom.xml delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/ForEachFuncTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/ForkFuncTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncCallAsyncTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncDSLSerializationTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncDoTaskTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncEventFilterTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncHttpTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncOAuth2HttpTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncOpenAPITest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncTryCatchTest.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/LaggedInMemoryEvents.java delete mode 100644 experimental/test/src/test/java/io/serverlessworkflow/fluent/test/TestSerializationUtils.java delete mode 100644 experimental/test/src/test/resources/logback.xml delete mode 100644 experimental/types/pom.xml delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/CallJava.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventPropertiesPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterSerializable.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FuncCloudEventPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FuncCloudEventPredicateFactory.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FunctionObject.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/InstanceIdFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopFunctionIndex.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndex.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexContext.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexFilter.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializableConsumer.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializableFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializablePredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/func/UniqueIdBiFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/ForTaskFunction.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/MapSetTaskConfiguration.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/ReflectionUtils.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TaskMetadataKeys.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TaskPredicate.java delete mode 100644 experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TypesUtils.java delete mode 100644 experimental/types/src/main/resources/META-INF/services/io.serverlessworkflow.impl.events.CloudEventPredicateFactory diff --git a/experimental/fluent/func/pom.xml b/experimental/fluent/func/pom.xml deleted file mode 100644 index dcf2aa96f..000000000 --- a/experimental/fluent/func/pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental-fluent - 8.0.0-SNAPSHOT - - - Serverless Workflow :: Experimental :: Fluent :: Functional - serverlessworkflow-experimental-fluent-func - - - 17 - 17 - UTF-8 - - - - - io.serverlessworkflow - serverlessworkflow-experimental-types - - - io.serverlessworkflow - serverlessworkflow-impl-json - - - io.serverlessworkflow - serverlessworkflow-fluent-spec - - - io.cloudevents - cloudevents-core - - - - org.junit.jupiter - junit-jupiter-api - test - - - org.mockito - mockito-core - ${version.org.mockito} - test - - - \ No newline at end of file diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallGrpcTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallGrpcTaskBuilder.java deleted file mode 100644 index 6d3b377f0..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallGrpcTaskBuilder.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.CallGRPC; -import io.serverlessworkflow.api.types.GRPCArguments; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import io.serverlessworkflow.fluent.spec.spi.CallGrpcTaskFluent; - -public class FuncCallGrpcTaskBuilder extends TaskBaseBuilder - implements CallGrpcTaskFluent, - FuncTaskTransformations, - ConditionalTaskBuilder { - - FuncCallGrpcTaskBuilder() { - final CallGRPC callGRPC = new CallGRPC(); - callGRPC.setWith(new GRPCArguments()); - super.setTask(callGRPC); - } - - @Override - public FuncCallGrpcTaskBuilder self() { - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallHttpTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallHttpTaskBuilder.java deleted file mode 100644 index bf06e5897..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallHttpTaskBuilder.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.CallHTTP; -import io.serverlessworkflow.api.types.HTTPArguments; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import io.serverlessworkflow.fluent.spec.spi.CallHttpTaskFluent; - -public class FuncCallHttpTaskBuilder extends TaskBaseBuilder - implements CallHttpTaskFluent, - FuncTaskTransformations, - ConditionalTaskBuilder { - - FuncCallHttpTaskBuilder() { - super.setTask(new CallHTTP().withWith(new HTTPArguments())); - } - - @Override - public FuncCallHttpTaskBuilder self() { - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallOpenAPITaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallOpenAPITaskBuilder.java deleted file mode 100644 index 8c86af9b0..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallOpenAPITaskBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.CallOpenAPI; -import io.serverlessworkflow.api.types.OpenAPIArguments; -import io.serverlessworkflow.api.types.WithOpenAPIParameters; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import io.serverlessworkflow.fluent.spec.spi.CallOpenAPITaskFluent; - -public class FuncCallOpenAPITaskBuilder extends TaskBaseBuilder - implements CallOpenAPITaskFluent, - FuncTaskTransformations, - ConditionalTaskBuilder { - - FuncCallOpenAPITaskBuilder() { - final CallOpenAPI callOpenAPI = new CallOpenAPI(); - callOpenAPI.setWith(new OpenAPIArguments().withParameters(new WithOpenAPIParameters())); - super.setTask(callOpenAPI); - } - - @Override - public FuncCallOpenAPITaskBuilder self() { - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallTaskBuilder.java deleted file mode 100644 index ab3cdf9df..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncCallTaskBuilder.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.func.CallJava; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.SerializableFunction; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import java.util.function.Consumer; -import java.util.function.Function; - -public class FuncCallTaskBuilder extends TaskBaseBuilder - implements FuncTaskTransformations, - ConditionalTaskBuilder { - - private CallTask callTaskJava; - - FuncCallTaskBuilder() {} - - @Override - protected FuncCallTaskBuilder self() { - return this; - } - - public FuncCallTaskBuilder function(SerializableFunction function) { - return function(function, null); - } - - public FuncCallTaskBuilder function(Function function, Class argClass) { - return function(function, argClass, null); - } - - public FuncCallTaskBuilder function( - Function function, Class argClass, Class returnClass) { - this.callTaskJava = - new CallTask().withCallFunction(CallJava.function(function, argClass, returnClass)); - super.setTask(this.callTaskJava.getCallFunction()); - return this; - } - - public FuncCallTaskBuilder function(ContextFunction function) { - return function(function, null); - } - - public FuncCallTaskBuilder function(ContextFunction function, Class argClass) { - return function(function, argClass, null); - } - - public FuncCallTaskBuilder function( - ContextFunction function, Class argClass, Class returnClass) { - this.callTaskJava = - new CallTask().withCallFunction(CallJava.function(function, argClass, returnClass)); - super.setTask(this.callTaskJava.getCallFunction()); - return this; - } - - public FuncCallTaskBuilder function(FilterFunction function) { - return function(function, null); - } - - public FuncCallTaskBuilder function(FilterFunction function, Class argClass) { - return function(function, argClass, null); - } - - public FuncCallTaskBuilder function( - FilterFunction function, Class argClass, Class outputClass) { - this.callTaskJava = - new CallTask().withCallFunction(CallJava.function(function, argClass, outputClass)); - super.setTask(this.callTaskJava.getCallFunction()); - return this; - } - - /** Accept a side-effect Consumer; engine should pass input through unchanged. */ - public FuncCallTaskBuilder consumer(Consumer consumer) { - this.callTaskJava = new CallTask().withCallFunction(CallJava.consumer(consumer)); - super.setTask(this.callTaskJava.getCallFunction()); - return this; - } - - /** Accept a Consumer with explicit input type hint. */ - public FuncCallTaskBuilder consumer(Consumer consumer, Class argClass) { - this.callTaskJava = new CallTask().withCallFunction(CallJava.consumer(consumer, argClass)); - super.setTask(this.callTaskJava.getCallFunction()); - return this; - } - - public CallTask build() { - if (this.callTaskJava == null) { - throw new IllegalStateException( - "Call task is not configured. Call function(...) or consumer(...) before build()."); - } - return this.callTaskJava; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncDoTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncDoTaskBuilder.java deleted file mode 100644 index 8de4ff865..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncDoTaskBuilder.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncDoFluent; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.BaseDoTaskBuilder; -import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder; -import java.util.function.Consumer; - -public class FuncDoTaskBuilder extends BaseDoTaskBuilder - implements FuncTaskTransformations, - ConditionalTaskBuilder, - FuncDoFluent { - - public FuncDoTaskBuilder(int listSizeOffset) { - super(new FuncTaskItemListBuilder(listSizeOffset)); - } - - @Override - public FuncDoTaskBuilder self() { - return this; - } - - @Override - public FuncDoTaskBuilder emit(String name, Consumer itemsConfigurer) { - this.listBuilder().emit(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder listen(String name, Consumer itemsConfigurer) { - this.listBuilder().listen(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder raise(String name, Consumer itemsConfigurer) { - this.listBuilder().raise(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder forEach(String name, Consumer itemsConfigurer) { - this.listBuilder().forEach(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder set(String name, Consumer itemsConfigurer) { - this.listBuilder().set(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder set(String name, String expr) { - this.listBuilder().set(name, expr); - return this; - } - - @Override - public FuncDoTaskBuilder switchCase( - String name, Consumer itemsConfigurer) { - this.listBuilder().switchCase(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder function(String name, Consumer cfg) { - this.listBuilder().function(name, cfg); - return this; - } - - @Override - public FuncDoTaskBuilder fork(String name, Consumer itemsConfigurer) { - this.listBuilder().fork(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder http(String name, Consumer itemsConfigurer) { - this.listBuilder().http(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder openapi( - String name, Consumer itemsConfigurer) { - this.listBuilder().openapi(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder grpc(String name, Consumer itemsConfigurer) { - this.listBuilder().grpc(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder workflow(String name, Consumer itemsConfigurer) { - this.listBuilder().workflow(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder subflow(String name, Consumer itemsConfigurer) { - this.listBuilder().subflow(name, itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder subflow(Consumer itemsConfigurer) { - this.listBuilder().subflow(itemsConfigurer); - return this; - } - - @Override - public FuncDoTaskBuilder tryCatch(String name, Consumer itemsConfigurer) { - this.listBuilder().tryCatch(name, itemsConfigurer); - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitEventPropertiesBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitEventPropertiesBuilder.java deleted file mode 100644 index a71e383ee..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitEventPropertiesBuilder.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.cloudevents.CloudEventData; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.EventDataFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.SerializableFunction; -import io.serverlessworkflow.fluent.spec.AbstractEventPropertiesBuilder; -import java.util.function.Function; - -public class FuncEmitEventPropertiesBuilder - extends AbstractEventPropertiesBuilder { - - @Override - protected FuncEmitEventPropertiesBuilder self() { - return this; - } - - public FuncEmitEventPropertiesBuilder data(SerializableFunction function) { - this.eventProperties.setData(new EventDataFunction().withFunction(function)); - return this; - } - - public FuncEmitEventPropertiesBuilder data( - Function function, Class clazz) { - this.eventProperties.setData(new EventDataFunction().withFunction(function, clazz)); - return this; - } - - public FuncEmitEventPropertiesBuilder data( - ContextFunction function, Class clazz) { - this.eventProperties.setData(new EventDataFunction().withFunction(function, clazz)); - return this; - } - - public FuncEmitEventPropertiesBuilder data( - FilterFunction function, Class clazz) { - this.eventProperties.setData(new EventDataFunction().withFunction(function, clazz)); - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitTaskBuilder.java deleted file mode 100644 index 13af9e883..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEmitTaskBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.AbstractEmitTaskBuilder; - -public class FuncEmitTaskBuilder - extends AbstractEmitTaskBuilder - implements ConditionalTaskBuilder, - FuncTaskTransformations { - FuncEmitTaskBuilder() { - super(); - } - - @Override - protected FuncEmitTaskBuilder self() { - return this; - } - - @Override - protected FuncEmitEventPropertiesBuilder newEventPropertiesBuilder() { - return new FuncEmitEventPropertiesBuilder(); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEventFilterBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEventFilterBuilder.java deleted file mode 100644 index 1d033d86d..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEventFilterBuilder.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.fluent.spec.AbstractEventFilterBuilder; - -public class FuncEventFilterBuilder - extends AbstractEventFilterBuilder { - - @Override - protected FuncEventFilterBuilder self() { - return this; - } - - @Override - protected FuncEventFilterPropertiesBuilder newEventPropertiesBuilder() { - return new FuncEventFilterPropertiesBuilder(); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEventFilterPropertiesBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEventFilterPropertiesBuilder.java deleted file mode 100644 index 5bb8e64f7..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncEventFilterPropertiesBuilder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.cloudevents.CloudEvent; -import io.cloudevents.CloudEventData; -import io.serverlessworkflow.api.types.func.ContextPredicate; -import io.serverlessworkflow.api.types.func.EventDataPredicate; -import io.serverlessworkflow.api.types.func.EventPropertiesPredicate; -import io.serverlessworkflow.api.types.func.FilterPredicate; -import io.serverlessworkflow.fluent.spec.AbstractEventPropertiesBuilder; -import java.util.function.Predicate; - -public class FuncEventFilterPropertiesBuilder - extends AbstractEventPropertiesBuilder { - - public FuncEventFilterPropertiesBuilder() { - super(new EventPropertiesPredicate()); - } - - @Override - protected FuncEventFilterPropertiesBuilder self() { - return this; - } - - public FuncEventFilterPropertiesBuilder data(Predicate predicate) { - this.eventProperties.setData( - new EventDataPredicate().withPredicate(predicate, CloudEventData.class)); - return this; - } - - public FuncEventFilterPropertiesBuilder data(ContextPredicate predicate) { - this.eventProperties.setData( - new EventDataPredicate().withPredicate(predicate, CloudEventData.class)); - return this; - } - - public FuncEventFilterPropertiesBuilder data(FilterPredicate predicate) { - this.eventProperties.setData( - new EventDataPredicate().withPredicate(predicate, CloudEventData.class)); - return this; - } - - public FuncEventFilterPropertiesBuilder envelope(Predicate predicate) { - ((EventPropertiesPredicate) eventProperties).withPredicate(predicate, CloudEvent.class); - return this; - } - - public FuncEventFilterPropertiesBuilder envelope(ContextPredicate predicate) { - ((EventPropertiesPredicate) eventProperties).withPredicate(predicate, CloudEvent.class); - return this; - } - - public FuncEventFilterPropertiesBuilder envelope(FilterPredicate predicate) { - ((EventPropertiesPredicate) eventProperties).withPredicate(predicate, CloudEvent.class); - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncForTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncForTaskBuilder.java deleted file mode 100644 index cf58071ac..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncForTaskBuilder.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.ForTask; -import io.serverlessworkflow.api.types.ForTaskConfiguration; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.func.CallJava; -import io.serverlessworkflow.api.types.func.LoopFunction; -import io.serverlessworkflow.api.types.func.LoopPredicate; -import io.serverlessworkflow.api.types.func.LoopPredicateIndex; -import io.serverlessworkflow.api.types.utils.ForTaskFunction; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import io.serverlessworkflow.fluent.spec.spi.ForEachTaskFluent; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; - -public class FuncForTaskBuilder extends TaskBaseBuilder - implements FuncTaskTransformations, - ConditionalTaskBuilder, - ForEachTaskFluent { - - private final ForTask forTask; - private final List items; - - FuncForTaskBuilder() { - this.forTask = new ForTask(); - this.forTask.withFor(new ForTaskConfiguration()); - this.items = new ArrayList<>(); - super.setTask(forTask); - } - - @Override - protected FuncForTaskBuilder self() { - return this; - } - - public FuncForTaskBuilder whileC(LoopPredicate predicate) { - ForTaskFunction.withWhile(forTask, predicate); - return this; - } - - public FuncForTaskBuilder whileC(LoopPredicateIndex predicate) { - ForTaskFunction.withWhile(forTask, predicate); - return this; - } - - public FuncForTaskBuilder collection(Function> collectionF) { - ForTaskFunction.withCollection(forTask, collectionF); - return this; - } - - public FuncForTaskBuilder collection( - Function> collectionF, Class clazz) { - ForTaskFunction.withCollection(forTask, collectionF, clazz); - return this; - } - - public FuncForTaskBuilder tasks(String name, LoopFunction function) { - if (name == null || name.isBlank()) { - name = "for-task-" + this.items.size(); - } - this.items.add( - new TaskItem( - name, - new Task() - .withCallTask( - new CallTask() - .withCallFunction( - CallJava.loopFunction(function, this.forTask.getFor().getEach()))))); - return this; - } - - public FuncForTaskBuilder tasks(LoopFunction function) { - return this.tasks(null, function); - } - - @Override - public FuncForTaskBuilder each(String each) { - this.forTask.getFor().withEach(each); - return this; - } - - @Override - public FuncForTaskBuilder in(String in) { - this.forTask.getFor().withIn(in); - return this; - } - - @Override - public FuncForTaskBuilder at(String at) { - this.forTask.getFor().withAt(at); - return this; - } - - @Override - public FuncForTaskBuilder whileC(String expression) { - this.forTask.setWhile(expression); - return this; - } - - public FuncForTaskBuilder tasks(Consumer consumer) { - final FuncTaskItemListBuilder builder = new FuncTaskItemListBuilder(this.items.size()); - consumer.accept(builder); - this.items.addAll(builder.build()); - return this; - } - - public ForTask build() { - this.forTask.setDo(this.items); - return this.forTask; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncForkTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncForkTaskBuilder.java deleted file mode 100644 index 9d43116ce..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncForkTaskBuilder.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.func.CallJava; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.AbstractForkTaskBuilder; -import io.serverlessworkflow.fluent.spec.spi.ForkTaskFluent; -import java.util.function.Function; - -public class FuncForkTaskBuilder - extends AbstractForkTaskBuilder - implements FuncTaskTransformations, - ConditionalTaskBuilder, - ForkTaskFluent { - - FuncForkTaskBuilder() { - super(); - } - - @Override - protected FuncForkTaskBuilder self() { - return this; - } - - @Override - protected FuncTaskItemListBuilder newTaskItemListBuilder(int listOffsetSize) { - return new FuncTaskItemListBuilder(listOffsetSize); - } - - public FuncForkTaskBuilder branch(String name, Function function) { - return branch(name, function, null); - } - - public FuncForkTaskBuilder branch( - String name, Function function, Class argParam) { - return branch(name, function, argParam, null); - } - - public FuncForkTaskBuilder branch( - String name, Function function, Class argParam, Class returnClass) { - this.appendBranch( - new TaskItem( - this.defaultBranchName(name, this.currentOffset()), - new Task() - .withCallTask( - new CallTask() - .withCallFunction(CallJava.function(function, argParam, returnClass))))); - return this; - } - - public FuncForkTaskBuilder branch(Function function) { - return this.branch(null, function); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncListenTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncListenTaskBuilder.java deleted file mode 100644 index b2478157a..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncListenTaskBuilder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.utils.TaskPredicate; -import io.serverlessworkflow.api.types.utils.TypesUtils; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.AbstractListenTaskBuilder; -import java.util.function.Predicate; - -public class FuncListenTaskBuilder - extends AbstractListenTaskBuilder - implements ConditionalTaskBuilder, - FuncTaskTransformations { - - FuncListenTaskBuilder(FuncTaskItemListBuilder factory) { - super(factory); - } - - public FuncListenTaskBuilder until(Predicate predicate, Class predClass) { - TaskPredicate.withPredicate( - super.getListenTask(), TypesUtils.UNTIL_PRED_NAME, predicate, predClass); - return this; - } - - @Override - protected FuncListenTaskBuilder self() { - return this; - } - - @Override - protected FuncListenToBuilder newEventConsumptionStrategyBuilder() { - return new FuncListenToBuilder(super.getListenTask()); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncListenToBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncListenToBuilder.java deleted file mode 100644 index 1f6585ca0..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncListenToBuilder.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.AllEventConsumptionStrategy; -import io.serverlessworkflow.api.types.AnyEventConsumptionStrategy; -import io.serverlessworkflow.api.types.ListenTask; -import io.serverlessworkflow.api.types.ListenTo; -import io.serverlessworkflow.api.types.OneEventConsumptionStrategy; -import io.serverlessworkflow.api.types.Until; -import io.serverlessworkflow.api.types.func.ContextPredicate; -import io.serverlessworkflow.api.types.func.FilterPredicate; -import io.serverlessworkflow.api.types.utils.TaskPredicate; -import io.serverlessworkflow.api.types.utils.TypesUtils; -import io.serverlessworkflow.fluent.spec.AbstractEventConsumptionStrategyBuilder; -import java.util.function.Predicate; - -public class FuncListenToBuilder - extends AbstractEventConsumptionStrategyBuilder< - FuncListenToBuilder, ListenTo, FuncEventFilterBuilder> { - - private final ListenTo listenTo = new ListenTo(); - private final ListenTask listenTask; - - public FuncListenToBuilder(ListenTask listenTask) { - this.listenTask = listenTask; - } - - @Override - protected FuncEventFilterBuilder newEventFilterBuilder() { - return new FuncEventFilterBuilder(); - } - - // TODO: move these methods to default on an interface - - @Override - protected void setOne(OneEventConsumptionStrategy strategy) { - this.listenTo.setOneEventConsumptionStrategy(strategy); - } - - @Override - protected void setAll(AllEventConsumptionStrategy strategy) { - this.listenTo.setAllEventConsumptionStrategy(strategy); - } - - @Override - protected void setAny(AnyEventConsumptionStrategy strategy) { - this.listenTo.setAnyEventConsumptionStrategy(strategy); - } - - @Override - protected ListenTo getEventConsumptionStrategy() { - return this.listenTo; - } - - @Override - protected void setUntilForAny(Until until) { - this.listenTo.getAnyEventConsumptionStrategy().setUntil(until); - } - - public FuncListenToBuilder until(Predicate predicate, Class predClass) { - TaskPredicate.withPredicate(listenTask, TypesUtils.UNTIL_PRED_NAME, predicate, predClass); - return this; - } - - public FuncListenToBuilder until(ContextPredicate predicate, Class predClass) { - TaskPredicate.withPredicate(listenTask, TypesUtils.UNTIL_PRED_NAME, predicate, predClass); - return this; - } - - public FuncListenToBuilder until(FilterPredicate predicate, Class predClass) { - TaskPredicate.withPredicate(listenTask, TypesUtils.UNTIL_PRED_NAME, predicate, predClass); - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncRaiseTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncRaiseTaskBuilder.java deleted file mode 100644 index 6afc5d62c..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncRaiseTaskBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.BaseRaiseTaskBuilder; - -public class FuncRaiseTaskBuilder extends BaseRaiseTaskBuilder - implements FuncTaskTransformations, - ConditionalTaskBuilder { - - FuncRaiseTaskBuilder() { - super(); - } - - @Override - protected FuncRaiseTaskBuilder self() { - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSetTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSetTaskBuilder.java deleted file mode 100644 index aaad58c84..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSetTaskBuilder.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.utils.MapSetTaskConfiguration; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.spec.SetTaskBuilder; -import java.util.Map; - -public class FuncSetTaskBuilder extends SetTaskBuilder - implements ConditionalTaskBuilder { - - public FuncSetTaskBuilder expr(Map map) { - this.setTaskConfiguration = MapSetTaskConfiguration.map(map); - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSwitchTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSwitchTaskBuilder.java deleted file mode 100644 index 90fb37d5e..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncSwitchTaskBuilder.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.FlowDirective; -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.SwitchCase; -import io.serverlessworkflow.api.types.SwitchItem; -import io.serverlessworkflow.api.types.SwitchTask; -import io.serverlessworkflow.api.types.utils.TaskPredicate; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import io.serverlessworkflow.fluent.spec.spi.SwitchTaskFluent; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Predicate; - -public class FuncSwitchTaskBuilder extends TaskBaseBuilder - implements FuncTaskTransformations, - ConditionalTaskBuilder, - SwitchTaskFluent { - - private final SwitchTask switchTask; - private final List switchItems; - - FuncSwitchTaskBuilder() { - this.switchTask = new SwitchTask(); - this.switchItems = new ArrayList<>(); - super.setTask(switchTask); - } - - @Override - protected FuncSwitchTaskBuilder self() { - return this; - } - - public FuncSwitchTaskBuilder onPredicate(Consumer consumer) { - return this.onPredicate(null, consumer); - } - - public FuncSwitchTaskBuilder onPredicate( - String name, Consumer consumer) { - final SwitchCasePredicateBuilder switchCase = - new SwitchCasePredicateBuilder(defaultItemNameIfBlank(name)); - consumer.accept(switchCase); - final SwitchCase switchCaseValue = switchCase.build(); - - // Handling default cases - if (TaskPredicate.predicate(switchTask, switchCase.name) == null) { - Objects.requireNonNull(switchCaseValue.getThen(), "Then is required"); - if (switchCaseValue.getThen().getFlowDirectiveEnum() != null) { - return this.onDefault(switchCaseValue.getThen().getFlowDirectiveEnum()); - } else { - return this.onDefault(switchCaseValue.getThen().getString()); - } - } - this.switchItems.add(new SwitchItem(switchCase.name, switchCase.build())); - return this; - } - - @Override - public FuncSwitchTaskBuilder on(String name, Consumer switchCaseConsumer) { - final SwitchCaseBuilder switchCase = new SwitchCaseBuilder(); - switchCaseConsumer.accept(switchCase); - this.switchItems.add(new SwitchItem(defaultItemNameIfBlank(name), switchCase.build())); - return this; - } - - @Override - public int switchItemCount() { - return this.switchItems.size(); - } - - public SwitchTask build() { - this.switchTask.setSwitch(this.switchItems); - return switchTask; - } - - public final class SwitchCasePredicateBuilder { - private final SwitchCase switchCase; - private final String name; - - SwitchCasePredicateBuilder(String name) { - this.name = name; - this.switchCase = new SwitchCase(); - } - - public SwitchCasePredicateBuilder when(Predicate when) { - TaskPredicate.withPredicate(FuncSwitchTaskBuilder.this.switchTask, name, when); - return this; - } - - public SwitchCasePredicateBuilder when(Predicate when, Class whenClass) { - TaskPredicate.withPredicate(FuncSwitchTaskBuilder.this.switchTask, name, when, whenClass); - return this; - } - - public SwitchCasePredicateBuilder then(String taskName) { - this.switchCase.setThen(new FlowDirective().withString(taskName)); - return this; - } - - public SwitchCasePredicateBuilder then(FlowDirectiveEnum then) { - this.switchCase.setThen(new FlowDirective().withFlowDirectiveEnum(then)); - return this; - } - - public SwitchCase build() { - return this.switchCase; - } - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTaskItemListBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTaskItemListBuilder.java deleted file mode 100644 index 86daac8cd..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTaskItemListBuilder.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.api.types.CallGRPC; -import io.serverlessworkflow.api.types.CallHTTP; -import io.serverlessworkflow.api.types.CallOpenAPI; -import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.fluent.func.spi.FuncDoFluent; -import io.serverlessworkflow.fluent.spec.BaseTaskItemListBuilder; -import io.serverlessworkflow.fluent.spec.TaskItemListBuilder; -import io.serverlessworkflow.fluent.spec.WaitTaskBuilder; -import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -public class FuncTaskItemListBuilder extends BaseTaskItemListBuilder - implements FuncDoFluent { - - protected static final String TYPE_FUNCTION = "function"; - - public FuncTaskItemListBuilder(final int listOffsetSize) { - super(listOffsetSize); - } - - public FuncTaskItemListBuilder(final List list) { - super(list); - } - - @Override - protected FuncTaskItemListBuilder self() { - return this; - } - - @Override - protected FuncTaskItemListBuilder newItemListBuilder(int listOffsetSize) { - return new FuncTaskItemListBuilder(listOffsetSize); - } - - @Override - public FuncTaskItemListBuilder function(String name, Consumer consumer) { - name = this.defaultNameAndRequireConfig(name, consumer, TYPE_FUNCTION); - final FuncCallTaskBuilder callTaskJavaBuilder = new FuncCallTaskBuilder(); - consumer.accept(callTaskJavaBuilder); - return addTaskItem(new TaskItem(name, new Task().withCallTask(callTaskJavaBuilder.build()))); - } - - @Override - public FuncTaskItemListBuilder function(Consumer consumer) { - return this.function(null, consumer); - } - - @Override - public FuncTaskItemListBuilder set(String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_SET); - final FuncSetTaskBuilder funcSetTaskBuilder = new FuncSetTaskBuilder(); - itemsConfigurer.accept(funcSetTaskBuilder); - return this.addTaskItem(new TaskItem(name, new Task().withSetTask(funcSetTaskBuilder.build()))); - } - - @Override - public FuncTaskItemListBuilder set(String name, String expr) { - return this.set(name, s -> s.expr(expr)); - } - - public FuncTaskItemListBuilder set(String name, Map map) { - return this.set(name, s -> s.expr(map)); - } - - @Override - public FuncTaskItemListBuilder emit(String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_EMIT); - final FuncEmitTaskBuilder emitTaskJavaBuilder = new FuncEmitTaskBuilder(); - itemsConfigurer.accept(emitTaskJavaBuilder); - return this.addTaskItem( - new TaskItem(name, new Task().withEmitTask(emitTaskJavaBuilder.build()))); - } - - @Override - public FuncTaskItemListBuilder listen( - String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_LISTEN); - final FuncListenTaskBuilder listenTaskJavaBuilder = new FuncListenTaskBuilder(this); - itemsConfigurer.accept(listenTaskJavaBuilder); - return this.addTaskItem( - new TaskItem(name, new Task().withListenTask(listenTaskJavaBuilder.build()))); - } - - @Override - public FuncTaskItemListBuilder raise( - String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_RAISE); - final FuncRaiseTaskBuilder raiseTaskJavaBuilder = new FuncRaiseTaskBuilder(); - itemsConfigurer.accept(raiseTaskJavaBuilder); - return this.addTaskItem( - new TaskItem(name, new Task().withRaiseTask(raiseTaskJavaBuilder.build()))); - } - - @Override - public FuncTaskItemListBuilder forEach( - String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_FOR); - final FuncForTaskBuilder forTaskJavaBuilder = new FuncForTaskBuilder(); - itemsConfigurer.accept(forTaskJavaBuilder); - return this.addTaskItem(new TaskItem(name, new Task().withForTask(forTaskJavaBuilder.build()))); - } - - @Override - public FuncTaskItemListBuilder switchCase( - String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_SWITCH); - final FuncSwitchTaskBuilder funcSwitchTaskBuilder = new FuncSwitchTaskBuilder(); - itemsConfigurer.accept(funcSwitchTaskBuilder); - return this.addTaskItem( - new TaskItem(name, new Task().withSwitchTask(funcSwitchTaskBuilder.build()))); - } - - @Override - public FuncTaskItemListBuilder fork(String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_FORK); - final FuncForkTaskBuilder forkTaskJavaBuilder = new FuncForkTaskBuilder(); - itemsConfigurer.accept(forkTaskJavaBuilder); - return this.addTaskItem( - new TaskItem(name, new Task().withForkTask(forkTaskJavaBuilder.build()))); - } - - @Override - public FuncTaskItemListBuilder http( - String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_HTTP); - - final FuncCallHttpTaskBuilder httpTaskJavaBuilder = new FuncCallHttpTaskBuilder(); - itemsConfigurer.accept(httpTaskJavaBuilder); - - final CallHTTP callHTTP = httpTaskJavaBuilder.build(); - final CallTask callTask = new CallTask(); - callTask.setCallHTTP(callHTTP); - final Task task = new Task(); - task.setCallTask(callTask); - - return this.addTaskItem(new TaskItem(name, task)); - } - - @Override - public FuncTaskItemListBuilder openapi( - String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_OPENAPI); - - final FuncCallOpenAPITaskBuilder openAPITaskBuilder = new FuncCallOpenAPITaskBuilder(); - itemsConfigurer.accept(openAPITaskBuilder); - - final CallOpenAPI callOpenAPI = openAPITaskBuilder.build(); - final CallTask callTask = new CallTask(); - callTask.setCallOpenAPI(callOpenAPI); - final Task task = new Task(); - task.setCallTask(callTask); - - return this.addTaskItem(new TaskItem(name, task)); - } - - @Override - public FuncTaskItemListBuilder grpc( - String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_GRPC); - - final FuncCallGrpcTaskBuilder grpcTaskBuilder = new FuncCallGrpcTaskBuilder(); - itemsConfigurer.accept(grpcTaskBuilder); - - final CallGRPC callGRPC = grpcTaskBuilder.build(); - final CallTask callTask = new CallTask(); - callTask.setCallGRPC(callGRPC); - final Task task = new Task(); - task.setCallTask(callTask); - - return this.addTaskItem(new TaskItem(name, task)); - } - - @Override - public FuncTaskItemListBuilder workflow( - String name, Consumer itemsConfigurer) { - return this.addDelegatedWorkflow(name, itemsConfigurer, TYPE_WORKFLOW); - } - - @Override - public FuncTaskItemListBuilder workflow(Consumer itemsConfigurer) { - return this.workflow(null, itemsConfigurer); - } - - @Override - public FuncTaskItemListBuilder subflow( - String name, Consumer itemsConfigurer) { - return this.addDelegatedWorkflow(name, itemsConfigurer, TYPE_WORKFLOW); - } - - @Override - public FuncTaskItemListBuilder subflow(Consumer itemsConfigurer) { - return this.subflow(null, itemsConfigurer); - } - - private FuncTaskItemListBuilder addDelegatedWorkflow( - String name, Consumer itemsConfigurer, String delegateType) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, delegateType); - // Preserve the original offset when delegating to avoid duplicate task names - // across appended .tasks(...) blocks - final int effectiveOffset = this.getOffset() + this.mutableList().size(); - final TaskItemListBuilder delegate = new TaskItemListBuilder(effectiveOffset); - delegate.workflow(name, itemsConfigurer); - final List taskItems = delegate.build(); - if (taskItems.size() != 1) { - throw new IllegalStateException( - String.format( - "Expected %s delegate '%s' to build exactly 1 TaskItem, but got %d", - delegateType, name, taskItems.size())); - } - return addTaskItem(taskItems.get(0)); - } - - @Override - public FuncTaskItemListBuilder tryCatch( - String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_TRY); - final FuncTryTaskBuilder tryTaskBuilder = new FuncTryTaskBuilder(); - itemsConfigurer.accept(tryTaskBuilder); - return this.addTaskItem(new TaskItem(name, new Task().withTryTask(tryTaskBuilder.build()))); - } - - public FuncTaskItemListBuilder wait(Consumer itemsConfigurer) { - return wait(null, itemsConfigurer); - } - - public FuncTaskItemListBuilder wait(String name, Consumer itemsConfigurer) { - name = this.defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_WAIT); - final WaitTaskBuilder waitTaskBuilder = new WaitTaskBuilder(); - itemsConfigurer.accept(waitTaskBuilder); - return this.addTaskItem(new TaskItem(name, new Task().withWaitTask(waitTaskBuilder.build()))); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTryTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTryTaskBuilder.java deleted file mode 100644 index b9f8640b8..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTryTaskBuilder.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.BaseTryTaskBuilder; -import java.util.function.Consumer; - -public class FuncTryTaskBuilder - extends BaseTryTaskBuilder - implements FuncTaskTransformations, - ConditionalTaskBuilder { - - FuncTryTaskBuilder() { - super(new FuncTaskItemListBuilder(0)); - } - - @Override - protected FuncTryTaskBuilder self() { - return this; - } - - /** - * Defines the tasks to execute within the try. - * - * @param tryHandler a consumer that configures the tasks to be executed in the try - * @return this builder instance for method chaining - */ - public FuncTryTaskBuilder tryCatch(Consumer tryHandler) { - return this.tryHandler(tryHandler); - } - - /** - * Defines a catch that handles specific errors and executes tasks when those errors occur. - * - * @param catchErrors a consumer that configures which errors to catch (e.g., by type, status - * code) - * @param catchHandler a consumer that configures the tasks to execute when the specified errors - * are caught - * @return this builder instance for method chaining - */ - public FuncTryTaskBuilder catchError( - Consumer catchErrors, Consumer catchHandler) { - return this.catchHandler(handler -> handler.errorsWith(catchErrors).doTasks(catchHandler)); - } - - /** - * Defines a conditional catch that executes tasks when a specific condition is met. - * - * @param expr a runtime expression that evaluates to a boolean, determining whether to execute - * the catch handler - * @param catchHandler a consumer that configures the tasks to execute when the condition - * evaluates to true - * @return this builder instance for method chaining - */ - public FuncTryTaskBuilder catchWhen(String expr, Consumer catchHandler) { - return this.catchHandler(handler -> handler.when(expr).doTasks(catchHandler)); - } - - /** - * Defines a catch that handles errors of a specific type. - * - * @param type the error type to catch (e.g., "java.lang.NullPointerException") - * @param catchHandler a consumer that configures the tasks to execute when an error of the - * specified type is caught - * @return this builder instance for method chaining - */ - public FuncTryTaskBuilder catchType(String type, Consumer catchHandler) { - return this.catchHandler( - handler -> handler.errorsWith(err -> err.type(type)).doTasks(catchHandler)); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncWorkflowBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncWorkflowBuilder.java deleted file mode 100644 index 6f5dd62f7..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncWorkflowBuilder.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.types.Defaults.DEFAULT_NAMESPACE; -import static io.serverlessworkflow.types.Defaults.DEFAULT_VERSION; - -import io.serverlessworkflow.fluent.func.spi.FuncTransformations; -import io.serverlessworkflow.fluent.spec.BaseWorkflowBuilder; -import java.util.UUID; - -public class FuncWorkflowBuilder - extends BaseWorkflowBuilder - implements FuncTransformations { - - protected FuncWorkflowBuilder(final String name, final String namespace, final String version) { - super(name, namespace, version); - } - - public static FuncWorkflowBuilder workflow( - final String name, final String namespace, final String version) { - return new FuncWorkflowBuilder(name, namespace, version); - } - - public static FuncWorkflowBuilder workflow(final String name, final String namespace) { - return new FuncWorkflowBuilder(name, namespace, DEFAULT_VERSION); - } - - public static FuncWorkflowBuilder workflow(final String name) { - return new FuncWorkflowBuilder(name, DEFAULT_NAMESPACE, DEFAULT_VERSION); - } - - public static FuncWorkflowBuilder workflow() { - return new FuncWorkflowBuilder( - UUID.randomUUID().toString(), DEFAULT_NAMESPACE, DEFAULT_VERSION); - } - - @Override - protected FuncDoTaskBuilder newDo(int listSizeOffset) { - return new FuncDoTaskBuilder(listSizeOffset); - } - - @Override - protected FuncWorkflowBuilder self() { - return this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallGrpcConfigurer.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallGrpcConfigurer.java deleted file mode 100644 index a3e552f50..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallGrpcConfigurer.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.configurers; - -import io.serverlessworkflow.fluent.func.FuncCallGrpcTaskBuilder; -import java.util.function.Consumer; - -@FunctionalInterface -public interface FuncCallGrpcConfigurer extends Consumer {} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallHttpConfigurer.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallHttpConfigurer.java deleted file mode 100644 index d852f82ca..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallHttpConfigurer.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.configurers; - -import io.serverlessworkflow.fluent.func.FuncCallHttpTaskBuilder; -import java.util.function.Consumer; - -@FunctionalInterface -public interface FuncCallHttpConfigurer extends Consumer {} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallOpenAPIConfigurer.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallOpenAPIConfigurer.java deleted file mode 100644 index 210b5792b..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncCallOpenAPIConfigurer.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.configurers; - -import io.serverlessworkflow.fluent.func.FuncCallOpenAPITaskBuilder; -import java.util.function.Consumer; - -@FunctionalInterface -public interface FuncCallOpenAPIConfigurer extends Consumer {} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncEmitConfigurer.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncEmitConfigurer.java deleted file mode 100644 index 44e5fbd95..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncEmitConfigurer.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.configurers; - -import io.serverlessworkflow.fluent.func.FuncEmitTaskBuilder; -import java.util.function.Consumer; - -@FunctionalInterface -public interface FuncEmitConfigurer extends Consumer {} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncListenConfigurer.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncListenConfigurer.java deleted file mode 100644 index ee18a05bf..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncListenConfigurer.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.configurers; - -import io.serverlessworkflow.fluent.func.FuncListenTaskBuilder; -import java.util.function.Consumer; - -@FunctionalInterface -public interface FuncListenConfigurer extends Consumer {} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncTaskConfigurer.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncTaskConfigurer.java deleted file mode 100644 index e3815ad77..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/FuncTaskConfigurer.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.configurers; - -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import java.util.function.Consumer; - -public interface FuncTaskConfigurer extends Consumer {} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/SwitchCaseConfigurer.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/SwitchCaseConfigurer.java deleted file mode 100644 index 55cf25c5a..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/configurers/SwitchCaseConfigurer.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.configurers; - -import io.serverlessworkflow.fluent.func.FuncSwitchTaskBuilder; -import java.util.function.Consumer; - -@FunctionalInterface -public interface SwitchCaseConfigurer - extends Consumer {} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/BaseFuncListenSpec.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/BaseFuncListenSpec.java deleted file mode 100644 index 95d3f4ef3..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/BaseFuncListenSpec.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.api.types.func.ContextPredicate; -import io.serverlessworkflow.api.types.func.FilterPredicate; -import io.serverlessworkflow.fluent.func.FuncEventFilterBuilder; -import io.serverlessworkflow.fluent.func.FuncListenToBuilder; -import io.serverlessworkflow.fluent.spec.dsl.BaseListenSpec; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Predicate; - -public abstract class BaseFuncListenSpec - extends BaseListenSpec { - - protected BaseFuncListenSpec(ToInvoker toInvoker) { - super( - toInvoker, - // allApplier - (tb, filters) -> tb.all(castFilters(filters)), - // anyApplier - (tb, filters) -> tb.any(castFilters(filters)), - // oneApplier - FuncListenToBuilder::one); - } - - @SuppressWarnings("unchecked") - private static Consumer[] castFilters(Consumer[] arr) { - return (Consumer[]) arr; - } - - public SELF until(Predicate predicate, Class predClass) { - Objects.requireNonNull(predicate, "predicate"); - this.setUntilStep(u -> u.until(predicate, predClass)); - return self(); - } - - public SELF until(ContextPredicate predicate, Class predClass) { - Objects.requireNonNull(predicate, "predicate"); - this.setUntilStep(u -> u.until(predicate, predClass)); - return self(); - } - - public SELF until(FilterPredicate predicate, Class predClass) { - Objects.requireNonNull(predicate, "predicate"); - this.setUntilStep(u -> u.until(predicate, predClass)); - return self(); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CommonFuncOps.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CommonFuncOps.java deleted file mode 100644 index 1bc386294..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CommonFuncOps.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.func.SerializableFunction; -import io.serverlessworkflow.api.types.func.SerializablePredicate; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import io.serverlessworkflow.fluent.func.FuncCallTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncSwitchTaskBuilder; -import io.serverlessworkflow.fluent.func.configurers.SwitchCaseConfigurer; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; - -interface CommonFuncOps { - - default Consumer fn(Function function, Class argClass) { - return f -> f.function(function, argClass); - } - - default Consumer fn(SerializableFunction function) { - Class clazz = ReflectionUtils.inferInputType(function); - return f -> f.function(function, clazz); - } - - default Consumer cases(SwitchCaseConfigurer... cases) { - return s -> { - for (SwitchCaseConfigurer c : cases) { - s.onPredicate(c); - } - }; - } - - default SwitchCaseSpec caseOf(Predicate when, Class whenClass) { - return new SwitchCaseSpec().when(when, whenClass); - } - - default SwitchCaseSpec caseOf(SerializablePredicate when) { - return new SwitchCaseSpec().when(when, ReflectionUtils.inferInputType(when)); - } - - default SwitchCaseConfigurer caseDefault(String task) { - return s -> s.then(task); - } - - default SwitchCaseConfigurer caseDefault(FlowDirectiveEnum directive) { - return s -> s.then(directive); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ConsumeStep.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ConsumeStep.java deleted file mode 100644 index ae968ed91..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ConsumeStep.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.fluent.func.FuncCallTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import java.util.function.Consumer; - -public final class ConsumeStep extends Step, FuncCallTaskBuilder> { - private final String name; // may be null - private final Consumer consumer; - private final Class argClass; // may be null - - ConsumeStep(Consumer consumer, Class argClass) { - this(null, consumer, argClass); - } - - ConsumeStep(String name, Consumer consumer, Class argClass) { - this.name = name; - this.consumer = consumer; - this.argClass = argClass; - } - - @Override - protected void configure(FuncTaskItemListBuilder list, Consumer post) { - if (name == null) { - list.function( - cb -> { - // prefer the typed consumer if your builder supports it; otherwise fallback: - if (argClass != null) cb.consumer(consumer, argClass); - else cb.consumer(consumer); - post.accept(cb); - }); - } else { - list.function( - name, - cb -> { - if (argClass != null) cb.consumer(consumer, argClass); - else cb.consumer(consumer); - post.accept(cb); - }); - } - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CtxBiFunction.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CtxBiFunction.java deleted file mode 100644 index 5668ab6ad..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/CtxBiFunction.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.impl.WorkflowContextData; - -/** - * Functions that expect a {@link WorkflowContextData} injection in runtime - * - * @param The task payload input - * @param The task result output - */ -@FunctionalInterface -public interface CtxBiFunction { - R apply(WorkflowContextData context, T payload); -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/EmitStep.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/EmitStep.java deleted file mode 100644 index 89c2402d4..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/EmitStep.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.fluent.func.FuncEmitTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import java.util.Objects; -import java.util.function.Consumer; - -/** Chainable emit step; applies FuncEmitSpec then queued export/when. */ -public final class EmitStep extends Step { - - private final String name; // nullable - private final Consumer cfg; - - EmitStep(String name, Consumer cfg) { - this.name = name; - this.cfg = Objects.requireNonNull(cfg, "cfg"); - } - - @Override - protected void configure(FuncTaskItemListBuilder list, Consumer postApply) { - if (name == null) { - list.emit( - e -> { - cfg.accept(e); - postApply.accept(e); - }); - } else { - list.emit( - name, - e -> { - cfg.accept(e); - postApply.accept(e); - }); - } - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallGrpcStep.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallGrpcStep.java deleted file mode 100644 index daa93ad6f..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallGrpcStep.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.fluent.func.FuncCallGrpcTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import io.serverlessworkflow.fluent.spec.configurers.AuthenticationConfigurer; -import io.serverlessworkflow.fluent.spec.spi.CallGrpcTaskFluent; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public class FuncCallGrpcStep extends Step { - - private final List>> steps = new ArrayList<>(); - - private String name; - - public FuncCallGrpcStep(String name) { - this.name = name; - } - - public FuncCallGrpcStep() {} - - public void setName(String name) { - this.name = name; - } - - public FuncCallGrpcStep proto(String uri) { - steps.add(b -> b.proto(uri)); - return this; - } - - public FuncCallGrpcStep proto(String uri, AuthenticationConfigurer authenticationConfigurer) { - steps.add(b -> b.proto(uri, authenticationConfigurer)); - return this; - } - - public FuncCallGrpcStep service(String name, String host) { - steps.add(b -> b.service(name, host)); - return this; - } - - public FuncCallGrpcStep service(String name, String host, int port) { - steps.add(b -> b.service(name, host, port)); - return this; - } - - public FuncCallGrpcStep method(String method) { - steps.add(b -> b.method(method)); - return this; - } - - public FuncCallGrpcStep argument(String name, Object value) { - steps.add(b -> b.argument(name, value)); - return this; - } - - public FuncCallGrpcStep arguments(java.util.Map arguments) { - steps.add(b -> b.arguments(arguments)); - return this; - } - - public FuncCallGrpcStep authentication(AuthenticationConfigurer authenticationConfigurer) { - steps.add(b -> b.authentication(authenticationConfigurer)); - return this; - } - - @Override - protected void configure(FuncTaskItemListBuilder list, Consumer post) { - list.grpc( - name, - builder -> { - for (Consumer> c : steps) { - c.accept(builder); - } - post.accept(builder); - }); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallHttpStep.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallHttpStep.java deleted file mode 100644 index 5e7246281..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallHttpStep.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.fluent.func.FuncCallHttpTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import io.serverlessworkflow.fluent.spec.dsl.BaseCallHttpSpec; -import io.serverlessworkflow.fluent.spec.spi.CallHttpTaskFluent; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public class FuncCallHttpStep extends Step - implements BaseCallHttpSpec { - - private final List>> steps = new ArrayList<>(); - - private String name; - - public FuncCallHttpStep(String name) { - this.name = name; - } - - public FuncCallHttpStep() {} - - @Override - public FuncCallHttpStep self() { - return this; - } - - protected void configure(FuncTaskItemListBuilder list, Consumer post) { - list.http( - name, - builder -> { - this.accept(builder); - post.accept(builder); - }); - } - - @Override - public List>> steps() { - return steps; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallOpenAPIStep.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallOpenAPIStep.java deleted file mode 100644 index b6530cbfc..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallOpenAPIStep.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.api.types.OpenAPIArguments; -import io.serverlessworkflow.fluent.func.FuncCallOpenAPITaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import io.serverlessworkflow.fluent.spec.configurers.AuthenticationConfigurer; -import io.serverlessworkflow.fluent.spec.spi.CallOpenAPITaskFluent; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -public class FuncCallOpenAPIStep extends Step { - - private final List>> steps = new ArrayList<>(); - - private String name; - - public FuncCallOpenAPIStep(String name) { - this.name = name; - } - - public FuncCallOpenAPIStep() {} - - public void setName(String name) { - this.name = name; - } - - public FuncCallOpenAPIStep document(String uri) { - steps.add(b -> b.document(uri)); - return this; - } - - public FuncCallOpenAPIStep document( - String uri, AuthenticationConfigurer authenticationConfigurer) { - steps.add(b -> b.document(uri, authenticationConfigurer)); - return this; - } - - public FuncCallOpenAPIStep document(URI uri) { - steps.add(b -> b.document(uri)); - return this; - } - - public FuncCallOpenAPIStep document(URI uri, AuthenticationConfigurer authenticationConfigurer) { - steps.add(b -> b.document(uri, authenticationConfigurer)); - return this; - } - - public FuncCallOpenAPIStep operation(String operationId) { - steps.add(b -> b.operation(operationId)); - return this; - } - - public FuncCallOpenAPIStep parameters(Map params) { - steps.add(b -> b.parameters(params)); - return this; - } - - public FuncCallOpenAPIStep parameter(String name, String value) { - steps.add(b -> b.parameter(name, value)); - return this; - } - - public FuncCallOpenAPIStep redirect(boolean redirect) { - steps.add(b -> b.redirect(redirect)); - return this; - } - - public FuncCallOpenAPIStep authentication(AuthenticationConfigurer authenticationConfigurer) { - steps.add(b -> b.authentication(authenticationConfigurer)); - return this; - } - - public FuncCallOpenAPIStep output(OpenAPIArguments.WithOpenAPIOutput output) { - steps.add(b -> b.output(output)); - return this; - } - - @Override - protected void configure( - FuncTaskItemListBuilder list, Consumer post) { - list.openapi( - name, - builder -> { - for (Consumer> c : steps) { - c.accept(builder); - } - post.accept(builder); - }); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallStep.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallStep.java deleted file mode 100644 index 036534b8a..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncCallStep.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.fluent.func.FuncCallTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import java.util.function.Consumer; -import java.util.function.Function; - -public final class FuncCallStep extends Step, FuncCallTaskBuilder> { - - private final String name; - private final Function fn; - private final ContextFunction ctxFn; - private final FilterFunction filterFn; - private final Class argClass; - private final Class returnClass; - - /** Function variant (unnamed). */ - FuncCallStep(Function fn, Class argClass, Class returnClass) { - this(null, fn, argClass, returnClass); - } - - /** Function variant (named). */ - FuncCallStep(String name, Function fn, Class argClass, Class returnClass) { - this.name = name; - this.fn = fn; - this.ctxFn = null; - this.filterFn = null; - this.argClass = argClass; - this.returnClass = returnClass; - } - - /** ContextFunction variant (unnamed). */ - FuncCallStep(ContextFunction ctxFn, Class argClass, Class returnClass) { - this(null, ctxFn, argClass, returnClass); - } - - /** ContextFunction variant (named). */ - FuncCallStep(String name, ContextFunction ctxFn, Class argClass, Class returnClass) { - this.name = name; - this.fn = null; - this.ctxFn = ctxFn; - this.filterFn = null; - this.argClass = argClass; - this.returnClass = returnClass; - } - - /** FilterFunction variant (unnamed). */ - FuncCallStep(FilterFunction filterFn, Class argClass, Class returnClass) { - this(null, filterFn, argClass, returnClass); - } - - /** FilterFunction variant (named). */ - FuncCallStep( - String name, FilterFunction filterFn, Class argClass, Class returnClass) { - this.name = name; - this.fn = null; - this.ctxFn = null; - this.filterFn = filterFn; - this.argClass = argClass; - this.returnClass = returnClass; - } - - @Override - protected void configure(FuncTaskItemListBuilder list, Consumer post) { - final Consumer apply = - cb -> { - if (ctxFn != null) { - cb.function(ctxFn, argClass, returnClass); - } else if (filterFn != null) { - cb.function(filterFn, argClass, returnClass); - } else { - cb.function(fn, argClass, returnClass); - } - post.accept(cb); - }; - - if (name == null) { - list.function(apply); - } else { - list.function(name, apply); - } - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java deleted file mode 100644 index 34e37b3fc..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java +++ /dev/null @@ -1,2714 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.cloudevents.CloudEventData; -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.OAuth2AuthenticationData; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.InstanceIdFunction; -import io.serverlessworkflow.api.types.func.LoopFunction; -import io.serverlessworkflow.api.types.func.SerializableConsumer; -import io.serverlessworkflow.api.types.func.SerializableFunction; -import io.serverlessworkflow.api.types.func.SerializablePredicate; -import io.serverlessworkflow.api.types.func.UniqueIdBiFunction; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import io.serverlessworkflow.fluent.func.FuncCallTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncEmitTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncRaiseTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncSwitchTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import io.serverlessworkflow.fluent.func.FuncTryTaskBuilder; -import io.serverlessworkflow.fluent.func.configurers.FuncCallGrpcConfigurer; -import io.serverlessworkflow.fluent.func.configurers.FuncCallHttpConfigurer; -import io.serverlessworkflow.fluent.func.configurers.FuncCallOpenAPIConfigurer; -import io.serverlessworkflow.fluent.func.configurers.FuncTaskConfigurer; -import io.serverlessworkflow.fluent.func.configurers.SwitchCaseConfigurer; -import io.serverlessworkflow.fluent.spec.AbstractEventConsumptionStrategyBuilder; -import io.serverlessworkflow.fluent.spec.EventFilterBuilder; -import io.serverlessworkflow.fluent.spec.OAuth2AuthenticationPolicyBuilder; -import io.serverlessworkflow.fluent.spec.OAuth2AuthenticationPolicyBuilder.OAuth2AuthenticationPropertiesEndpointsBuilder; -import io.serverlessworkflow.fluent.spec.ScheduleBuilder; -import io.serverlessworkflow.fluent.spec.TimeoutBuilder; -import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder; -import io.serverlessworkflow.fluent.spec.configurers.AuthenticationConfigurer; -import io.serverlessworkflow.fluent.spec.configurers.WorkflowConfigurer; -import io.serverlessworkflow.fluent.spec.dsl.DSL; -import io.serverlessworkflow.fluent.spec.dsl.UseSpec; -import io.serverlessworkflow.fluent.spec.dsl.WorkflowSpec; -import io.serverlessworkflow.impl.TaskContextData; -import io.serverlessworkflow.impl.WorkflowContextData; -import java.net.URI; -import java.time.Duration; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * Fluent, ergonomic shortcuts for building function-centric workflows. - * - *

This DSL wraps the lower-level builders with strongly-typed helpers that: - * - *

    - *
  • Infer input types for Java lambdas where possible. - *
  • Expose chainable steps (e.g., {@code emit(...).exportAs(...).when(...)}) via {@link Step} - * subclasses. - *
  • Provide opinionated helpers for CloudEvents (JSON/bytes) and listen strategies. - *
  • Offer context-aware function variants ({@code withContext}, {@code withInstanceId}, {@code - * withUniqueId}, {@code agent}). - *
- * - *

Typical usage: - * - *

{@code
- * Workflow wf = FuncWorkflowBuilder.workflow("example")
- * .tasks(
- * FuncDSL.function(String::trim, String.class),
- * FuncDSL.emit(FuncDSL.produced("org.acme.started").jsonData(MyPayload.class)),
- * FuncDSL.listen(FuncDSL.toAny("type.one", "type.two"))
- * .outputAs(map -> map.get("value")),
- * FuncDSL.switchWhenOrElse((Integer v) -> v > 0, "positive", FlowDirectiveEnum.END, Integer.class)
- * ).build();
- * }
- */ -public final class FuncDSL { - private static final CommonFuncOps OPS = new CommonFuncOps() {}; - - private FuncDSL() {} - - /** - * Create a builder configurer for a {@link FuncCallTaskBuilder} that invokes a plain Java {@link - * Function} with an explicit input type. - * - * @param function the function to call during task execution - * @param argClass the expected input class for type-safe model conversion - * @param input type - * @param output type - * @return a consumer that configures a {@code FuncCallTaskBuilder} - */ - public static Consumer fn( - Function function, Class argClass) { - return OPS.fn(function, argClass); - } - - /** - * Create a builder configurer for a {@link FuncCallTaskBuilder} that invokes a plain Java {@link - * Function}. The input type is inferred when possible. - * - * @param function the function to call during task execution - * @param input type - * @param output type - * @return a consumer that configures a {@code FuncCallTaskBuilder} - */ - public static Consumer fn(SerializableFunction function) { - return f -> - f.function( - function, - ReflectionUtils.inferInputType(function), - ReflectionUtils.inferResultType(function)); - } - - /** - * Compose multiple switch cases into a single configurer for {@link FuncSwitchTaskBuilder}. - * - * @param cases one or more {@link SwitchCaseConfigurer} built via {@link - * #caseOf(SerializablePredicate)} or {@link #caseDefault(String)} - * @return a consumer to apply on a switch task builder - */ - public static Consumer cases(SwitchCaseConfigurer... cases) { - return OPS.cases(cases); - } - - /** - * Start a typed switch case using a Java {@link Predicate} with explicit input type. - * - * @param when the predicate used to match this case - * @param whenClass the predicate input class (used for typed conversion) - * @param predicate input type - * @return a fluent builder to set the consequent action (e.g., {@code then("taskName")}) - */ - public static SwitchCaseSpec caseOf(Predicate when, Class whenClass) { - return OPS.caseOf(when, whenClass); - } - - /** - * Start a switch case using a Java {@link Predicate}. Type inference is used when possible. - * - * @param when the predicate used to match this case - * @param predicate input type - * @return a fluent builder to set the consequent action (e.g., {@code then("taskName")}) - */ - public static SwitchCaseSpec caseOf(SerializablePredicate when) { - return OPS.caseOf(when); - } - - /** - * Default branch for a switch that jumps to a task name. - * - * @param task task name to continue with when no predicate matches - * @return switch case configurer - */ - public static SwitchCaseConfigurer caseDefault(String task) { - return OPS.caseDefault(task); - } - - /** - * Default branch for a switch that uses a {@link FlowDirectiveEnum} (e.g. {@code END}, {@code - * CONTINUE}). - * - * @param directive fallback directive when no predicate matches - * @return switch case configurer - */ - public static SwitchCaseConfigurer caseDefault(FlowDirectiveEnum directive) { - return OPS.caseDefault(directive); - } - - /** - * Begin building a {@code listen} specification with no pre-selected strategy. - * - * @return a new {@link FuncListenSpec} - */ - public static FuncListenSpec to() { - return new FuncListenSpec(); - } - - /** - * Convenience to listen for exactly one event type. - * - * @param type CloudEvent type to listen for - * @return a {@link FuncListenSpec} set to {@code one(type)} - */ - public static FuncListenSpec toOne(String type) { - return new FuncListenSpec().one(consumed(type)); - } - - public static FuncListenSpec toOne(FuncEventFilterSpec filter) { - return new FuncListenSpec().one(filter); - } - - /** - * Convenience to listen for all the given event types (logical AND). - * - * @param types CloudEvent types - * @return a {@link FuncListenSpec} set to {@code all(types...)} - */ - public static FuncListenSpec toAll(String... types) { - FuncEventFilterSpec[] events = new FuncEventFilterSpec[types.length]; - for (int i = 0; i < types.length; i++) { - events[i] = consumed(types[i]); - } - return new FuncListenSpec().all(events); - } - - /** - * Convenience to listen for any of the given event types (logical OR). - * - * @param types CloudEvent types - * @return a {@link FuncListenSpec} set to {@code any(types...)} - */ - public static FuncListenSpec toAny(String... types) { - FuncEventFilterSpec[] events = new FuncEventFilterSpec[types.length]; - for (int i = 0; i < types.length; i++) { - events[i] = consumed(types[i]); - } - return new FuncListenSpec().any(events); - } - - /** - * Build an {@code emit} event configurer by supplying a type and a function that produces {@link - * CloudEventData}. The function is invoked at runtime with the current payload. - * - * @param type CloudEvent type - * @param function function that maps workflow input to {@link CloudEventData} - * @param input type to the function - * @return a consumer to configure {@link FuncEmitTaskBuilder} - */ - public static Consumer produced( - String type, SerializableFunction function) { - return event -> - event.event(e -> e.type(type).data(function, ReflectionUtils.inferInputType(function))); - } - - /** - * Same as {@link #produced(String, SerializableFunction)} but with an explicit input class to - * guide conversion. - * - * @param type CloudEvent type - * @param function function that maps workflow input to {@link CloudEventData} - * @param inputClass expected input class for conversion - * @param input type - * @return a consumer to configure {@link FuncEmitTaskBuilder} - */ - public static Consumer produced( - String type, Function function, Class inputClass) { - return event -> event.event(e -> e.type(type).data(function, inputClass)); - } - - public static Consumer produced( - String type, ContextFunction function) { - return event -> - event.event(e -> e.type(type).data(function, ReflectionUtils.inferInputType(function))); - } - - public static Consumer produced( - String type, FilterFunction function) { - return event -> - event.event(e -> e.type(type).data(function, ReflectionUtils.inferInputType(function))); - } - - /** - * Emit a JSON CloudEvent for a POJO input type. Sets {@code contentType=application/json} and - * serializes the input to bytes using the configured JSON mapper. - * - * @param type CloudEvent type - * @param inputClass input POJO class (used for typing and conversion) - * @param input type - * @return a consumer to configure {@link FuncEmitTaskBuilder} - */ - public static Consumer producedJson(String type, Class inputClass) { - return b -> new FuncEmitSpec().type(type).jsonData(inputClass).accept(b); - } - - /** - * Emit a CloudEvent with arbitrary bytes payload generated by a custom serializer. - * - * @param type CloudEvent type - * @param serializer function producing bytes from the input - * @param inputClass expected input class for conversion - * @param input type - * @return a consumer to configure {@link FuncEmitTaskBuilder} - */ - public static Consumer producedBytes( - String type, Function serializer, Class inputClass) { - return b -> new FuncEmitSpec().type(type).bytesData(serializer, inputClass).accept(b); - } - - /** - * Emit a CloudEvent where the input model is serialized to bytes using UTF-8. Useful for - * string-like payloads (e.g., already-built JSON or text). - * - * @param type CloudEvent type - * @return a consumer to configure {@link FuncEmitTaskBuilder} - */ - public static Consumer producedBytesUtf8(String type) { - return b -> new FuncEmitSpec().type(type).bytesDataUtf8().accept(b); - } - - /** - * Starts building an event emission specification with a predefined type. - * - * @param type CloudEvent type to be emitted - * @return a new {@link FuncEmitSpec} instance pre-configured with the event type - */ - public static FuncEmitSpec produced(String type) { - return new FuncEmitSpec().type(type); - } - - /** - * Starts building a function-centric event filter specification for a specific CloudEvent type. * - * - *

This creates an empty {@link FuncEventFilterSpec} which acts as a fluent builder for - * matching incoming CloudEvents. It is typically passed to a {@code listen} strategy like {@link - * #toOne(String)} or {@code to().any(...)}. - * - * @param type the {@code type} attribute of the CloudEvent to listen for - * @return a new {@link FuncEventFilterSpec} instance pre-configured with the event type - */ - public static FuncEventFilterSpec consumed(String type) { - return new FuncEventFilterSpec().type(type); - } - - /** - * Build a call step for functions that need {@link WorkflowContextData} as the first parameter. - * The DSL wraps it as a {@link ContextFunction} and injects the runtime context. - * - *

Signature expected: {@code (ctx, payload) -> result} - * - * @param fn context-aware function - * @param in payload input class - * @param input type - * @param result type - * @return a call step - */ - public static FuncCallStep withContext(ContextFunction fn, Class in) { - return withContext(null, fn, in); - } - - public static FuncCallStep withContext(ContextFunction fn) { - return withContext(null, fn, ReflectionUtils.inferInputType(fn)); - } - - /** - * Named variant of {@link #withContext(ContextFunction, Class)}. - * - * @param name task name - * @param fn context-aware function - * @param in payload input class - * @param input type - * @param result type - * @return a named call step - */ - public static FuncCallStep withContext( - String name, ContextFunction fn, Class in) { - return withContext(name, fn, in, ReflectionUtils.inferResultType(fn)); - } - - public static FuncCallStep withContext( - String name, ContextFunction fn, Class in, Class out) { - return new FuncCallStep<>(name, fn, in, out); - } - - public static FuncCallStep withContext(String name, ContextFunction fn) { - return withContext(name, fn, ReflectionUtils.inferInputType(fn)); - } - - /** - * Build a call step for functions that need {@link WorkflowContextData} and {@link - * TaskContextData} as the first and second parameter. The DSL wraps it as a {@link - * FilterFunction} and injects the runtime context. - * - *

Signature expected: {@code (payload, wctx, tctx) -> result} - * - * @param fn context-aware filter function - * @param in payload input class - * @param input type - * @param result type - * @return a call step - */ - public static FuncCallStep withFilter(FilterFunction fn, Class in) { - return withFilter(null, fn, in); - } - - /** - * Named variant of {@link #withFilter(FilterFunction, Class)}. - * - * @param name task name - * @param fn context-aware filter function - * @param in payload input class - * @param input type - * @param result type - * @return a named call step - */ - public static FuncCallStep withFilter( - String name, FilterFunction fn, Class in) { - return withFilter(name, fn, in, ReflectionUtils.inferResultType(fn)); - } - - public static FuncCallStep withFilter( - String name, FilterFunction fn, Class in, Class out) { - return new FuncCallStep<>(name, fn, in, out); - } - - public static FuncCallStep withFilter(FilterFunction fn) { - return withFilter(null, fn, ReflectionUtils.inferInputType(fn)); - } - - public static FuncCallStep withFilter(String name, FilterFunction fn) { - return withFilter(name, fn, ReflectionUtils.inferInputType(fn)); - } - - /** - * Named variant of {@link #withInstanceId(InstanceIdFunction, Class)}. - * - * @param name task name - * @param fn instance-id-aware function - * @param in payload input class - * @param input type - * @param result type - * @return a named call step - */ - public static FuncCallStep withInstanceId( - String name, InstanceIdFunction fn, Class in) { - return withInstanceId(name, fn, in, ReflectionUtils.inferResultType(fn)); - } - - public static FuncCallStep withInstanceId( - String name, InstanceIdFunction fn, Class in, Class out) { - ContextFunction jcf = (payload, wctx) -> fn.apply(wctx.instanceData().id(), payload); - return new FuncCallStep<>(name, jcf, in, out); - } - - /** - * Build a call step for functions that expect the workflow instance ID as the first parameter. - * The instance ID is extracted from the runtime context. - * - *

Signature expected: {@code (instanceId, payload) -> result} - * - * @param fn instance-id-aware function - * @param in payload input class - * @param input type - * @param result type - * @return a call step - */ - public static FuncCallStep withInstanceId(InstanceIdFunction fn, Class in) { - return withInstanceId(null, fn, in); - } - - public static FuncCallStep withInstanceId(String name, InstanceIdFunction fn) { - return withInstanceId(name, fn, ReflectionUtils.inferInputType(fn)); - } - - public static FuncCallStep withInstanceId(InstanceIdFunction fn) { - return withInstanceId(null, fn, ReflectionUtils.inferInputType(fn)); - } - - /** - * Builds a composition of the current workflow instance id and the definition of the task - * position as a JSON pointer, used as a stable "unique id" for the task. - * - * @param wctx workflow context - * @param tctx task context - * @return a unique id in the form {@code "-"} - */ - static String defaultUniqueId(WorkflowContextData wctx, TaskContextData tctx) { - return String.format("%s-%s", wctx.instanceData().id(), tctx.position().jsonPointer()); - } - - /** - * Build a named call step for functions that expect a composite "unique id" as the first - * parameter. This id is derived from the workflow instance id and the task definition position, - * encoded as a JSON pointer. - * - *

The unique ID follows the pattern: {@code "-"} where the JSON - * pointer represents the task's position in the workflow definition. - * - *

This overload requires explicit input class and infers the output type from the function - * signature. - * - *

Signature expected: {@code (uniqueId, payload) -> result} - * - *

Example: - * - *

{@code
-   * tasks(
-   *   withUniqueId("processOrder",
-   *     (String uniqueId, OrderRequest order) -> {
-   *       // Use uniqueId for stateful operations (e.g., database keys, cache entries)
-   *       return orderService.process(uniqueId, order);
-   *     },
-   *     OrderRequest.class
-   *   )
-   * );
-   * }
- * - * @param name task name (or {@code null} for an anonymous task) - * @param fn unique-id-aware function accepting (uniqueId, payload) and returning a result - * @param in payload input class for type-safe conversion - * @param input type - * @param result type - * @return a named call step that can be chained with additional configurations - * @see #withUniqueId(String, UniqueIdBiFunction, Class, Class) - * @see #withUniqueId(String, UniqueIdBiFunction) - * @see #withUniqueId(UniqueIdBiFunction, Class) - * @see #withUniqueId(UniqueIdBiFunction) - */ - public static FuncCallStep withUniqueId( - String name, UniqueIdBiFunction fn, Class in) { - return withUniqueId(name, fn, in, ReflectionUtils.inferResultType(fn)); - } - - /** - * Build a named call step for functions that expect a composite "unique id" as the first - * parameter, with explicit input and output type classes. - * - *

The unique ID follows the pattern: {@code "-"} where the JSON - * pointer represents the task's position in the workflow definition. - * - *

This overload provides complete control over type conversion by explicitly specifying both - * input and output classes. Use this when automatic type inference is not sufficient or when you - * need to ensure specific serialization/deserialization behavior. - * - *

Signature expected: {@code (uniqueId, payload) -> result} - * - *

Example: - * - *

{@code
-   * tasks(
-   *   withUniqueId("enrichData",
-   *     (String uniqueId, Map input) -> {
-   *       // Process and transform with explicit types
-   *       return dataEnricher.enrich(uniqueId, input);
-   *     },
-   *     Map.class,
-   *     EnrichedData.class
-   *   )
-   * );
-   * }
- * - * @param name task name (or {@code null} for an anonymous task) - * @param fn unique-id-aware function accepting (uniqueId, payload) and returning a result - * @param in payload input class for type-safe conversion - * @param out result output class for type-safe conversion - * @param input type - * @param result type - * @return a named call step that can be chained with additional configurations - * @see #withUniqueId(String, UniqueIdBiFunction, Class) - * @see #withUniqueId(String, UniqueIdBiFunction) - * @see #withUniqueId(UniqueIdBiFunction, Class) - * @see #withUniqueId(UniqueIdBiFunction) - */ - public static FuncCallStep withUniqueId( - String name, UniqueIdBiFunction fn, Class in, Class out) { - FilterFunction jff = - (payload, wctx, tctx) -> fn.apply(defaultUniqueId(wctx, tctx), payload); - return new FuncCallStep<>(name, jff, in, out); - } - - /** - * Build a named call step for functions that expect a composite "unique id" as the first - * parameter, with automatic type inference. - * - *

The unique ID follows the pattern: {@code "-"} where the JSON - * pointer represents the task's position in the workflow definition. - * - *

This overload uses reflection to automatically infer both input and output types from the - * {@link UniqueIdBiFunction} interface. This is the most concise variant but requires the - * function to be serializable for type inference to work. - * - *

Signature expected: {@code (uniqueId, payload) -> result} - * - *

Example: - * - *

{@code
-   * tasks(
-   *   withUniqueId("cacheResult",
-   *     (String uniqueId, ProcessRequest req) -> {
-   *       cache.store(uniqueId, req);
-   *       return processor.handle(req);
-   *     }
-   *   )
-   * );
-   * }
- * - * @param name task name (or {@code null} for an anonymous task) - * @param fn unique-id-aware function with serializable signature for type inference - * @param input type (inferred automatically) - * @param result type (inferred automatically) - * @return a named call step that can be chained with additional configurations - * @see #withUniqueId(String, UniqueIdBiFunction, Class) - * @see #withUniqueId(String, UniqueIdBiFunction, Class, Class) - * @see #withUniqueId(UniqueIdBiFunction) - */ - public static FuncCallStep withUniqueId(String name, UniqueIdBiFunction fn) { - return withUniqueId(name, fn, ReflectionUtils.inferInputType(fn)); - } - - /** - * Build an unnamed call step for functions that expect a composite "unique id" as the first - * parameter. - * - *

The unique ID follows the pattern: {@code "-"} where the JSON - * pointer represents the task's position in the workflow definition. - * - *

This overload requires an explicit input class and infers the output type from the function - * signature. Use this when you don't need to assign a specific task name. - * - *

Signature expected: {@code (uniqueId, payload) -> result} - * - *

Example: - * - *

{@code
-   * tasks(
-   *   withUniqueId(
-   *     (String uniqueId, CustomerData data) -> {
-   *       logger.log("Processing " + uniqueId);
-   *       return customerProcessor.process(data);
-   *     },
-   *     CustomerData.class
-   *   )
-   * );
-   * }
- * - * @param fn unique-id-aware function accepting (uniqueId, payload) and returning a result - * @param in payload input class for type-safe conversion - * @param input type - * @param result type - * @return an unnamed call step that can be chained with additional configurations - * @see #withUniqueId(String, UniqueIdBiFunction, Class) - * @see #withUniqueId(String, UniqueIdBiFunction, Class, Class) - * @see #withUniqueId(UniqueIdBiFunction) - */ - public static FuncCallStep withUniqueId(UniqueIdBiFunction fn, Class in) { - return withUniqueId(null, fn, in); - } - - /** - * Build an unnamed call step for functions that expect a composite "unique id" as the first - * parameter, with automatic type inference. - * - *

The unique ID follows the pattern: {@code "-"} where the JSON - * pointer represents the task's position in the workflow definition. - * - *

This is the most concise overload, using reflection to automatically infer both input and - * output types. It creates an anonymous task, which is useful for quick inline operations. - * - *

Signature expected: {@code (uniqueId, payload) -> result} - * - *

Example: - * - *

{@code
-   * tasks(
-   *   withUniqueId((String uniqueId, String input) -> {
-   *     // Quick stateful operation with unique ID
-   *     stateManager.update(uniqueId, input);
-   *     return input.toUpperCase();
-   *   })
-   * );
-   * }
- * - * @param fn unique-id-aware function with serializable signature for type inference - * @param input type (inferred automatically) - * @param result type (inferred automatically) - * @return an unnamed call step that can be chained with additional configurations - * @see #withUniqueId(String, UniqueIdBiFunction) - * @see #withUniqueId(UniqueIdBiFunction, Class) - * @see #withUniqueId(String, UniqueIdBiFunction, Class) - */ - public static FuncCallStep withUniqueId(UniqueIdBiFunction fn) { - return withUniqueId(null, fn, ReflectionUtils.inferInputType(fn)); - } - - /** - * Create a fire-and-forget side-effect step (unnamed). The consumer receives the typed input. - * - * @param consumer side-effect function - * @param inputClass expected input class for conversion - * @param input type - * @return a {@link ConsumeStep} which can be chained and added via {@link - * #tasks(FuncTaskConfigurer...)} - */ - public static ConsumeStep consume(Consumer consumer, Class inputClass) { - return new ConsumeStep<>(consumer, inputClass); - } - - public static ConsumeStep consume(SerializableConsumer consumer) { - return consume(consumer, ReflectionUtils.inferInputType(consumer)); - } - - /** - * Named variant of {@link #consume(Consumer, Class)}. - * - * @param name task name - * @param consumer side-effect function - * @param inputClass expected input class - * @param input type - * @return a named {@link ConsumeStep} - */ - public static ConsumeStep consume(String name, Consumer consumer, Class inputClass) { - return new ConsumeStep<>(name, consumer, inputClass); - } - - public static ConsumeStep consume(String name, SerializableConsumer consumer) { - return consume(name, consumer, ReflectionUtils.inferInputType(consumer)); - } - - /** - * Agent-style sugar for methods that receive a "memory id" as first parameter. The DSL uses a - * derived unique id composed of the workflow instance id and the task position (JSON pointer), - * via {@link #withUniqueId(UniqueIdBiFunction, Class)}. - * - *

Signature expected: {@code (uniqueId, payload) -> result} - * - * @param fn (uniqueId, payload) -> result - * @param in payload input class - * @param input type - * @param result type - * @return a call step - */ - public static FuncCallStep agent(UniqueIdBiFunction fn, Class in) { - return withUniqueId(fn, in); - } - - public static FuncCallStep agent(UniqueIdBiFunction fn) { - return withUniqueId(fn, ReflectionUtils.inferInputType(fn)); - } - - /** - * Named agent-style sugar. See {@link #agent(UniqueIdBiFunction, Class)}. - * - *

Signature expected: {@code (uniqueId, payload) -> result} - * - * @param name task name - * @param fn (uniqueId, payload) -> result - * @param in payload input class - * @param input type - * @param result type - * @return a named call step - */ - public static FuncCallStep agent( - String name, UniqueIdBiFunction fn, Class in) { - return withUniqueId(name, fn, in); - } - - public static FuncCallStep agent(String name, UniqueIdBiFunction fn) { - return withUniqueId(name, fn, ReflectionUtils.inferInputType(fn)); - } - - /** - * Create a {@link FuncCallStep} that calls a simple Java {@link Function} with explicit input - * type. - * - * @param fn the function to execute at runtime - * @param inputClass expected input class for model conversion - * @param input type - * @param result type - * @return a call step which supports chaining (e.g., {@code .exportAs(...).when(...)}) - */ - public static FuncCallStep function(Function fn, Class inputClass) { - return function(fn, inputClass, null); - } - - /** - * Create a {@link FuncCallStep} that calls a simple Java {@link Function} with explicit input - * type. - * - * @param fn the function to execute at runtime - * @param inputClass expected input class for model conversion - * @param outputClass expected outputClass class for model conversion - * @param input type - * @param result type - * @return a call step which supports chaining (e.g., {@code .exportAs(...).when(...)}) - */ - public static FuncCallStep function( - Function fn, Class inputClass, Class outputClass) { - return new FuncCallStep<>(fn, inputClass, outputClass); - } - - /** - * Create a {@link FuncCallStep} that invokes a plain Java {@link Function} with inferred input - * type. - * - * @param fn the function to execute - * @param input type - * @param output type - * @return a call step - */ - public static FuncCallStep function(SerializableFunction fn) { - return new FuncCallStep<>( - fn, ReflectionUtils.inferInputType(fn), ReflectionUtils.inferResultType(fn)); - } - - /** - * Named variant of {@link #function(SerializableFunction)} with inferred input type. - * - * @param name task name - * @param fn the function to execute - * @param input type - * @param output type - * @return a named call step - */ - public static FuncCallStep function(String name, SerializableFunction fn) { - return new FuncCallStep<>( - name, fn, ReflectionUtils.inferInputType(fn), ReflectionUtils.inferResultType(fn)); - } - - /** - * Named variant of {@link #function(Function, Class)} with explicit input type. - * - * @param name task name - * @param fn the function to execute - * @param inputClass expected input class - * @param input type - * @param output type - * @return a named call step - */ - public static FuncCallStep function( - String name, Function fn, Class inputClass) { - return new FuncCallStep<>(name, fn, inputClass, null); - } - - /** - * Named variant of {@link #function(Function, Class)} with explicit input type. - * - * @param name task name - * @param fn the function to execute - * @param inputClass expected input class - * @param outputClass expected output class - * @param input type - * @param output type - * @return a named call step - */ - public static FuncCallStep function( - String name, Function fn, Class inputClass, Class outputClass) { - return new FuncCallStep<>(name, fn, inputClass, outputClass); - } - - // ------------------ tasks ---------------- // - - /** - * Compose a list of step configurers into a single {@code tasks} block. Preserves order and - * defers application to the underlying list builder. - * - * @param steps one or more step configurers (including {@link Step} subclasses) - * @return a consumer for {@link FuncTaskItemListBuilder} - */ - public static Consumer tasks(FuncTaskConfigurer... steps) { - Objects.requireNonNull(steps, "Steps in a tasks are required"); - final List snapshot = List.of(steps.clone()); - return list -> snapshot.forEach(s -> s.accept(list)); - } - - /** - * Starts building a function-centric event emission specification. - * - *

This creates an empty {@link FuncEmitSpec} which acts as a fluent builder for the properties - * (e.g., type, source, data) of the CloudEvent to be emitted. It is typically passed to the - * {@link #emit(Consumer)} step. - * - * @return a new {@link FuncEmitSpec} instance for fluent configuration - */ - public static FuncEmitSpec produced() { - return new FuncEmitSpec(); - } - - /** - * Create an {@code emit} step from a low-level {@link FuncEmitTaskBuilder} configurer. Prefer - * higher-level helpers like {@link #emitJson(String, Class)} where possible. - * - * @param cfg emit builder configurer - * @return an {@link EmitStep} supporting chaining (e.g., {@code .exportAs(...).when(...)}) - */ - public static EmitStep emit(Consumer cfg) { - return new EmitStep(null, cfg); - } - - /** - * Named variant of {@link #emit(Consumer)}. - * - * @param name task name - * @param cfg emit builder configurer - * @return a named {@link EmitStep} - */ - public static EmitStep emit(String name, Consumer cfg) { - return new EmitStep(name, cfg); - } - - /** - * Convenience for emitting a CloudEvent using a function that builds {@link CloudEventData}. - * - * @param type CloudEvent type - * @param fn function that produces event data from the input - * @param input type - * @return an {@link EmitStep} - */ - public static EmitStep emit(String type, SerializableFunction fn) { - return new EmitStep(null, produced(type, fn)); - } - - /** - * Named variant of {@link #emit(String, SerializableFunction)}. - * - * @param name task name - * @param type CloudEvent type - * @param fn function producing {@link CloudEventData} - * @param input type - * @return a named {@link EmitStep} - */ - public static EmitStep emit( - String name, String type, SerializableFunction fn) { - return new EmitStep(name, produced(type, fn)); - } - - /** - * Emit a bytes-based CloudEvent using a custom serializer and explicit input class. - * - * @param name task name - * @param type CloudEvent type - * @param serializer function producing bytes - * @param inputClass expected input class - * @param input type - * @return a named {@link EmitStep} - */ - public static EmitStep emit( - String name, String type, Function serializer, Class inputClass) { - return new EmitStep(name, producedBytes(type, serializer, inputClass)); - } - - /** - * Unnamed variant of {@link #emit(String, String, Function, Class)}. - * - * @param type CloudEvent type - * @param serializer function producing bytes - * @param inputClass expected input class - * @param input type - * @return an {@link EmitStep} - */ - public static EmitStep emit( - String type, Function serializer, Class inputClass) { - return new EmitStep(null, producedBytes(type, serializer, inputClass)); - } - - /** - * Emit a JSON CloudEvent from a POJO input class (unnamed). - * - * @param type CloudEvent type - * @param inputClass input POJO class - * @param input type - * @return an {@link EmitStep} - */ - public static EmitStep emitJson(String type, Class inputClass) { - return new EmitStep(null, producedJson(type, inputClass)); - } - - /** - * Emit a JSON CloudEvent from a POJO input class (named). - * - * @param name task name - * @param type CloudEvent type - * @param inputClass input POJO class - * @param input type - * @return a named {@link EmitStep} - */ - public static EmitStep emitJson(String name, String type, Class inputClass) { - return new EmitStep(name, producedJson(type, inputClass)); - } - - /** - * Create a {@code listen} step from a {@link FuncListenSpec}. - * - * @param spec a listen spec (e.g., {@code toAny("a","b")}, {@code toOne("x")}) - * @return a {@link ListenStep} supporting chaining (e.g., {@code .outputAs(...).when(...)}) - */ - public static ListenStep listen(FuncListenSpec spec) { - return new ListenStep(null, spec); - } - - /** - * Named variant of {@link #listen(FuncListenSpec)}. - * - * @param name task name - * @param spec listen spec - * @return a named {@link ListenStep} - */ - public static ListenStep listen(String name, FuncListenSpec spec) { - return new ListenStep(name, spec); - } - - /** - * Low-level switch case configurer using a custom builder consumer. Prefer the {@link - * #caseOf(SerializablePredicate)} helpers when possible. - * - * @param taskName optional task name - * @param switchCase consumer to configure the {@link FuncSwitchTaskBuilder} - * @return a list configurer - */ - public static FuncTaskConfigurer switchCase( - String taskName, Consumer switchCase) { - return list -> list.switchCase(taskName, switchCase); - } - - /** - * Variant of {@link #switchCase(String, Consumer)} without a name. - * - * @param switchCase consumer to configure the {@link FuncSwitchTaskBuilder} - * @return a list configurer - */ - public static FuncTaskConfigurer switchCase(Consumer switchCase) { - return list -> list.switchCase(switchCase); - } - - /** - * Convenience to apply multiple {@link SwitchCaseConfigurer} built via {@link - * #caseOf(SerializablePredicate)}. - * - * @param cases case configurers - * @return list configurer - */ - public static FuncTaskConfigurer switchCase(SwitchCaseConfigurer... cases) { - return switchCase(null, cases); - } - - /** - * Named variant of {@link #switchCase(SwitchCaseConfigurer...)}. - * - * @param taskName task name - * @param cases case configurers - * @return list configurer - */ - public static FuncTaskConfigurer switchCase(String taskName, SwitchCaseConfigurer... cases) { - Objects.requireNonNull(cases, "cases are required"); - final List snapshot = List.of(cases.clone()); - return list -> list.switchCase(taskName, s -> snapshot.forEach(s::onPredicate)); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code raise} task. - * - * @param configurer raise task builder configurer - * @return list configurer - */ - public static FuncTaskConfigurer raise(Consumer configurer) { - return list -> list.raise(configurer); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code raise} task. - * - * @param name task name - * @param configurer raise task builder configurer - * @return list configurer - */ - public static FuncTaskConfigurer raise(String name, Consumer configurer) { - return list -> list.raise(name, configurer); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code try/catch} task. - * - * @param configurer try task builder configurer - * @return list configurer - */ - public static FuncTaskConfigurer tryCatch(Consumer configurer) { - return list -> list.tryCatch(configurer); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code try/catch} task. - * - * @param name task name - * @param configurer try task builder configurer - * @return list configurer - */ - public static FuncTaskConfigurer tryCatch(String name, Consumer configurer) { - return list -> list.tryCatch(name, configurer); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code wait} task configured with a duration - * expression. - * - *

Example: {@code tasks(wait("PT5M"))} - * - * @param durationExpression duration expression or ISO 8601 literal - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer wait(String durationExpression) { - return taskList -> taskList.wait(w -> w.wait(durationExpression)); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code wait} task configured with a - * duration expression. - * - *

Example: {@code tasks(wait("pause", "PT5M"))} - * - * @param name task name - * @param durationExpression duration expression or ISO 8601 literal - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer wait(String name, String durationExpression) { - return taskList -> taskList.wait(name, w -> w.wait(durationExpression)); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code wait} task configured with an inline - * duration builder. - * - *

Example: {@code tasks(wait(timeoutSeconds(30)))} - * - * @param duration timeout builder consumer - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer wait(Consumer duration) { - return taskList -> taskList.wait(w -> w.wait(duration)); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code wait} task configured with an - * inline duration builder. - * - *

Example: {@code tasks(wait("pause", timeoutSeconds(30)))} - * - * @param name task name - * @param duration timeout builder consumer - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer wait(String name, Consumer duration) { - return taskList -> taskList.wait(name, w -> w.wait(duration)); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code wait} task configured with seconds. - * - *

Example: {@code tasks(waitSeconds(30))} - * - * @param seconds wait duration in seconds - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitSeconds(int seconds) { - return taskList -> taskList.wait(w -> w.wait(t -> t.duration(d -> d.seconds(seconds)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code wait} task configured with - * seconds. - * - *

Example: {@code tasks(waitSeconds("pause", 30))} - * - * @param name task name - * @param seconds wait duration in seconds - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitSeconds(String name, int seconds) { - return taskList -> taskList.wait(name, w -> w.wait(t -> t.duration(d -> d.seconds(seconds)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code wait} task configured with minutes. - * - *

Example: {@code tasks(waitMinutes(5))} - * - * @param minutes wait duration in minutes - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitMinutes(int minutes) { - return taskList -> taskList.wait(w -> w.wait(t -> t.duration(d -> d.minutes(minutes)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code wait} task configured with - * minutes. - * - *

Example: {@code tasks(waitMinutes("pause", 5))} - * - * @param name task name - * @param minutes wait duration in minutes - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitMinutes(String name, int minutes) { - return taskList -> taskList.wait(name, w -> w.wait(t -> t.duration(d -> d.minutes(minutes)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code wait} task configured with hours. - * - *

Example: {@code tasks(waitHours(2))} - * - * @param hours wait duration in hours - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitHours(int hours) { - return taskList -> taskList.wait(w -> w.wait(t -> t.duration(d -> d.hours(hours)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code wait} task configured with hours. - * - *

Example: {@code tasks(waitHours("longPause", 2))} - * - * @param name task name - * @param hours wait duration in hours - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitHours(String name, int hours) { - return taskList -> taskList.wait(name, w -> w.wait(t -> t.duration(d -> d.hours(hours)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code wait} task configured with days. - * - *

Example: {@code tasks(waitDays(1))} - * - * @param days wait duration in days - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitDays(int days) { - return taskList -> taskList.wait(w -> w.wait(t -> t.duration(d -> d.days(days)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code wait} task configured with days. - * - *

Example: {@code tasks(waitDays("dailyDelay", 1))} - * - * @param name task name - * @param days wait duration in days - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitDays(String name, int days) { - return taskList -> taskList.wait(name, w -> w.wait(t -> t.duration(d -> d.days(days)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code wait} task configured with milliseconds. - * - *

Example: {@code tasks(waitMillis(500))} - * - * @param milliseconds wait duration in milliseconds - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitMillis(int milliseconds) { - return taskList -> - taskList.wait(w -> w.wait(t -> t.duration(d -> d.milliseconds(milliseconds)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code wait} task configured with - * milliseconds. - * - *

Example: {@code tasks(waitMillis("shortPause", 500))} - * - * @param name task name - * @param milliseconds wait duration in milliseconds - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer waitMillis(String name, int milliseconds) { - return taskList -> - taskList.wait(name, w -> w.wait(t -> t.duration(d -> d.milliseconds(milliseconds)))); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a {@code wait} task configured with a Java {@link - * java.time.Duration}. - * - *

The Duration is converted to DurationInline format. - * - *

Example: {@code tasks(wait(Duration.ofMinutes(5).plusSeconds(30)))} - * - * @param duration wait duration as a Java Duration - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer wait(Duration duration) { - return taskList -> taskList.wait(w -> w.wait(duration)); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named {@code wait} task configured with a Java - * {@link java.time.Duration}. - * - *

The Duration is converted to DurationInline format. - * - *

Example: {@code tasks(wait("pause", Duration.ofMinutes(5)))} - * - * @param name task name - * @param duration wait duration as a Java Duration - * @return a {@link FuncTaskConfigurer} that adds a WaitTask - */ - public static FuncTaskConfigurer wait(String name, Duration duration) { - return taskList -> taskList.wait(name, w -> w.wait(duration)); - } - - /** - * Sugar for a single-case switch: if predicate matches, jump to {@code thenTask}. - * - * @param pred predicate - * @param thenTask task name when predicate is true - * @param predClass predicate class - * @param predicate input type - * @return list configurer - */ - public static FuncTaskConfigurer switchWhen( - Predicate pred, String thenTask, Class predClass) { - return switchWhen(null, pred, thenTask, predClass); - } - - /** - * Named variant of {@link #switchWhen(Predicate, String, Class)}. - * - * @param taskName task name for the switch task - * @param pred predicate - * @param thenTask task name when predicate is true - * @param predClass predicate class - * @param predicate input type - * @return list configurer - */ - public static FuncTaskConfigurer switchWhen( - String taskName, Predicate pred, String thenTask, Class predClass) { - return list -> list.switchCase(taskName, cases(caseOf(pred, predClass).then(thenTask))); - } - - /** - * JQ-based condition: if the JQ expression evaluates truthy → jump to {@code thenTask}. - * - *

-   * switchWhen(".approved == true", "approveOrder")
-   * 
- * - *

The JQ expression is evaluated against the task input at runtime. When the predicate is - * false, the workflow follows the default flow directive for the switch task (as defined by the - * underlying implementation / spec). - * - * @param jqExpression JQ expression evaluated against the current task input - * @param thenTask task name to jump to when the expression evaluates truthy - * @return list configurer - */ - public static FuncTaskConfigurer switchWhen(String jqExpression, String thenTask) { - return switchWhen(null, jqExpression, thenTask); - } - - /** - * Named variant of {@link #switchWhen(String, String)}. - * - * @param taskName task name for the switch task - * @param jqExpression JQ expression evaluated against the current task input - * @param thenTask task name to jump to when the expression evaluates truthy - * @return list configurer - */ - public static FuncTaskConfigurer switchWhen( - String taskName, String jqExpression, String thenTask) { - return list -> list.switchCase(taskName, sw -> sw.on(c -> c.when(jqExpression).then(thenTask))); - } - - /** - * Sugar for a single-case switch with a default {@link FlowDirectiveEnum} fallback. - * - * @param pred predicate - * @param thenTask task name when predicate is true - * @param otherwise default flow directive when predicate is false - * @param predClass predicate class - * @param predicate input type - * @return list configurer - */ - public static FuncTaskConfigurer switchWhenOrElse( - Predicate pred, String thenTask, FlowDirectiveEnum otherwise, Class predClass) { - return switchWhenOrElse(null, pred, thenTask, otherwise, predClass); - } - - public static FuncTaskConfigurer switchWhenOrElse( - SerializablePredicate pred, String thenTask, FlowDirectiveEnum otherwise) { - return switchWhenOrElse(null, pred, thenTask, otherwise); - } - - /** - * Named variant of {@link #switchWhenOrElse(Predicate, String, FlowDirectiveEnum, Class)}. - * - * @param taskName task name for the switch task - * @param pred predicate - * @param thenTask task name when predicate is true - * @param otherwise default flow directive when predicate is false - * @param predClass predicate class - * @param predicate input type - * @return list configurer - */ - public static FuncTaskConfigurer switchWhenOrElse( - String taskName, - Predicate pred, - String thenTask, - FlowDirectiveEnum otherwise, - Class predClass) { - return list -> - list.switchCase( - taskName, - FuncDSL.cases(caseOf(pred, predClass).then(thenTask), caseDefault(otherwise))); - } - - public static FuncTaskConfigurer switchWhenOrElse( - String taskName, - SerializablePredicate pred, - String thenTask, - FlowDirectiveEnum otherwise) { - return switchWhenOrElse( - taskName, pred, thenTask, otherwise, ReflectionUtils.inferInputType(pred)); - } - - /** - * Sugar for a single-case switch with a default task fallback. - * - * @param pred predicate - * @param thenTask task name when predicate is true - * @param otherwiseTask task name when predicate is false - * @param predClass predicate class - * @param predicate input type - * @return list configurer - */ - public static FuncTaskConfigurer switchWhenOrElse( - Predicate pred, String thenTask, String otherwiseTask, Class predClass) { - return switchWhenOrElse(null, pred, thenTask, otherwiseTask, predClass); - } - - public static FuncTaskConfigurer switchWhenOrElse( - SerializablePredicate pred, String thenTask, String otherwiseTask) { - return switchWhenOrElse(null, pred, thenTask, otherwiseTask); - } - - /** - * Named variant of {@link #switchWhenOrElse(Predicate, String, String, Class)}. - * - * @param taskName task name for the switch task - * @param pred predicate - * @param thenTask task name when predicate is true - * @param otherwiseTask task name when predicate is false - * @param predClass predicate class - * @param predicate input type - * @return list configurer - */ - public static FuncTaskConfigurer switchWhenOrElse( - String taskName, - Predicate pred, - String thenTask, - String otherwiseTask, - Class predClass) { - return list -> - list.switchCase( - taskName, cases(caseOf(pred, predClass).then(thenTask), caseDefault(otherwiseTask))); - } - - public static FuncTaskConfigurer switchWhenOrElse( - String taskName, SerializablePredicate pred, String thenTask, String otherwiseTask) { - return switchWhenOrElse( - taskName, pred, thenTask, otherwiseTask, ReflectionUtils.inferInputType(pred)); - } - - /** - * JQ-based condition: if the JQ expression evaluates truthy → jump to {@code thenTask}, otherwise - * follow the {@link FlowDirectiveEnum} given in {@code otherwise}. - * - *

-   * switchWhenOrElse(".approved == true", "sendEmail", FlowDirectiveEnum.END)
-   * 
- * - *

The JQ expression is evaluated against the task input at runtime. - * - * @param jqExpression JQ expression evaluated against the current task input - * @param thenTask task to jump to if the expression evaluates truthy - * @param otherwise default flow directive when the expression is falsy - * @return list configurer - */ - public static FuncTaskConfigurer switchWhenOrElse( - String jqExpression, String thenTask, FlowDirectiveEnum otherwise) { - return switchWhenOrElse(null, jqExpression, thenTask, otherwise); - } - - /** - * Named variant of {@link #switchWhenOrElse(String, String, FlowDirectiveEnum)}. - * - * @param taskName task name for the switch task - * @param jqExpression JQ expression evaluated against the current task input - * @param thenTask task to jump to if the expression evaluates truthy - * @param otherwise default flow directive when the expression is falsy - * @return list configurer - */ - public static FuncTaskConfigurer switchWhenOrElse( - String taskName, String jqExpression, String thenTask, FlowDirectiveEnum otherwise) { - - Objects.requireNonNull(jqExpression, "jqExpression"); - Objects.requireNonNull(thenTask, "thenTask"); - Objects.requireNonNull(otherwise, "otherwise"); - - return list -> - list.switchCase( - taskName, sw -> sw.on(c -> c.when(jqExpression).then(thenTask)).onDefault(otherwise)); - } - - /** - * JQ-based condition: if the JQ expression evaluates truthy → jump to {@code thenTask}, else jump - * to {@code otherwiseTask}. - * - *

-   * switchWhenOrElse(".score >= 80", "pass", "fail")
-   * 
- * - *

The JQ expression is evaluated against the task input at runtime. - * - * @param jqExpression JQ expression evaluated against the current task input - * @param thenTask task name when truthy - * @param otherwiseTask task name when falsy - * @return list configurer - */ - public static FuncTaskConfigurer switchWhenOrElse( - String jqExpression, String thenTask, String otherwiseTask) { - return switchWhenOrElse(null, jqExpression, thenTask, otherwiseTask); - } - - /** - * Named variant of {@link #switchWhenOrElse(String, String, String)}. - * - * @param taskName task name for the switch task - * @param jqExpression JQ expression evaluated against the current task input - * @param thenTask task name when truthy - * @param otherwiseTask task name when falsy - * @return list configurer - */ - public static FuncTaskConfigurer switchWhenOrElse( - String taskName, String jqExpression, String thenTask, String otherwiseTask) { - - Objects.requireNonNull(jqExpression, "jqExpression"); - Objects.requireNonNull(thenTask, "thenTask"); - Objects.requireNonNull(otherwiseTask, "otherwiseTask"); - - return list -> - list.switchCase( - taskName, - sw -> sw.on(c -> c.when(jqExpression).then(thenTask)).onDefault(otherwiseTask)); - } - - /** - * Java functional {@code forEach}: collection is computed from the current input at runtime. - * - * @param collection function that returns the collection to iterate - * @param body inner task list body - * @param input type for the collection function - * @return list configurer - */ - public static FuncTaskConfigurer forEach( - SerializableFunction> collection, Consumer body) { - return forEach(null, collection, body); - } - - /** - * Named variant of {@link #forEach(SerializableFunction, Consumer)}. - * - * @param taskName task name for the for-loop task - * @param collection function that returns the collection to iterate - * @param body inner task list body - * @param input type for the collection function - * @return list configurer - */ - public static FuncTaskConfigurer forEach( - String taskName, - SerializableFunction> collection, - Consumer body) { - return list -> - list.forEach( - taskName, - j -> j.collection(collection, ReflectionUtils.inferInputType(collection)).tasks(body)); - } - - public static FuncTaskConfigurer forEach( - SerializableFunction> collection, LoopFunction function) { - return forEach(null, collection, function); - } - - public static FuncTaskConfigurer forEach( - String taskName, - SerializableFunction> collection, - LoopFunction function) { - return list -> - list.forEach( - taskName, - j -> - j.collection(collection, ReflectionUtils.inferInputType(collection)) - .tasks(function)); - } - - public static FuncTaskConfigurer forEachItem( - SerializableFunction> collection, SerializableFunction function) { - return forEachItem(null, collection, function); - } - - public static FuncTaskConfigurer forEachItem( - String taskName, SerializableFunction> collection, Function function) { - return forEach(taskName, collection, ((t, v) -> function.apply((V) v))); - } - - /** - * Java functional {@code forEach}: iterate over a constant collection. - * - * @param collection static collection to iterate - * @param body inner task list body - * @param ignored (kept for signature consistency) - * @return list configurer - */ - public static FuncTaskConfigurer forEach( - Collection collection, Consumer body) { - return forEach(null, collection, body); - } - - /** - * Named variant of {@link #forEach(Collection, Consumer)}. - * - * @param taskName task name for the for-loop task - * @param collection static collection to iterate - * @param body inner task list body - * @param ignored (kept for signature consistency) - * @return list configurer - */ - public static FuncTaskConfigurer forEach( - String taskName, Collection collection, Consumer body) { - Function> f = ctx -> collection; - return list -> list.forEach(taskName, j -> j.collection(f).tasks(body)); - } - - /** - * Java functional {@code forEach} helper for an immutable {@link List}. - * - * @param collection list to iterate - * @param body inner task list body - * @param element type - * @return list configurer - */ - public static FuncTaskConfigurer forEach( - List collection, Consumer body) { - return forEach(null, collection, body); - } - - /** - * Named variant of {@link #forEach(List, Consumer)}. - * - * @param taskName task name for the for-loop task - * @param collection list to iterate - * @param body inner task list body - * @param element type - * @return list configurer - */ - public static FuncTaskConfigurer forEach( - String taskName, List collection, Consumer body) { - return list -> list.forEach(taskName, j -> j.collection(ctx -> collection).tasks(body)); - } - - /** - * This is helper to quickly build fork task where every branch is unnamed and consist of just one - * task. For more advanced use cases, please check FuncTaskItemListBuilder.fork - * - * @param name the name of the fork task - * @param branches every task in this input array will become a branch of the fork. - * @return FuncTaskConfigurer - */ - public static FuncTaskConfigurer fork(String name, FuncTaskConfigurer... branches) { - if (branches == null || branches.length == 0) { - throw new IllegalArgumentException("branches must not be null or empty"); - } - return list -> - list.fork( - name, - forkBuilder -> { - for (FuncTaskConfigurer branch : branches) { - forkBuilder.branch((FuncTaskItemListBuilder v) -> branch.accept(v)); - } - }); - } - - public static FuncTaskConfigurer fork(FuncTaskConfigurer... branches) { - return fork(null, branches); - } - - /** - * Set a raw expression on the current list (advanced). - * - * @param expr expression string - * @return list configurer - */ - public static FuncTaskConfigurer set(String expr) { - return list -> list.set(expr); - } - - /** - * Set values on the current list from a map (advanced). - * - * @param map map of values to set - * @return list configurer - */ - public static FuncTaskConfigurer set(Map map) { - return list -> list.set(s -> s.expr(map)); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a sub-workflow call task using a {@link - * WorkflowConfigurer}. - * - *

{@code
-   * tasks(
-   *     subflow(
-   *         workflow("org.acme", "sub-workflow", "0.1.0")
-   *             .input("id", 99)
-   *             .await(false)
-   *     )
-   * );
-   * }
- * - * @param configurer nested workflow configurer - * @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list - */ - public static FuncTaskConfigurer subflow(WorkflowConfigurer configurer) { - Objects.requireNonNull(configurer, "configurer"); - return list -> list.subflow(configurer); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a named sub-workflow call task. - * - * @param name task name - * @param configurer nested workflow configurer - * @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list - */ - public static FuncTaskConfigurer subflow(String name, Consumer configurer) { - Objects.requireNonNull(name, "name"); - Objects.requireNonNull(configurer, "configurer"); - return list -> list.subflow(name, configurer); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds an unnamed sub-workflow call task. - * - * @param configurer nested workflow configurer - * @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list - */ - public static FuncTaskConfigurer subflow(Consumer configurer) { - Objects.requireNonNull(configurer, "configurer"); - return list -> list.subflow(configurer); - } - - /** - * Alias for {@link #subflow(WorkflowConfigurer)}. - * - * @param configurer nested workflow configurer - * @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list - */ - public static FuncTaskConfigurer workflowTask(WorkflowConfigurer configurer) { - return subflow(configurer); - } - - /** - * Create a {@link FuncTaskConfigurer} that adds a workflow subflow task. - * - * @param configurer configurer for the nested workflow task - * @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list - * @deprecated use {@link #subflow(WorkflowConfigurer)} to avoid ambiguity with spec-side factory - * methods - */ - @Deprecated - public static FuncTaskConfigurer workflow(WorkflowConfigurer configurer) { - return subflow(configurer); - } - - /** - * Create a new {@link WorkflowSpec} to be used as a factory for workflow definitions. - * - * @param namespace workflow namespace - * @param name workflow name - * @param version workflow version - * @return a new {@link WorkflowSpec} instance - */ - public static WorkflowSpec workflow(String namespace, String name, String version) { - return DSL.workflow(namespace, name, version); - } - - /** - * Create a new {@link WorkflowSpec} to be used as a factory for workflow definitions. - * - * @param namespace workflow namespace - * @param name workflow name - * @return a new {@link WorkflowSpec} instance - */ - public static WorkflowSpec workflow(String namespace, String name) { - return DSL.workflow(namespace, name); - } - - /** - * Create a new {@link WorkflowSpec} to be used as a factory for workflow definitions. - * - * @return a new {@link WorkflowSpec} instance - */ - public static WorkflowSpec workflow() { - return DSL.workflow(); - } - - // --------------------------------------------------------------------------- - // HTTP / OpenAPI - // --------------------------------------------------------------------------- - - /** - * Low-level HTTP call entrypoint using a {@link FuncCallHttpConfigurer}. - * - *

This overload creates an unnamed HTTP task. - * - * @param configurer the configurer that mutates the underlying HTTP call builder - * @return a {@link FuncTaskConfigurer} that adds an HTTP task to the tasks list - */ - public static FuncTaskConfigurer call(FuncCallHttpConfigurer configurer) { - return call(null, configurer); - } - - /** - * Low-level HTTP call entrypoint using a {@link FuncCallHttpConfigurer}. - * - *

This overload allows assigning an explicit task name. - * - * @param name task name, or {@code null} for an anonymous task - * @param configurer the configurer that mutates the underlying HTTP call builder - * @return a {@link FuncTaskConfigurer} that adds an HTTP task to the tasks list - */ - public static FuncTaskConfigurer call(String name, FuncCallHttpConfigurer configurer) { - Objects.requireNonNull(configurer, "configurer"); - return list -> list.http(name, configurer); - } - - /** - * HTTP call using a fluent {@link FuncCallHttpStep}. - * - *

This overload creates an unnamed HTTP task. - * - *

{@code
-   * tasks(FuncDSL.call(FuncDSL.http().GET().endpoint("http://service/api")));
-   * }
- * - * @param spec fluent HTTP spec built via {@link #http()} - * @return a {@link FuncTaskConfigurer} that adds an HTTP task - */ - public static FuncTaskConfigurer call(FuncCallHttpStep spec) { - return call(null, spec); - } - - /** - * HTTP call using a fluent {@link FuncCallHttpStep} with explicit task name. - * - *
{@code
-   * tasks(FuncDSL.call("fetchUsers", FuncDSL.http().GET().endpoint("http://service/users")));
-   * }
- * - * @param name task name, or {@code null} for an anonymous task - * @param spec fluent HTTP spec built via {@link #http()} - * @return a {@link FuncTaskConfigurer} that adds an HTTP task - */ - public static FuncTaskConfigurer call(String name, FuncCallHttpStep spec) { - Objects.requireNonNull(spec, "spec"); - return call(name, (FuncCallHttpConfigurer) spec::accept); - } - - /** - * OpenAPI call using a fluent {@link FuncCallOpenAPIStep}. - * - *

This overload creates an unnamed OpenAPI call task. - * - *

{@code
-   * FuncWorkflowBuilder.workflow("openapi-call")
-   *   .tasks(call(openapi().document("https://petstore.swagger.io/v2/swagger.json", auth("openapi-auth")).operation("getPetById"))
-   * )
-   * .build();
-   * }
- * - * @param spec fluent OpenAPI spec built via {@link #openapi()} - * @return a {@link FuncTaskConfigurer} that adds an OpenAPI call task to the workflow - */ - public static FuncTaskConfigurer call(FuncCallOpenAPIStep spec) { - return call(null, spec); - } - - /** - * OpenAPI call using a fluent {@link FuncCallOpenAPIStep} with an explicit task name. - * - *

Example: - * - *

{@code
-   * FuncWorkflowBuilder.workflow("openapi-call-named")
-   * .tasks(
-   * FuncDSL.call(
-   * "fetchPet",
-   * FuncDSL.openapi()
-   * .document("https://petstore.swagger.io/v2/swagger.json", DSL.auth("openapi-auth"))
-   * .operation("getPetById")
-   * .parameter("id", 123)
-   * )
-   * )
-   * .build();
-   * }
- * - * @param name task name, or {@code null} for an anonymous task - * @param spec fluent OpenAPI spec built via {@link #openapi()} - * @return a {@link FuncTaskConfigurer} that adds a named OpenAPI call task - */ - public static FuncTaskConfigurer call(String name, FuncCallOpenAPIStep spec) { - Objects.requireNonNull(spec, "spec"); - spec.setName(name); - return spec; - } - - /** - * Low-level OpenAPI call entrypoint using a {@link FuncCallOpenAPIConfigurer}. - * - *

This overload creates an unnamed OpenAPI call task. - * - * @param configurer configurer that mutates the underlying OpenAPI call builder - * @return a {@link FuncTaskConfigurer} that adds an OpenAPI call task - */ - public static FuncTaskConfigurer call(FuncCallOpenAPIConfigurer configurer) { - return call(null, configurer); - } - - /** - * Low-level OpenAPI call entrypoint using a {@link FuncCallOpenAPIConfigurer}. - * - *

This overload allows assigning an explicit task name. - * - * @param name task name, or {@code null} for an anonymous task - * @param configurer configurer that mutates the underlying OpenAPI call builder - * @return a {@link FuncTaskConfigurer} that adds an OpenAPI call task - */ - public static FuncTaskConfigurer call(String name, FuncCallOpenAPIConfigurer configurer) { - Objects.requireNonNull(configurer, "configurer"); - return list -> list.openapi(name, configurer); - } - - /** - * gRPC call using a fluent {@link FuncCallGrpcStep}. - * - *

This overload creates an unnamed gRPC call task. - * - *

{@code
-   * tasks(FuncDSL.call(FuncDSL.grpc()
-   *     .proto("proto/greeter.proto")
-   *     .service("Greeter", "localhost")
-   *     .method("SayHello")
-   *     .argument("name", "World")));
-   * }
- * - * @param spec fluent gRPC spec built via {@link #grpc()} - * @return a {@link FuncTaskConfigurer} that adds a gRPC call task - */ - public static FuncTaskConfigurer call(FuncCallGrpcStep spec) { - return call(null, spec); - } - - /** - * gRPC call using a fluent {@link FuncCallGrpcStep} with an explicit task name. - * - *
{@code
-   * tasks(
-   * FuncDSL.call(
-   * "greet",
-   * FuncDSL.grpc()
-   *     .proto("proto/greeter.proto")
-   *     .service("Greeter", "localhost")
-   *     .method("SayHello")
-   *     .argument("name", "World"))
-   * );
-   * }
- * - * @param name task name, or {@code null} for an anonymous task - * @param spec fluent gRPC spec built via {@link #grpc()} - * @return a {@link FuncTaskConfigurer} that adds a named gRPC call task - */ - public static FuncTaskConfigurer call(String name, FuncCallGrpcStep spec) { - Objects.requireNonNull(spec, "spec"); - spec.setName(name); - return spec; - } - - /** - * Low-level gRPC call entrypoint using a {@link FuncCallGrpcConfigurer}. - * - *

This overload creates an unnamed gRPC call task. - * - * @param configurer configurer that mutates the underlying gRPC call builder - * @return a {@link FuncTaskConfigurer} that adds a gRPC call task - */ - public static FuncTaskConfigurer call(FuncCallGrpcConfigurer configurer) { - return call(null, configurer); - } - - /** - * Low-level gRPC call entrypoint using a {@link FuncCallGrpcConfigurer}. - * - *

This overload allows assigning an explicit task name. - * - * @param name task name, or {@code null} for an anonymous task - * @param configurer configurer that mutates the underlying gRPC call builder - * @return a {@link FuncTaskConfigurer} that adds a gRPC call task - */ - public static FuncTaskConfigurer call(String name, FuncCallGrpcConfigurer configurer) { - Objects.requireNonNull(configurer, "configurer"); - return list -> list.grpc(name, configurer); - } - - /** - * Create a new OpenAPI specification to be used with {@link #call(FuncCallOpenAPIStep)}. - * - *

Typical usage: - * - *

{@code
-   * FuncDSL.call(
-   * openapi()
-   * .document("https://petstore.swagger.io/v2/swagger.json")
-   * .operation("getPetById"))
-   * );
-   * }
- * - * @return a new {@link FuncCallOpenAPIStep} - */ - public static FuncCallOpenAPIStep openapi() { - return new FuncCallOpenAPIStep(); - } - - /** - * Named variant of {@link #openapi()}. - * - * @param name task name to be used when the spec is attached via {@link - * #call(FuncCallOpenAPIStep)} - * @return a new named {@link FuncCallOpenAPIStep} - */ - public static FuncCallOpenAPIStep openapi(String name) { - return new FuncCallOpenAPIStep(name); - } - - /** - * Create a new gRPC specification to be used with {@link #call(FuncCallGrpcStep)}. - * - *

Typical usage: - * - *

{@code
-   * FuncDSL.call(
-   * grpc()
-   * .proto("proto/greeter.proto")
-   *          .service("Greeter", "localhost")
-   *          .method("SayHello")
-   *          .argument("name", "World"));
-   * }
- * - * @return a new {@link FuncCallGrpcStep} - */ - public static FuncCallGrpcStep grpc() { - return new FuncCallGrpcStep(); - } - - /** - * Named variant of {@link #grpc()}. - * - * @param name task name to be used when the spec is attached via {@link #call(FuncCallGrpcStep)} - * @return a new named {@link FuncCallGrpcStep} - */ - public static FuncCallGrpcStep grpc(String name) { - return new FuncCallGrpcStep(name); - } - - /** - * Create a new HTTP specification to be used with {@link #call(FuncCallHttpStep)}. - * - *

Typical usage: - * - *

{@code
-   * FuncDSL.call(http().GET().endpoint("http://service/api").acceptJSON());
-   * }
- * - * @return a new {@link FuncCallHttpStep} - */ - public static FuncCallHttpStep http() { - return new FuncCallHttpStep(); - } - - /** - * Named variant of {@link #http()}. - * - * @param name task name to be used when the spec is attached via {@link #call(FuncCallHttpStep)} - * @return a new named {@link FuncCallHttpStep} - */ - public static FuncCallHttpStep http(String name) { - return new FuncCallHttpStep(name); - } - - /** - * Create a new HTTP specification preconfigured with an endpoint expression and authentication. - * - *
{@code
-   * FuncDSL.call(
-   * FuncDSL.http("http://service/api", auth -> auth.use("my-auth"))
-   * .GET()
-   * );
-   * }
- * - * @param urlExpr expression or literal string for the endpoint URL - * @param auth authentication configurer (e.g. {@code auth -> auth.use("my-auth")}) - * @return a {@link FuncCallHttpStep} preconfigured with endpoint + auth - */ - public static FuncCallHttpStep http(String urlExpr, AuthenticationConfigurer auth) { - return new FuncCallHttpStep().endpoint(urlExpr, auth); - } - - /** - * Create a new HTTP specification preconfigured with a {@link URI} and authentication. - * - * @param url concrete URI to call - * @param auth authentication configurer - * @return a {@link FuncCallHttpStep} preconfigured with URI + auth - */ - public static FuncCallHttpStep http(URI url, AuthenticationConfigurer auth) { - return new FuncCallHttpStep().uri(url, auth); - } - - /** - * Convenience for building an unnamed {@code GET} HTTP step using a string endpoint. - * - *
{@code
-   * tasks(
-   * FuncDSL.call(
-   * FuncDSL.get("http://service/health")
-   * )
-   * );
-   * }
- * - * @param endpoint literal or expression for the endpoint URL - * @return a {@link FuncCallHttpStep} that can be chained and later passed to {@link - * #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep get(String endpoint) { - return get(null, endpoint); - } - - /** - * Convenience for building a named {@code GET} HTTP step using a string endpoint. - * - *
{@code
-   * tasks(
-   * FuncDSL.call(
-   * FuncDSL.get("checkHealth", "http://service/health")
-   * )
-   * );
-   * }
- * - * @param name task name - * @param endpoint literal or expression for the endpoint URL - * @return a named {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep get(String name, String endpoint) { - return http(name).GET().endpoint(endpoint); - } - - /** - * Convenience for building an unnamed authenticated {@code GET} HTTP step using a string - * endpoint. - * - *
{@code
-   * tasks(
-   * FuncDSL.call(
-   * FuncDSL.get("http://service/api/users", auth -> auth.use("user-service-auth"))
-   * )
-   * );
-   * }
- * - * @param endpoint literal or expression for the endpoint URL - * @param auth authentication configurer - * @return a {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep get(String endpoint, AuthenticationConfigurer auth) { - return get(null, endpoint, auth); - } - - /** - * Convenience for building a named authenticated {@code GET} HTTP step using a string endpoint. - * - * @param name task name - * @param endpoint literal or expression for the endpoint URL - * @param auth authentication configurer - * @return a named {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep get(String name, String endpoint, AuthenticationConfigurer auth) { - return http(name).GET().endpoint(endpoint, auth); - } - - /** - * Convenience for building an unnamed {@code GET} HTTP step using a {@link URI}. - * - * @param endpoint concrete URI to call - * @return a {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep get(URI endpoint) { - return get(null, endpoint); - } - - /** - * Convenience for building a named {@code GET} HTTP step using a {@link URI}. - * - * @param name task name - * @param endpoint concrete URI to call - * @return a named {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep get(String name, URI endpoint) { - return http(name).GET().uri(endpoint); - } - - /** - * Convenience for building an unnamed authenticated {@code GET} HTTP step using a {@link URI}. - * - * @param endpoint concrete URI to call - * @param auth authentication configurer - * @return a {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep get(URI endpoint, AuthenticationConfigurer auth) { - return get(null, endpoint, auth); - } - - /** - * Convenience for building a named authenticated {@code GET} HTTP step using a {@link URI}. - * - * @param name task name - * @param endpoint concrete URI to call - * @param auth authentication configurer - * @return a named {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep get(String name, URI endpoint, AuthenticationConfigurer auth) { - return http(name).GET().uri(endpoint, auth); - } - - /** - * Convenience for building an unnamed {@code POST} HTTP step with a body and string endpoint. - * - *
{@code
-   * tasks(
-   * FuncDSL.call(
-   * FuncDSL.post(
-   * Map.of("name", "Ricardo"),
-   * "http://service/api/users"
-   * )
-   * )
-   * );
-   * }
- * - * @param body HTTP request body (literal value or expression-compatible object) - * @param endpointExpr literal or expression for the endpoint URL - * @return a {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep post(Object body, String endpointExpr) { - return post(null, body, endpointExpr); - } - - /** - * Convenience for building a named {@code POST} HTTP step with a body and string endpoint. - * - * @param name task name - * @param body HTTP request body (literal value or expression-compatible object) - * @param endpoint literal or expression for the endpoint URL - * @return a named {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep post(String name, Object body, String endpoint) { - return http(name).POST().endpoint(endpoint).body(body); - } - - /** - * Convenience for building an unnamed authenticated {@code POST} HTTP step with body and - * endpoint. - * - * @param body HTTP request body - * @param endpoint literal or expression for the endpoint URL - * @param auth authentication configurer - * @return a {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep post(Object body, String endpoint, AuthenticationConfigurer auth) { - return post(null, body, endpoint, auth); - } - - /** - * Convenience for building a named authenticated {@code POST} HTTP step with body and endpoint. - * - * @param name task name - * @param body HTTP request body - * @param endpoint literal or expression for the endpoint URL - * @param auth authentication configurer - * @return a named {@link FuncCallHttpStep} that can be passed to {@link #call(FuncCallHttpStep)} - */ - public static FuncCallHttpStep post( - String name, Object body, String endpoint, AuthenticationConfigurer auth) { - - return http(name).POST().endpoint(endpoint, auth).body(body); - } - - /** - * Extracts and deserializes the workflow input data into the specified type from a workflow - * context. - * - *

This utility method provides type-safe access to the workflow's initial input. - * - *

Use this method when you have access to the {@link WorkflowContextData} and need to retrieve - * the original input that was provided when the workflow instance was started. - * - *

Usage Example: - * - *

{@code
-   * inputFrom((object, WorkflowContextData workflowContext) -> {
-   *   OrderRequest order = input(workflowContext, OrderRequest.class);
-   *   return new Input(order);
-   * });
-   * }
- * - * @param the type to deserialize the input into - * @param context the workflow context containing instance data and input - * @param inputClass the class object representing the target type for deserialization - * @return the deserialized workflow input object of type T - */ - public static T input(WorkflowContextData context, Class inputClass) { - return context - .instanceData() - .input() - .as(inputClass) - .orElseThrow( - () -> - new IllegalStateException( - "Workflow input is missing or cannot be deserialized into type " - + inputClass.getName() - + " when calling FuncDSL.input(WorkflowContextData, Class).")); - } - - /** - * Extracts and deserializes the task input data into the specified type from a task context. - * - *

This utility method provides type-safe access to a task's input. - * - *

Use this method when you have access to the {@link TaskContextData} and need to retrieve the - * input provided to that task. - * - *

Usage Example: - * - *

{@code
-   * inputFrom((Object obj, TaskContextData taskContextData) -> {
-   * OrderRequest order = input(taskContextData, OrderRequest.class);
-   * return order;
-   * });
-   * }
- * - * @param the type to deserialize the input into - * @param taskContextData the task context from which to retrieve the task input - * @param inputClass the class object representing the target type for deserialization - * @return the deserialized task input object of type T - */ - public static T input(TaskContextData taskContextData, Class inputClass) { - return taskContextData - .input() - .as(inputClass) - .orElseThrow( - () -> - new IllegalStateException( - "Workflow input is missing or cannot be deserialized into type " - + inputClass.getName() - + " when calling FuncDSL.input(TaskContextData, Class).")); - } - - /** - * Extracts and deserializes the output data from a task into the specified type. - * - *

This utility method provides type-safe access to a task's output. - * - *

Use this method when you need to access the result/output produced by a task execution. This - * is particularly useful in subsequent tasks that need to process or transform the output of a - * previous task in the workflow. - * - *

Usage Example: - * - *

{@code
-   * .exportAs((object, workflowContext, taskContextData) -> {
-   * Long output = output(taskContextData, Long.class);
-   * return output * 2;
-   * })
-   * }
- * - * @param the type to deserialize the task output into - * @param taskContextData the task context containing the output data - * @param outputClass the class object representing the target type for deserialization - * @return the deserialized task output object of type T - */ - public static T output(TaskContextData taskContextData, Class outputClass) { - return taskContextData - .output() - .as(outputClass) - .orElseThrow( - () -> - new IllegalStateException( - "Task output is missing or cannot be deserialized into type " - + outputClass.getName() - + " when calling FuncDSL.output(TaskContextData, Class).")); - } - - // --------------------------------------------------------------------------- - // Facades to base DSL (Timeouts, Schedules, Event Strategies) - // --------------------------------------------------------------------------- - - /** - * Shortcut to configure a timeout in days. - * - * @see DSL#timeoutDays(int) - */ - public static Consumer timeoutDays(int days) { - return DSL.timeoutDays(days); - } - - /** - * Shortcut to configure a timeout in hours. - * - * @see DSL#timeoutHours(int) - */ - public static Consumer timeoutHours(int hours) { - return DSL.timeoutHours(hours); - } - - /** - * Shortcut to configure a timeout in minutes. - * - * @see DSL#timeoutMinutes(int) - */ - public static Consumer timeoutMinutes(int minutes) { - return DSL.timeoutMinutes(minutes); - } - - /** - * Shortcut to configure a timeout in seconds. - * - * @see DSL#timeoutSeconds(int) - */ - public static Consumer timeoutSeconds(int seconds) { - return DSL.timeoutSeconds(seconds); - } - - /** - * Shortcut to configure a timeout in milliseconds. - * - * @see DSL#timeoutMillis(int) - */ - public static Consumer timeoutMillis(int milliseconds) { - return DSL.timeoutMillis(milliseconds); - } - - // ---- Schedules ----// - - /** - * @see DSL#every(Consumer) - */ - public static Consumer every(Consumer duration) { - return DSL.every(duration); - } - - /** - * @see DSL#every(String) - */ - public static Consumer every(String durationExpression) { - return DSL.every(durationExpression); - } - - /** - * @see DSL#cron(String) - */ - public static Consumer cron(String cron) { - return DSL.cron(cron); - } - - /** - * @see DSL#after(Consumer) - */ - public static Consumer after(Consumer duration) { - return DSL.after(duration); - } - - /** - * @see DSL#after(String) - */ - public static Consumer after(String durationExpression) { - return DSL.after(durationExpression); - } - - /** - * @see DSL#on(Consumer) - */ - public static Consumer on( - Consumer> strategy) { - return DSL.on(strategy); - } - - // ---- Schedule Event Strategies ----// - - /** - * @see DSL#one(String) - */ - public static Consumer> one(String eventType) { - return DSL.one(eventType); - } - - /** - * @see DSL#one(Consumer) - */ - public static Consumer> one( - Consumer filter) { - return DSL.one(filter); - } - - /** - * @see DSL#all(Consumer[]) - */ - @SafeVarargs - public static Consumer> all( - Consumer... filters) { - return DSL.all(filters); - } - - /** - * Creates an 'all' event consumption strategy using a specific event type string. - * - * @param eventType the event type - * @return a consumer configuring the event strategy builder - * @see DSL#all(Consumer[]) - */ - public static Consumer> allOfType( - String eventType) { - return DSL.all(DSL.event().type(eventType)); - } - - /** - * @see DSL#any(Consumer[]) - */ - @SafeVarargs - public static Consumer> any( - Consumer... filters) { - return DSL.any(filters); - } - - // --------------------------------------------------------------------------- - // Facades to base DSL (Use, Secrets, and Authentication) - // --------------------------------------------------------------------------- - - /** - * @see DSL#secret(String) - */ - public static UseSpec secret(String secret) { - return DSL.secret(secret); - } - - /** - * @see DSL#secrets(String...) - */ - public static UseSpec secrets(String... secret) { - return DSL.secrets(secret); - } - - /** - * @see DSL#auth(String, AuthenticationConfigurer) - */ - public static UseSpec auth(String name, AuthenticationConfigurer auth) { - return DSL.auth(name, auth); - } - - /** - * @see DSL#use() - */ - public static UseSpec use() { - return DSL.use(); - } - - /** - * @see DSL#use(String) - */ - public static AuthenticationConfigurer use(String authName) { - return DSL.use(authName); - } - - /** - * @see DSL#basic(String, String) - */ - public static AuthenticationConfigurer basic(String username, String password) { - return DSL.basic(username, password); - } - - /** - * @see DSL#basic(String) - */ - public static AuthenticationConfigurer basic(String secret) { - return DSL.basic(secret); - } - - /** - * @see DSL#bearer(String) - */ - public static AuthenticationConfigurer bearer(String token) { - return DSL.bearer(token); - } - - /** - * @see DSL#bearerUse(String) - */ - public static AuthenticationConfigurer bearerUse(String secret) { - return DSL.bearerUse(secret); - } - - /** - * @see DSL#digest(String, String) - */ - public static AuthenticationConfigurer digest(String username, String password) { - return DSL.digest(username, password); - } - - /** - * @see DSL#digest(String) - */ - public static AuthenticationConfigurer digest(String secret) { - return DSL.digest(secret); - } - - /** - * @see DSL#oidc(String, OAuth2AuthenticationData.OAuth2AuthenticationDataGrant) - */ - public static AuthenticationConfigurer oidc( - String authority, OAuth2AuthenticationData.OAuth2AuthenticationDataGrant grant) { - return DSL.oidc(authority, grant); - } - - /** - * @see DSL#oidc(String, OAuth2AuthenticationData.OAuth2AuthenticationDataGrant, String, String) - */ - public static AuthenticationConfigurer oidc( - String authority, - OAuth2AuthenticationData.OAuth2AuthenticationDataGrant grant, - String clientId, - String clientSecret) { - return DSL.oidc(authority, grant, clientId, clientSecret); - } - - /** - * @see DSL#oidc(String) - */ - public static AuthenticationConfigurer oidc(String secret) { - return DSL.oidc(secret); - } - - /** - * @see DSL#oauth2(String, - * io.serverlessworkflow.api.types.OAuth2AuthenticationData.OAuth2AuthenticationDataGrant) - */ - public static AuthenticationConfigurer oauth2( - String authority, - io.serverlessworkflow.api.types.OAuth2AuthenticationData.OAuth2AuthenticationDataGrant - grant) { - return DSL.oauth2(authority, grant); - } - - /** - * @see DSL#oauth2(String, - * io.serverlessworkflow.api.types.OAuth2AuthenticationData.OAuth2AuthenticationDataGrant, - * String, String) - */ - public static AuthenticationConfigurer oauth2( - String authority, - io.serverlessworkflow.api.types.OAuth2AuthenticationData.OAuth2AuthenticationDataGrant grant, - String clientId, - String clientSecret) { - return DSL.oauth2(authority, grant, clientId, clientSecret); - } - - /** - * @see DSL#oauth2(String) - */ - public static AuthenticationConfigurer oauth2(String secret) { - return DSL.oauth2(secret); - } - - /** - * @see DSL#oauth2(String, OAuth2AuthenticationData.OAuth2AuthenticationDataGrant, String, String, - * Consumer) - */ - public static AuthenticationConfigurer oauth2( - String authority, - OAuth2AuthenticationData.OAuth2AuthenticationDataGrant grant, - String clientId, - String clientSecret, - Consumer endpoints) { - return DSL.oauth2(authority, grant, clientId, clientSecret, endpoints); - } - - /** - * @see DSL#oauth2(Consumer) - */ - public static AuthenticationConfigurer oauth2(Consumer cfg) { - return DSL.oauth2(cfg); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEmitSpec.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEmitSpec.java deleted file mode 100644 index 0e4e079f4..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEmitSpec.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.cloudevents.CloudEventData; -import io.cloudevents.core.data.BytesCloudEventData; -import io.cloudevents.core.data.PojoCloudEventData; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.EventDataFunction; -import io.serverlessworkflow.api.types.func.SerializableFunction; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import io.serverlessworkflow.fluent.func.FuncEmitEventPropertiesBuilder; -import io.serverlessworkflow.fluent.func.FuncEmitTaskBuilder; -import io.serverlessworkflow.fluent.func.configurers.FuncEmitConfigurer; -import io.serverlessworkflow.fluent.spec.dsl.EventEmitPropertiesSpec; -import io.serverlessworkflow.impl.jackson.JsonUtils; -import java.nio.charset.StandardCharsets; -import java.util.function.Function; - -public final class FuncEmitSpec - extends EventEmitPropertiesSpec - implements FuncEmitConfigurer { - - @Override - protected FuncEmitSpec self() { - return this; - } - - /** Sets the event data and the contentType to `application/json` */ - public FuncEmitSpec jsonData(SerializableFunction function) { - Class clazz = ReflectionUtils.inferInputType(function); - addPropertyStep(e -> e.data(new EventDataFunction().withFunction(function, clazz))); - return JSON(); - } - - /** Sets the event data and the contentType to `application/octet-stream` */ - public FuncEmitSpec bytesData(Function serializer, Class clazz) { - addPropertyStep( - e -> e.data(payload -> BytesCloudEventData.wrap(serializer.apply(payload)), clazz)); - return OCTET_STREAM(); - } - - public FuncEmitSpec bytesDataUtf8() { - return bytesData((String s) -> s.getBytes(StandardCharsets.UTF_8), String.class); - } - - /** Sets the event data and the contentType to `application/json` */ - public FuncEmitSpec jsonData(Function function, Class clazz) { - addPropertyStep(e -> e.data(new EventDataFunction().withFunction(function, clazz))); - return JSON(); - } - - /** JSON with default mapper (PojoCloudEventData + application/json). */ - public FuncEmitSpec jsonData(Class clazz) { - addPropertyStep( - e -> - e.data( - payload -> - PojoCloudEventData.wrap( - payload, p -> JsonUtils.mapper().writeValueAsString(p).getBytes()), - clazz)); - return JSON(); - } - - public FuncEmitSpec jsonData(ContextFunction function, Class clazz) { - addPropertyStep( - e -> - e.data( - payload -> - PojoCloudEventData.wrap( - payload, p -> JsonUtils.mapper().writeValueAsString(p).getBytes()), - clazz)); - return JSON(); - } - - @Override - public void accept(FuncEmitTaskBuilder funcEmitTaskBuilder) { - funcEmitTaskBuilder.event(e -> getPropertySteps().forEach(step -> step.accept(e))); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEventFilterSpec.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEventFilterSpec.java deleted file mode 100644 index 49f92f0f6..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncEventFilterSpec.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import com.fasterxml.jackson.core.type.TypeReference; -import io.cloudevents.CloudEvent; -import io.cloudevents.CloudEventData; -import io.cloudevents.core.CloudEventUtils; -import io.cloudevents.core.data.PojoCloudEventData; -import io.cloudevents.jackson.PojoCloudEventDataMapper; -import io.serverlessworkflow.api.types.func.ContextPredicate; -import io.serverlessworkflow.api.types.func.FilterPredicate; -import io.serverlessworkflow.api.types.func.SerializablePredicate; -import io.serverlessworkflow.fluent.func.FuncEventFilterBuilder; -import io.serverlessworkflow.fluent.func.FuncEventFilterPropertiesBuilder; -import io.serverlessworkflow.fluent.spec.dsl.AbstractEventFilterSpec; -import io.serverlessworkflow.impl.TaskContextData; -import io.serverlessworkflow.impl.WorkflowContextData; -import io.serverlessworkflow.impl.jackson.JsonUtils; -import java.util.Map; -import java.util.Objects; - -/** - * Fluent DSL specification builder for configuring CloudEvent filters within a Serverless Workflow - * execution. - */ -public final class FuncEventFilterSpec - extends AbstractEventFilterSpec< - FuncEventFilterSpec, FuncEventFilterPropertiesBuilder, FuncEventFilterBuilder> { - - /** - * Returns the current instance of the builder. - * - * @return the current {@link FuncEventFilterSpec} instance. - */ - @Override - protected FuncEventFilterSpec self() { - return this; - } - - /** - * Configures the filter to match incoming event based on a Predicate. This is the Listen - * counterpart to Emit's jsonData(Function). - * - * @param predicate the predicate to evaluate against the entire {@link CloudEvent}. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec envelope(SerializablePredicate predicate) { - addPropertyStep(e -> e.envelope(predicate)); - return this; - } - - /** - * Configures the filter to match incoming event data based on a ContextPredicate, allowing - * evaluation against the {@link CloudEvent} and the current {@link WorkflowContextData}. - * - * @param predicate the context-aware predicate to evaluate. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec envelope(ContextPredicate predicate) { - addPropertyStep(e -> e.envelope(predicate)); - return this; - } - - /** - * Configures the filter to match incoming event data based on a FilterPredicate, allowing - * evaluation against the {@link CloudEvent}, {@link WorkflowContextData}, and {@link - * TaskContextData}. - * - * @param predicate the filter predicate to evaluate. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec envelope(FilterPredicate predicate) { - addPropertyStep(e -> e.envelope(predicate)); - return this; - } - - /** - * Configures the filter to match incoming event data based on a Predicate evaluated directly - * against the raw {@link CloudEventData} payload. - * - * @param predicate the predicate to evaluate against the event data. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec data(SerializablePredicate predicate) { - addPropertyStep(e -> e.data(predicate)); - return this; - } - - /** - * Configures the filter to match incoming event data based on a ContextPredicate evaluated - * directly against the raw {@link CloudEventData} payload and the current {@link - * WorkflowContextData}. - * - * @param predicate the context-aware predicate to evaluate. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec data(ContextPredicate predicate) { - addPropertyStep(e -> e.data(predicate)); - return this; - } - - /** - * Configures the filter to match incoming event data based on a FilterPredicate evaluated - * directly against the raw {@link CloudEventData} payload, {@link WorkflowContextData}, and - * {@link TaskContextData}. - * - * @param predicate the filter predicate to evaluate. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec data(FilterPredicate predicate) { - addPropertyStep(e -> e.data(predicate)); - return this; - } - - /** - * Evaluates the given predicate against the CloudEvent data payload, automatically parsed as a - * Map. - * - *

For example, you can evaluate this filter as: - * - *

-   * .dataAsMap(map -> "123".equals(map.get("orderId")))
-   * 
- * - * @param predicate the predicate to evaluate against the parsed Map. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec dataAsMap(SerializablePredicate> predicate) { - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce) -> { - Map ceDataMap = asCEDataMap(ce); - return !ceDataMap.isEmpty() && predicate.test(ceDataMap); - })); - return this; - } - - /** - * Evaluates the given ContextPredicate against the CloudEvent data payload (parsed as a Map) and - * the current WorkflowContextData. - * - * @param predicate the context-aware predicate to evaluate against the parsed Map. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec dataAsMap(ContextPredicate> predicate) { - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce, WorkflowContextData context) -> { - Map ceDataMap = asCEDataMap(ce); - return !ceDataMap.isEmpty() && predicate.test(ceDataMap, context); - })); - return this; - } - - /** - * Evaluates the given FilterPredicate against the CloudEvent data payload (parsed as a Map), the - * current WorkflowContextData, and the TaskContextData. - * - * @param predicate the filter predicate to evaluate against the parsed Map and task/workflow - * contexts. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec dataAsMap(FilterPredicate> predicate) { - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce, WorkflowContextData context, TaskContextData taskContext) -> { - Map ceDataMap = asCEDataMap(ce); - return !ceDataMap.isEmpty() && predicate.test(ceDataMap, context, taskContext); - })); - return this; - } - - /** - * Evaluates the given predicate against the CloudEvent data payload, automatically parsed into - * the specified target type. - * - *

For example, you can evaluate this filter as: - * - *

-   * .dataAs(Order.class, order -> order.getId() == 123)
-   * 
- * - * @param targetType The class of the type to deserialize the payload into. - * @param predicate The predicate to evaluate against the parsed object. - * @param The target type. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec dataAs(Class targetType, SerializablePredicate predicate) { - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce) -> { - T parsedData = parseCEData(ce, targetType); - return parsedData != null && predicate.test(parsedData); - })); - return this; - } - - /** - * Evaluates the given ContextPredicate against the CloudEvent data payload (parsed into the - * specified target type) and the current WorkflowContextData. - * - * @param targetType The class of the type to deserialize the payload into. - * @param predicate The context-aware predicate to evaluate against the parsed object. - * @param The target type. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec dataAs(Class targetType, ContextPredicate predicate) { - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce, WorkflowContextData context) -> { - T parsedData = parseCEData(ce, targetType); - return parsedData != null && predicate.test(parsedData, context); - })); - return this; - } - - /** - * Evaluates the given FilterPredicate against the CloudEvent data payload (parsed into the - * specified target type), the current WorkflowContextData, and the TaskContextData. - * - * @param targetType The class of the type to deserialize the payload into. - * @param predicate The filter predicate to evaluate against the parsed object and contexts. - * @param The target type. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec dataAs(Class targetType, FilterPredicate predicate) { - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce, WorkflowContextData context, TaskContextData taskContext) -> { - T parsedData = parseCEData(ce, targetType); - return parsedData != null && predicate.test(parsedData, context, taskContext); - })); - return this; - } - - /** - * Filter events which field carries the current workflow instance ID. For example, given the data - * payload: - * - *
-   * {
-   * "order": { "number": 123 },
-   * "workflowInstanceId": "123456789"
-   * }
-   * 
- * - *

You would call dataByInstanceId("workflowInstanceId"). Events matching the - * current instance ID in the field workflowInstanceId would match this filter. - * - * @param fieldName name of the field in the CE data that carries the instance ID. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec dataByInstanceId(String fieldName) { - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce, WorkflowContextData context) -> { - Map ceDataMap = asCEDataMap(ce); - return Objects.equals(ceDataMap.get(fieldName), context.instanceData().id()); - })); - return this; - } - - /** - * Same as {@link #dataByInstanceId(String)}, but now the filter looks at the CE extension name. - * - * @param extensionName the extension name where to fetch the given workflow instance ID to match - * with the current execution. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec extensionByInstanceId(String extensionName) { - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce, WorkflowContextData context) -> - context.instanceData().id().equals(ce.getExtension(extensionName)))); - return this; - } - - /** - * Matches events that carry in the CE data payload fields with the same values as the input of - * the current task. - * - *

For example, you can filter events carrying specific data using - * dataFields("orderId", "customerId"). Events where the CE data payload matches the task - * input for all provided fields will pass this filter. - * - * @param fieldNames the field names to match this filter. - * @return the current {@link FuncEventFilterSpec} instance. - */ - public FuncEventFilterSpec dataFields(String... fieldNames) { - if (fieldNames == null || fieldNames.length == 0) return this; - - addPropertyStep( - e -> - e.envelope( - (CloudEvent ce, WorkflowContextData context, TaskContextData taskContext) -> { - Map input = taskContext.rawInput().asMap().orElse(Map.of()); - Map ceDataMap = asCEDataMap(ce); - - return !ceDataMap.isEmpty() - && java.util.Arrays.stream(fieldNames) - .allMatch( - fieldName -> - Objects.equals(ceDataMap.get(fieldName), input.get(fieldName))); - })); - return this; - } - - /** - * Helper method to safely extract and parse the {@link CloudEvent} data payload into a Map. - * - * @param ce the incoming {@link CloudEvent} to parse. - * @return a {@link Map} containing the parsed data, or an empty map if parsing fails or data is - * null. - */ - private Map asCEDataMap(CloudEvent ce) { - if (ce.getData() == null) return Map.of(); - PojoCloudEventData> mappedData = - CloudEventUtils.mapData( - ce, PojoCloudEventDataMapper.from(JsonUtils.mapper(), new TypeReference<>() {})); - if (mappedData == null || mappedData.getValue() == null) { - return Map.of(); - } - - return mappedData.getValue(); - } - - /** - * Helper method to safely parse the {@link CloudEvent} data payload into a specified target class - * type. - * - * @param ce the incoming {@link CloudEvent} to parse. - * @param targetType the class representing the target type. - * @param the target type parameter. - * @return an instance of the parsed type, or null if parsing fails or data is null. - */ - private T parseCEData(CloudEvent ce, Class targetType) { - if (ce.getData() == null) return null; - try { - return JsonUtils.mapper().readValue(ce.getData().toBytes(), targetType); - } catch (Exception e) { - return null; - } - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncListenSpec.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncListenSpec.java deleted file mode 100644 index 334a219ac..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncListenSpec.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.fluent.func.FuncListenTaskBuilder; -import io.serverlessworkflow.fluent.func.configurers.FuncListenConfigurer; - -public final class FuncListenSpec extends BaseFuncListenSpec - implements FuncListenConfigurer { - - public FuncListenSpec() { - super(FuncListenTaskBuilder::to); - } - - @Override - protected FuncListenSpec self() { - return this; - } - - @Override - public void accept(FuncListenTaskBuilder funcListenTaskBuilder) { - acceptInto(funcListenTaskBuilder); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ListenStep.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ListenStep.java deleted file mode 100644 index debd3b968..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/ListenStep.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.fluent.func.FuncListenTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import java.util.function.Consumer; - -/** Chainable listen step; applies FuncListenSpec then queued export/when. */ -public final class ListenStep extends Step { - - private final String name; // nullable - private final FuncListenSpec spec; - - ListenStep(String name, FuncListenSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - protected void configure( - FuncTaskItemListBuilder list, Consumer postApply) { - if (name == null) { - list.listen( - lb -> { - spec.accept(lb); - postApply.accept(lb); - }); - } else { - list.listen( - name, - lb -> { - spec.accept(lb); - postApply.accept(lb); - }); - } - } -} 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 deleted file mode 100644 index c5d218791..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/Step.java +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.SerializableFunction; -import io.serverlessworkflow.api.types.func.SerializablePredicate; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import io.serverlessworkflow.fluent.func.FuncTaskItemListBuilder; -import io.serverlessworkflow.fluent.func.configurers.FuncTaskConfigurer; -import io.serverlessworkflow.fluent.func.spi.ConditionalTaskBuilder; -import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations; -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import io.serverlessworkflow.fluent.spec.TimeoutBuilder; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; - -/** - * A deferred configurer that can chain when/inputFrom/outputAs/exportAs and apply them later to the - * concrete task builder (e.g., Call/Emit/Listen builder). - */ -abstract class Step, B> implements FuncTaskConfigurer { - - private final List> postConfigurers = new ArrayList<>(); - - @SuppressWarnings("unchecked") - protected SELF self() { - return (SELF) this; - } - - // --------------------------------------------------------------------------- - // ConditionalTaskBuilder passthroughs (if/when) - // --------------------------------------------------------------------------- - - /** Queue a {@code when(predicate)} to be applied on the concrete builder. */ - public SELF when(SerializablePredicate predicate) { - postConfigurers.add( - b -> - ((ConditionalTaskBuilder) b) - .when(predicate, ReflectionUtils.inferInputType(predicate))); - return self(); - } - - /** Queue a {@code when(predicate, argClass)} to be applied on the concrete builder. */ - public SELF when(Predicate predicate, Class argClass) { - postConfigurers.add(b -> ((ConditionalTaskBuilder) b).when(predicate, argClass)); - return self(); - } - - public SELF when(String jqExpr) { - postConfigurers.add(b -> ((TaskBaseBuilder) b).when(jqExpr)); - return self(); - } - - /** - * Queue a {@code then(taskName)} to be applied on the concrete builder. Directs the workflow - * engine to jump to the named task after this one completes. - * - * @param taskName the name of the next task to execute - * @return this step for further chaining - * @see DSL - * Reference - Task - */ - public SELF then(String taskName) { - postConfigurers.add(b -> ((TaskBaseBuilder) b).then(taskName)); - return self(); - } - - /** - * Queue a {@code then(directive)} to be applied on the concrete builder. Directs the workflow - * engine to apply the given flow directive after this task completes. - * - * @param directive the flow directive (e.g., {@link FlowDirectiveEnum#END}) - * @return this step for further chaining - * @see DSL - * Reference - Task - */ - public SELF then(FlowDirectiveEnum directive) { - postConfigurers.add(b -> ((TaskBaseBuilder) b).then(directive)); - return self(); - } - - // --------------------------------------------------------------------------- - // FuncTaskTransformations passthroughs: EXPORT (fn/context/filter + JQ) - // --------------------------------------------------------------------------- - - /** - * Shapes what the task exports for downstream consumers using a Java function. - * - *

This method queues an {@code exportAs} transformation to be applied when the step is built. - * It allows chaining transformations in a fluent manner. - * - *

{@code exportAs} controls what the task exports for downstream consumers - * (the next task, events, etc.), immediately updating the workflow context. - * - *

Example: - * - *

{@code
-   * agent("draftNewsletter", drafter::draft, Draft.class)
-   *     .exportAs(draft -> Map.of("draftText", draft.text()))
-   *     .when(condition);
-   * }
- * - * @param the context type - * @param the export type (what gets written in the workflow context) - * @param function the transformation function - * @return this step for method chaining - * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(Function) - */ - public SELF exportAs(SerializableFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .exportAs(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes what the task exports for downstream consumers using a Java function with explicit - * context input type. - * - *

This variant allows you to explicitly specify the input type class for better type safety. - * - * @param the workflow context type - * @param the export type (what gets written in the context) - * @param function the transformation function - * @param taskResultClass the class of the workflow context type - * @return this step for method chaining - * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(Function, Class) - */ - public SELF exportAs(Function function, Class taskResultClass) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function, taskResultClass)); - return self(); - } - - /** - * Shapes what the task exports for downstream consumers using a context-aware filter function. - * - *

This variant provides access to both workflow and task context, allowing you to inspect - * metadata when shaping the export. - * - * @param the workflow context type - * @param the export type (what gets written in the context) - * @param function the filter function with workflow and task context - * @return this step for method chaining - * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(FilterFunction) - */ - public SELF exportAs(FilterFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .exportAs(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes what the task exports for downstream consumers using a context-aware filter function - * with explicit input type. - * - * @param the workflow context type - * @param the export type (what gets written in the context) - * @param function the filter function with workflow and task context - * @param taskResultClass the class of the workflow context type - * @return this step for method chaining - * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(FilterFunction, - * Class) - */ - public SELF exportAs(FilterFunction function, Class taskResultClass) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function, taskResultClass)); - return self(); - } - - /** - * Shapes what the task exports for downstream consumers using a context-aware function. - * - *

This variant provides access to workflow context, allowing you to inspect workflow metadata - * when shaping the export. - * - * @param the workflow context type - * @param the export type (what gets written in the context) - * @param function the context function with workflow context - * @return this step for method chaining - * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(ContextFunction) - */ - public SELF exportAs(ContextFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .exportAs(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes what the task exports for downstream consumers using a context-aware function with - * explicit input type. - * - * @param the workflow context type - * @param the export type (what gets written in the context) - * @param function the context function with workflow context - * @param taskResultClass the class of the workflow context type - * @return this step for method chaining - * @see io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations#exportAs(ContextFunction, - * Class) - */ - public SELF exportAs(ContextFunction function, Class taskResultClass) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).exportAs(function, taskResultClass)); - return self(); - } - - /** - * Overrides the workflow context with the current task output. - * - * @return this step for method chaining - */ - public SELF exportAsTaskOutput() { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .exportAs((context, workflowContext, taskContext) -> taskContext.output())); - return self(); - } - - /** - * Shapes what the task exports for downstream consumers using a JQ expression. - * - *

This variant allows you to use JQ expressions to transform the task result before it's - * forwarded to the next step or event. - * - *

Example: - * - *

{@code
-   * // Given that your context has this attribute already
-   * exportAs("$.username")
-   * }
- * - * @param jqExpression the JQ expression to transform the export - * @return this step for method chaining - */ - public SELF exportAs(String jqExpression) { - postConfigurers.add(b -> ((TaskBaseBuilder) b).exportAs(jqExpression)); - return self(); - } - - // --------------------------------------------------------------------------- - // FuncTaskTransformations passthroughs: OUTPUT (fn/context/filter + JQ) - // --------------------------------------------------------------------------- - - /** - * Shapes what gets written back into the workflow data document using a Java function. - * - *

This method queues an {@code outputAs} transformation to be applied when the step is built. - * It allows chaining transformations in a fluent manner. - * - *

{@code outputAs} controls what gets written back into the workflow data document. Use this - * when you want to rename fields, drop internal details, or construct a composite DTO. - * - *

Example: - * - *

{@code
-   * agent("investmentAnalyst", analyst::analyse, InvestmentMemo.class)
-   *     .outputAs(memo -> Map.of("memo", memo))
-   *     .when(condition);
-   * }
- * - * @param the task result type - * @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(SerializableFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .outputAs(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes what gets written back into the workflow data document using a Java function with - * explicit input type. - * - *

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 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) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function, taskResultClass)); - return self(); - } - - /** - * Shapes what gets written back into the workflow data document using a context-aware filter - * function. - * - *

This variant provides access to both workflow and task context, allowing you to inspect - * metadata, task input, and raw output when shaping the committed output. - * - *

Example: - * - *

{@code
-   * get("fetchMarketData", "http://localhost:8081/market-data/{ticker}")
-   *     .outputAs((MarketDataSnapshot snapshot,
-   *                WorkflowContextData wf,
-   *                TaskContextData task) -> {
-   *         var input = task.input().asMap().orElseThrow();
-   *         var rawBody = task.rawOutput().asText().orElseThrow();
-   *         return new InvestmentPrompt(
-   *             snapshot.ticker(),
-   *             input.get("objective").toString(),
-   *             rawBody
-   *         );
-   *     }, MarketDataSnapshot.class);
-   * }
- * - * @param the task result type - * @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(FilterFunction) - */ - public SELF outputAs(FilterFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .outputAs(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes what gets written back into the workflow data document using a context-aware filter - * function with explicit input type. - * - * @param the task result type - * @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(FilterFunction, Class) - */ - public SELF outputAs(FilterFunction function, Class taskResultClass) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function, taskResultClass)); - return self(); - } - - /** - * Shapes what gets written back into the workflow data document using a context-aware function. - * - *

This variant provides access to workflow context, allowing you to inspect workflow metadata - * when shaping the committed output. - * - * @param the task result type - * @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(ContextFunction) - */ - public SELF outputAs(ContextFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .outputAs(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes what gets written back into the workflow data document using a context-aware function - * with explicit input type. - * - * @param the task result type - * @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(ContextFunction, Class) - */ - public SELF outputAs(ContextFunction function, Class taskResultClass) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(function, taskResultClass)); - return self(); - } - - /** - * Shapes what gets written back into the workflow data document using a JQ expression. - * - *

This variant allows you to use JQ expressions to project the task result into the workflow - * data. - * - *

Example: - * - *

{@code
-   * outputAs("$.username")
-   * }
- * - * @param jqExpression the JQ expression to transform the output - * @return this step for method chaining - */ - public SELF outputAs(String jqExpression) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).outputAs(jqExpression)); - return self(); - } - - // --------------------------------------------------------------------------- - // FuncTaskTransformations passthroughs: INPUT (fn/context/filter + JQ) - // --------------------------------------------------------------------------- - - /** - * Shapes the task input using a Java function. - * - *

This method queues an {@code inputFrom} transformation to be applied when the step is built. - * It allows chaining transformations in a fluent manner. - * - *

Without transformations, a task sees the whole workflow data as its input. - * Use {@code inputFrom} to give it a smaller, focused view. - * - *

Example: - * - *

{@code
-   * function(...)
-   *     .inputFrom((MyData data) -> Map.of("seed", data.seed()));
-   * }
- * - * @param the input type (workflow data or task 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(SerializableFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .inputFrom(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes the task input using a Java function with explicit input type. - * - *

This variant allows you to explicitly specify the input type class for better type safety. - * - *

Example: - * - *

{@code
-   * inputFrom((InvestmentRequest in) ->
-   *         Map.of("ticker", in.ticker().toUpperCase()),
-   *     InvestmentRequest.class);
-   * }
- * - * @param the input type (workflow data or task 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) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function, inputClass)); - return self(); - } - - /** - * Shapes the task input using a context-aware filter function with access to workflow and task - * context. - * - *

This variant provides access to both the workflow context ({@code WorkflowContextData}) and - * task context ({@code TaskContextData}), allowing you to inspect workflow metadata, task - * position, and other contextual information. - * - *

Example: - * - *

{@code
-   * inputFrom((InvestmentRequest in,
-   *            WorkflowContextData wf,
-   *            TaskContextData task) -> Map.of(
-   *         "ticker", in.ticker(),
-   *         "objective", in.objective(),
-   *         "taskPos", task.position().jsonPointer() // e.g. /do/0/task
-   *     ));
-   * }
- * - * @param the input type (workflow data or task 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(FilterFunction) - */ - public SELF inputFrom(FilterFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .inputFrom(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes the task input using a context-aware filter function with explicit input type. - * - *

This variant combines the benefits of {@link #inputFrom(FilterFunction)} with explicit type - * specification. - * - * @param the input type (workflow data or task 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(FilterFunction, Class) - */ - public SELF inputFrom(FilterFunction function, Class inputClass) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function, inputClass)); - return self(); - } - - /** - * Shapes the task input using a context-aware function with access to workflow context. - * - *

This variant provides access to the workflow context ({@code WorkflowContextData}), allowing - * 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 function the context function with workflow context - * @return this step for method chaining - * @see io.serverlessworkflow.fluent.func.spi.FuncTransformations#inputFrom(ContextFunction) - */ - public SELF inputFrom(ContextFunction function) { - postConfigurers.add( - b -> - ((FuncTaskTransformations) b) - .inputFrom(function, ReflectionUtils.inferInputType(function))); - return self(); - } - - /** - * Shapes the task input using a context-aware function with explicit input type. - * - *

This variant combines the benefits of {@link #inputFrom(ContextFunction)} with explicit type - * specification. - * - * @param the input type (workflow data or task 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(ContextFunction, - * Class) - */ - public SELF inputFrom(ContextFunction function, Class inputClass) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(function, inputClass)); - return self(); - } - - /** - * Shapes the task input using a JQ expression. - * - *

This variant allows you to use JQ expressions to slice and transform the workflow data - * before it reaches the task. - * - *

Example: - * - *

{@code
-   * // Only pass the "seed" field into this task:
-   * function(...)
-   *     .inputFrom("$.seed");
-   * }
- * - * @param jqExpression the JQ expression to transform the input - * @return this step for method chaining - */ - public SELF inputFrom(String jqExpression) { - postConfigurers.add(b -> ((FuncTaskTransformations) b).inputFrom(jqExpression)); - return self(); - } - - public SELF timeout(String durationExpression) { - this.postConfigurers.add(b -> ((TaskBaseBuilder) b).timeout(durationExpression)); - return self(); - } - - public SELF timeout(Consumer timeout) { - this.postConfigurers.add(b -> ((TaskBaseBuilder) b).timeout(timeout)); - return self(); - } - - // --------------------------------------------------------------------------- - // wiring into the underlying list/builder - // --------------------------------------------------------------------------- - - @Override - public final void accept(FuncTaskItemListBuilder list) { - configure(list, this::applyPost); - } - - /** Implement per-step to attach to the correct builder and run {@code post} at the end. */ - protected abstract void configure(FuncTaskItemListBuilder list, Consumer post); - - /** Applies all queued post-configurers to the concrete builder. */ - private void applyPost(B builder) { - for (Consumer c : postConfigurers) c.accept(builder); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/SwitchCaseSpec.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/SwitchCaseSpec.java deleted file mode 100644 index 63d05a16a..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/SwitchCaseSpec.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.dsl; - -import io.serverlessworkflow.fluent.func.FuncSwitchTaskBuilder; -import io.serverlessworkflow.fluent.func.configurers.SwitchCaseConfigurer; -import java.util.function.Predicate; - -public class SwitchCaseSpec implements SwitchCaseConfigurer { - - private String then = ""; - private Predicate when; - private Class whenClass; - - public SwitchCaseSpec when(Predicate when, Class whenClass) { - this.when = when; - this.whenClass = whenClass; - return this; - } - - public SwitchCaseSpec when(Predicate when) { - this.when = when; - return this; - } - - public SwitchCaseSpec then(String directive) { - this.then = directive; - return this; - } - - @Override - public void accept(FuncSwitchTaskBuilder.SwitchCasePredicateBuilder switchCasePredicateBuilder) { - if (this.whenClass != null) { - switchCasePredicateBuilder.then(this.then).when(this.when, this.whenClass); - } else { - switchCasePredicateBuilder.then(this.then).when(this.when); - } - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/CallFnFluent.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/CallFnFluent.java deleted file mode 100644 index d2257c40e..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/CallFnFluent.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.spi; - -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import java.util.function.Consumer; - -public interface CallFnFluent, LIST> { - - LIST function(String name, Consumer cfg); - - default LIST function(Consumer cfg) { - return this.function(null, cfg); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/CallGrpcFluent.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/CallGrpcFluent.java deleted file mode 100644 index 977d0d834..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/CallGrpcFluent.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.spi; - -import io.serverlessworkflow.fluent.spec.TaskBaseBuilder; -import java.util.function.Consumer; - -public interface CallGrpcFluent, LIST> { - - LIST grpc(String name, Consumer itemsConfigurer); - - default LIST grpc(Consumer itemsConfigurer) { - return this.grpc(null, itemsConfigurer); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/ConditionalTaskBuilder.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/ConditionalTaskBuilder.java deleted file mode 100644 index 6c4ca97ab..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/ConditionalTaskBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.spi; - -import io.serverlessworkflow.api.types.TaskBase; -import io.serverlessworkflow.api.types.func.TypedPredicate; -import java.util.Objects; -import java.util.function.Predicate; - -public interface ConditionalTaskBuilder { - - TaskBase getTask(); - - @SuppressWarnings("unchecked") - default SELF when(Predicate predicate) { - ConditionalTaskBuilderHelper.setMetadata(getTask(), predicate); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF when(Predicate predicate, Class argClass) { - Objects.requireNonNull(argClass); - ConditionalTaskBuilderHelper.setMetadata(getTask(), new TypedPredicate<>(predicate, argClass)); - return (SELF) this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/ConditionalTaskBuilderHelper.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/ConditionalTaskBuilderHelper.java deleted file mode 100644 index 3d09eddfc..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/ConditionalTaskBuilderHelper.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.spi; - -import io.serverlessworkflow.api.types.TaskBase; -import io.serverlessworkflow.api.types.utils.TypesUtils; - -class ConditionalTaskBuilderHelper { - - private ConditionalTaskBuilderHelper() {} - - static void setMetadata(TaskBase task, Object predicate) { - TypesUtils.initMetadata(task).setAdditionalProperty(TypesUtils.IF_PREDICATE, predicate); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncDoFluent.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncDoFluent.java deleted file mode 100644 index 3efcae1c1..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncDoFluent.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.spi; - -import io.serverlessworkflow.fluent.func.FuncCallGrpcTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncCallHttpTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncCallOpenAPITaskBuilder; -import io.serverlessworkflow.fluent.func.FuncCallTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncEmitTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncForTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncForkTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncListenTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncRaiseTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncSetTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncSwitchTaskBuilder; -import io.serverlessworkflow.fluent.func.FuncTryTaskBuilder; -import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder; -import io.serverlessworkflow.fluent.spec.spi.CallHttpFluent; -import io.serverlessworkflow.fluent.spec.spi.CallOpenAPIFluent; -import io.serverlessworkflow.fluent.spec.spi.EmitFluent; -import io.serverlessworkflow.fluent.spec.spi.ForEachFluent; -import io.serverlessworkflow.fluent.spec.spi.ForkFluent; -import io.serverlessworkflow.fluent.spec.spi.ListenFluent; -import io.serverlessworkflow.fluent.spec.spi.RaiseFluent; -import io.serverlessworkflow.fluent.spec.spi.SetFluent; -import io.serverlessworkflow.fluent.spec.spi.SwitchFluent; -import io.serverlessworkflow.fluent.spec.spi.TryCatchFluent; -import io.serverlessworkflow.fluent.spec.spi.WorkflowFluent; -import java.util.function.Consumer; - -public interface FuncDoFluent> - extends SetFluent, - EmitFluent, - ForEachFluent, - SwitchFluent, - ForkFluent, - ListenFluent, - RaiseFluent, - TryCatchFluent, - CallFnFluent, - CallHttpFluent, - CallOpenAPIFluent, - CallGrpcFluent, - WorkflowFluent { - - default SELF subflow(String name, Consumer itemsConfigurer) { - return this.workflow(name, itemsConfigurer); - } - - default SELF subflow(Consumer itemsConfigurer) { - return this.workflow(itemsConfigurer); - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTaskTransformations.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTaskTransformations.java deleted file mode 100644 index 0d741d251..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTaskTransformations.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.spi; - -import io.serverlessworkflow.api.types.Export; -import io.serverlessworkflow.api.types.ExportAs; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.TypedContextFunction; -import io.serverlessworkflow.api.types.func.TypedFilterFunction; -import io.serverlessworkflow.api.types.func.TypedFunction; -import io.serverlessworkflow.fluent.spec.spi.TaskTransformationHandlers; -import java.util.function.Function; - -public interface FuncTaskTransformations> - extends TaskTransformationHandlers, FuncTransformations { - - @SuppressWarnings("unchecked") - default SELF exportAs(Function function) { - setExport(new Export().withAs(new ExportAs().withObject(function))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF exportAs(Function function, Class argClass) { - setExport( - new Export() - .withAs(new ExportAs().withObject(new TypedFunction(function, argClass)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF exportAs(FilterFunction function) { - setExport(new Export().withAs(new ExportAs().withObject(function))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF exportAs(FilterFunction function, Class argClass) { - setExport( - new Export() - .withAs(new ExportAs().withObject(new TypedFilterFunction<>(function, argClass)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF exportAs(ContextFunction function) { - setExport(new Export().withAs(new ExportAs().withObject(function))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF exportAs(ContextFunction function, Class argClass) { - setExport( - new Export() - .withAs(new ExportAs().withObject(new TypedContextFunction<>(function, argClass)))); - return (SELF) this; - } -} diff --git a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTransformations.java b/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTransformations.java deleted file mode 100644 index 8d1dc8ec2..000000000 --- a/experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncTransformations.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.spi; - -import io.serverlessworkflow.api.types.Input; -import io.serverlessworkflow.api.types.InputFrom; -import io.serverlessworkflow.api.types.Output; -import io.serverlessworkflow.api.types.OutputAs; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.TypedContextFunction; -import io.serverlessworkflow.api.types.func.TypedFilterFunction; -import io.serverlessworkflow.api.types.func.TypedFunction; -import io.serverlessworkflow.fluent.spec.spi.TransformationHandlers; -import java.util.function.Function; - -public interface FuncTransformations> - extends TransformationHandlers { - - @SuppressWarnings("unchecked") - default SELF inputFrom(Function function) { - setInput(new Input().withFrom(new InputFrom().withObject(function))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF inputFrom(Function function, Class argClass) { - setInput( - new Input().withFrom(new InputFrom().withObject(new TypedFunction<>(function, argClass)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF inputFrom(FilterFunction function) { - setInput(new Input().withFrom(new InputFrom().withObject(function))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF inputFrom(FilterFunction function, Class argClass) { - setInput( - new Input() - .withFrom(new InputFrom().withObject(new TypedFilterFunction<>(function, argClass)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF inputFrom(ContextFunction function) { - setInput(new Input().withFrom(new InputFrom().withObject((function)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF inputFrom(ContextFunction function, Class argClass) { - setInput( - new Input() - .withFrom(new InputFrom().withObject(new TypedContextFunction<>(function, argClass)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF inputFrom(String jqExpression) { - setInput(new Input().withFrom(new InputFrom().withString(jqExpression))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF outputAs(Function function) { - setOutput(new Output().withAs(new OutputAs().withObject(function))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF outputAs(Function function, Class argClass) { - setOutput( - new Output().withAs(new OutputAs().withObject(new TypedFunction<>(function, argClass)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF outputAs(FilterFunction function) { - setOutput(new Output().withAs(new OutputAs().withObject(function))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF outputAs(FilterFunction function, Class argClass) { - setOutput( - new Output() - .withAs(new OutputAs().withObject(new TypedFilterFunction<>(function, argClass)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF outputAs(ContextFunction function) { - setOutput(new Output().withAs(new OutputAs().withObject(function))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF outputAs(ContextFunction function, Class argClass) { - setOutput( - new Output() - .withAs(new OutputAs().withObject(new TypedContextFunction<>(function, argClass)))); - return (SELF) this; - } - - @SuppressWarnings("unchecked") - default SELF outputAs(String jqExpression) { - setOutput(new Output().withAs(new OutputAs().withString(jqExpression))); - return (SELF) this; - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLConsumeTest.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLConsumeTest.java deleted file mode 100644 index fb3150a0c..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLConsumeTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consume; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.Workflow; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -class FuncDSLConsumeTest { - - @Test - @DisplayName( - "consume(name, Consumer, Class) produces CallTask and leaves output unchanged by contract") - void consume_produces_callTask() { - AtomicReference sink = new AtomicReference<>(); - - Workflow wf = - FuncWorkflowBuilder.workflow("consumeStep") - .tasks( - consume( - "sendNewsletter", - (String reviewed) -> sink.set("CALLED:" + reviewed), - String.class)) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask should be present for consume step"); - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLOAuth2Test.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLOAuth2Test.java deleted file mode 100644 index 76a382c3b..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLOAuth2Test.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.call; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.http; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.oauth2; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import io.serverlessworkflow.api.types.OAuth2AuthenticationData; -import io.serverlessworkflow.api.types.OAuth2AuthenticationDataClient; -import io.serverlessworkflow.api.types.OAuth2ConnectAuthenticationProperties; -import io.serverlessworkflow.api.types.Workflow; -import java.net.URI; -import java.util.List; -import org.junit.jupiter.api.Test; - -class FuncDSLOAuth2Test { - - private static final String EXPR_ENDPOINT = "${ .endpoint }"; - - private static OAuth2ConnectAuthenticationProperties oauth2PropertiesOf(Workflow wf) { - var auth = - wf.getDo() - .get(0) - .getTask() - .getCallTask() - .getCallHTTP() - .getWith() - .getEndpoint() - .getEndpointConfiguration() - .getAuthentication() - .getAuthenticationPolicy(); - assertNotNull(auth.getOAuth2AuthenticationPolicy()); - return auth.getOAuth2AuthenticationPolicy() - .getOauth2() - .getOAuth2ConnectAuthenticationProperties(); - } - - @Test - void convenience_overload_sets_token_endpoint() { - Workflow wf = - FuncWorkflowBuilder.workflow("oauth2-token") - .tasks( - call( - http() - .POST() - .endpoint( - EXPR_ENDPOINT, - oauth2( - "https://auth.example.com/", - OAuth2AuthenticationData.OAuth2AuthenticationDataGrant - .CLIENT_CREDENTIALS, - "client-id", - "client-secret", - e -> e.token("/custom/token"))))) - .build(); - - var props = oauth2PropertiesOf(wf); - assertEquals(URI.create("https://auth.example.com/"), props.getAuthority().getLiteralUri()); - assertEquals( - OAuth2AuthenticationData.OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS, - props.getGrant()); - assertEquals("client-id", props.getClient().getId()); - assertEquals("client-secret", props.getClient().getSecret()); - assertEquals("/custom/token", props.getEndpoints().getToken()); - } - - @Test - void builder_overload_supports_full_oauth2_section() { - Workflow wf = - FuncWorkflowBuilder.workflow("oauth2-full") - .tasks( - call( - http() - .GET() - .endpoint( - EXPR_ENDPOINT, - oauth2( - o -> - o.endpoints( - e -> - e.token("/oauth2/token") - .revocation("/oauth2/revoke") - .introspection("/oauth2/introspect")) - .authority("https://auth.example.com/") - .grant( - OAuth2AuthenticationData.OAuth2AuthenticationDataGrant - .CLIENT_CREDENTIALS) - .scopes("read", "write") - .audiences("api://default") - .client( - c -> - c.id("client-id") - .secret("client-secret") - .authentication( - OAuth2AuthenticationDataClient - .ClientAuthentication - .CLIENT_SECRET_BASIC)))))) - .build(); - - var props = oauth2PropertiesOf(wf); - assertEquals(URI.create("https://auth.example.com/"), props.getAuthority().getLiteralUri()); - assertEquals( - OAuth2AuthenticationData.OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS, - props.getGrant()); - assertEquals(List.of("read", "write"), props.getScopes()); - assertEquals(List.of("api://default"), props.getAudiences()); - assertEquals("client-id", props.getClient().getId()); - assertEquals( - OAuth2AuthenticationDataClient.ClientAuthentication.CLIENT_SECRET_BASIC, - props.getClient().getAuthentication()); - assertEquals("/oauth2/token", props.getEndpoints().getToken()); - assertEquals("/oauth2/revoke", props.getEndpoints().getRevocation()); - assertEquals("/oauth2/introspect", props.getEndpoints().getIntrospection()); - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLScheduleTest.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLScheduleTest.java deleted file mode 100644 index 0bfe8f8b6..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLScheduleTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.after; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.allOfType; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.cron; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.every; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.on; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.one; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.timeoutHours; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.timeoutMinutes; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -import io.serverlessworkflow.api.types.Schedule; -import io.serverlessworkflow.api.types.Workflow; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -/** Tests for Schedule chaining via FuncWorkflowBuilder. */ -class FuncDSLScheduleTest { - - @Test - @DisplayName("schedule(every(expression)) configures an 'every' schedule string expression") - void schedule_every_expression_sets_schedule() { - Workflow wf = - FuncWorkflowBuilder.workflow("schedule-every-expr").schedule(every("PT15M")).build(); - - Schedule schedule = wf.getSchedule(); - assertNotNull(schedule, "Schedule should be configured"); - assertNotNull(schedule.getEvery(), "Every configuration should be set"); - assertEquals( - "PT15M", schedule.getEvery().getDurationLiteral(), "Duration expression should match"); - assertNull(schedule.getEvery().getDurationInline(), "Inline duration should be null"); - } - - @Test - @DisplayName("schedule(every(inline)) configures an 'every' schedule inline duration") - void schedule_every_inline_sets_schedule() { - Workflow wf = - FuncWorkflowBuilder.workflow("schedule-every-inline") - .schedule(every(timeoutMinutes(15))) - .build(); - - Schedule schedule = wf.getSchedule(); - assertNotNull(schedule, "Schedule should be configured"); - assertNotNull(schedule.getEvery(), "Every configuration should be set"); - assertNull(schedule.getEvery().getDurationExpression(), "Duration expression should be null"); - assertNotNull(schedule.getEvery().getDurationInline(), "Inline duration should be set"); - assertEquals(15, schedule.getEvery().getDurationInline().getMinutes(), "Minutes should match"); - } - - @Test - @DisplayName("schedule(cron) configures a 'cron' schedule string") - void schedule_cron_sets_schedule() { - Workflow wf = FuncWorkflowBuilder.workflow("schedule-cron").schedule(cron("0 0 * * *")).build(); - - Schedule schedule = wf.getSchedule(); - assertNotNull(schedule, "Schedule should be configured"); - assertEquals("0 0 * * *", schedule.getCron(), "Cron expression should match"); - assertNull(schedule.getEvery(), "Every configuration should be null"); - } - - @Test - @DisplayName("schedule(after(expression)) configures an 'after' schedule string expression") - void schedule_after_expression_sets_schedule() { - Workflow wf = - FuncWorkflowBuilder.workflow("schedule-after-expr").schedule(after("PT1H")).build(); - - Schedule schedule = wf.getSchedule(); - assertNotNull(schedule, "Schedule should be configured"); - assertNotNull(schedule.getAfter(), "After configuration should be set"); - assertEquals( - "PT1H", schedule.getAfter().getDurationLiteral(), "Duration expression should match"); - assertNull(schedule.getAfter().getDurationInline(), "Inline duration should be null"); - } - - @Test - @DisplayName("schedule(after(inline)) configures an 'after' schedule inline duration") - void schedule_after_inline_sets_schedule() { - Workflow wf = - FuncWorkflowBuilder.workflow("schedule-after-inline") - .schedule(after(timeoutHours(1))) - .build(); - - Schedule schedule = wf.getSchedule(); - assertNotNull(schedule, "Schedule should be configured"); - assertNotNull(schedule.getAfter(), "After configuration should be set"); - assertNull(schedule.getAfter().getDurationExpression(), "Duration expression should be null"); - assertNotNull(schedule.getAfter().getDurationInline(), "Inline duration should be set"); - assertEquals(1, schedule.getAfter().getDurationInline().getHours(), "Hours should match"); - } - - @Test - @DisplayName("schedule(on(one(event))) configures an 'on' schedule event consumption strategy") - void schedule_on_event_sets_schedule() { - Workflow wf = - FuncWorkflowBuilder.workflow("schedule-on-event") - .schedule(on(one("org.acme.startup"))) - .build(); - - Schedule schedule = wf.getSchedule(); - assertNotNull(schedule, "Schedule should be configured"); - assertNotNull(schedule.getOn(), "On configuration should be set"); - assertNotNull( - schedule.getOn().getOneEventConsumptionStrategy(), - "One consumption strategy should be set"); - assertEquals( - "org.acme.startup", - schedule.getOn().getOneEventConsumptionStrategy().getOne().getWith().getType(), - "Event type should match"); - } - - @Test - @DisplayName( - "schedule(on(allOfType(event))) configures an 'on' schedule with 'all' event consumption strategy") - void schedule_on_allOfType_event_sets_schedule() { - Workflow wf = - FuncWorkflowBuilder.workflow("schedule-on-allOfType-event") - .schedule(on(allOfType("org.acme.processing"))) - .build(); - - Schedule schedule = wf.getSchedule(); - assertNotNull(schedule, "Schedule should be configured"); - assertNotNull(schedule.getOn(), "On configuration should be set"); - assertNotNull( - schedule.getOn().getAllEventConsumptionStrategy(), - "All consumption strategy should be set"); - assertEquals( - "org.acme.processing", - schedule.getOn().getAllEventConsumptionStrategy().getAll().get(0).getWith().getType(), - "Event type should match in the filter"); - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTaskNameTest.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTaskNameTest.java deleted file mode 100644 index e2ca64d92..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTaskNameTest.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consume; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.forEach; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.forEachItem; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.switchWhen; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.switchWhenOrElse; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.SwitchCase; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.api.types.func.LoopFunction; -import io.serverlessworkflow.fluent.func.configurers.FuncTaskConfigurer; -import java.util.List; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -@DisplayName("FuncDSL — named control-flow overloads") -class FuncDSLTaskNameTest { - - private static Workflow buildWorkflow(FuncTaskConfigurer... steps) { - return FuncWorkflowBuilder.workflow("taskNameTest").tasks(steps).build(); - } - - private static List buildItems(FuncTaskConfigurer... steps) { - return buildWorkflow(steps).getDo(); - } - - @Nested - @DisplayName("switchWhen — named overloads") - class SwitchWhenTest { - - @Test - @DisplayName("named predicate overload uses taskName and stores predicate case") - void namedPredicateOverload() { - var items = - buildItems(switchWhen("checkSign", (Integer v) -> v > 0, "positive", Integer.class)); - assertEquals("checkSign", items.get(0).getName()); - SwitchCase sc = items.get(0).getTask().getSwitchTask().getSwitch().get(0).getSwitchCase(); - assertEquals("positive", sc.getThen().getString()); - } - - @Test - @DisplayName("named JQ overload uses taskName and configures when expression") - void namedJqOverload() { - var items = buildItems(switchWhen("approvalGate", ".approved == true", "approveOrder")); - assertEquals("approvalGate", items.get(0).getName()); - assertEquals( - ".approved == true", - items.get(0).getTask().getSwitchTask().getSwitch().get(0).getSwitchCase().getWhen()); - } - - @Test - @DisplayName("unnamed overloads produce auto-generated switch- names") - void unnamedAutoNames() { - var items = - buildItems( - switchWhen((Integer v) -> v > 0, "pos", Integer.class), switchWhen(".ok", "go")); - assertTrue(items.get(0).getName().startsWith("switch-")); - assertTrue(items.get(1).getName().startsWith("switch-")); - } - } - - @Nested - @DisplayName("switchWhenOrElse — named overloads") - class SwitchWhenOrElseTest { - - @Test - @DisplayName("named Predicate + directive overload") - void namedPredicateDirective() { - var items = - buildItems( - switchWhenOrElse( - "scoreGate", - (Integer v) -> v >= 80, - "pass", - FlowDirectiveEnum.END, - Integer.class)); - assertEquals("scoreGate", items.get(0).getName()); - var cases = items.get(0).getTask().getSwitchTask().getSwitch(); - assertEquals(2, cases.size()); - assertEquals("pass", cases.get(0).getSwitchCase().getThen().getString()); - assertEquals( - FlowDirectiveEnum.END, cases.get(1).getSwitchCase().getThen().getFlowDirectiveEnum()); - } - - @Test - @DisplayName("named SerializablePredicate + orElseTask overload") - void namedSerializablePredicateTask() { - var items = - buildItems(switchWhenOrElse("signGate", (Integer v) -> v > 0, "positive", "negative")); - assertEquals("signGate", items.get(0).getName()); - var cases = items.get(0).getTask().getSwitchTask().getSwitch(); - assertEquals("positive", cases.get(0).getSwitchCase().getThen().getString()); - assertEquals("negative", cases.get(1).getSwitchCase().getThen().getString()); - } - - @Test - @DisplayName("named JQ + directive overload") - void namedJqDirective() { - var items = - buildItems(switchWhenOrElse("examGate", ".score >= 80", "pass", FlowDirectiveEnum.END)); - assertEquals("examGate", items.get(0).getName()); - var cases = items.get(0).getTask().getSwitchTask().getSwitch(); - assertEquals(".score >= 80", cases.get(0).getSwitchCase().getWhen()); - assertEquals( - FlowDirectiveEnum.END, cases.get(1).getSwitchCase().getThen().getFlowDirectiveEnum()); - } - - @Test - @DisplayName("named JQ + orElseTask overload") - void namedJqTask() { - var items = buildItems(switchWhenOrElse("approvalGate", ".approved", "send", "draft")); - assertEquals("approvalGate", items.get(0).getName()); - var cases = items.get(0).getTask().getSwitchTask().getSwitch(); - assertEquals(".approved", cases.get(0).getSwitchCase().getWhen()); - assertEquals("draft", cases.get(1).getSwitchCase().getThen().getString()); - } - - @Test - @DisplayName("unnamed overloads produce auto-generated switch- names") - void unnamedAutoNames() { - var items = - buildItems( - switchWhenOrElse((Integer v) -> v > 0, "pos", FlowDirectiveEnum.END, Integer.class), - switchWhenOrElse((Integer v) -> v > 0, "pos", "neg"), - switchWhenOrElse(".ok", "go", FlowDirectiveEnum.END), - switchWhenOrElse(".ok", "go", "nope")); - for (int i = 0; i < items.size(); i++) { - assertTrue(items.get(i).getName().startsWith("switch-"), "item " + i); - } - } - - @Test - @DisplayName("JQ overloads throw NPE on null args") - void jqNullArgValidation() { - assertThrows( - NullPointerException.class, - () -> switchWhenOrElse((String) null, "pass", FlowDirectiveEnum.END)); - assertThrows( - NullPointerException.class, - () -> switchWhenOrElse("gate", (String) null, "pass", FlowDirectiveEnum.END)); - assertThrows( - NullPointerException.class, - () -> switchWhenOrElse("gate", ".x", (String) null, FlowDirectiveEnum.END)); - assertThrows( - NullPointerException.class, - () -> switchWhenOrElse("gate", ".x", "pass", (FlowDirectiveEnum) null)); - assertThrows( - NullPointerException.class, () -> switchWhenOrElse((String) null, "send", "draft")); - assertThrows( - NullPointerException.class, - () -> switchWhenOrElse("gate", (String) null, "send", "draft")); - assertThrows( - NullPointerException.class, () -> switchWhenOrElse("gate", ".x", (String) null, "draft")); - assertThrows( - NullPointerException.class, () -> switchWhenOrElse("gate", ".x", "send", (String) null)); - } - } - - @Nested - @DisplayName("forEach / forEachItem — named overloads") - class ForEachTest { - - @Test - @DisplayName("named SerializableFunction + body overload") - void namedFunctionBody() { - var items = buildItems(forEach("splitItems", (String s) -> List.of(s.split(",")), tb -> {})); - assertEquals("splitItems", items.get(0).getName()); - assertNotNull(items.get(0).getTask().getForTask()); - } - - @Test - @DisplayName("named SerializableFunction + LoopFunction overload") - void namedFunctionLoop() { - LoopFunction loopFn = (ctx, item) -> ctx; - var items = buildItems(forEach("mapItems", (String s) -> List.of(s.split(",")), loopFn)); - assertEquals("mapItems", items.get(0).getName()); - } - - @Test - @DisplayName("named forEachItem overload") - void namedForEachItem() { - var items = - buildItems( - forEachItem( - "transformEach", (String s) -> List.of(s.split(",")), (String item) -> item)); - assertEquals("transformEach", items.get(0).getName()); - } - - @Test - @DisplayName("named Collection + body overload") - void namedCollectionBody() { - var items = buildItems(forEach("iterateItems", List.of("a", "b"), tb -> {})); - assertEquals("iterateItems", items.get(0).getName()); - } - - @Test - @DisplayName("unnamed overloads produce auto-generated for- names") - void unnamedAutoNames() { - LoopFunction loopFn = (ctx, item) -> ctx; - var items = - buildItems( - forEach((String s) -> List.of(s), tb -> {}), - forEach((String s) -> List.of(s), loopFn), - forEachItem((String s) -> List.of(s), (String x) -> x), - forEach(List.of("a"), tb -> {}), - forEach(List.of("x", "y"), tb -> {})); - for (int i = 0; i < items.size(); i++) { - assertTrue(items.get(i).getName().startsWith("for-"), "item " + i); - } - } - } - - @Nested - @DisplayName("Integration — named control flow in realistic workflows") - class IntegrationTest { - - @Test - @DisplayName("named switchWhenOrElse with named branches") - void namedSwitchWithNamedBranches() { - Workflow wf = - buildWorkflow( - function("loadData", (String s) -> s, String.class), - switchWhenOrElse( - "validateData", - (String s) -> !s.isEmpty(), - "processValid", - "handleInvalid", - String.class), - consume("processValid", (String s) -> {}, String.class), - consume("handleInvalid", (String s) -> {}, String.class)); - var items = wf.getDo(); - assertEquals("loadData", items.get(0).getName()); - assertEquals("validateData", items.get(1).getName()); - assertEquals("processValid", items.get(2).getName()); - assertEquals("handleInvalid", items.get(3).getName()); - } - - @Test - @DisplayName("mixed named and unnamed control flow tasks") - void mixedNamedAndUnnamed() { - var items = - buildItems( - switchWhen("firstGate", (Integer v) -> v > 0, "pos", Integer.class), - switchWhen((String s) -> s.isEmpty(), "empty", String.class), - forEach("namedLoop", List.of(1, 2), tb -> {}), - forEach(List.of("x"), tb -> {})); - assertEquals("firstGate", items.get(0).getName()); - assertTrue(items.get(1).getName().startsWith("switch-")); - assertEquals("namedLoop", items.get(2).getName()); - assertTrue(items.get(3).getName().startsWith("for-")); - } - - @Test - @DisplayName("named JQ switchWhenOrElse in workflow") - void namedJqSwitchIntegration() { - var items = - buildItems( - function("fetchOrder", (String s) -> s, String.class), - switchWhenOrElse("checkApproval", ".approved == true", "fulfillOrder", "rejectOrder"), - consume("fulfillOrder", (String s) -> {}, String.class), - consume("rejectOrder", (String s) -> {}, String.class)); - assertEquals("checkApproval", items.get(1).getName()); - var cases = items.get(1).getTask().getSwitchTask().getSwitch(); - assertEquals(2, cases.size()); - assertEquals(".approved == true", cases.get(0).getSwitchCase().getWhen()); - assertEquals("rejectOrder", cases.get(1).getSwitchCase().getThen().getString()); - } - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTest.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTest.java deleted file mode 100644 index b4d89fa28..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLTest.java +++ /dev/null @@ -1,671 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.call; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consume; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.emit; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.get; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.grpc; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.http; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.listen; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.produced; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.switchWhenOrElse; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.toOne; -import static io.serverlessworkflow.fluent.spec.dsl.DSL.use; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -import io.serverlessworkflow.api.types.CallFunction; -import io.serverlessworkflow.api.types.CallGRPC; -import io.serverlessworkflow.api.types.CallHTTP; -import io.serverlessworkflow.api.types.Export; -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.RunTask; -import io.serverlessworkflow.api.types.RunWorkflow; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.fluent.func.dsl.FuncDSL; -import java.net.URI; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -/** Tests for Step chaining (exportAs/when) over function/emit/listen. */ -class FuncDSLTest { - - @Test - void function_step_exportAs_function_sets_export() { - Workflow wf = - FuncWorkflowBuilder.workflow("step-function-export") - .tasks( - // call + chain exportAs - function(String::trim, String.class) - .exportAs((String s) -> Map.of("len", s.length()))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected"); - Export ex = ((CallFunction) t.getCallTask().get()).getExport(); - assertNotNull(ex, "Export should be set via Step.exportAs(Function)"); - assertNotNull(ex.getAs(), "'as' should be populated"); - // functional export should not produce a literal string - assertNull( - ex.getAs().getString(), "Export 'as' must not be a literal string when using Function"); - } - - @Test - void function_step_when_compiles_and_builds() { - Workflow wf = - FuncWorkflowBuilder.workflow("step-function-when") - .tasks( - function((Integer v) -> v + 1, Integer.class) - .when((Integer v) -> v > 0, Integer.class)) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - assertNotNull(items.get(0).getTask().getCallTask(), "CallTask should still be present"); - // We don't assert internal predicate storage details; just ensure build success & presence. - } - - @Test - void emit_step_exportAs_javaFilter_sets_export() { - FilterFunction> jf = - (val, wfCtx, taskCtx) -> Map.of("wrapped", val, "wfId", wfCtx.instanceData().id()); - - Workflow wf = - FuncWorkflowBuilder.workflow("step-emit-export") - .tasks( - emit("emitWrapped", produced("org.acme.signal").bytesDataUtf8()) - .exportAs(jf)) // chaining on Step - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - Task t = items.get(0).getTask(); - assertNotNull(t.getEmitTask(), "EmitTask expected"); - - // Export is attached to Task - Export ex = t.getEmitTask().getExport(); - assertNotNull(ex, "Export should be set via Step.exportAs(JavaFilterFunction)"); - assertNotNull(ex.getAs(), "'as' should be populated"); - assertNull( - ex.getAs().getString(), "Export 'as' must not be a literal string when using function"); - } - - @Test - @DisplayName("listen(spec).exportAs(Function) sets Export on ListenTask holder") - void listen_step_exportAs_function_sets_export() { - Workflow wf = - FuncWorkflowBuilder.workflow("step-listen-export") - .tasks( - listen("waitHumanReview", toOne("org.acme.review.done")) - .exportAs((Object e) -> Map.of("seen", true))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - Task t = items.get(0).getTask(); - assertNotNull(t.getListenTask(), "ListenTask expected"); - - Export ex = t.getListenTask().getExport(); - assertNotNull(ex, "Export should be set via Step.exportAs(Function)"); - assertNotNull(ex.getAs(), "'as' should be populated"); - assertNull( - ex.getAs().getString(), "Export 'as' must not be a literal string when using function"); - } - - @Test - @DisplayName("emit(produced(type, fn)).when(...) -> still an EmitTask and builds") - void emit_step_when_compiles_and_builds() { - Workflow wf = - FuncWorkflowBuilder.workflow("step-emit-when") - .tasks(emit(produced("org.acme.sig").bytesDataUtf8()).when((Object ctx) -> true)) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - assertNotNull(items.get(0).getTask().getEmitTask(), "EmitTask should still be present"); - } - - @Test - @DisplayName("Mixed chaining: function.exportAs -> emit.when -> listen.exportAs") - void mixed_chaining_order_and_exports() { - Workflow wf = - FuncWorkflowBuilder.workflow("step-mixed") - .tasks( - function(String::strip, String.class).exportAs((String s) -> Map.of("s", s)), - emit(produced("org.acme.kickoff").bytesDataUtf8()).when((Object ignore) -> true), - listen(toOne("org.acme.done")).exportAs((Object e) -> Map.of("ok", true))) - .build(); - - List items = wf.getDo(); - assertEquals(3, items.size()); - - Task t0 = items.get(0).getTask(); - Task t1 = items.get(1).getTask(); - Task t2 = items.get(2).getTask(); - - assertNotNull(t0.getCallTask()); - assertNotNull(t1.getEmitTask()); - assertNotNull(t2.getListenTask()); - - assertNotNull( - ((CallFunction) t0.getCallTask().get()).getExport(), "function step should carry export"); - assertNotNull(t2.getListenTask().getExport(), "listen step should carry export"); - } - - @Test - void switchWhenOrElse_jq_to_taskName() { - Workflow wf = - FuncWorkflowBuilder.workflow("jqSwitch") - .tasks(switchWhenOrElse(".approved", "send", "draft")) - .build(); - Task switchTask = wf.getDo().get(0).getTask(); - assertNotNull(switchTask.getSwitchTask()); - var items = switchTask.getSwitchTask().getSwitch(); - assertEquals(2, items.size()); - assertEquals(".approved", items.get(0).getSwitchCase().getWhen()); - } - - @Test - void switchWhenOrElse_jq_to_directive() { - Workflow wf = - FuncWorkflowBuilder.workflow("jqSwitchDir") - .tasks(switchWhenOrElse(".score >= 80", "pass", FlowDirectiveEnum.END)) - .build(); - Task switchTask = wf.getDo().get(0).getTask(); - var items = switchTask.getSwitchTask().getSwitch(); - assertEquals(".score >= 80", items.get(0).getSwitchCase().getWhen()); - assertEquals( - FlowDirectiveEnum.END, items.get(1).getSwitchCase().getThen().getFlowDirectiveEnum()); - } - - @Test - void http_spec_via_call_builds_call_http_task() { - Workflow wf = - FuncWorkflowBuilder.workflow("http-call-spec") - .tasks(call("checkHealth", http().GET().endpoint("http://service/health"))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected for HTTP call"); - - // HTTP-specific call - assertInstanceOf( - CallHTTP.class, t.getCallTask().get(), "CallTask should be an instance of CallHTTP"); - - CallHTTP http = (CallHTTP) t.getCallTask().get(); - assertEquals("GET", http.getWith().getMethod(), "HTTP method should be GET"); - assertEquals( - "http://service/health", - http.getWith().getEndpoint().getUriTemplate().getLiteralUri().toString(), - "endpoint should match the DSL endpoint"); - } - - @Test - @DisplayName("get(endpoint) convenience creates unnamed GET CallHTTP task") - void get_convenience_creates_http_get() { - Workflow wf = - FuncWorkflowBuilder.workflow("http-get-convenience") - .tasks(get("http://service/status")) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected"); - - CallHTTP http = (CallHTTP) t.getCallTask().get(); - assertEquals("GET", http.getWith().getMethod()); - assertEquals( - "http://service/status", - http.getWith().getEndpoint().getUriTemplate().getLiteralUri().toString(), - "endpoint should be set from get(endpoint)"); - } - - @Test - @DisplayName("get(name, endpoint, auth -> auth.use(\"auth-id\")) wires authentication") - void get_named_with_authentication_uses_auth_policy() { - Workflow wf = - FuncWorkflowBuilder.workflow("http-get-auth") - .tasks(get("fetchUsers", "http://service/api/users", use("user-service-auth"))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - assertEquals("fetchUsers", items.get(0).getName(), "Task should use the provided name"); - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected"); - - CallHTTP http = (CallHTTP) t.getCallTask().get(); - assertEquals("GET", http.getWith().getMethod()); - assertEquals( - "http://service/api/users", - http.getWith() - .getEndpoint() - .getEndpointConfiguration() - .getUri() - .getLiteralEndpointURI() - .getLiteralUri() - .toString(), - "endpoint should be set from get(name, endpoint, auth)"); - - assertNotNull( - http.getWith().getEndpoint().getEndpointConfiguration().getAuthentication(), - "authentication should be configured"); - assertEquals( - "user-service-auth", - http.getWith() - .getEndpoint() - .getEndpointConfiguration() - .getAuthentication() - .getAuthenticationPolicyReference() - .getUse(), - "auth.use(\"...\") should set authentication.use"); - } - - @Test - @DisplayName("get(URI endpoint, auth) uses URI and authentication") - void get_with_uri_and_authentication() { - URI endpoint = URI.create("https://service.example.com/api/health"); - - Workflow wf = - FuncWorkflowBuilder.workflow("http-get-uri-auth") - .tasks(get("checkHealth", endpoint, auth -> auth.use("tls-auth"))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertEquals("checkHealth", items.get(0).getName(), "Task should use the provided name"); - assertNotNull(t.getCallTask()); - - CallHTTP http = (CallHTTP) t.getCallTask().get(); - assertEquals("GET", http.getWith().getMethod()); - assertEquals( - endpoint.toString(), - http.getWith() - .getEndpoint() - .getEndpointConfiguration() - .getUri() - .getLiteralEndpointURI() - .getLiteralUri() - .toString(), - "endpoint should be derived from URI"); - - assertNotNull(http.getWith().getEndpoint().getEndpointConfiguration().getAuthentication()); - assertEquals( - "tls-auth", - http.getWith() - .getEndpoint() - .getEndpointConfiguration() - .getAuthentication() - .getAuthenticationPolicyReference() - .getUse()); - } - - @Test - @DisplayName("post(body, endpoint) convenience creates POST CallHTTP with body") - void post_convenience_creates_http_post_with_body() { - Map body = Map.of("name", "Ricardo"); - - Workflow wf = - FuncWorkflowBuilder.workflow("http-post-convenience") - .tasks(FuncDSL.post(body, "http://service/api/users")) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected"); - - CallHTTP http = (CallHTTP) t.getCallTask().get(); - assertEquals("POST", http.getWith().getMethod()); - assertEquals( - "http://service/api/users", - http.getWith().getEndpoint().getUriTemplate().getLiteralUri().toString(), - "endpoint should be set from post(body, endpoint)"); - - assertNotNull(http.getWith().getBody(), "Body should be set on POST"); - assertEquals(body, http.getWith().getBody(), "Body should match the provided payload"); - } - - @Test - @DisplayName("post(name, body, endpoint, auth) wires name, method, endpoint, body and auth") - void post_named_with_authentication() { - Map body = Map.of("id", 123, "status", "NEW"); - - Workflow wf = - FuncWorkflowBuilder.workflow("http-post-named-auth") - .tasks( - FuncDSL.post( - "createOrder", - body, - "https://orders.example.com/api/orders", - auth -> auth.use("orders-auth"))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertEquals("createOrder", items.get(0).getName(), "Task should use the provided name"); - assertNotNull(t.getCallTask()); - - CallHTTP http = (CallHTTP) t.getCallTask().get(); - assertEquals("POST", http.getWith().getMethod()); - assertEquals( - "https://orders.example.com/api/orders", - http.getWith() - .getEndpoint() - .getEndpointConfiguration() - .getUri() - .getLiteralEndpointURI() - .getLiteralUri() - .toString()); - assertEquals(body, http.getWith().getBody()); - - assertNotNull(http.getWith().getEndpoint().getEndpointConfiguration().getAuthentication()); - assertEquals( - "orders-auth", - http.getWith() - .getEndpoint() - .getEndpointConfiguration() - .getAuthentication() - .getAuthenticationPolicyReference() - .getUse()); - } - - @Test - @DisplayName("call(http(\"...\", auth)) reuses fluent HTTP spec in call(...)") - void call_with_preconfigured_http_spec() { - Workflow wf = - FuncWorkflowBuilder.workflow("http-call-preconfigured") - .tasks( - call( - "preconfigured", - http("http://service/api", auth -> auth.use("svc-auth")) - .POST() - .body(Map.of("foo", "bar")))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertEquals("preconfigured", items.get(0).getName()); - assertNotNull(t.getCallTask()); - - CallHTTP http = (CallHTTP) t.getCallTask().get(); - assertEquals("POST", http.getWith().getMethod()); - assertEquals( - "http://service/api", - http.getWith() - .getEndpoint() - .getEndpointConfiguration() - .getUri() - .getLiteralEndpointURI() - .getLiteralUri() - .toString()); - assertEquals( - "svc-auth", - http.getWith() - .getEndpoint() - .getEndpointConfiguration() - .getAuthentication() - .getAuthenticationPolicyReference() - .getUse()); - assertEquals(Map.of("foo", "bar"), http.getWith().getBody()); - } - - @Test - @DisplayName("function(name, fn).then(taskName) sets FlowDirective string on the task") - void function_step_then_task_name_sets_flow_directive() { - Workflow wf = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks( - function("myfunction", String::trim, String.class).then("otherTask"), - function("otherTask", String::strip, String.class)) - .build(); - - List items = wf.getDo(); - assertEquals(2, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected"); - - CallFunction callJava = (CallFunction) t.getCallTask().get(); - assertNotNull(callJava.getThen(), "then() should be set on the task"); - assertEquals("otherTask", callJava.getThen().getString(), "then() should point to 'otherTask'"); - } - - @Test - @DisplayName("function(name, fn).then(FlowDirectiveEnum.END) sets END directive on the task") - void function_step_then_flow_directive_enum_sets_end() { - Workflow wf = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks(function("myfunction", String::trim, String.class).then(FlowDirectiveEnum.END)) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected"); - - CallFunction callJava = (CallFunction) t.getCallTask().get(); - assertNotNull(callJava.getThen(), "then() should be set on the task"); - assertEquals( - FlowDirectiveEnum.END, - callJava.getThen().getFlowDirectiveEnum(), - "then() should be FlowDirectiveEnum.END"); - } - - @Test - @DisplayName( - "consume(name, Consumer, Class).then(taskName) sets FlowDirective string on the task") - void consume_step_then_task_name_sets_flow_directive() { - Workflow wf = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks( - consume("sendNewsletter", (String s) -> {}, String.class).then("otherTask"), - function("nextTask", String::strip, String.class), - function("otherTask", String::strip, String.class)) - .build(); - - List items = wf.getDo(); - assertEquals(3, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected for consume step"); - - CallFunction callJava = (CallFunction) t.getCallTask().get(); - assertNotNull(callJava.getThen(), "then() should be set on the consume task"); - assertEquals("otherTask", callJava.getThen().getString(), "then() should point to 'otherTask'"); - } - - @Test - @DisplayName( - "consume(name, Consumer, Class).then(FlowDirectiveEnum.END) sets END directive on the task") - void consume_step_then_flow_directive_enum_sets_end() { - Workflow wf = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks( - consume("sendNewsletter", (String s) -> {}, String.class) - .then(FlowDirectiveEnum.END)) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected for consume step"); - - CallFunction callJava = (CallFunction) t.getCallTask().get(); - assertNotNull(callJava.getThen(), "then() should be set on the consume task"); - assertEquals( - FlowDirectiveEnum.END, - callJava.getThen().getFlowDirectiveEnum(), - "then() should be FlowDirectiveEnum.END"); - } - - @Test - @DisplayName( - "subflow(workflow(ns,name,ver).input(...).await(...)) creates RunTask/RunWorkflow with expected values") - void subflow_workflow_spec_with_input_and_await_creates_correct_run_task() { - Workflow wf = - FuncWorkflowBuilder.workflow("parent-workflow") - .tasks( - FuncDSL.subflow( - FuncDSL.workflow("org.test", "my-subflow", "1.0.0") - .input("id", 99) - .await(false))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - TaskItem taskItem = items.get(0); - Task t = taskItem.getTask(); - assertNotNull(t.getRunTask(), "RunTask expected for subflow"); - - RunTask runTask = t.getRunTask(); - assertNotNull(runTask.getRun(), "RunTask configuration should be present"); - - RunWorkflow runWorkflow = runTask.getRun().getRunWorkflow(); - assertNotNull(runWorkflow, "RunWorkflow should be selected"); - - // Verify workflow reference - assertEquals("org.test", runWorkflow.getWorkflow().getNamespace(), "Namespace should match"); - assertEquals("my-subflow", runWorkflow.getWorkflow().getName(), "Name should match"); - assertEquals("1.0.0", runWorkflow.getWorkflow().getVersion(), "Version should match"); - - // Verify input (accessed through workflow config) - assertNotNull(runWorkflow.getWorkflow().getInput(), "Input should be set"); - assertEquals( - 99, - runWorkflow.getWorkflow().getInput().getAdditionalProperties().get("id"), - "Input 'id' should match"); - - // Verify await - assertEquals(false, runWorkflow.isAwait(), "Await should be false"); - } - - @Test - @DisplayName("subflow(name, workflow(...)) creates named subflow task with RunTask/RunWorkflow") - void subflow_named_with_workflow_spec_creates_named_run_task() { - Workflow wf = - FuncWorkflowBuilder.workflow("parent-workflow") - .tasks( - FuncDSL.subflow( - "mySubflowTask", - w -> - w.namespace("org.acme") - .name("child-workflow") - .version("2.0.0") - .input("key", "value") - .await(true))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - TaskItem taskItem = items.get(0); - assertEquals("mySubflowTask", taskItem.getName(), "Task name should match"); - - Task t = taskItem.getTask(); - assertNotNull(t.getRunTask(), "RunTask expected for subflow"); - - RunWorkflow runWorkflow = t.getRunTask().getRun().getRunWorkflow(); - assertNotNull(runWorkflow, "RunWorkflow should be selected"); - assertEquals("org.acme", runWorkflow.getWorkflow().getNamespace()); - assertEquals("child-workflow", runWorkflow.getWorkflow().getName()); - assertEquals("2.0.0", runWorkflow.getWorkflow().getVersion()); - assertEquals(true, runWorkflow.isAwait(), "Await should be true"); - } - - @Test - @DisplayName("grpc(name).proto().service().method().argument() builds CallGRPC task") - void grpc_step_builds_call_grpc_task() { - Workflow wf = - FuncWorkflowBuilder.workflow("grpc-dsl-test") - .tasks( - call( - "greet", - grpc("greet") - .proto("proto/greeter.proto") - .service("Greeter", "localhost") - .method("SayHello") - .argument("name", "World"))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - assertEquals("greet", items.get(0).getName()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected for gRPC call"); - assertInstanceOf(CallGRPC.class, t.getCallTask().get(), "Should be CallGRPC"); - - CallGRPC grpcArgs = (CallGRPC) t.getCallTask().get(); - assertNotNull(grpcArgs.getWith().getProto(), "Proto should be set"); - assertEquals("Greeter", grpcArgs.getWith().getService().getName()); - assertEquals("localhost", grpcArgs.getWith().getService().getHost()); - assertEquals("SayHello", grpcArgs.getWith().getMethod()); - assertEquals("World", grpcArgs.getWith().getArguments().getAdditionalProperties().get("name")); - } - - @Test - @DisplayName("call(grpc().proto().service().method().argument(...)) unnamed gRPC task") - void grpc_unnamed_call_builds_task() { - Workflow wf = - FuncWorkflowBuilder.workflow("grpc-dsl-unnamed") - .tasks( - call( - grpc() - .proto("proto/svc.proto") - .service("Svc", "host") - .method("Call") - .arguments(Map.of("k", "v")))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask()); - assertInstanceOf(CallGRPC.class, t.getCallTask().get()); - assertEquals("Call", ((CallGRPC) t.getCallTask().get()).getWith().getMethod()); - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLUniqueIdTest.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLUniqueIdTest.java deleted file mode 100644 index cfac3f7d2..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLUniqueIdTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.agent; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.withUniqueId; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import io.serverlessworkflow.api.types.CallFunction; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.api.types.func.CallJava; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.UniqueIdBiFunction; -import io.serverlessworkflow.impl.TaskContextData; -import io.serverlessworkflow.impl.WorkflowContextData; -import io.serverlessworkflow.impl.WorkflowInstanceData; -import io.serverlessworkflow.impl.WorkflowPosition; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -/** - * Verifies that withUniqueId/agent wrap the user's function so that, at runtime, the first argument - * is a "unique id" composed as instanceId + "-" + jsonPointer (e.g., inst-123-/do/0/task). - */ -class FuncDSLUniqueIdTest { - - @SuppressWarnings("unchecked") - private static FilterFunction extractFilterFunction(CallFunction callJava) { - if (callJava.getWith().getAdditionalProperties().get(CallJava.FUNCTION_NAME_KEY) - instanceof FilterFunction f) { - return f; - } - fail("CallTask is not a CallJavaFilterFunction; DSL contract may have changed."); - return null; // unreachable - } - - @Test - @DisplayName( - "withUniqueId(name, fn, in) composes uniqueId = instanceId-jsonPointer and passes it") - void withUniqueId_uses_json_pointer_for_unique_id() { - AtomicReference receivedUniqueId = new AtomicReference<>(); - AtomicReference receivedPayload = new AtomicReference<>(); - - UniqueIdBiFunction fn = - (uniqueId, payload) -> { - receivedUniqueId.set(uniqueId); - receivedPayload.set(payload); - return payload.toUpperCase(); - }; - - Workflow wf = - FuncWorkflowBuilder.workflow("wf-unique-named") - .tasks(withUniqueId("notify", fn, String.class)) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size(), "one task expected"); - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected"); - - CallFunction cj = (CallFunction) t.getCallTask().get(); - var jff = extractFilterFunction(cj); - assertNotNull(jff, "JavaFilterFunction must be present for withUniqueId"); - - // Mockito stubs for runtime contexts - WorkflowInstanceData inst = mock(WorkflowInstanceData.class); - when(inst.id()).thenReturn("inst-123"); - - WorkflowContextData wctx = mock(WorkflowContextData.class); - when(wctx.instanceData()).thenReturn(inst); - - // Use JSON Pointer for the unique component instead of task name - final String pointer = "/do/0/task"; - WorkflowPosition pos = mock(WorkflowPosition.class); - when(pos.jsonPointer()).thenReturn(pointer); - - TaskContextData tctx = mock(TaskContextData.class); - when(tctx.position()).thenReturn(pos); - - Object result = jff.apply("hello", wctx, tctx); - - assertEquals( - "inst-123-" + pointer, receivedUniqueId.get(), "uniqueId must be instanceId-jsonPointer"); - assertEquals( - "hello", receivedPayload.get(), "payload should be forwarded to the user function"); - assertEquals("HELLO", result, "wrapped function result should be returned"); - } - - @Test - @DisplayName("agent(fn, in) composes uniqueId = instanceId-jsonPointer and passes it") - void agent_uses_json_pointer_for_unique_id() { - AtomicReference receivedUniqueId = new AtomicReference<>(); - AtomicReference receivedPayload = new AtomicReference<>(); - - UniqueIdBiFunction fn = - (uniqueId, payload) -> { - receivedUniqueId.set(uniqueId); - receivedPayload.set(payload); - return payload + 1; - }; - - Workflow wf = FuncWorkflowBuilder.workflow("wf-agent").tasks(agent(fn, Integer.class)).build(); - - List items = wf.getDo(); - assertEquals(1, items.size(), "one task expected"); - Task t = items.get(0).getTask(); - assertNotNull(t.getCallTask(), "CallTask expected"); - - CallFunction cj = (CallFunction) t.getCallTask().get(); - var jff = extractFilterFunction(cj); - assertNotNull(jff, "JavaFilterFunction must be present for agent/withUniqueId"); - - WorkflowInstanceData inst = mock(WorkflowInstanceData.class); - when(inst.id()).thenReturn("wf-999"); - - WorkflowContextData wctx = mock(WorkflowContextData.class); - when(wctx.instanceData()).thenReturn(inst); - - final String pointer = "/do/0/task"; - WorkflowPosition pos = mock(WorkflowPosition.class); - when(pos.jsonPointer()).thenReturn(pointer); - - TaskContextData tctx = mock(TaskContextData.class); - when(tctx.position()).thenReturn(pos); - - Object result = jff.apply(41, wctx, tctx); - - assertEquals( - "wf-999-" + pointer, receivedUniqueId.get(), "uniqueId must be instanceId-jsonPointer"); - assertEquals(41, receivedPayload.get(), "payload should be forwarded to the user function"); - assertEquals(42, result, "wrapped function result should be returned"); - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLWaitTest.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLWaitTest.java deleted file mode 100644 index 712c328da..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncDSLWaitTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.tasks; -import static io.serverlessworkflow.fluent.spec.dsl.DSL.timeoutSeconds; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.dsl.FuncDSL; -import java.time.Duration; -import org.junit.jupiter.api.Test; - -public class FuncDSLWaitTest { - - @Test - public void when_wait_with_string_expression() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow").tasks(tasks(FuncDSL.wait("PT5S"))).build(); - - assertEquals(1, wf.getDo().size()); - var waitTask = wf.getDo().get(0).getTask().getWaitTask(); - assertNotNull(waitTask); - assertEquals("PT5S", waitTask.getWait().get()); - } - - @Test - public void when_wait_with_timeout_builder() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.wait(timeoutSeconds(10)))) - .build(); - - assertEquals(1, wf.getDo().size()); - var waitTask = wf.getDo().get(0).getTask().getWaitTask(); - assertNotNull(waitTask); - assertEquals(10, waitTask.getWait().getDurationInline().getSeconds()); - } - - @Test - public void when_wait_named_with_string() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.wait("pause", "PT15S"))) - .build(); - - assertEquals("pause", wf.getDo().get(0).getName()); - assertEquals("PT15S", wf.getDo().get(0).getTask().getWaitTask().getWait().get()); - } - - @Test - public void when_wait_seconds_unnamed() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow").tasks(tasks(FuncDSL.waitSeconds(30))).build(); - - var waitTask = wf.getDo().get(0).getTask().getWaitTask(); - var inline = waitTask.getWait().getDurationInline(); - assertNotNull(inline); - assertEquals(30, inline.getSeconds()); - assertEquals(0, inline.getMinutes()); - } - - @Test - public void when_wait_seconds_named() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.waitSeconds("pause", 45))) - .build(); - - assertEquals("pause", wf.getDo().get(0).getName()); - assertEquals( - 45, wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline().getSeconds()); - } - - @Test - public void when_wait_minutes_unnamed() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow").tasks(tasks(FuncDSL.waitMinutes(10))).build(); - - var inline = wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline(); - assertEquals(10, inline.getMinutes()); - assertEquals(0, inline.getSeconds()); - } - - @Test - public void when_wait_minutes_named() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.waitMinutes("delay", 15))) - .build(); - - assertEquals("delay", wf.getDo().get(0).getName()); - assertEquals( - 15, wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline().getMinutes()); - } - - @Test - public void when_wait_hours_unnamed() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow").tasks(tasks(FuncDSL.waitHours(2))).build(); - - var inline = wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline(); - assertEquals(2, inline.getHours()); - } - - @Test - public void when_wait_hours_named() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.waitHours("longPause", 3))) - .build(); - - assertEquals("longPause", wf.getDo().get(0).getName()); - assertEquals( - 3, wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline().getHours()); - } - - @Test - public void when_wait_days_unnamed() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow").tasks(tasks(FuncDSL.waitDays(1))).build(); - - assertEquals( - 1, wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline().getDays()); - } - - @Test - public void when_wait_days_named() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.waitDays("dailyDelay", 5))) - .build(); - - assertEquals("dailyDelay", wf.getDo().get(0).getName()); - assertEquals( - 5, wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline().getDays()); - } - - @Test - public void when_wait_millis_unnamed() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow").tasks(tasks(FuncDSL.waitMillis(500))).build(); - - var inline = wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline(); - assertEquals(500, inline.getMilliseconds()); - } - - @Test - public void when_wait_millis_named() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.waitMillis("shortPause", 250))) - .build(); - - assertEquals("shortPause", wf.getDo().get(0).getName()); - assertEquals( - 250, - wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline().getMilliseconds()); - } - - @Test - public void when_wait_with_duration() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.wait(Duration.ofMinutes(5).plusSeconds(30)))) - .build(); - - var inline = wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline(); - assertEquals(5, inline.getMinutes()); - assertEquals(30, inline.getSeconds()); - } - - @Test - public void when_wait_with_duration_named() { - Workflow wf = - FuncWorkflowBuilder.workflow("waitFlow") - .tasks(tasks(FuncDSL.wait("custom", Duration.ofHours(1)))) - .build(); - - assertEquals("custom", wf.getDo().get(0).getName()); - assertEquals( - 1, wf.getDo().get(0).getTask().getWaitTask().getWait().getDurationInline().getHours()); - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncEventFilterSpecTest.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncEventFilterSpecTest.java deleted file mode 100644 index 26c8be35b..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncEventFilterSpecTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consumed; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.listen; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.toOne; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.Workflow; -import java.util.List; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -/** - * Tests for the Event Filter DSL specification. Verifies that the fluent builder correctly wires - * the payload parsing and contextual lambdas into the final Workflow definitions. - */ -class FuncEventFilterSpecTest { - - // Dummy POJO for dataAs(Class) testing - static class TestOrder { - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - } - - @Test - @DisplayName("consumed(...).dataAsMap builds successfully into a ListenTask") - void dataAsMap_compilesAndBuildsListenTask() { - Workflow wf = - FuncWorkflowBuilder.workflow("filter-data-as-map") - .tasks( - listen( - "listenMap", - toOne(consumed("org.test.event").dataAsMap(map -> map.containsKey("orderId"))))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getListenTask(), "ListenTask expected for dataAsMap filter"); - } - - @Test - @DisplayName("consumed(...).dataAs(Class) builds successfully into a ListenTask") - void dataAsClass_compilesAndBuildsListenTask() { - Workflow wf = - FuncWorkflowBuilder.workflow("filter-data-as-class") - .tasks( - listen( - "listenClass", - toOne( - consumed("org.test.event") - .dataAs(TestOrder.class, order -> order.getId() > 0)))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getListenTask(), "ListenTask expected for dataAs(Class) filter"); - } - - @Test - @DisplayName("consumed(...).dataFields builds successfully into a ListenTask") - void dataFields_compilesAndBuildsListenTask() { - Workflow wf = - FuncWorkflowBuilder.workflow("filter-data-fields") - .tasks( - listen( - "listenFields", - toOne(consumed("org.test.event").dataFields("orderId", "customerId")))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getListenTask(), "ListenTask expected for dataFields filter"); - } - - @Test - @DisplayName("consumed(...).dataByInstanceId builds successfully into a ListenTask") - void dataByInstanceId_compilesAndBuildsListenTask() { - Workflow wf = - FuncWorkflowBuilder.workflow("filter-data-instance-id") - .tasks( - listen( - "listenDataId", - toOne(consumed("org.test.event").dataByInstanceId("workflowInstanceId")))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getListenTask(), "ListenTask expected for dataByInstanceId filter"); - } - - @Test - @DisplayName("consumed(...).extensionByInstanceId builds successfully into a ListenTask") - void extensionByInstanceId_compilesAndBuildsListenTask() { - Workflow wf = - FuncWorkflowBuilder.workflow("filter-ext-instance-id") - .tasks( - listen( - "listenExtId", - toOne(consumed("org.test.event").extensionByInstanceId("workflowinstanceid")))) - .build(); - - List items = wf.getDo(); - assertEquals(1, items.size()); - - Task t = items.get(0).getTask(); - assertNotNull(t.getListenTask(), "ListenTask expected for extensionByInstanceId filter"); - } -} diff --git a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncTaskItemDefaultNamingTest.java b/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncTaskItemDefaultNamingTest.java deleted file mode 100644 index 3a441b703..000000000 --- a/experimental/fluent/func/src/test/java/io/serverlessworkflow/fluent/func/FuncTaskItemDefaultNamingTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import io.serverlessworkflow.api.types.TaskItem; -import java.util.List; -import org.junit.jupiter.api.Test; - -public class FuncTaskItemDefaultNamingTest { - - @Test - void testFuncForEachTaskAutoNaming() { - // Testing the Func domain builder directly to ensure the functional DSL - // behaves identically to the spec DSL regarding default naming. - FuncTaskItemListBuilder funcBuilder = new FuncTaskItemListBuilder(0); - - funcBuilder.forEach( - null, - f -> - f.each("item") - .in("$.list") - // Inner tasks inside the Func ForEach loop - .tasks( - tb -> - tb.set(null, "$.a = 1") // Using the Func set(name, expr) shortcut - .http(null, hb -> hb.endpoint("http://func")))); - - List topItems = funcBuilder.build(); - assertEquals(1, topItems.size()); - assertEquals("for-0", topItems.get(0).getName(), "Top level Func ForEach should be for-0"); - - // Fetch the inner tasks of the Func 'for' loop - List nestedItems = topItems.get(0).getTask().getForTask().getDo(); - assertNotNull(nestedItems, "Nested Func forEach items must not be null"); - assertEquals(2, nestedItems.size()); - - // Verify inner builder list indexes independently starting at 0 - assertEquals("set-0", nestedItems.get(0).getName()); - assertEquals("http-1", nestedItems.get(1).getName()); - } - - @Test - void testFuncForkTaskMultipleBranchesAppends() { - FuncForkTaskBuilder forkBuilder = new FuncForkTaskBuilder(); - - // 1. Call branches() - list is initially empty, offset should be 0 - forkBuilder.branches(b -> b.set(null, "$.a = 1")); - - // 2. Call branch() - list has 1 item, so it should use index 1 - forkBuilder.branch((Object x) -> x); - - // 3. Call branches() again - list has 2 items, offset should be 2 - forkBuilder.branches(b -> b.set(null, "$.b = 2")); - - // Build and verify - List branches = forkBuilder.build().getFork().getBranches(); - - assertEquals(3, branches.size(), "All branches should be appended to the list"); - - assertEquals("set-0", branches.get(0).getName(), "First branches() call starts at 0"); - assertEquals("branch-1", branches.get(1).getName(), "branch() call picks up index 1"); - assertEquals("set-2", branches.get(2).getName(), "Second branches() call picks up index 2"); - } - - @Test - void testFuncForTaskMultipleTasksAppends() { - io.serverlessworkflow.fluent.func.FuncForTaskBuilder forBuilder = - new io.serverlessworkflow.fluent.func.FuncForTaskBuilder(); - - forBuilder.each("item").in("$.list"); - - // 1. Fluent builder - list is empty, offset is 0 - forBuilder.tasks(tb -> tb.set(null, "$.a = 1")); - - // 2. Functional LoopFunction shortcut - list has 1 item, index should be 1 - forBuilder.tasks(null, (Object ctx, Object item) -> ctx); - - // 3. Fluent builder again - list has 2 items, offset should be 2 - forBuilder.tasks(tb -> tb.http(null, hb -> hb.endpoint("http://test"))); - - // Build and verify - List forTasks = forBuilder.build().getDo(); - - assertEquals(3, forTasks.size(), "All tasks should be appended to the loop"); - - assertEquals("set-0", forTasks.get(0).getName(), "First fluent block starts at 0"); - assertEquals("for-task-1", forTasks.get(1).getName(), "Functional task picks up index 1"); - assertEquals("http-2", forTasks.get(2).getName(), "Second fluent block picks up index 2"); - } -} diff --git a/experimental/fluent/jackson/pom.xml b/experimental/fluent/jackson/pom.xml deleted file mode 100644 index 10b764f89..000000000 --- a/experimental/fluent/jackson/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental-fluent - 8.0.0-SNAPSHOT - - serverlessworkflow-experimental-fluent-serialization-jackson - Serverless Workflow :: Experimental :: Fluent :: Serialization:: Jackson - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - - - io.serverlessworkflow - serverlessworkflow-experimental-types - - - io.serverlessworkflow - serverlessworkflow-serialization - - - io.serverlessworkflow - serverlessworkflow-impl-json - - - io.serverlessworkflow - serverlessworkflow-api - - - \ No newline at end of file diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsDeserializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsDeserializer.java deleted file mode 100644 index b9e65b05f..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsDeserializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JacksonException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import io.serverlessworkflow.api.types.ExportAs; -import io.serverlessworkflow.api.types.jackson.ExportAsDeserializer; -import java.io.IOException; - -public class FuncExportAsDeserializer extends ExportAsDeserializer { - - @Override - public ExportAs deserialize(JsonParser p, DeserializationContext ctxt) - throws IOException, JacksonException { - return SerializationUtils.deserializeFilterClass( - p, ctxt, f -> new ExportAs().withObject(f), ExportAs.class); - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsMixIn.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsMixIn.java deleted file mode 100644 index 944edad50..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsMixIn.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.serverlessworkflow.api.types.jackson.OutputAsMixIn; - -@JsonSerialize(using = FuncExportAsSerializer.class) -@JsonDeserialize(using = FuncExportAsDeserializer.class) -public class FuncExportAsMixIn extends OutputAsMixIn {} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsSerializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsSerializer.java deleted file mode 100644 index 3821bfac2..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncExportAsSerializer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import io.serverlessworkflow.api.types.ExportAs; -import io.serverlessworkflow.api.types.jackson.ExportAsSerializer; -import java.io.IOException; - -public class FuncExportAsSerializer extends ExportAsSerializer { - - public void serialize(ExportAs value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { - if (SerializationUtils.isFilterSerializable(value.getObject())) { - SerializationUtils.serializeObjectWithType(gen, value.getObject()); - } else { - super.serialize(value, gen, serializers); - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromDeserializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromDeserializer.java deleted file mode 100644 index 6b0c5ab6c..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromDeserializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JacksonException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import io.serverlessworkflow.api.types.InputFrom; -import io.serverlessworkflow.api.types.jackson.InputFromDeserializer; -import java.io.IOException; - -public class FuncInputFromDeserializer extends InputFromDeserializer { - - @Override - public InputFrom deserialize(JsonParser p, DeserializationContext ctxt) - throws IOException, JacksonException { - return SerializationUtils.deserializeFilterClass( - p, ctxt, f -> new InputFrom().withObject(f), InputFrom.class); - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromMixIn.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromMixIn.java deleted file mode 100644 index 1e4e91c3c..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromMixIn.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.serverlessworkflow.api.types.jackson.OutputAsMixIn; - -@JsonSerialize(using = FuncInputFromSerializer.class) -@JsonDeserialize(using = FuncInputFromDeserializer.class) -public class FuncInputFromMixIn extends OutputAsMixIn {} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromSerializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromSerializer.java deleted file mode 100644 index 277f04730..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncInputFromSerializer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import io.serverlessworkflow.api.types.InputFrom; -import io.serverlessworkflow.api.types.jackson.InputFromSerializer; -import java.io.IOException; - -public class FuncInputFromSerializer extends InputFromSerializer { - - public void serialize(InputFrom value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { - if (SerializationUtils.isFilterSerializable(value.getObject())) { - SerializationUtils.serializeObjectWithType(gen, value.getObject()); - } else { - super.serialize(value, gen, serializers); - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncJacksonModule.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncJacksonModule.java deleted file mode 100644 index 7068d77aa..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncJacksonModule.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.databind.BeanDescription; -import com.fasterxml.jackson.databind.SerializationConfig; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; -import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; -import io.serverlessworkflow.api.types.ExportAs; -import io.serverlessworkflow.api.types.FunctionArguments; -import io.serverlessworkflow.api.types.InputFrom; -import io.serverlessworkflow.api.types.OutputAs; -import io.serverlessworkflow.api.types.TaskMetadata; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.LoopFunction; -import io.serverlessworkflow.api.types.func.LoopFunctionIndex; -import io.serverlessworkflow.api.types.func.LoopPredicate; -import io.serverlessworkflow.api.types.func.LoopPredicateIndex; -import io.serverlessworkflow.api.types.func.LoopPredicateIndexContext; -import io.serverlessworkflow.api.types.func.LoopPredicateIndexFilter; -import io.serverlessworkflow.api.types.func.SerializableConsumer; -import io.serverlessworkflow.api.types.func.SerializableFunction; -import io.serverlessworkflow.api.types.func.SerializablePredicate; -import java.lang.invoke.SerializedLambda; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; - -public class FuncJacksonModule extends SimpleModule { - - private static final long serialVersionUID = 1L; - - public void setupModule(com.fasterxml.jackson.databind.Module.SetupContext context) { - SerializableFunctionSerializer serializer = new SerializableFunctionSerializer(); - super.addSerializer(SerializableFunction.class, serializer); - super.addSerializer(SerializablePredicate.class, serializer); - super.addSerializer(SerializableConsumer.class, serializer); - super.addSerializer(ContextFunction.class, serializer); - super.addSerializer(FilterFunction.class, serializer); - super.addSerializer(LoopFunction.class, serializer); - super.addSerializer(LoopFunctionIndex.class, serializer); - super.addSerializer(LoopPredicate.class, serializer); - super.addSerializer(LoopPredicateIndex.class, serializer); - super.addSerializer(LoopPredicateIndexContext.class, serializer); - super.addSerializer(LoopPredicateIndexFilter.class, serializer); - - super.addSerializer(TaskMetadata.class, new TaskMetadataSerializer()); - super.addDeserializer(TaskMetadata.class, new TaskMetadataDeserializer()); - super.addSerializer(FunctionArguments.class, new FunctionArgumentsSerializer()); - super.addDeserializer(FunctionArguments.class, new FunctionArgumentsDeserializer()); - super.addDeserializer(Function.class, new FunctionDeserializer(Function.class)); - super.addDeserializer(Predicate.class, new FunctionDeserializer(Predicate.class)); - super.addDeserializer(Consumer.class, new FunctionDeserializer(Consumer.class)); - super.addDeserializer(ContextFunction.class, new FunctionDeserializer(ContextFunction.class)); - super.addDeserializer(FilterFunction.class, new FunctionDeserializer(FilterFunction.class)); - super.addDeserializer(LoopFunction.class, new FunctionDeserializer(LoopFunction.class)); - super.addDeserializer( - LoopFunctionIndex.class, new FunctionDeserializer(LoopFunctionIndex.class)); - super.addDeserializer(LoopPredicate.class, new FunctionDeserializer(LoopPredicate.class)); - super.addDeserializer( - LoopPredicateIndex.class, new FunctionDeserializer(LoopPredicateIndex.class)); - super.addDeserializer( - LoopPredicateIndexContext.class, new FunctionDeserializer(LoopPredicateIndexContext.class)); - super.addDeserializer( - LoopPredicateIndexFilter.class, new FunctionDeserializer(LoopPredicateIndexFilter.class)); - - super.setSerializerModifier( - new BeanSerializerModifier() { - @Override - public List changeProperties( - SerializationConfig config, - BeanDescription beanDesc, - List beanProperties) { - if (beanDesc.getBeanClass().equals(SerializedLambda.class)) { - beanProperties.add(new SerializedLambdaWriter(beanProperties.get(0))); - } - return beanProperties; - } - }); - super.addDeserializer(SerializedLambda.class, new SerializedLambdaDeserializer()); - - super.setMixInAnnotation(OutputAs.class, FuncOutputAsMixIn.class); - super.setMixInAnnotation(ExportAs.class, FuncExportAsMixIn.class); - super.setMixInAnnotation(InputFrom.class, FuncInputFromMixIn.class); - - super.setupModule(context); - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsDeserializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsDeserializer.java deleted file mode 100644 index ffa17fd41..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsDeserializer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JacksonException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import io.serverlessworkflow.api.types.OutputAs; -import io.serverlessworkflow.api.types.jackson.OutputAsDeserializer; -import java.io.IOException; - -public class FuncOutputAsDeserializer extends OutputAsDeserializer { - - @Override - public OutputAs deserialize(JsonParser p, DeserializationContext ctxt) - throws IOException, JacksonException { - return SerializationUtils.deserializeFilterClass( - p, ctxt, f -> new OutputAs().withObject(f), OutputAs.class); - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsMixIn.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsMixIn.java deleted file mode 100644 index dfb846705..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsMixIn.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.serverlessworkflow.api.types.jackson.OutputAsMixIn; - -@JsonSerialize(using = FuncOutputAsSerializer.class) -@JsonDeserialize(using = FuncOutputAsDeserializer.class) -public class FuncOutputAsMixIn extends OutputAsMixIn {} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsSerializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsSerializer.java deleted file mode 100644 index e1bc3e0e7..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FuncOutputAsSerializer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import io.serverlessworkflow.api.types.OutputAs; -import io.serverlessworkflow.api.types.jackson.OutputAsSerializer; -import java.io.IOException; - -public class FuncOutputAsSerializer extends OutputAsSerializer { - - public void serialize(OutputAs value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { - if (SerializationUtils.isFilterSerializable(value.getObject())) { - SerializationUtils.serializeObjectWithType(gen, value.getObject()); - } else { - super.serialize(value, gen, serializers); - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionArgumentsDeserializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionArgumentsDeserializer.java deleted file mode 100644 index 5911314bc..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionArgumentsDeserializer.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import io.serverlessworkflow.api.types.FunctionArguments; -import java.io.IOException; - -public class FunctionArgumentsDeserializer extends JsonDeserializer { - - @Override - public FunctionArguments deserialize(JsonParser p, DeserializationContext ctxt) - throws IOException { - try { - FunctionArguments result = new FunctionArguments(); - SerializationUtils.deserializeMap(p, ctxt, result.getAdditionalProperties()); - return result; - } catch (ReflectiveOperationException e) { - throw new IOException(e); - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionArgumentsSerializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionArgumentsSerializer.java deleted file mode 100644 index bb411443a..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionArgumentsSerializer.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import io.serverlessworkflow.api.types.FunctionArguments; -import java.io.IOException; - -public class FunctionArgumentsSerializer extends JsonSerializer { - - @Override - public void serialize(FunctionArguments value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { - SerializationUtils.serializeMap(gen, value.getAdditionalProperties()); - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionDeserializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionDeserializer.java deleted file mode 100644 index 44f2648b7..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/FunctionDeserializer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import java.io.IOException; -import java.lang.invoke.SerializedLambda; - -public class FunctionDeserializer extends JsonDeserializer { - - private final Class objectClass; - - public FunctionDeserializer(Class objectClass) { - this.objectClass = objectClass; - } - - @Override - public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - try { - return objectClass.cast( - ReflectionUtils.functionFromSerialized(p.readValueAs(SerializedLambda.class))); - } catch (ReflectiveOperationException e) { - throw new IOException(e); - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializableFunctionSerializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializableFunctionSerializer.java deleted file mode 100644 index 4dd61c2aa..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializableFunctionSerializer.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import java.io.IOException; -import java.lang.invoke.SerializedLambda; -import java.util.Optional; - -public class SerializableFunctionSerializer extends JsonSerializer { - - @Override - public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { - Optional serializedLambda = ReflectionUtils.serializedFromFunction(value); - if (serializedLambda.isPresent()) { - gen.writeObject(serializedLambda.orElseThrow()); - } else { - gen.writeString(value.toString()); - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializationUtils.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializationUtils.java deleted file mode 100644 index 3da29d808..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializationUtils.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import io.serverlessworkflow.api.types.func.FilterSerializable; -import io.serverlessworkflow.api.types.func.FunctionObject; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import io.serverlessworkflow.serialization.DeserializeHelper; -import java.io.IOException; -import java.lang.invoke.SerializedLambda; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.function.Function; - -class SerializationUtils { - - private SerializationUtils() {} - - private static final String TYPE = "type"; - private static final String VALUE = "value"; - private static final String NULL = "null"; - - public static void serializeObjectWithType(JsonGenerator gen, Object value) throws IOException { - gen.writeStartObject(); - if (value == null) { - gen.writeStringField(TYPE, NULL); - } else { - if (value instanceof FunctionObject) { - gen.writeStringField(TYPE, SerializedLambda.class.getName()); - try { - gen.writeObjectField(VALUE, ReflectionUtils.serializedLambda(value)); - } catch (ReflectiveOperationException e) { - throw new IOException(e); - } - } else { - gen.writeStringField(TYPE, value.getClass().getName()); - if (value instanceof Optional optional) { - writeOptionalWithType(gen, optional); - } else { - gen.writeObjectField(VALUE, value); - } - } - } - gen.writeEndObject(); - } - - public static Object deserializeObjectWithType(DeserializationContext ctxt, JsonNode objectNode) - throws IOException, ReflectiveOperationException { - String className = objectNode.get(TYPE).asText(); - if (NULL.equals(className)) { - return null; - } - Class clazz = ReflectionUtils.loadClass(className); - if (clazz.equals(Optional.class)) { - return readOptionalWithType(ctxt, objectNode.get(VALUE)); - } else { - Object value = ctxt.readTreeAsValue(objectNode.get(VALUE), clazz); - return value instanceof SerializedLambda sl - ? ReflectionUtils.functionFromSerialized(sl) - : value; - } - } - - public static void writeOptionalWithType(JsonGenerator gen, Optional optional) - throws IOException { - if (!optional.isEmpty()) { - gen.writeFieldName(VALUE); - serializeObjectWithType(gen, optional.orElseThrow()); - } - } - - public static Optional readOptionalWithType(DeserializationContext ctxt, JsonNode objectNode) - throws IOException, ReflectiveOperationException { - return objectNode == null - ? Optional.empty() - : Optional.of(deserializeObjectWithType(ctxt, objectNode)); - } - - public static void serializeMap(JsonGenerator gen, Map map) throws IOException { - gen.writeStartObject(); - for (Map.Entry entry : map.entrySet()) { - gen.writeFieldName(entry.getKey()); - SerializationUtils.serializeObjectWithType(gen, entry.getValue()); - } - gen.writeEndObject(); - } - - public static void deserializeMap( - JsonParser p, DeserializationContext ctxt, Map map) - throws IOException, ReflectiveOperationException { - ObjectNode node = (ObjectNode) ctxt.readTree(p); - for (Entry item : node.properties()) { - map.put(item.getKey(), deserializeObjectWithType(ctxt, item.getValue())); - } - } - - public static T deserializeFilterClass( - JsonParser p, - DeserializationContext ctxt, - Function setter, - Class objectClass) - throws IOException { - TreeNode treeNode = p.readValueAsTree(); - if (treeNode instanceof ObjectNode node && SerializationUtils.hasType(node)) { - try { - return setter.apply( - (FilterSerializable) SerializationUtils.deserializeObjectWithType(ctxt, node)); - } catch (ReflectiveOperationException e) { - throw new IOException(e); - } - } else { - return DeserializeHelper.deserializeOneOf( - treeNode, p, objectClass, List.of(String.class, Object.class)); - } - } - - public static boolean isFilterSerializable(Object object) { - return object instanceof FilterSerializable; - } - - public static boolean hasType(ObjectNode node) { - return node.has(TYPE); - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializedLambdaDeserializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializedLambdaDeserializer.java deleted file mode 100644 index 87c6c8397..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializedLambdaDeserializer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import java.io.IOException; -import java.lang.invoke.SerializedLambda; - -public class SerializedLambdaDeserializer extends JsonDeserializer { - - static final String CAPTURING_CLASS = "capturingClass"; - static final String FUNCTIONAL_CLASS = "functionalInterfaceClass"; - static final String FUNCTIONAL_METHOD_NAME = "functionalInterfaceMethodName"; - static final String FUNCTIONAL_METHOD_SIGNATURE = "functionalInterfaceMethodSignature"; - static final String METHOD_KIND = "implMethodKind"; - static final String METHOD_CLASS = "implClass"; - static final String METHOD_NAME = "implMethodName"; - static final String METHOD_SIGNATURE = "implMethodSignature"; - static final String METHOD_TYPE = "instantiatedMethodType"; - static final String CAPTURED_ARGS = "capturedArgs"; - - @Override - public SerializedLambda deserialize(JsonParser p, DeserializationContext ctxt) - throws IOException { - TreeNode tree = p.readValueAsTree(); - - if (tree instanceof ObjectNode node) { - try { - return new SerializedLambda( - ReflectionUtils.loadCapturingClass(node.get(CAPTURING_CLASS).asText()), - node.get(FUNCTIONAL_CLASS).asText(), - node.get(FUNCTIONAL_METHOD_NAME).asText(), - node.get(FUNCTIONAL_METHOD_SIGNATURE).asText(), - node.get(METHOD_KIND).asInt(), - node.get(METHOD_CLASS).asText(), - node.get(METHOD_NAME).asText(), - node.get(METHOD_SIGNATURE).asText(), - node.get(METHOD_TYPE).asText(), - fromArray(ctxt, (ArrayNode) node.get(CAPTURED_ARGS))); - } catch (ReflectiveOperationException ex) { - throw new IOException("Error unmarshalling SerializedLambda " + node, ex); - } - } else { - throw new IOException( - "Node " - + tree - + " is not an object and therefore cannot be converted into SerializedLambda"); - } - } - - private Object[] fromArray(DeserializationContext ctxt, ArrayNode node) - throws IOException, ReflectiveOperationException { - if (node == null) { - return new Object[0]; - } else { - Object[] result = new Object[node.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = SerializationUtils.deserializeObjectWithType(ctxt, node.get(i)); - } - return result; - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializedLambdaWriter.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializedLambdaWriter.java deleted file mode 100644 index 49162c11d..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/SerializedLambdaWriter.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; -import java.io.IOException; -import java.lang.invoke.SerializedLambda; - -public class SerializedLambdaWriter extends BeanPropertyWriter { - - private static final long serialVersionUID = 1L; - - public SerializedLambdaWriter(BeanPropertyWriter base) { - super(base); - } - - @Override - public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) - throws IOException { - SerializedLambda sl = (SerializedLambda) bean; - int size = sl.getCapturedArgCount(); - if (size > 0) { - gen.writeArrayFieldStart(SerializedLambdaDeserializer.CAPTURED_ARGS); - for (int i = 0; i < size; i++) { - SerializationUtils.serializeObjectWithType(gen, sl.getCapturedArg(i)); - } - gen.writeEndArray(); - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/TaskMetadataDeserializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/TaskMetadataDeserializer.java deleted file mode 100644 index 50a30d9c4..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/TaskMetadataDeserializer.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import io.serverlessworkflow.api.types.TaskMetadata; -import java.io.IOException; - -public class TaskMetadataDeserializer extends JsonDeserializer { - - @Override - public TaskMetadata deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - try { - TaskMetadata result = new TaskMetadata(); - SerializationUtils.deserializeMap(p, ctxt, result.getAdditionalProperties()); - return result; - } catch (ReflectiveOperationException e) { - throw new IOException(e); - } - } -} diff --git a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/TaskMetadataSerializer.java b/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/TaskMetadataSerializer.java deleted file mode 100644 index 5c39de2af..000000000 --- a/experimental/fluent/jackson/src/main/java/io/serverlessworkflow/fluent/func/serialization/jackson/TaskMetadataSerializer.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.func.serialization.jackson; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import io.serverlessworkflow.api.types.TaskMetadata; -import java.io.IOException; - -public class TaskMetadataSerializer extends JsonSerializer { - @Override - public void serialize(TaskMetadata value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { - SerializationUtils.serializeMap(gen, value.getAdditionalProperties()); - } -} diff --git a/experimental/fluent/jackson/src/main/resources/META-INF/native-image/io.serverlessworkflow/serverlessworkflow-experimental-fluent-serialization-jackson/reflect-config.json b/experimental/fluent/jackson/src/main/resources/META-INF/native-image/io.serverlessworkflow/serverlessworkflow-experimental-fluent-serialization-jackson/reflect-config.json deleted file mode 100644 index d781f6b38..000000000 --- a/experimental/fluent/jackson/src/main/resources/META-INF/native-image/io.serverlessworkflow/serverlessworkflow-experimental-fluent-serialization-jackson/reflect-config.json +++ /dev/null @@ -1,197 +0,0 @@ -[ - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FuncExportAsDeserializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FuncExportAsSerializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FuncInputFromDeserializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FuncInputFromSerializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FuncOutputAsDeserializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FuncOutputAsSerializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FunctionArgumentsDeserializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FunctionArgumentsSerializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.FunctionDeserializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.SerializableFunctionSerializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.SerializedLambdaDeserializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.TaskMetadataDeserializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - }, - { - "name": "io.serverlessworkflow.fluent.func.serialization.jackson.TaskMetadataSerializer", - "queryAllPublicConstructors": true, - "queryAllDeclaredConstructors": true, - "queryAllPublicMethods": true, - "queryAllDeclaredMethods": true, - "allPublicConstructors": true, - "allDeclaredConstructors": true, - "allPublicMethods": true, - "allDeclaredMethods": true, - "allPublicFields": true, - "allDeclaredFields": true, - "allPublicClasses": true, - "allDeclaredClasses": true - } -] diff --git a/experimental/fluent/jackson/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module b/experimental/fluent/jackson/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module deleted file mode 100644 index 3ae3675c6..000000000 --- a/experimental/fluent/jackson/src/main/resources/META-INF/services/com.fasterxml.jackson.databind.Module +++ /dev/null @@ -1 +0,0 @@ -io.serverlessworkflow.fluent.func.serialization.jackson.FuncJacksonModule \ No newline at end of file diff --git a/experimental/fluent/pom.xml b/experimental/fluent/pom.xml deleted file mode 100644 index 15f289354..000000000 --- a/experimental/fluent/pom.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental - 8.0.0-SNAPSHOT - - Serverless Workflow :: Experimental :: Fluent - serverlessworkflow-experimental-fluent - pom - - - 17 - 17 - UTF-8 - - - - - - io.serverlessworkflow - serverlessworkflow-experimental-types - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-fluent-spec - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-impl-json - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-experimental-agentic - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-experimental-lambda - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-experimental-fluent-agentic - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-experimental-fluent-agentic - ${project.version} - test-jar - test - - - - - - func - jackson - - \ No newline at end of file diff --git a/experimental/lambda-fluent/pom.xml b/experimental/lambda-fluent/pom.xml deleted file mode 100644 index 0a4212c57..000000000 --- a/experimental/lambda-fluent/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental - 8.0.0-SNAPSHOT - - - serverlessworkflow-lambda-fluent - Serverless Workflow :: Experimental :: Lambda Fluent - pom - - - 17 - 17 - UTF-8 - - - - - io.serverlessworkflow - serverlessworkflow-experimental-fluent-func - - - io.serverlessworkflow - serverlessworkflow-experimental-lambda - - - \ No newline at end of file diff --git a/experimental/lambda/pom.xml b/experimental/lambda/pom.xml deleted file mode 100644 index 22f9f897f..000000000 --- a/experimental/lambda/pom.xml +++ /dev/null @@ -1,64 +0,0 @@ - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental - 8.0.0-SNAPSHOT - - serverlessworkflow-experimental-lambda - Serverless Workflow :: Experimental :: Lambda - - - io.serverlessworkflow - serverlessworkflow-experimental-types - - - io.serverlessworkflow - serverlessworkflow-experimental-model - test - - - io.serverlessworkflow - serverlessworkflow-impl-core - - - io.serverlessworkflow - serverlessworkflow-impl-jq - - - io.serverlessworkflow - serverlessworkflow-experimental-fluent-func - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.junit.jupiter - junit-jupiter-params - test - - - org.assertj - assertj-core - test - - - org.awaitility - awaitility - test - - - ch.qos.logback - logback-classic - test - - - \ No newline at end of file diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/AbstractJavaCallExecutor.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/AbstractJavaCallExecutor.java deleted file mode 100644 index c723fc87c..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/AbstractJavaCallExecutor.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowContext; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowModelFactory; -import io.serverlessworkflow.impl.executors.CallableTask; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -public abstract class AbstractJavaCallExecutor implements CallableTask { - - protected final Optional> inputClass; - private final Optional> outputClass; - private final Optional typeConverter; - private final boolean directCompletable; - private final boolean convertedCompletable; - - protected AbstractJavaCallExecutor( - Optional> inputClass, Optional> outputClass) { - this.inputClass = inputClass; - this.outputClass = outputClass; - this.typeConverter = outputClass.flatMap(DataTypeConverterRegistry.get()::find); - this.directCompletable = outputClass.filter(c -> c.equals(CompletableFuture.class)).isPresent(); - this.convertedCompletable = - typeConverter.filter(c -> c.targetType().equals(CompletableFuture.class)).isPresent(); - } - - @Override - public CompletableFuture apply( - WorkflowContext workflowContext, TaskContext taskContext, WorkflowModel input) { - WorkflowModelFactory modelFactory = workflowContext.definition().application().modelFactory(); - - if (directCompletable) { - return ((CompletableFuture) - callJavaFunction(workflowContext, taskContext, model2Input(input))) - .thenApply(v -> output2Model(modelFactory, input, convertResponse(v))); - } else if (convertedCompletable) { - return ((CompletableFuture) - convertTypedResponse( - callJavaFunction(workflowContext, taskContext, model2Input(input)))) - .thenApply(v -> output2Model(modelFactory, input, convertResponse(v))); - } else if (outputClass.isPresent()) { - return CompletableFuture.supplyAsync( - () -> callJavaFunction(workflowContext, taskContext, model2Input(input)), - workflowContext.definition().application().executorService()) - .thenApply(v -> output2Model(modelFactory, input, convertTypedResponse(v))); - } else { - Object result = - convertResponse(callJavaFunction(workflowContext, taskContext, model2Input(input))); - return result instanceof CompletableFuture future - ? future.thenApply(v -> output2Model(modelFactory, input, convertResponse(v))) - : CompletableFuture.completedFuture(output2Model(modelFactory, input, result)); - } - } - - protected abstract V callJavaFunction( - WorkflowContext workflowContext, TaskContext taskContext, T input); - - protected T model2Input(WorkflowModel model) { - return JavaFuncUtils.convertT(model, inputClass); - } - - protected Object convertTypedResponse(V obj) { - return obj == null ? null : typeConverter.map(c -> c.apply(obj)).orElse(obj); - } - - protected Object convertResponse(Object obj) { - return obj == null || obj instanceof CompletableFuture - ? obj - : DataTypeConverterRegistry.get().find(obj.getClass()).map(c -> c.apply(obj)).orElse(obj); - } - - protected WorkflowModel output2Model( - WorkflowModelFactory modelFactory, WorkflowModel input, Object result) { - return modelFactory.fromAny(input, result); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/DataTypeConverter.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/DataTypeConverter.java deleted file mode 100644 index 53c316ac8..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/DataTypeConverter.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.impl.ServicePriority; -import java.util.function.Function; - -public interface DataTypeConverter extends Function, ServicePriority { - Class sourceType(); - - Class targetType(); -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/DataTypeConverterRegistry.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/DataTypeConverterRegistry.java deleted file mode 100644 index aa7b4cdbb..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/DataTypeConverterRegistry.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.ServiceLoader; -import java.util.concurrent.ConcurrentHashMap; - -public class DataTypeConverterRegistry { - - private static final DataTypeConverterRegistry instance = new DataTypeConverterRegistry(); - - public static DataTypeConverterRegistry get() { - return instance; - } - - @SuppressWarnings("rawtypes") - private final Iterable converters; - - @SuppressWarnings("rawtypes") - private final Map, Optional> convertersMap; - - private DataTypeConverterRegistry() { - this.converters = ServiceLoader.load(DataTypeConverter.class); - this.convertersMap = new ConcurrentHashMap<>(); - } - - @SuppressWarnings("rawtypes") - public Optional find(Class clazz) { - return convertersMap.computeIfAbsent(clazz, this::searchConverter); - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private Optional searchConverter(Class clazz) { - List candidates = new ArrayList<>(); - for (DataTypeConverter converter : converters) { - if (converter.sourceType().equals(clazz)) { - candidates.add(converter); - } - } - if (!candidates.isEmpty()) { - return first(candidates); - } - - for (DataTypeConverter converter : converters) { - if (converter.sourceType().isAssignableFrom(clazz)) { - candidates.add(converter); - } - } - return candidates.isEmpty() ? Optional.empty() : first(candidates); - } - - @SuppressWarnings("rawtypes") - private Optional first(List candidates) { - Collections.sort(candidates); - return Optional.of(candidates.get(0)); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaCallFunctionBuilder.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaCallFunctionBuilder.java deleted file mode 100644 index c9a20266f..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaCallFunctionBuilder.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.api.types.CallFunction; -import io.serverlessworkflow.api.types.func.CallJava; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.LoopFunction; -import io.serverlessworkflow.api.types.func.LoopFunctionIndex; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowMutablePosition; -import io.serverlessworkflow.impl.executors.CallFunctionExecutorBuilder; -import io.serverlessworkflow.impl.executors.CallableTaskFactory; -import java.util.Map; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Function; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class JavaCallFunctionBuilder extends CallFunctionExecutorBuilder { - - private static final Logger logger = LoggerFactory.getLogger(JavaCallFunctionBuilder.class); - - @Override - public int priority() { - return DEFAULT_PRIORITY - 10; - } - - @Override - public CallableTaskFactory init( - CallFunction task, WorkflowDefinition definition, WorkflowMutablePosition position) { - if (CallJava.JAVA_CALL_KEY.equals(task.getCall())) { - if (task.getWith() == null) { - throw new IllegalArgumentException( - "At least one key " - + CallJava.FUNCTION_NAME_KEY - + " is expected as Java function argument"); - } - Map props = task.getWith().getAdditionalProperties(); - Object obj = props.get(CallJava.FUNCTION_NAME_KEY); - if (obj == null) { - throw new IllegalArgumentException( - "Missing required Java function argument '" + CallJava.FUNCTION_NAME_KEY + "'"); - } - Optional> input = - (Optional>) props.getOrDefault(CallJava.INPUT_CLASS_KEY, Optional.empty()); - Optional> output = - (Optional>) props.getOrDefault(CallJava.OUTPUT_CLASS_KEY, Optional.empty()); - if (obj instanceof ContextFunction fn) { - return () -> new JavaContextFunctionCallExecutor(input, output, fn); - } else if (obj instanceof FilterFunction fn) { - return () -> new JavaFilterFunctionCallExecutor(input, output, fn); - } else if (obj instanceof LoopFunction loop) { - return () -> - new JavaLoopFunctionCallExecutor( - loop, (String) props.get(CallJava.VAR_NAME_KEY), input, output); - } else if (obj instanceof LoopFunctionIndex loop) { - return () -> - new JavaLoopFunctionIndexCallExecutor( - loop, - (String) props.get(CallJava.VAR_NAME_KEY), - (String) props.get(CallJava.INDEX_NAME_KEY), - input, - output); - - } else if (obj instanceof Function fn) { - return () -> new JavaFunctionCallExecutor(input, output, fn); - } else if (obj instanceof Consumer consumer) { - return () -> new JavaConsumerCallExecutor(input, consumer); - } else { - throw new UnsupportedOperationException("Unrecognized function " + obj); - } - } else { - logger.info("Calling regular function handler for task call {}", task.getCall()); - return super.init(task, definition, position); - } - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaConsumerCallExecutor.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaConsumerCallExecutor.java deleted file mode 100644 index 0d28cd392..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaConsumerCallExecutor.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowContext; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.executors.CallableTask; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; - -public class JavaConsumerCallExecutor implements CallableTask { - - private final Optional> inputClass; - private final Consumer consumer; - - public JavaConsumerCallExecutor(Optional> inputClass, Consumer consumer) { - this.inputClass = inputClass; - this.consumer = consumer; - } - - @Override - public CompletableFuture apply( - WorkflowContext workflowContext, TaskContext taskContext, WorkflowModel input) { - T typed = JavaFuncUtils.convertT(input, inputClass); - consumer.accept(typed); - return CompletableFuture.completedFuture(input); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaContextFunctionCallExecutor.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaContextFunctionCallExecutor.java deleted file mode 100644 index b8c600b7f..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaContextFunctionCallExecutor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowContext; -import java.util.Optional; - -public class JavaContextFunctionCallExecutor extends AbstractJavaCallExecutor { - - private final ContextFunction function; - - public JavaContextFunctionCallExecutor( - Optional> inputClass, - Optional> outputClass, - ContextFunction function) { - super(inputClass, outputClass); - this.function = function; - } - - @Override - protected V callJavaFunction(WorkflowContext workflowContext, TaskContext taskContext, T input) { - return function.apply(input, workflowContext); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFilterFunctionCallExecutor.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFilterFunctionCallExecutor.java deleted file mode 100644 index 638b0dd12..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFilterFunctionCallExecutor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowContext; -import java.util.Optional; - -public class JavaFilterFunctionCallExecutor extends AbstractJavaCallExecutor { - - private final FilterFunction function; - - public JavaFilterFunctionCallExecutor( - Optional> inputClass, - Optional> outputClass, - FilterFunction function) { - super(inputClass, outputClass); - this.function = function; - } - - @Override - protected V callJavaFunction(WorkflowContext workflowContext, TaskContext taskContext, T input) { - return function.apply(input, workflowContext, taskContext); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaForExecutorBuilder.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaForExecutorBuilder.java deleted file mode 100644 index 0be8770bd..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaForExecutorBuilder.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import static io.serverlessworkflow.impl.executors.func.JavaFuncUtils.safeObject; - -import io.serverlessworkflow.api.types.ForTask; -import io.serverlessworkflow.api.types.func.LoopPredicate; -import io.serverlessworkflow.api.types.func.LoopPredicateIndex; -import io.serverlessworkflow.api.types.func.LoopPredicateIndexContext; -import io.serverlessworkflow.api.types.func.LoopPredicateIndexFilter; -import io.serverlessworkflow.api.types.func.TypedFunction; -import io.serverlessworkflow.api.types.utils.ForTaskFunction; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowMutablePosition; -import io.serverlessworkflow.impl.WorkflowPredicate; -import io.serverlessworkflow.impl.WorkflowValueResolver; -import io.serverlessworkflow.impl.executors.ForExecutor.ForExecutorBuilder; -import io.serverlessworkflow.impl.expressions.ExpressionDescriptor; -import java.util.Collection; -import java.util.Optional; - -public class JavaForExecutorBuilder extends ForExecutorBuilder { - - protected JavaForExecutorBuilder( - WorkflowMutablePosition position, ForTask task, WorkflowDefinition definition) { - super(position, task, definition); - } - - @Override - protected Optional buildWhileFilter() { - final Object whilePred = ForTaskFunction.getWhilePredicate(task); - Optional> whileClass = ForTaskFunction.getWhileClass(task); - String varName = task.getFor().getEach(); - String indexName = task.getFor().getAt(); - if (whilePred instanceof LoopPredicateIndexFilter pred) { - return Optional.of( - (w, t, n) -> { - Object item = safeObject(t.variables().get(varName)); - return pred.test( - JavaFuncUtils.convert(n, whileClass), - item, - (Integer) safeObject(t.variables().get(indexName)), - w, - t); - }); - } else if (whilePred instanceof LoopPredicate pred) { - return Optional.of( - (w, t, n) -> { - Object item = safeObject(t.variables().get(varName)); - return pred.test(JavaFuncUtils.convert(n, whileClass), item); - }); - } else if (whilePred instanceof LoopPredicateIndexContext pred) { - return Optional.of( - (w, t, n) -> { - Object item = safeObject(t.variables().get(varName)); - return pred.test( - JavaFuncUtils.convert(n, whileClass), - item, - (Integer) safeObject(t.variables().get(indexName)), - w); - }); - } else if (whilePred instanceof LoopPredicateIndex pred) { - return Optional.of( - (w, t, n) -> { - Object item = safeObject(t.variables().get(varName)); - return pred.test( - JavaFuncUtils.convert(n, whileClass), - item, - (Integer) safeObject(t.variables().get(indexName))); - }); - } - return super.buildWhileFilter(); - } - - protected WorkflowValueResolver> buildCollectionFilter() { - Object inCollection = collectionFilterObject(); - return inCollection != null - ? application - .expressionFactory() - .resolveCollection(ExpressionDescriptor.object(inCollection)) - : super.buildCollectionFilter(); - } - - private Object collectionFilterObject() { - return ForTaskFunction.getForClass(task) - .map(forClass -> typedCollectionFunction(forClass)) - .orElse(ForTaskFunction.getInCollection(task)); - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private Object typedCollectionFunction(Class forClass) { - return new TypedFunction(ForTaskFunction.getInCollection(task), forClass); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFuncUtils.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFuncUtils.java deleted file mode 100644 index 7f677d1b4..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFuncUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowPredicate; -import io.serverlessworkflow.impl.expressions.ExpressionDescriptor; -import java.util.Optional; - -public class JavaFuncUtils { - - static Object safeObject(Object obj) { - return obj instanceof WorkflowModel model ? model.asJavaObject() : obj; - } - - static WorkflowPredicate from(WorkflowApplication application, Object predicate) { - return application.expressionFactory().buildPredicate(ExpressionDescriptor.object(predicate)); - } - - static T convertT(WorkflowModel model, Optional> inputClass) { - return model.isNull() - ? null - : inputClass - .map( - c -> - model - .as(c) - .orElseThrow( - () -> - new IllegalArgumentException( - "Model " + model + " cannot be converted to type " + c))) - .orElseGet(() -> (T) model.asJavaObject()); - } - - static Object convert(WorkflowModel model, Optional> inputClass) { - if (model.isNull()) { - return null; - } - return inputClass.isPresent() - ? model - .as(inputClass.orElseThrow()) - .orElseThrow( - () -> - new IllegalArgumentException( - "Model " + model + " cannot be converted to type " + inputClass)) - : model.asJavaObject(); - } - - private JavaFuncUtils() {} -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFunctionCallExecutor.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFunctionCallExecutor.java deleted file mode 100644 index dc99ac916..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaFunctionCallExecutor.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowContext; -import java.util.Optional; -import java.util.function.Function; - -public class JavaFunctionCallExecutor extends AbstractJavaCallExecutor { - - private final Function function; - - public JavaFunctionCallExecutor( - Optional> inputClass, Optional> outputClass, Function function) { - super(inputClass, outputClass); - this.function = function; - } - - @Override - protected V callJavaFunction(WorkflowContext workflowContext, TaskContext taskContext, T input) { - return function.apply(input); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaListenExecutorBuilder.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaListenExecutorBuilder.java deleted file mode 100644 index a528c7d16..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaListenExecutorBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.api.types.ListenTask; -import io.serverlessworkflow.api.types.Until; -import io.serverlessworkflow.api.types.utils.TaskPredicate; -import io.serverlessworkflow.api.types.utils.TypesUtils; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowMutablePosition; -import io.serverlessworkflow.impl.WorkflowPredicate; -import io.serverlessworkflow.impl.executors.ListenExecutor.ListenExecutorBuilder; - -public class JavaListenExecutorBuilder extends ListenExecutorBuilder { - - protected JavaListenExecutorBuilder( - WorkflowMutablePosition position, ListenTask task, WorkflowDefinition definition) { - super(position, task, definition); - } - - @Override - protected WorkflowPredicate buildUntilPredicate(Until until) { - Object predicate = TaskPredicate.predicate(task, TypesUtils.UNTIL_PRED_NAME); - return predicate != null - ? JavaFuncUtils.from(application, predicate) - : super.buildUntilPredicate(until); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaLoopFunctionCallExecutor.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaLoopFunctionCallExecutor.java deleted file mode 100644 index f22af220a..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaLoopFunctionCallExecutor.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import static io.serverlessworkflow.impl.executors.func.JavaFuncUtils.safeObject; - -import io.serverlessworkflow.api.types.func.LoopFunction; -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowContext; -import java.util.Optional; - -public class JavaLoopFunctionCallExecutor extends AbstractJavaCallExecutor { - - private final LoopFunction function; - private final String varName; - - public JavaLoopFunctionCallExecutor( - LoopFunction function, - String varName, - Optional> inputClass, - Optional> outputClass) { - super(inputClass, outputClass); - this.function = function; - this.varName = varName; - } - - @Override - protected R callJavaFunction(WorkflowContext workflowContext, TaskContext taskContext, T input) { - return function.apply(input, (V) safeObject(taskContext.variables().get(varName))); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaLoopFunctionIndexCallExecutor.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaLoopFunctionIndexCallExecutor.java deleted file mode 100644 index 360c65174..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaLoopFunctionIndexCallExecutor.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import static io.serverlessworkflow.impl.executors.func.JavaFuncUtils.safeObject; - -import io.serverlessworkflow.api.types.func.LoopFunctionIndex; -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowContext; -import java.util.Optional; - -public class JavaLoopFunctionIndexCallExecutor extends AbstractJavaCallExecutor { - - private final LoopFunctionIndex function; - private final String varName; - private final String indexName; - - public JavaLoopFunctionIndexCallExecutor( - LoopFunctionIndex function, - String varName, - String indexName, - Optional> inputClass, - Optional> outputClass) { - super(inputClass, outputClass); - this.function = function; - this.varName = varName; - this.indexName = indexName; - } - - @Override - protected R callJavaFunction(WorkflowContext workflowContext, TaskContext taskContext, T input) { - return function.apply( - input, - (V) safeObject(taskContext.variables().get(varName)), - (Integer) safeObject(taskContext.variables().get(indexName))); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaSwitchExecutorBuilder.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaSwitchExecutorBuilder.java deleted file mode 100644 index 0f63a7375..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaSwitchExecutorBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.api.types.SwitchItem; -import io.serverlessworkflow.api.types.SwitchTask; -import io.serverlessworkflow.api.types.utils.TaskPredicate; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowMutablePosition; -import io.serverlessworkflow.impl.WorkflowPredicate; -import io.serverlessworkflow.impl.executors.SwitchExecutor.SwitchExecutorBuilder; -import java.util.Optional; - -public class JavaSwitchExecutorBuilder extends SwitchExecutorBuilder { - - protected JavaSwitchExecutorBuilder( - WorkflowMutablePosition position, SwitchTask task, WorkflowDefinition definition) { - super(position, task, definition); - } - - @Override - protected Optional buildFilter(SwitchItem item) { - Object predicate = TaskPredicate.predicate(task, item.getName()); - return predicate != null - ? Optional.of(JavaFuncUtils.from(application, predicate)) - : super.buildFilter(item); - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaTaskExecutorFactory.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaTaskExecutorFactory.java deleted file mode 100644 index 9e0628762..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/executors/func/JavaTaskExecutorFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.executors.func; - -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskBase; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowMutablePosition; -import io.serverlessworkflow.impl.executors.DefaultTaskExecutorFactory; -import io.serverlessworkflow.impl.executors.TaskExecutorBuilder; - -public class JavaTaskExecutorFactory extends DefaultTaskExecutorFactory { - - public TaskExecutorBuilder getTaskExecutor( - WorkflowMutablePosition position, Task task, WorkflowDefinition definition) { - if (task.getForTask() != null) { - return new JavaForExecutorBuilder(position, task.getForTask(), definition); - } else if (task.getSwitchTask() != null) { - return new JavaSwitchExecutorBuilder(position, task.getSwitchTask(), definition); - } else if (task.getListenTask() != null) { - return new JavaListenExecutorBuilder(position, task.getListenTask(), definition); - } else { - return super.getTaskExecutor(position, task, definition); - } - } -} diff --git a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java b/experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java deleted file mode 100644 index 9f9d53fed..000000000 --- a/experimental/lambda/src/main/java/io/serverlessworkflow/impl/expressions/func/JavaExpressionFactory.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.expressions.func; - -import io.cloudevents.CloudEventData; -import io.serverlessworkflow.api.types.TaskBase; -import io.serverlessworkflow.api.types.TaskMetadata; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.ContextPredicate; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.FilterPredicate; -import io.serverlessworkflow.api.types.func.TypedContextFunction; -import io.serverlessworkflow.api.types.func.TypedContextPredicate; -import io.serverlessworkflow.api.types.func.TypedFilterFunction; -import io.serverlessworkflow.api.types.func.TypedFilterPredicate; -import io.serverlessworkflow.api.types.func.TypedFunction; -import io.serverlessworkflow.api.types.func.TypedPredicate; -import io.serverlessworkflow.api.types.utils.TypesUtils; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowPredicate; -import io.serverlessworkflow.impl.expressions.AbstractExpressionFactory; -import io.serverlessworkflow.impl.expressions.ExpressionDescriptor; -import io.serverlessworkflow.impl.expressions.ObjectExpression; -import java.time.OffsetDateTime; -import java.util.Collection; -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Predicate; - -public class JavaExpressionFactory extends AbstractExpressionFactory { - - @Override - public ObjectExpression buildExpression(ExpressionDescriptor descriptor) { - Object value = descriptor.asObject(); - if (value instanceof Function func) { - return (w, t, n) -> func.apply(n.asJavaObject()); - } else if (value instanceof TypedFunction func) { - return (w, t, n) -> func.function().apply(convert(n, func.argClass())); - } else if (value instanceof FilterFunction func) { - return (w, t, n) -> func.apply(n.asJavaObject(), w, t); - } else if (value instanceof TypedFilterFunction func) { - return (w, t, n) -> func.function().apply(convert(n, func.argClass()), w, t); - } else if (value instanceof ContextFunction func) { - return (w, t, n) -> func.apply(n.asJavaObject(), w); - } else if (value instanceof TypedContextFunction func) { - return (w, t, n) -> func.function().apply(convert(n, func.argClass()), w); - } else { - return (w, t, n) -> value; - } - } - - private T convert(WorkflowModel model, Class argClass) { - return model.isNull() - ? null - : model - .as(argClass) - .orElseThrow( - () -> - new IllegalArgumentException( - "Cannot convert model " + model.asJavaObject() + " to class" + argClass)); - } - - @Override - public int priority(ExpressionDescriptor descriptor) { - Object value = descriptor.asObject(); - if (value instanceof Function - || value instanceof TypedFunction - || value instanceof FilterFunction - || value instanceof TypedFilterFunction - || value instanceof ContextFunction - || value instanceof TypedContextFunction - || value instanceof Predicate - || value instanceof TypedPredicate - || value instanceof ContextPredicate - || value instanceof TypedContextPredicate - || value instanceof FilterPredicate - || value instanceof TypedFilterPredicate - || value instanceof Boolean) { - return DEFAULT_PRIORITY - 500; - } else if (descriptor.asString() == null) { - return MIN_PRIORITY; - } else { - return DEFAULT_PRIORITY + 500; - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private WorkflowPredicate fromPredicate(Predicate pred) { - return (w, t, n) -> pred.test(n.asJavaObject()); - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private WorkflowPredicate fromPredicate(TypedPredicate pred) { - return (w, t, n) -> pred.pred().test(convert(n, pred.argClass())); - } - - private WorkflowPredicate fromPredicate(ContextPredicate pred) { - return (w, t, n) -> pred.test(n.asJavaObject(), w); - } - - private WorkflowPredicate fromPredicate(TypedContextPredicate pred) { - return (w, t, n) -> pred.predicate().test(convert(n, pred.argClass()), w); - } - - private WorkflowPredicate fromPredicate(FilterPredicate pred) { - return (w, t, n) -> pred.test(n.asJavaObject(), w, t); - } - - private WorkflowPredicate fromPredicate(TypedFilterPredicate pred) { - return (w, t, n) -> pred.predicate().test(convert(n, pred.argClass()), w, t); - } - - @Override - public Optional buildIfFilter(TaskBase task) { - TaskMetadata metadata = task.getMetadata(); - if (metadata != null) { - Object obj = metadata.getAdditionalProperties().get(TypesUtils.IF_PREDICATE); - if (obj instanceof Predicate pred) { - return Optional.of(fromPredicate(pred)); - } else if (obj instanceof TypedPredicate pred) { - return Optional.of(fromPredicate(pred)); - } else if (obj instanceof ContextPredicate pred) { - return Optional.of(fromPredicate(pred)); - } else if (obj instanceof TypedContextPredicate pred) { - return Optional.of(fromPredicate(pred)); - } else if (obj instanceof FilterPredicate pred) { - return Optional.of(fromPredicate(pred)); - } else if (obj instanceof TypedFilterPredicate pred) { - return Optional.of(fromPredicate(pred)); - } - } - return Optional.empty(); - } - - @Override - public WorkflowPredicate buildPredicate(ExpressionDescriptor desc) { - Object value = desc.asObject(); - if (value instanceof Predicate pred) { - return fromPredicate(pred); - } else if (value instanceof TypedPredicate pred) { - return fromPredicate(pred); - } else if (value instanceof ContextPredicate pred) { - return fromPredicate(pred); - } else if (value instanceof TypedContextPredicate pred) { - return fromPredicate(pred); - } else if (value instanceof FilterPredicate pred) { - return fromPredicate(pred); - } else if (value instanceof TypedFilterPredicate pred) { - return fromPredicate(pred); - } else if (value instanceof Boolean bool) { - return (w, f, n) -> bool; - } else { - throw new IllegalArgumentException("value should be a predicate or a boolean"); - } - } - - @Override - protected String toString(Object eval) { - return asClass(eval, String.class); - } - - @Override - protected CloudEventData toCloudEventData(Object eval) { - return asClass(eval, CloudEventData.class); - } - - @Override - protected OffsetDateTime toDate(Object eval) { - return asClass(eval, OffsetDateTime.class); - } - - @Override - protected Map toMap(Object eval) { - return asClass(eval, Map.class); - } - - @Override - protected Collection toCollection(Object obj) { - return asClass(obj, Collection.class); - } - - private T asClass(Object obj, Class clazz) { - return clazz.cast(obj); - } -} diff --git a/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.executors.CallableTaskBuilder b/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.executors.CallableTaskBuilder deleted file mode 100644 index e6c043b77..000000000 --- a/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.executors.CallableTaskBuilder +++ /dev/null @@ -1,2 +0,0 @@ -io.serverlessworkflow.impl.executors.func.JavaCallFunctionBuilder - diff --git a/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.executors.TaskExecutorFactory b/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.executors.TaskExecutorFactory deleted file mode 100644 index 710fa4db4..000000000 --- a/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.executors.TaskExecutorFactory +++ /dev/null @@ -1 +0,0 @@ -io.serverlessworkflow.impl.executors.func.JavaTaskExecutorFactory \ No newline at end of file diff --git a/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.expressions.ExpressionFactory b/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.expressions.ExpressionFactory deleted file mode 100644 index 722ea0f0c..000000000 --- a/experimental/lambda/src/main/resources/META-INF/services/io.serverlessworkflow.impl.expressions.ExpressionFactory +++ /dev/null @@ -1 +0,0 @@ -io.serverlessworkflow.impl.expressions.func.JavaExpressionFactory \ No newline at end of file diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallJavaContextFunctionTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallJavaContextFunctionTest.java deleted file mode 100644 index a7d46b94a..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallJavaContextFunctionTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.Document; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.api.types.func.CallJava; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.impl.WorkflowApplication; -import java.util.List; -import java.util.concurrent.ExecutionException; -import org.junit.jupiter.api.Test; - -class CallJavaContextFunctionTest { - - // Reuse the same Person type used in CallTest - record Person(String name, int age) {} - - @Test - void testJavaContextFunction_simple() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - var ctxFn = - (ContextFunction) - (person, workflowContext) -> - person.name - + "@" - + workflowContext.definition().workflow().getDocument().getName(); - - Workflow workflow = - new Workflow() - .withDocument( - new Document() - .withNamespace("test") - .withName("testJavaContextCall") - .withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "javaContextCall", - new Task() - .withCallTask( - new CallTask() - .withCallFunction(CallJava.function(ctxFn, Person.class)))))); - - var out = - app.workflowDefinition(workflow) - .instance(new Person("Elisa", 30)) - .start() - .get() - .asText() - .orElseThrow(); - - assertThat(out).isEqualTo("Elisa@testJavaContextCall"); - } - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallTest.java deleted file mode 100644 index 063d9fd1b..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/CallTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.api.types.CallFunction; -import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.Document; -import io.serverlessworkflow.api.types.FlowDirective; -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.ForTask; -import io.serverlessworkflow.api.types.ForTaskConfiguration; -import io.serverlessworkflow.api.types.SwitchCase; -import io.serverlessworkflow.api.types.SwitchItem; -import io.serverlessworkflow.api.types.SwitchTask; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.TaskMetadata; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.api.types.func.CallJava; -import io.serverlessworkflow.api.types.utils.ForTaskFunction; -import io.serverlessworkflow.api.types.utils.TaskPredicate; -import io.serverlessworkflow.api.types.utils.TypesUtils; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowModel; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; -import java.util.function.Predicate; -import org.junit.jupiter.api.Test; - -class CallTest { - - @Test - void testJavaFunction() throws InterruptedException, ExecutionException { - internalJavaFunctionTest(JavaFunctions::getName, Person.class); - } - - @Test - void testJavaFunctionFuture() throws InterruptedException, ExecutionException { - internalJavaFunctionTest(JavaFunctions::getNameFuture, Person.class); - } - - @Test - void testJavaFunctionConverter() throws InterruptedException, ExecutionException { - internalJavaFunctionTest(JavaFunctions::getNameStringBuilder, Person.class); - } - - private void internalJavaFunctionTest(Function function, Class clazz) - throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testJavaCall").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "javaCall", - new Task() - .withCallTask( - new CallTask() - .withCallFunction(CallJava.function(function, clazz)))))); - - assertThat( - app.workflowDefinition(workflow) - .instance(new Person("Francisco", 33)) - .start() - .get() - .asText() - .orElseThrow()) - .isEqualTo("Francisco Javierito"); - } - } - - @Test - void testForLoop() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - ForTaskConfiguration forConfig = new ForTaskConfiguration(); - ForTask forTask = - new ForTask() - .withFor(forConfig) - .withDo( - List.of( - new TaskItem( - "javaCall", - new Task() - .withCallTask( - new CallTask() - .withCallFunction( - CallJava.loopFunction( - CallTest::sum, forConfig.getEach())))))); - ForTaskFunction.withCollection(forTask, v -> v, Collection.class); - ForTaskFunction.withWhile(forTask, CallTest::isEven); - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testLoop").withVersion("1.0")) - .withDo(List.of(new TaskItem("forLoop", new Task().withForTask(forTask)))); - - assertThat( - app.workflowDefinition(workflow) - .instance(List.of(2, 4, 6, 7)) - .start() - .get() - .asNumber() - .orElseThrow()) - .isEqualTo(12); - } - } - - @Test - void testSwitch() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testSwitch").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "switch", - new Task() - .withSwitchTask( - TaskPredicate.withPredicate( - new SwitchTask() - .withSwitch( - List.of( - new SwitchItem( - "odd", - new SwitchCase() - .withThen( - new FlowDirective() - .withFlowDirectiveEnum( - FlowDirectiveEnum.END))))), - "odd", - CallTest::isOdd, - Integer.class))), - new TaskItem( - "java", - new Task() - .withCallTask( - new CallTask() - .withCallFunction(CallJava.function(CallTest::zero)))))); - - WorkflowDefinition definition = app.workflowDefinition(workflow); - assertThat(definition.instance(3).start().get().asNumber().orElseThrow()).isEqualTo(3); - assertThat(definition.instance(4).start().get().asNumber().orElseThrow()).isEqualTo(0); - } - } - - @Test - void testIf() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testIf").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "java", - new Task() - .withCallTask( - new CallTask() - .withCallFunction( - withPredicate( - CallJava.function(CallTest::zero), - CallTest::isOdd)))))); - WorkflowDefinition definition = app.workflowDefinition(workflow); - assertThat(definition.instance(3).start().get().asNumber().orElseThrow()).isEqualTo(0); - assertThat(definition.instance(4).start().get().asNumber().orElseThrow()).isEqualTo(4); - } - } - - @Test - void testIfWithModel() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testIf").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "java", - new Task() - .withCallTask( - new CallTask() - .withCallFunction( - withPredicate( - CallJava.function( - CallTest::zeroWithModel, WorkflowModel.class), - CallTest::isOdd)))))); - WorkflowDefinition definition = app.workflowDefinition(workflow); - assertThat(definition.instance(3).start().get().asNumber().orElseThrow()).isEqualTo(0); - assertThat(definition.instance(4).start().get().asNumber().orElseThrow()).isEqualTo(4); - } - } - - private CallFunction withPredicate(CallFunction call, Predicate pred) { - return call.withMetadata( - new TaskMetadata().withAdditionalProperty(TypesUtils.IF_PREDICATE, pred)); - } - - public static boolean isEven(Object model, Integer number) { - return !isOdd(number); - } - - public static boolean isOdd(Integer number) { - return number % 2 != 0; - } - - public static int zero(Integer value) { - return 0; - } - - public static int zeroWithModel(WorkflowModel value) { - return 0; - } - - public static Integer sum(Object model, Integer item) { - return model instanceof Collection ? item : (Integer) model + item; - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/EventFilteringTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/EventFilteringTest.java deleted file mode 100644 index aefaeeb41..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/EventFilteringTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consume; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consumed; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.emitJson; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.listen; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.switchWhenOrElse; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.to; -import static org.awaitility.Awaitility.await; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.cloudevents.CloudEvent; -import io.cloudevents.CloudEventData; -import io.cloudevents.core.builder.CloudEventBuilder; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowInstance; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowStatus; -import io.serverlessworkflow.impl.events.EventPublisher; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import org.junit.jupiter.api.Test; - -public class EventFilteringTest { - - private static final ObjectMapper MAPPER = new ObjectMapper(); - - // --- Mock Service Methods (replacing Quarkus Agents) --- - public NewsletterDraft writeDraft(NewsletterRequest req) { - return new NewsletterDraft("Draft: " + req.topic(), "Initial body..."); - } - - public NewsletterDraft editDraft(HumanReview review) { - return new NewsletterDraft("Edited Draft", "Fixed based on: " + review.notes()); - } - - public void sendEmail(NewsletterDraft draft) { - // Simulates MailService.send - } - - @Test - public void testIntelligentNewsletterApprovalPath() throws Exception { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - - Workflow workflow = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks( - function("draftAgent", this::writeDraft).exportAsTaskOutput(), - emitJson("draftReady", "org.acme.email.review.required", NewsletterDraft.class), - listen( - "waitHumanReview", - to().one( - consumed("org.acme.newsletter.review.done") - .extensionByInstanceId("instanceid"))) - .outputAs( - (List events) -> { - try { - return MAPPER.readValue(events.get(0).toBytes(), HumanReview.class); - } catch (Exception e) { - throw new RuntimeException("Failed to deserialize HumanReview", e); - } - }), - switchWhenOrElse( - h -> HumanReview.NEEDS_REVISION.equals(h.status()), - "humanEditorAgent", - "sendNewsletter", - HumanReview.class), - function("humanEditorAgent", this::editDraft) - .exportAsTaskOutput() - .then("draftReady"), - consume("sendNewsletter", this::sendEmail) - .inputFrom( - (payload, wfc, tfc) -> - payload instanceof HumanReview ? wfc.context() : payload)) - .build(); - - WorkflowDefinition definition = app.workflowDefinition(workflow); - WorkflowInstance instance = definition.instance(new NewsletterRequest("Tech Stocks")); - CompletableFuture future = instance.start(); - - // Wait for it to hit the listen state - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.WAITING); - - EventPublisher publisher = app.eventPublishers().iterator().next(); - - // --- THE NEGATIVE TEST: Fire an event with the WRONG instance id --- - CloudEvent maliciousEvent = - CloudEventBuilder.v1() - .withId("event-wrong") - .withSource(URI.create("test:/human-editor")) - .withType("org.acme.newsletter.review.done") - .withExtension("instanceid", "SOME-OTHER-ID-12345") // Does not match instance.id() - .withData( - "application/json", - "{\"status\":\"APPROVED\", \"notes\":\"Malicious approval\"}" - .getBytes(StandardCharsets.UTF_8)) - .build(); - - publisher.publish(maliciousEvent).toCompletableFuture().join(); - - await() - .pollDelay(Duration.ofMillis(250)) - .atMost(Duration.ofMillis(500)) - .until(() -> instance.status() == WorkflowStatus.WAITING && !future.isDone()); - - // --- THE POSITIVE TEST: Fire the CORRECT event --- - CloudEvent humanReviewEvent = - CloudEventBuilder.v1() - .withId("event-123") - .withSource(URI.create("test:/human-editor")) - .withType("org.acme.newsletter.review.done") - .withExtension("instanceid", instance.id()) // Matches exactly - .withData( - "application/json", - "{\"status\":\"APPROVED\", \"notes\":\"Looks good\"}" - .getBytes(StandardCharsets.UTF_8)) - .build(); - - publisher.publish(humanReviewEvent).toCompletableFuture().join(); - - // Assert successful completion - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.COMPLETED); - } - } - - // --- Mock Domain Models --- - public record NewsletterRequest(String topic) {} - - public record NewsletterDraft(String title, String body) {} - - public record HumanReview(String status, String notes) { - public static final String NEEDS_REVISION = "NEEDS_REVISION"; - public static final String APPROVED = "APPROVED"; - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FluentDSLCallTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FluentDSLCallTest.java deleted file mode 100644 index 8abf5b464..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FluentDSLCallTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowInstance; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.jackson.JsonUtils; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import org.junit.jupiter.api.Test; - -public class FluentDSLCallTest { - - @Test - void testJavaFunction() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - final Workflow workflow = - FuncWorkflowBuilder.workflow("testJavaCall") - .tasks(tasks -> tasks.function(f -> f.function(JavaFunctions::getName))) - .build(); - assertThat( - app.workflowDefinition(workflow) - .instance(new Person("Francisco", 33)) - .start() - .get() - .asText() - .orElseThrow()) - .isEqualTo("Francisco Javierito"); - } - } - - @Test - void textExportFunction() { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - final Workflow workflow = - FuncWorkflowBuilder.workflow("testExportFunction") - .tasks( - function(JavaFunctions::getName, Person.class) - .exportAs( - (prevContext, w, t) -> t.output().asText().orElseThrow() + " Tirado")) - .build(); - WorkflowInstance instance = - app.workflowDefinition(workflow).instance(new Person("Francisco", 33)); - assertThat(instance.start().join().asText().orElseThrow()).isEqualTo("Francisco Javierito"); - assertThat(instance.context().asText().orElseThrow()).isEqualTo("Francisco Javierito Tirado"); - } - } - - @Test - void testForLoop() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow() - .tasks( - t -> - t.forEach( - f -> - f.whileC(CallTest::isEven) - .collection(v -> (Collection) v) - .tasks(CallTest::sum))) - .build(); - - assertThat( - app.workflowDefinition(workflow) - .instance(List.of(2, 4, 6)) - .start() - .get() - .asNumber() - .orElseThrow()) - .isEqualTo(12); - } - } - - @Test - void testSwitch() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow() - .tasks( - tasks -> - tasks - .switchCase( - switchOdd -> - switchOdd.onPredicate( - item -> - item.when(CallTest::isOdd).then(FlowDirectiveEnum.END))) - .function(callJava -> callJava.function(CallTest::zero))) - .build(); - - WorkflowDefinition definition = app.workflowDefinition(workflow); - assertThat(definition.instance(3).start().get().asNumber().orElseThrow()).isEqualTo(3); - assertThat(definition.instance(4).start().get().asNumber().orElseThrow()).isEqualTo(0); - } - } - - @Test - void set_with_map() { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow() - .tasks(f -> f.set(s -> s.expr(Map.of("message", "hello world!")))) - .build(); - - WorkflowDefinition workflowDefinition = app.workflowDefinition(workflow); - - Map output = - workflowDefinition.instance(Map.of()).start().join().asMap().orElseThrow(); - - assertEquals(Map.of("message", "hello world!"), output); - } - } - - @Test - void set_with_string() { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow() - .tasks(f -> f.set(s -> s.expr("{message:\"hello world!\"}"))) - .build(); - - WorkflowDefinition workflowDefinition = app.workflowDefinition(workflow); - - WorkflowModel model = workflowDefinition.instance(Map.of()).start().join(); - - assertEquals( - JsonUtils.mapper().createObjectNode().put("message", "hello world!"), - model.asJavaObject()); - } - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ForTaskFunctionRegressionTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ForTaskFunctionRegressionTest.java deleted file mode 100644 index c7b4fdeaa..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ForTaskFunctionRegressionTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.Document; -import io.serverlessworkflow.api.types.ForTask; -import io.serverlessworkflow.api.types.ForTaskConfiguration; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.api.types.func.CallJava; -import io.serverlessworkflow.api.types.utils.ForTaskFunction; -import io.serverlessworkflow.impl.WorkflowApplication; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ExecutionException; -import org.junit.jupiter.api.Test; - -class ForTaskFunctionRegressionTest { - - @Test - void forLoopWithExplicitCollectionClassExecutesSuccessfully() - throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - ForTaskConfiguration forConfig = new ForTaskConfiguration(); - ForTask forTask = - new ForTask() - .withDo( - List.of( - new TaskItem( - "javaCall", - new Task() - .withCallTask( - new CallTask() - .withCallFunction( - CallJava.loopFunction( - CallTest::sum, forConfig.getEach())))))); - ForTaskFunction.withWhile(forTask, CallTest::isEven); - ForTaskFunction.withCollection(forTask, v -> v, Collection.class); - Workflow workflow = - new Workflow() - .withDocument( - new Document() - .withNamespace("test") - .withName("loop-with-collection-class") - .withVersion("1.0")) - .withDo( - List.of( - new TaskItem("forLoop", new Task().withForTask(forTask.withFor(forConfig))))); - - var result = app.workflowDefinition(workflow).instance(List.of(2, 4, 6)).start().get(); - - assertThat(result.asNumber().orElseThrow()).isEqualTo(12); - } - } -} 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 deleted file mode 100644 index 7510eada9..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLDataFlowTransformationHelpersTest.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.input; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.output; - -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.WorkflowInstance; -import io.serverlessworkflow.impl.WorkflowModel; -import org.assertj.core.api.SoftAssertions; -import org.junit.jupiter.api.Test; - -public class FuncDSLDataFlowTransformationHelpersTest { - - @Test - void test_input_with_inputFrom() { - - SoftAssertions softly = new SoftAssertions(); - - Workflow workflow = - FuncWorkflowBuilder.workflow("reviewSubmissionWithModel") - .tasks( - function( - "add5", - (Long input) -> { - softly.assertThat(input).isEqualTo(10L); - return input + 5; - }), - function("returnEnriched", (Long enrichedValue) -> enrichedValue, Long.class) - .inputFrom( - (Long object, WorkflowContextData workflowContext) -> { - softly.assertThat(object).isEqualTo(15L); - Long input = input(workflowContext, Long.class); - softly.assertThat(input).isEqualTo(10L); - return object + input; - })) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition def = app.workflowDefinition(workflow); - WorkflowModel model = def.instance(10L).start().join(); - Number number = model.asNumber().orElseThrow(); - softly.assertThat(number.longValue()).isEqualTo(25L); - } - - softly.assertAll(); - } - - @Test - void test_input_with_outputAs() { - - SoftAssertions softly = new SoftAssertions(); - - Workflow workflow = - FuncWorkflowBuilder.workflow("enrichOutputWithModelTest") - .tasks( - function( - "add5", - (Long input) -> { - softly.assertThat(input).isEqualTo(10L); - return input + 5; - }, - Long.class) - .outputAs( - (object, workflowContext, taskContextData) -> { - softly.assertThat(object).isEqualTo(15L); - Long input = input(workflowContext, Long.class); - softly.assertThat(input).isEqualTo(10L); - return input + object; - }, - Long.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition def = app.workflowDefinition(workflow); - - WorkflowModel model = def.instance(10L).start().join(); - Number number = model.asNumber().orElseThrow(); - - softly.assertThat(number.longValue()).isEqualTo(25L); - } - - softly.assertAll(); - } - - @Test - void test_output_with_exportAs() { - - SoftAssertions softly = new SoftAssertions(); - - Workflow workflow = - FuncWorkflowBuilder.workflow("enrichOutputWithInputTest") - .tasks( - function( - "add5", - (Long input) -> { - softly.assertThat(input).isEqualTo(10L); - return input + 5; - }, - Long.class) - .exportAs( - (Long object, - WorkflowContextData workflowContext, - TaskContextData taskContextData) -> { - Long taskOutput = output(taskContextData, Long.class); - softly.assertThat(taskOutput).isEqualTo(15L); - return taskOutput * 2; - })) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition def = app.workflowDefinition(workflow); - WorkflowModel model = def.instance(10L).start().join(); - Number number = model.asNumber().orElseThrow(); - softly.assertThat(number.longValue()).isEqualTo(15L); - } - - softly.assertAll(); - } - - @Test - void test_input_with_inputFrom_fluent_way() { - SoftAssertions softly = new SoftAssertions(); - - Workflow workflow = - FuncWorkflowBuilder.workflow("enrichOutputWithInputTest") - .tasks( - function("sumFive", (Long input) -> input + 5, Long.class) - .inputFrom( - (object, workflowContext, taskContextData) -> - input(taskContextData, Long.class) * 2)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition def = app.workflowDefinition(workflow); - WorkflowModel model = def.instance(10L).start().join(); - Number number = model.asNumber().orElseThrow(); - - softly.assertThat(number.longValue()).isEqualTo(25L); - } - - softly.assertAll(); - } - - @Test - void test_input_with_exportAs() { - - SoftAssertions softly = new SoftAssertions(); - - Workflow workflow = - FuncWorkflowBuilder.workflow("enrichExportWithInputTest") - .tasks( - function( - "add5", - (Long input) -> { - softly.assertThat(input).isEqualTo(10L); - return input + 5; - }, - Long.class) - .exportAs( - (Long object, - WorkflowContextData workflowContext, - TaskContextData taskContextData) -> { - Long taskOutput = output(taskContextData, Long.class); - softly.assertThat(taskOutput).isEqualTo(15L); - Long input = input(workflowContext, Long.class); - softly.assertThat(input).isEqualTo(10L); - return input + taskOutput; - })) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition def = app.workflowDefinition(workflow); - - WorkflowInstance instance = def.instance(10L); - instance.start().join(); - Number number = instance.context().asNumber().orElseThrow(); - - softly.assertThat(number.longValue()).isEqualTo(25L); - } - - softly.assertAll(); - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLReflectionsTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLReflectionsTest.java deleted file mode 100644 index bdb959390..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/FuncDSLReflectionsTest.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.agent; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.switchWhenOrElse; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.withContext; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.withFilter; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.withInstanceId; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -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 java.util.Optional; -import org.junit.jupiter.api.Test; - -public class FuncDSLReflectionsTest { - - @Test - void check_serializable_function() { - Workflow wf = - FuncWorkflowBuilder.workflow("strip-function").tasks(function(String::strip)).build(); - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Optional output = - app.workflowDefinition(wf).instance("Hello World! ").start().join().asText(); - assertTrue(output.isPresent()); - assertEquals("Hello World!", output.get()); - } - } - - @Test - void check_serializable_function_with_non_serializable_capture() { - // 1. Create a clearly non-serializable object - class NonSerializableService { - String appendSuffix(String text) { - return text + " - Processed successfully"; - } - } - - NonSerializableService service = new NonSerializableService(); - - Workflow wf = - FuncWorkflowBuilder.workflow("capture-function") - .tasks(function(service::appendSuffix)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Optional output = - app.workflowDefinition(wf).instance("Test Input").start().join().asText(); - - assertTrue(output.isPresent()); - assertEquals("Test Input - Processed successfully", output.get()); - } - } - - @Test - void check_serializable_predicate_switch() { - Workflow wf = - FuncWorkflowBuilder.workflow("predicate-test") - .tasks( - // Infers Integer.class automatically - switchWhenOrElse((Integer v) -> v > 10, "highValueTask", FlowDirectiveEnum.END), - // Only executes if > 10 - function("highValueTask", (Integer v) -> v * 2)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - // Test True path - Optional highOutput = - app.workflowDefinition(wf).instance(15).start().join().as(Integer.class); - - assertTrue(highOutput.isPresent()); - assertEquals(30, highOutput.get()); - - // Test False path (ends immediately, returning original input) - Optional lowOutput = - app.workflowDefinition(wf).instance(5).start().join().as(Integer.class); - - assertTrue(lowOutput.isPresent()); - assertEquals(5, lowOutput.get()); - } - } - - @Test - void check_serializable_unique_id_bifunction() { - Workflow wf = - FuncWorkflowBuilder.workflow("agent-unique-id-test") - .tasks( - // Infers String.class for the payload (the second parameter) - agent( - (String uniqueId, Integer payload) -> - "ID=[" + uniqueId + "] Payload=[" + payload + "]")) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Optional output = app.workflowDefinition(wf).instance(123).start().join().asText(); - - assertTrue(output.isPresent()); - // The uniqueId should contain the workflow instance ID and the JSON pointer - assertTrue(output.get().contains("ID=[")); - assertTrue(output.get().contains("] Payload=[123]")); - } - } - - @Test - void check_serializable_java_context_function() { - Workflow wf = - FuncWorkflowBuilder.workflow("context-function-test") - .tasks( - // Infers String.class for the payload (the first parameter) - withContext( - (String payload, WorkflowContextData wctx) -> - payload + " processed by " + wctx.instanceData().id())) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Optional output = - app.workflowDefinition(wf).instance("Context Data").start().join().asText(); - - assertTrue(output.isPresent()); - assertTrue(output.get().startsWith("Context Data processed by ")); - } - } - - @Test - void check_serializable_java_filter_function() { - Workflow wf = - FuncWorkflowBuilder.workflow("filter-function-test") - .tasks( - // Infers String.class for the payload (the first parameter) - withFilter( - (String payload, WorkflowContextData wctx, TaskContextData tctx) -> - payload + " at position " + tctx.position().jsonPointer())) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Optional output = - app.workflowDefinition(wf).instance("Filter Data").start().join().asText(); - - assertTrue(output.isPresent()); - // It should append the task JSON pointer (likely "/tasks/0" or similar depending on spec) - assertTrue(output.get().startsWith("Filter Data at position do/")); - } - } - - @Test - void check_serializable_instance_id_function() { - Workflow wf = - FuncWorkflowBuilder.workflow("instance-id-test") - .tasks( - // Infers Integer.class for the payload (the second parameter) - withInstanceId( - "", - (String instanceId, Integer payload) -> - "Instance=[" + instanceId + "] Payload=[" + payload + "]")) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Optional output = app.workflowDefinition(wf).instance(456).start().join().asText(); - - assertTrue(output.isPresent()); - // The instanceId should be populated automatically by the workflow runtime - assertTrue(output.get().contains("Instance=[")); - assertTrue(output.get().contains("] Payload=[456]")); - } - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/JavaFunctions.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/JavaFunctions.java deleted file mode 100644 index 17bf9dfd5..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/JavaFunctions.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import io.serverlessworkflow.impl.TaskContextData; -import io.serverlessworkflow.impl.WorkflowContextData; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -public class JavaFunctions { - - static Person personPojo(String name) { - return new Person(name + " Javierito", 23); - } - - static String getName(Person person) { - return person.name() + " Javierito"; - } - - static CompletableFuture getNameFuture(Person person) { - return CompletableFuture.completedFuture(getName(person)); - } - - static CompletableFuture getNameStringBuilder(Person person) { - StringBuilder sb = new StringBuilder(person.name()); - sb.append(" Javierito"); - return CompletableFuture.completedFuture(sb); - } - - static String getFilterName( - Person person, WorkflowContextData workflowContext, TaskContextData taskContext) { - return person.name() + "_" + workflowContext.instanceData().id() + "_" + taskContext.taskName(); - } - - static String getContextName(Person person, WorkflowContextData workflowContext) { - return person.name() + "_" + workflowContext.instanceData().id(); - } - - static Map addJavierito(Map map) { - return Map.of("name", map.get("name") + " Javierito"); - } - - static String addJavieritoString(String value) { - return value + " Javierito"; - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ListenUntilCurrentTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ListenUntilCurrentTest.java deleted file mode 100644 index 32cc57afe..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ListenUntilCurrentTest.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.listen; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.toAny; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowInstance; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowModelCollection; -import io.serverlessworkflow.impl.WorkflowStatus; -import io.serverlessworkflow.impl.events.EventPublisher; -import java.net.URI; -import java.time.Duration; -import java.util.concurrent.CompletableFuture; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ListenUntilCurrentTest { - - private static final Logger log = LoggerFactory.getLogger(ListenUntilCurrentTest.class); - private static final ObjectMapper MAPPER = new ObjectMapper(); - - private CloudEvent createOrderEvent(String instanceId, int orderNum) { - Order order = new Order("order-" + orderNum, "PENDING", 100.0 * orderNum); - try { - return CloudEventBuilder.v1() - .withId("event-" + orderNum) - .withSource(URI.create("test:/orders")) - .withType("order.created") - .withExtension("instanceid", instanceId) - .withData("application/json", MAPPER.writeValueAsBytes(order)) - .build(); - } catch (Exception e) { - throw new RuntimeException("Failed to create order event", e); - } - } - - @Test - public void testCurrentToAnyWithUntilExpression() throws Exception { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow("test-toany-until") - .tasks( - listen( - "waitOrders", - toAny("order.created") - .until( - (WorkflowModelCollection events) -> { - log.info("Predicate called!"); - log.info(" Param type: {}", events.getClass().getName()); - log.info(" Param value: {}", events); - log.info(" Event count: {}", (long) events.size()); - boolean result = (long) events.size() >= 3; - log.info(" Returning: {}", result); - return result; - }, - WorkflowModelCollection.class))) - .build(); - - WorkflowDefinition definition = app.workflowDefinition(workflow); - WorkflowInstance instance = definition.instance(new Object()); - CompletableFuture future = instance.start(); - - // Wait for WAITING status - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.WAITING); - - EventPublisher publisher = app.eventPublishers().iterator().next(); - - // Emit 3 order events - log.info("Publishing event 1..."); - publisher.publish(createOrderEvent(instance.id(), 1)).toCompletableFuture().join(); - - log.info("Publishing event 2..."); - publisher.publish(createOrderEvent(instance.id(), 2)).toCompletableFuture().join(); - - log.info("Publishing event 3..."); - publisher.publish(createOrderEvent(instance.id(), 3)).toCompletableFuture().join(); - - // Workflow should complete after 3 events - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.COMPLETED); - - WorkflowModel result = future.join(); - long count = ((WorkflowModelCollection) result).size(); - log.info("Workflow completed with {} items", count); - assertEquals(3, count); - } - } - - @Test - public void testToAnyWithUntilContextPredicate() { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow("test-toany-until-context") - .tasks( - listen( - "waitOrders", - toAny("order.created") - .until( - (events, context) -> { - log.info("ContextPredicate called!"); - log.info(" Events count: {}", (long) events.size()); - assertNotNull(context); - log.info(" Context instance id: {}", context.instanceData().id()); - // Stop after 2 events - return (long) events.size() >= 2; - }, - WorkflowModelCollection.class))) - .build(); - - WorkflowDefinition definition = app.workflowDefinition(workflow); - WorkflowInstance instance = definition.instance(new Object()); - CompletableFuture future = instance.start(); - - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.WAITING); - - EventPublisher publisher = app.eventPublishers().iterator().next(); - - log.info("Publishing event 1..."); - publisher.publish(createOrderEvent(instance.id(), 1)).toCompletableFuture().join(); - - log.info("Publishing event 2..."); - publisher.publish(createOrderEvent(instance.id(), 2)).toCompletableFuture().join(); - - // Should complete after 2 events - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.COMPLETED); - - WorkflowModel result = future.join(); - long count = ((WorkflowModelCollection) result).size(); - log.info("Workflow completed with {} items", count); - assertEquals(2, count); - } - } - - @Test - public void testToAnyWithUntilFilterPredicate() { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow("test-toany-until-filter") - .tasks( - listen( - "waitOrders", - toAny("order.created") - .until( - (events, workflowCtx, taskCtx) -> { - log.info("FilterPredicate called!"); - log.info(" Events count: {}", (long) events.size()); - assertNotNull(workflowCtx); - assertNotNull(taskCtx); - log.info(" Task position: {}", taskCtx.position()); - return (long) events.size() >= 3; - }, - WorkflowModelCollection.class))) - .build(); - - WorkflowDefinition definition = app.workflowDefinition(workflow); - WorkflowInstance instance = definition.instance(new Object()); - CompletableFuture future = instance.start(); - - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.WAITING); - - EventPublisher publisher = app.eventPublishers().iterator().next(); - - log.info("Publishing event 1..."); - publisher.publish(createOrderEvent(instance.id(), 1)).toCompletableFuture().join(); - - log.info("Publishing event 2..."); - publisher.publish(createOrderEvent(instance.id(), 2)).toCompletableFuture().join(); - - log.info("Publishing event 3..."); - publisher.publish(createOrderEvent(instance.id(), 3)).toCompletableFuture().join(); - - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.COMPLETED); - - WorkflowModel result = future.join(); - long count = ((WorkflowModelCollection) result).size(); - log.info("Workflow completed with {} items", count); - assertEquals(3, count); - } - } - - public record Order(String id, String status, double amount) {} -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ListenUntilValidationTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ListenUntilValidationTest.java deleted file mode 100644 index f2f629f3d..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ListenUntilValidationTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.*; -import static org.junit.jupiter.api.Assertions.*; - -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import org.junit.jupiter.api.Test; - -public class ListenUntilValidationTest { - - @Test - public void testUntilWithAllThrowsException() { - IllegalArgumentException exception = - assertThrows( - IllegalArgumentException.class, - () -> { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow("test-all-until-invalid") - .tasks( - listen( - "waitOrders", - toAll("order.created") - .until( - (io.serverlessworkflow.impl.WorkflowModelCollection - events) -> events.stream().count() >= 3, - io.serverlessworkflow.impl.WorkflowModelCollection.class))) - .build(); - - app.workflowDefinition(workflow); - } - }); - - assertTrue(exception.getMessage().contains("until() is only supported with any()")); - assertTrue(exception.getMessage().contains("ALL")); - } - - @Test - public void testUntilWithOneThrowsException() { - IllegalArgumentException exception = - assertThrows( - IllegalArgumentException.class, - () -> { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow("test-one-until-invalid") - .tasks( - listen( - "waitOrders", - toOne("order.created") - .until( - (io.serverlessworkflow.impl.WorkflowModelCollection - events) -> events.stream().count() >= 3, - io.serverlessworkflow.impl.WorkflowModelCollection.class))) - .build(); - - app.workflowDefinition(workflow); - } - }); - - assertTrue(exception.getMessage().contains("until() is only supported with any()")); - assertTrue(exception.getMessage().contains("ONE")); - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ModelTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ModelTest.java deleted file mode 100644 index 7e922981a..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/ModelTest.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.api.types.Document; -import io.serverlessworkflow.api.types.DurationInline; -import io.serverlessworkflow.api.types.Output; -import io.serverlessworkflow.api.types.OutputAs; -import io.serverlessworkflow.api.types.Set; -import io.serverlessworkflow.api.types.SetTask; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import io.serverlessworkflow.api.types.TimeoutAfter; -import io.serverlessworkflow.api.types.WaitTask; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.utils.MapSetTaskConfiguration; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowInstance; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.function.Function; -import org.junit.jupiter.api.Test; - -class ModelTest { - - @Test - void testStringExpression() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testString").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "doNothing", - new Task() - .withWaitTask( - new WaitTask() - .withWait( - new TimeoutAfter() - .withDurationInline( - new DurationInline().withMilliseconds(10))))))) - .withOutput( - new Output() - .withAs( - new OutputAs() - .withObject( - (Function) JavaFunctions::addJavieritoString))); - - assertThat( - app.workflowDefinition(workflow) - .instance("Francisco") - .start() - .get() - .asText() - .orElseThrow()) - .isEqualTo("Francisco Javierito"); - } - } - - @Test - void testMapExpression() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testMap").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "javierito", - new Task() - .withSetTask( - new SetTask() - .withSet( - new Set() - .withSetTaskConfiguration( - MapSetTaskConfiguration.map( - Map.of("name", "Francisco")))) - .withOutput( - new Output() - .withAs( - new OutputAs() - .withObject( - (Function) - JavaFunctions::addJavierito))))))); - assertThat( - app.workflowDefinition(workflow) - .instance(Map.of()) - .start() - .get() - .asMap() - .map(m -> m.get("name")) - .orElseThrow()) - .isEqualTo("Francisco Javierito"); - } - } - - @Test - void testStringPOJOExpression() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testPojo").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "doNothing", - new Task() - .withWaitTask( - new WaitTask() - .withWait( - new TimeoutAfter() - .withDurationInline( - new DurationInline().withMilliseconds(10))))))) - .withOutput( - new Output() - .withAs( - new OutputAs() - .withObject((Function) JavaFunctions::personPojo))); - - assertThat( - app.workflowDefinition(workflow) - .instance("Francisco") - .start() - .get() - .as(Person.class) - .orElseThrow() - .name()) - .isEqualTo("Francisco Javierito"); - } - } - - @Test - void testPOJOStringExpression() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testPojo").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "doNothing", - new Task() - .withWaitTask( - new WaitTask() - .withWait( - new TimeoutAfter() - .withDurationInline( - new DurationInline().withMilliseconds(10))))))) - .withOutput( - new Output() - .withAs( - new OutputAs() - .withObject((Function) JavaFunctions::getName))); - - assertThat( - app.workflowDefinition(workflow) - .instance(new Person("Francisco", 33)) - .start() - .get() - .asText() - .orElseThrow()) - .isEqualTo("Francisco Javierito"); - } - } - - @Test - void testPOJOStringExpressionWithContext() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testPojo").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "doNothing", - new Task() - .withWaitTask( - new WaitTask() - .withWait( - new TimeoutAfter() - .withDurationInline( - new DurationInline().withMilliseconds(10))))))) - .withOutput( - new Output() - .withAs( - new OutputAs() - .withObject( - (ContextFunction) - JavaFunctions::getContextName))); - WorkflowInstance instance = - app.workflowDefinition(workflow).instance(new Person("Francisco", 33)); - assertThat(instance.start().get().asText().orElseThrow()) - .isEqualTo("Francisco_" + instance.id()); - } - } - - @Test - void testPOJOStringExpressionWithFilter() throws InterruptedException, ExecutionException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - new Workflow() - .withDocument( - new Document().withNamespace("test").withName("testPojo").withVersion("1.0")) - .withDo( - List.of( - new TaskItem( - "doNothing", - new Task() - .withWaitTask( - new WaitTask() - .withOutput( - new Output() - .withAs( - new OutputAs() - .withObject( - (FilterFunction) - JavaFunctions::getFilterName))) - .withWait( - new TimeoutAfter() - .withDurationInline( - new DurationInline().withMilliseconds(10))))))); - WorkflowInstance instance = - app.workflowDefinition(workflow).instance(new Person("Francisco", 33)); - assertThat(instance.start().get().asText().orElseThrow()) - .isEqualTo("Francisco_" + instance.id() + "_doNothing"); - } - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/Person.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/Person.java deleted file mode 100644 index b0b891fe3..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/Person.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -record Person(String name, int age) {} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/StringBuilder2String.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/StringBuilder2String.java deleted file mode 100644 index 24caaedf9..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/StringBuilder2String.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import io.serverlessworkflow.impl.executors.func.DataTypeConverter; - -public class StringBuilder2String implements DataTypeConverter { - - @Override - public String apply(StringBuilder t) { - return t.toString(); - } - - @Override - public Class sourceType() { - return StringBuilder.class; - } - - @Override - public Class targetType() { - return String.class; - } -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/WorkflowNumberConversionTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/WorkflowNumberConversionTest.java deleted file mode 100644 index c0b422b38..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/WorkflowNumberConversionTest.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; - -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowModel; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.function.Function; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class WorkflowNumberConversionTest { - - @Test - void integer_score_from_task_output_is_compatible_with_outputAs_integer_class() { - Workflow workflow = - FuncWorkflowBuilder.workflow("numbers") - .tasks( - function( - "scoreProposal", - (Proposal input) -> { - Integer score = calculateScore(input.abstractText()); - return score; - }, - Proposal.class) - .outputAs( - (Integer score) -> new ProposalScore(score, score >= 7), Integer.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = - app.workflowDefinition(workflow) - .instance(new Proposal("Workflow, workflow, workflow...")) - .start() - .join(); - Assertions.assertNotNull(model); - ProposalScore result = model.as(ProposalScore.class).orElseThrow(); - Assertions.assertEquals(10, result.score()); - Assertions.assertTrue(result.accepted()); - } - } - - @Test - void long_to_integer_conversion() { - Workflow workflow = - FuncWorkflowBuilder.workflow("longToInt") - .tasks( - function("convertLong", Function.identity(), Long.class) - .outputAs((Integer result) -> result * 2, Integer.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance(100L).start().join(); - Integer result = model.as(Integer.class).orElseThrow(); - Assertions.assertEquals(200, result); - } - } - - @Test - void integer_to_long_conversion() { - Workflow workflow = - FuncWorkflowBuilder.workflow("intToLong") - .tasks( - function("convertInt", Function.identity(), Integer.class) - .outputAs((Long result) -> result * 3L, Long.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance(50).start().join(); - Long result = model.as(Long.class).orElseThrow(); - Assertions.assertEquals(150L, result); - } - } - - @Test - void integer_to_big_integer_conversion() { - Workflow workflow = - FuncWorkflowBuilder.workflow("integerToBigInteger") - .tasks( - function("convertInt", Function.identity(), Integer.class) - .outputAs( - (BigInteger result) -> result.multiply(BigInteger.valueOf(3)), - BigInteger.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance(50).start().join(); - BigInteger result = model.as(BigInteger.class).orElseThrow(); - Assertions.assertEquals(BigInteger.valueOf(150), result); - } - } - - @Test - void double_to_integer_conversion() { - Workflow workflow = - FuncWorkflowBuilder.workflow("doubleToInt") - .tasks( - function("convertDouble", Function.identity(), Double.class) - .outputAs((Integer result) -> result + 5, Integer.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance(42.7).start().join(); - Integer result = model.as(Integer.class).orElseThrow(); - Assertions.assertEquals(47, result); - } - } - - @Test - void double_to_big_decimal_conversion() { - Workflow workflow = - FuncWorkflowBuilder.workflow("doubleToInt") - .tasks( - function("convertDouble", Function.identity(), Double.class) - .outputAs( - (BigDecimal result) -> result.add(BigDecimal.valueOf(5)), BigDecimal.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance(42.7).start().join(); - BigDecimal result = model.as(BigDecimal.class).orElseThrow(); - Assertions.assertEquals(BigDecimal.valueOf(47.7), result); - } - } - - @Test - void float_to_double_conversion() { - Workflow workflow = - FuncWorkflowBuilder.workflow("floatToDouble") - .tasks( - function("convertFloat", Function.identity(), Float.class) - .outputAs((Double result) -> result * 1.5, Double.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance(10.0f).start().join(); - Double result = model.as(Double.class).orElseThrow(); - Assertions.assertEquals(15.0, result, 0.001); - } - } - - @Test - void short_to_integer_conversion() { - Workflow workflow = - FuncWorkflowBuilder.workflow("shortToInt") - .tasks( - function("convertShort", (Short input) -> input.intValue(), Short.class) - .outputAs((Integer result) -> result * 10, Integer.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance((short) 5).start().join(); - Integer result = model.as(Integer.class).orElseThrow(); - Assertions.assertEquals(50, result); - } - } - - @Test - void byte_to_integer_conversion() { - Workflow workflow = - FuncWorkflowBuilder.workflow("byteToInt") - .tasks( - function("convertByte", Function.identity(), Byte.class) - .outputAs((Integer result) -> result + 100, Integer.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance((byte) 25).start().join(); - Integer result = model.as(Integer.class).orElseThrow(); - Assertions.assertEquals(125, result); - } - } - - @Test - void number_conversion_with_string_output() { - // This verifies that model.as(Integer.class) (via asNumber(Integer.class)) returns - // Optional.empty() - Workflow workflow = - FuncWorkflowBuilder.workflow("stringOutput") - .tasks(function("returnString", (Integer input) -> "result: " + input, Integer.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowModel model = app.workflowDefinition(workflow).instance(42).start().join(); - Assertions.assertTrue(model.as(Integer.class).isEmpty()); - Assertions.assertEquals("result: 42", model.as(String.class).orElseThrow()); - } - } - - private Integer calculateScore(String abstractText) { - return abstractText.contains("Workflow") ? 10 : 5; - } - - public record ProposalScore(Integer score, boolean accepted) {} - - public record Proposal(String abstractText) {} -} diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/WorkflowThenTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/WorkflowThenTest.java deleted file mode 100644 index 7940eee71..000000000 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/executors/func/WorkflowThenTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverless.workflow.impl.executors.func; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consume; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; - -import io.serverlessworkflow.api.types.FlowDirectiveEnum; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowModel; -import java.util.Arrays; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class WorkflowThenTest { - - private static final Logger log = LoggerFactory.getLogger(WorkflowThenTest.class); - - @Test - void consume_then_skips_next_task_and_jumps_to_target() { - - Workflow wf = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks( - consume("sendNewsletter", input -> log.debug("Consuming: {}", input)) - .then("otherTask"), - function("nextTask", v -> "nextTask: " + v, String.class), - function("otherTask", v -> "otherTask: " + v, String.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition def = app.workflowDefinition(wf); - WorkflowModel model = def.instance("hello newsletter").start().join(); - - String output = model.asText().orElseThrow(); - Assertions.assertEquals("otherTask: hello newsletter", output); - } - } - - @Test - void function_then_skips_next_task_and_jumps_to_target() { - - Workflow wf = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks( - function("arrayFromString", input -> input.split(","), String.class) - .then("otherTask"), - function("nextTask", arr -> "nextTask: " + Arrays.toString(arr), String[].class), - function("otherTask", arr -> "otherTask: " + Arrays.toString(arr), String[].class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition def = app.workflowDefinition(wf); - String output = def.instance("hello,from,cncf").start().join().asText().orElseThrow(); - - Assertions.assertEquals("otherTask: [hello, from, cncf]", output); - } - } - - @Test - void function_then_end_directive_stops_workflow_execution() { - - Workflow wf = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks( - function("uppercase", String::toUpperCase, String.class) - .then(FlowDirectiveEnum.END), - function("lowercase", String::toLowerCase, String.class)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition def = app.workflowDefinition(wf); - String output = - def.instance("Hello Alice, Hello Bob, Hello Everyone!") - .start() - .join() - .asText() - .orElseThrow(); - - Assertions.assertEquals("HELLO ALICE, HELLO BOB, HELLO EVERYONE!", output); - } - } -} diff --git a/experimental/lambda/src/test/resources/META-INF/services/io.serverlessworkflow.impl.executors.func.DataTypeConverter b/experimental/lambda/src/test/resources/META-INF/services/io.serverlessworkflow.impl.executors.func.DataTypeConverter deleted file mode 100644 index c3cb695ad..000000000 --- a/experimental/lambda/src/test/resources/META-INF/services/io.serverlessworkflow.impl.executors.func.DataTypeConverter +++ /dev/null @@ -1 +0,0 @@ -io.serverless.workflow.impl.executors.func.StringBuilder2String \ No newline at end of file diff --git a/experimental/model/pom.xml b/experimental/model/pom.xml deleted file mode 100644 index ca71d249a..000000000 --- a/experimental/model/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental - 8.0.0-SNAPSHOT - - serverlessworkflow-experimental-model - Serverless Workflow :: Experimental :: Model - - - io.serverlessworkflow - serverlessworkflow-impl-core - - - org.junit.jupiter - junit-jupiter-engine - - - org.assertj - assertj-core - - - ch.qos.logback - logback-classic - - - \ No newline at end of file diff --git a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModel.java b/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModel.java deleted file mode 100644 index 506663b62..000000000 --- a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModel.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import io.serverlessworkflow.impl.AbstractWorkflowModel; -import io.serverlessworkflow.impl.WorkflowModel; -import java.time.OffsetDateTime; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -public class JavaModel extends AbstractWorkflowModel { - - protected Object object; - - public JavaModel(Object object) { - this.object = asJavaObject(object); - } - - protected void setObject(Object object) { - this.object = object; - } - - @Override - public Optional asBoolean() { - return object instanceof Boolean value ? Optional.of(value) : Optional.empty(); - } - - @Override - public Collection asCollection() { - return object instanceof Collection value - ? new JavaModelCollection(value) - : Collections.emptyList(); - } - - @Override - public Optional asText() { - return object instanceof String value ? Optional.of(value) : Optional.empty(); - } - - @Override - public Optional asDate() { - return object instanceof OffsetDateTime value ? Optional.of(value) : Optional.empty(); - } - - @Override - public Optional asNumber() { - return object instanceof Number value ? Optional.of(value) : Optional.empty(); - } - - @Override - protected Optional asNumber(Class targetNumberClass) { - return object instanceof Number num ? asSubclass(num, targetNumberClass) : Optional.empty(); - } - - @Override - public Optional> asMap() { - return object instanceof Map ? Optional.of((Map) object) : Optional.empty(); - } - - @Override - public Object asJavaObject() { - return object; - } - - static Object asJavaObject(Object object) { - if (object instanceof WorkflowModel model) { - return model.asJavaObject(); - } else if (object instanceof Map map) { - return ((Map) map) - .entrySet().stream() - .collect(Collectors.toMap(Entry::getKey, e -> asJavaObject(e.getValue()))); - } else if (object instanceof Collection col) { - return col.stream().map(JavaModel::asJavaObject).collect(Collectors.toList()); - } else { - return object; - } - } - - @Override - public Class objectClass() { - return object != null ? object.getClass() : Object.class; - } - - @Override - protected Optional convert(Class clazz) { - return object != null && clazz.isAssignableFrom(object.getClass()) - ? Optional.of(clazz.cast(object)) - : Optional.empty(); - } - - @Override - public int hashCode() { - return Objects.hash(object); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - JavaModel other = (JavaModel) obj; - return Objects.equals(object, other.object); - } -} diff --git a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelCollection.java b/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelCollection.java deleted file mode 100644 index 469b4c9a8..000000000 --- a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelCollection.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import io.serverlessworkflow.impl.CollectionConversionUtils; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowModelCollection; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -public class JavaModelCollection implements Collection, WorkflowModelCollection { - - protected final Collection object; - - protected JavaModelCollection() { - this.object = new ArrayList<>(); - } - - protected JavaModelCollection(Collection object) { - this.object = (Collection) JavaModel.asJavaObject(object); - } - - @Override - public int size() { - return object.size(); - } - - @Override - public boolean isEmpty() { - return object.isEmpty(); - } - - @Override - public boolean contains(Object o) { - throw new UnsupportedOperationException("contains() is not supported yet"); - } - - private class ModelIterator implements Iterator { - - private Iterator wrapped; - - public ModelIterator(Iterator wrapped) { - this.wrapped = wrapped; - } - - @Override - public boolean hasNext() { - return wrapped.hasNext(); - } - - @Override - public WorkflowModel next() { - Object obj = wrapped.next(); - return obj instanceof WorkflowModel value ? value : nextItem(obj); - } - } - - protected WorkflowModel nextItem(Object obj) { - return new JavaModel(obj); - } - - @Override - public Iterator iterator() { - return new ModelIterator(object.iterator()); - } - - private List toModelList() { - List models = new ArrayList<>(object.size()); - for (Object obj : object) - models.add(obj instanceof WorkflowModel value ? value : nextItem(obj)); - - return models; - } - - @Override - public Object[] toArray() { - return toModelList().toArray(); - } - - @Override - public T[] toArray(T[] a) { - return toModelList().toArray(a); - } - - @Override - public boolean add(WorkflowModel e) { - return object.add(e.asJavaObject()); - } - - @Override - public boolean remove(Object o) { - return object.remove(((WorkflowModel) o).asJavaObject()); - } - - @Override - public boolean containsAll(Collection c) { - throw new UnsupportedOperationException("containsAll is not supported yet"); - } - - @Override - public boolean addAll(Collection c) { - int size = size(); - c.forEach(this::add); - return size() > size; - } - - @Override - public boolean removeAll(Collection c) { - int size = size(); - c.forEach(this::remove); - return size() < size; - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException("retainAll() is not supported yet"); - } - - @Override - public void clear() { - object.clear(); - } - - @Override - public Object asJavaObject() { - return object; - } - - @Override - public Class objectClass() { - return object.getClass(); - } - - @Override - public Optional as(Class clazz) { - if (object == null) return Optional.empty(); - - if (clazz.isInstance(this)) return Optional.of(clazz.cast(this)); - if (clazz.isInstance(object)) return Optional.of(clazz.cast(object)); - - return CollectionConversionUtils.as(object, clazz); - } - - @Override - public int hashCode() { - return Objects.hash(object); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!(obj instanceof JavaModelCollection)) return false; - JavaModelCollection other = (JavaModelCollection) obj; - return Objects.equals(object, other.object); - } -} diff --git a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelCollectionMarshaller.java b/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelCollectionMarshaller.java deleted file mode 100644 index 385e197f3..000000000 --- a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelCollectionMarshaller.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import io.serverlessworkflow.impl.marshaller.CustomObjectMarshaller; -import io.serverlessworkflow.impl.marshaller.WorkflowInputBuffer; -import io.serverlessworkflow.impl.marshaller.WorkflowOutputBuffer; -import java.util.Collection; - -public class JavaModelCollectionMarshaller implements CustomObjectMarshaller { - - @Override - public void write(WorkflowOutputBuffer buffer, JavaModelCollection object) { - buffer.writeObject(object.asJavaObject()); - } - - @Override - public JavaModelCollection read( - WorkflowInputBuffer buffer, Class clazz) { - return new JavaModelCollection((Collection) buffer.readObject()); - } - - @Override - public Class getObjectClass() { - return JavaModelCollection.class; - } - - @Override - public int priority() { - return Integer.MAX_VALUE; - } -} diff --git a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelFactory.java b/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelFactory.java deleted file mode 100644 index c66335e7c..000000000 --- a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelFactory.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import io.cloudevents.CloudEvent; -import io.cloudevents.CloudEventData; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowModelCollection; -import io.serverlessworkflow.impl.WorkflowModelFactory; -import java.time.OffsetDateTime; -import java.util.Map; - -public class JavaModelFactory implements WorkflowModelFactory { - private final JavaModel TrueModel = new JavaModel(Boolean.TRUE); - private final JavaModel FalseModel = new JavaModel(Boolean.FALSE); - private final JavaModel NullModel = new JavaModel(null); - - @Override - public WorkflowModel combine(Map workflowVariables) { - return new JavaModel(workflowVariables); - } - - @Override - public WorkflowModelCollection createCollection() { - return new JavaModelCollection(); - } - - @Override - public WorkflowModel from(boolean value) { - return value ? TrueModel : FalseModel; - } - - @Override - public WorkflowModel from(Number value) { - return new JavaModel(value); - } - - @Override - public WorkflowModel from(String value) { - return new JavaModel(value); - } - - @Override - public WorkflowModel from(CloudEvent ce) { - return new JavaModel(ce); - } - - @Override - public WorkflowModel from(CloudEventData ce) { - return new JavaModel(ce); - } - - @Override - public WorkflowModel from(OffsetDateTime value) { - return new JavaModel(value); - } - - @Override - public WorkflowModel from(Map map) { - return new JavaModel(map); - } - - @Override - public WorkflowModel fromNull() { - return NullModel; - } - - @Override - public WorkflowModel fromOther(Object obj) { - return new JavaModel(obj); - } - - @Override - public int priority() { - return DEFAULT_PRIORITY + 10; - } -} diff --git a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelMarshaller.java b/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelMarshaller.java deleted file mode 100644 index bf279f8bf..000000000 --- a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/JavaModelMarshaller.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import io.serverlessworkflow.impl.marshaller.CustomObjectMarshaller; -import io.serverlessworkflow.impl.marshaller.WorkflowInputBuffer; -import io.serverlessworkflow.impl.marshaller.WorkflowOutputBuffer; - -public class JavaModelMarshaller implements CustomObjectMarshaller { - - @Override - public void write(WorkflowOutputBuffer buffer, JavaModel object) { - buffer.writeObject(object.asJavaObject()); - } - - @Override - public JavaModel read(WorkflowInputBuffer buffer, Class clazz) { - return new JavaModel(buffer.readObject()); - } - - @Override - public Class getObjectClass() { - return JavaModel.class; - } - - @Override - public int priority() { - return Integer.MAX_VALUE; - } -} diff --git a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/SerializableObjectMarshaller.java b/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/SerializableObjectMarshaller.java deleted file mode 100644 index 33eeeea8c..000000000 --- a/experimental/model/src/main/java/io/serverlessworkflow/impl/model/func/SerializableObjectMarshaller.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import io.serverlessworkflow.impl.marshaller.CustomObjectMarshaller; -import io.serverlessworkflow.impl.marshaller.WorkflowInputBuffer; -import io.serverlessworkflow.impl.marshaller.WorkflowOutputBuffer; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.io.UncheckedIOException; - -public class SerializableObjectMarshaller implements CustomObjectMarshaller { - - @Override - public void write(WorkflowOutputBuffer buffer, Serializable object) { - try (ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(bytesOut)) { - out.writeObject(object); - buffer.writeBytes(bytesOut.toByteArray()); - } catch (IOException io) { - throw new UncheckedIOException(io); - } - } - - @Override - public Serializable read(WorkflowInputBuffer buffer, Class objectClass) { - try (ByteArrayInputStream bytesIn = new ByteArrayInputStream(buffer.readBytes()); - ObjectInputStream in = new ObjectInputStream(bytesIn)) { - return objectClass.cast(in.readObject()); - } catch (IOException io) { - throw new UncheckedIOException(io); - } catch (ClassNotFoundException ex) { - throw new IllegalStateException(ex); - } - } - - @Override - public Class getObjectClass() { - return Serializable.class; - } - - @Override - public int priority() { - return Integer.MAX_VALUE; - } -} diff --git a/experimental/model/src/main/resources/META-INF/services/io.serverlessworkflow.impl.WorkflowModelFactory b/experimental/model/src/main/resources/META-INF/services/io.serverlessworkflow.impl.WorkflowModelFactory deleted file mode 100644 index 4b198a4d2..000000000 --- a/experimental/model/src/main/resources/META-INF/services/io.serverlessworkflow.impl.WorkflowModelFactory +++ /dev/null @@ -1 +0,0 @@ -io.serverlessworkflow.impl.model.func.JavaModelFactory \ No newline at end of file diff --git a/experimental/model/src/main/resources/META-INF/services/io.serverlessworkflow.impl.marshaller.CustomObjectMarshaller b/experimental/model/src/main/resources/META-INF/services/io.serverlessworkflow.impl.marshaller.CustomObjectMarshaller deleted file mode 100644 index b79cfb3e5..000000000 --- a/experimental/model/src/main/resources/META-INF/services/io.serverlessworkflow.impl.marshaller.CustomObjectMarshaller +++ /dev/null @@ -1,3 +0,0 @@ -io.serverlessworkflow.impl.model.func.JavaModelMarshaller -io.serverlessworkflow.impl.model.func.JavaModelCollectionMarshaller -io.serverlessworkflow.impl.model.func.SerializableObjectMarshaller \ No newline at end of file diff --git a/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/Address.java b/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/Address.java deleted file mode 100644 index 37a141ff8..000000000 --- a/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/Address.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import java.io.Serializable; - -record Address(String street, int number) implements Serializable {} diff --git a/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/JavaModelSerializationTest.java b/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/JavaModelSerializationTest.java deleted file mode 100644 index 4d7f07456..000000000 --- a/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/JavaModelSerializationTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.impl.marshaller.DefaultBufferFactory; -import io.serverlessworkflow.impl.marshaller.WorkflowBufferFactory; -import io.serverlessworkflow.impl.marshaller.WorkflowInputBuffer; -import io.serverlessworkflow.impl.marshaller.WorkflowOutputBuffer; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.util.List; -import org.junit.jupiter.api.Test; - -class JavaModelSerializationTest { - - @Test - void testSerializableJavaModel() { - testMarshallUnMarshall( - new JavaModel(new Person("Pepe Gotera", 32, new Address("Rue del Percebe", 13)))); - } - - @Test - void testSerializableJavaModelCollection() { - testMarshallUnMarshall( - new JavaModelCollection( - List.of(new Person("Pepe Gotera", 32, new Address("Rue del Percebe", 13))))); - } - - private void testMarshallUnMarshall(Object object) { - WorkflowBufferFactory factory = DefaultBufferFactory.factory(); - ByteArrayOutputStream output = new ByteArrayOutputStream(); - try (WorkflowOutputBuffer writer = factory.output(output)) { - writer.writeObject(object); - } - ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); - try (WorkflowInputBuffer reader = factory.input(input)) { - assertThat(reader.readObject()).isEqualTo(object); - } - } -} diff --git a/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/Person.java b/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/Person.java deleted file mode 100644 index de7dba780..000000000 --- a/experimental/model/src/test/java/io/serverlessworkflow/impl/model/func/Person.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.impl.model.func; - -import java.io.Serializable; - -record Person(String name, int age, Address address) implements Serializable {} diff --git a/experimental/pom.xml b/experimental/pom.xml deleted file mode 100644 index 1fda5a72a..000000000 --- a/experimental/pom.xml +++ /dev/null @@ -1,59 +0,0 @@ - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-parent - 8.0.0-SNAPSHOT - - serverlessworkflow-experimental - pom - Serverless Workflow :: Experimental - - - - io.serverlessworkflow - serverlessworkflow-impl-core - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-impl-jq - ${project.version} - test - - - io.serverlessworkflow - serverlessworkflow-experimental-lambda - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-experimental-model - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-experimental-types - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-experimental-fluent-func - ${project.version} - - - io.serverlessworkflow - serverlessworkflow-experimental-fluent-serialization-jackson - ${project.version} - - - - - types - lambda - lambda-fluent - fluent - model - test - - \ No newline at end of file diff --git a/experimental/test/pom.xml b/experimental/test/pom.xml deleted file mode 100644 index bb09d60cc..000000000 --- a/experimental/test/pom.xml +++ /dev/null @@ -1,116 +0,0 @@ - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental - 8.0.0-SNAPSHOT - - serverlessworkflow-experimental-test - Serverless Workflow :: Experimental :: Test - - 4.0.2 - - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.mockito - mockito-core - test - - - org.assertj - assertj-core - test - - - org.awaitility - awaitility - test - - - ch.qos.logback - logback-classic - test - - - io.serverlessworkflow - serverlessworkflow-experimental-fluent-func - test - - - io.serverlessworkflow - serverlessworkflow-experimental-lambda - test - - - io.serverlessworkflow - serverlessworkflow-impl-http - ${project.version} - test - - - io.serverlessworkflow - serverlessworkflow-impl-model - ${project.version} - test - - - com.squareup.okhttp3 - mockwebserver - - - io.serverlessworkflow - serverlessworkflow-impl-template-resolver - ${project.version} - test - - - io.serverlessworkflow - serverlessworkflow-impl-jq - test - - - io.serverlessworkflow - serverlessworkflow-impl-openapi - ${project.version} - test - - - io.serverlessworkflow - serverlessworkflow-impl-jackson-jwt - ${project.version} - test - - - org.glassfish.jersey.media - jersey-media-json-jackson - ${version.org.glassfish.jersey} - test - - - org.glassfish.jersey.core - jersey-client - ${version.org.glassfish.jersey} - test - - - io.serverlessworkflow - serverlessworkflow-api - test - - - org.junit.jupiter - junit-jupiter-params - test - - - io.serverlessworkflow - serverlessworkflow-experimental-fluent-serialization-jackson - test - - - \ No newline at end of file diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/ForEachFuncTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/ForEachFuncTest.java deleted file mode 100644 index cea746e57..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/ForEachFuncTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.*; -import static io.serverlessworkflow.fluent.test.TestSerializationUtils.writeAndReadInMemory; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; - -import io.cloudevents.CloudEvent; -import io.cloudevents.core.data.PojoCloudEventData; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.lifecycle.TraceExecutionListener; -import java.io.IOException; -import java.time.Duration; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; -import org.junit.jupiter.api.Test; - -public class ForEachFuncTest { - - private record Order(String id) {} - - private record EnhancedOrder(String id, int salary) {} - - private record OrdersPayload(List orders) {} - - private record OrderName(String id, String name) {} - - @Test - void testForEachIteration() throws IOException { - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("foreach-workflow") - .tasks(forEachItem(OrdersPayload::orders, ForEachFuncTest::enhace)) - .build()); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - OrdersPayload input = - new OrdersPayload( - List.of(new Order("ORD-001"), new Order("ORD-002"), new Order("ORD-003"))); - WorkflowModel result = app.workflowDefinition(workflow).instance(input).start().join(); - assertThat(result.as(EnhancedOrder.class).orElseThrow().id()) - .isEqualTo(input.orders().get(input.orders.size() - 1).id()); - } - } - - @Test - void testForEachEmit() { - - String eventType = "test.item.emitted"; - Workflow workflow = - FuncWorkflowBuilder.workflow("forEach-bug-reproducer") - .tasks( - // ForEach should emit 3 events, one per item - forEach( - (Collection> items) -> items, - emitJson(eventType, Map.class).inputFrom("$item"))) - .build(); - - List publishedEvents = new CopyOnWriteArrayList<>(); - LaggedInMemoryEvents eventBroker = new LaggedInMemoryEvents(); - eventBroker.register(eventType, ce -> publishedEvents.add(ce)); - - try (WorkflowApplication app = - WorkflowApplication.builder() - .withEventConsumer(eventBroker) - .withEventPublisher(eventBroker) - .withListener(new TraceExecutionListener()) - .build()) { - app.workflowDefinition(workflow) - .instance( - List.of( - new OrderName("item-1", "first"), - new OrderName("item-2", "second"), - new OrderName("item-3", "third"))) - .start() - .join(); - await() - .atMost(Duration.ofSeconds(2)) - .pollInterval(Duration.ofMillis(10)) - .until(() -> publishedEvents.size() == 3); - - assertThat( - publishedEvents.stream() - .map(CloudEvent::getData) - .map(PojoCloudEventData.class::cast) - .map(p -> p.getValue()) - .toList()) - .isEqualTo( - List.of( - Map.of("id", "item-1", "name", "first"), - Map.of("id", "item-2", "name", "second"), - Map.of("id", "item-3", "name", "third"))); - } - } - - private static EnhancedOrder enhace(Order order) { - return new EnhancedOrder(order.id(), 1000); - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/ForkFuncTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/ForkFuncTest.java deleted file mode 100644 index c63f8ed72..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/ForkFuncTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.*; -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import java.io.IOException; -import org.junit.jupiter.api.Test; - -public class ForkFuncTest { - - private int value = 2; - - public int getValue() { - return value; - } - - @Test - void testForkVerbose() throws IOException { - testIt( - FuncWorkflowBuilder.workflow("parallel-execution-workflow") - .tasks( - funcTaskItemListBuilder -> - funcTaskItemListBuilder.fork( - funcForkTaskBuilder -> - funcForkTaskBuilder.branches( - inner -> { - inner.function(f -> f.function(this::doubleIt)); - inner.function(f -> f.function(this::halfIt)); - }))) - .build()); - } - - @Test - void testForkSyntaxSugar() throws IOException { - testIt( - FuncWorkflowBuilder.workflow("parallel-execution-workflow") - .tasks(fork(function(this::doubleIt), function(this::halfIt))) - .build()); - } - - private void testIt(Workflow workflow) throws IOException { - workflow = TestSerializationUtils.writeAndReadInMemory(workflow); - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - assertThat( - app.workflowDefinition(workflow).instance(8).start().join().asCollection().stream() - .flatMap(m -> m.asMap().orElseThrow().values().stream()) - .toList()) - .containsExactlyInAnyOrder(2, 18); - } - } - - private int doubleIt(int number) { - return (number << 1) + value; - } - - private int halfIt(int number) { - return (number >> 1) - value; - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncCallAsyncTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncCallAsyncTest.java deleted file mode 100644 index d4188a6c1..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncCallAsyncTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowInstance; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.lifecycle.WorkflowExecutionListener; -import io.serverlessworkflow.impl.lifecycle.WorkflowStartedEvent; -import java.io.IOException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicLong; -import org.junit.jupiter.api.Test; - -public class FuncCallAsyncTest { - - private void safeSleep(long millis) { - try { - Thread.sleep(millis); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - - private CompletableFuture waitAsync(Integer waitTime) { - return CompletableFuture.supplyAsync( - () -> { - safeSleep(waitTime); - return 1; - }); - } - - private Integer waitSync(Integer waitTime) { - safeSleep(waitTime); - return 1; - } - - @Test - void testCompletableCall() throws IOException { - runIt(FuncWorkflowBuilder.workflow("waitCompletable").tasks(function(this::waitAsync)).build()); - } - - @Test - void testReferencedFunctionCall() throws IOException { - runIt(FuncWorkflowBuilder.workflow("waitReference").tasks(function(this::waitSync)).build()); - } - - @Test - void testLambdaCall() throws IOException { - runIt(FuncWorkflowBuilder.workflow("waitLambda").tasks(function(v -> 1)).build()); - } - - private class TimeListener implements WorkflowExecutionListener { - - private AtomicLong startTime = new AtomicLong(); - - @Override - public void onWorkflowStarted(WorkflowStartedEvent ev) { - startTime.set(System.currentTimeMillis()); - } - } - - private void runIt(Workflow workflow) throws IOException { - TimeListener listener = new TimeListener(); - try (WorkflowApplication app = WorkflowApplication.builder().withListener(listener).build()) { - final long waitTime = 200; - WorkflowInstance instance = - app.workflowDefinition(TestSerializationUtils.writeAndReadInMemory(workflow)) - .instance(waitTime); - CompletableFuture future = instance.start(); - assertThat(System.currentTimeMillis() - listener.startTime.get()).isLessThan(waitTime); - assertThat(future.join().asNumber().map(Number::intValue).orElseThrow()).isEqualTo(1); - } - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncDSLSerializationTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncDSLSerializationTest.java deleted file mode 100644 index c8d753f49..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncDSLSerializationTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static io.serverlessworkflow.api.WorkflowWriter.workflowAsBytes; -import static io.serverlessworkflow.api.WorkflowWriter.workflowAsString; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.withContext; -import static io.serverlessworkflow.fluent.test.TestSerializationUtils.writeAndReadInMemory; -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.api.WorkflowFormat; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowContextData; -import io.serverlessworkflow.impl.WorkflowDefinition; -import java.io.IOException; -import java.util.Map; -import java.util.function.Consumer; -import java.util.stream.Stream; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -public class FuncDSLSerializationTest { - - @ParameterizedTest - @MethodSource("workflows") - public void testSpecFeaturesParsing(Workflow workflow, Consumer assertion) - throws IOException { - Workflow otherWorkflow = writeAndReadInMemory(workflow); - assertWorkflowEquals(workflow, otherWorkflow); - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - assertion.accept(application.workflowDefinition(otherWorkflow)); - } - } - - static Stream workflows() { - final int QUANTITY = 3; - return Stream.of( - Arguments.of( - FuncWorkflowBuilder.workflow("hello") - .tasks(t -> t.set("sayHelloWorld", b -> b.expr(Map.of("result", "hello world!")))) - .build(), - new CheckResult(Map.of(), Map.of("result", "hello world!"))), - Arguments.of( - FuncWorkflowBuilder.workflow("inc") - .tasks(function(FuncDSLSerializationTest::inc)) - .build(), - new CheckResult(1, 2)), - Arguments.of( - FuncWorkflowBuilder.workflow("incContext") - .tasks(withContext(FuncDSLSerializationTest::incContext)) - .build(), - new CheckResult(1, 3)), - Arguments.of( - FuncWorkflowBuilder.workflow("incLambda") - .tasks(function((Integer number) -> number + QUANTITY)) - .build(), - new CheckResult(1, 4))); - } - - private static class CheckResult implements Consumer { - - private final Object input; - private final Object output; - - public CheckResult(Object input, Object output) { - this.input = input; - this.output = output; - } - - @Override - public void accept(WorkflowDefinition t) { - assertThat(t.instance(this.input).start().join().asJavaObject()).isEqualTo(this.output); - } - } - - private static void assertWorkflowEquals(Workflow workflow, Workflow other) throws IOException { - assertThat(workflowAsString(workflow, WorkflowFormat.YAML)) - .isEqualTo(workflowAsString(other, WorkflowFormat.YAML)); - assertThat(workflowAsBytes(workflow, WorkflowFormat.JSON)) - .isEqualTo(workflowAsBytes(other, WorkflowFormat.JSON)); - } - - private static Integer inc(Integer quantity) { - return quantity + 1; - } - - private static Integer incContext(Integer quantity, WorkflowContextData workflowContext) { - return quantity + 2; - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncDoTaskTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncDoTaskTest.java deleted file mode 100644 index 28a2dc22f..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncDoTaskTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowInstance; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowStatus; -import java.io.IOException; -import java.net.URI; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import org.junit.jupiter.api.Test; - -public class FuncDoTaskTest { - - @Test - void testDoTaskRaiseAndTryCatch() throws IOException { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - - var workflow = - FuncWorkflowBuilder.workflow("test-do-task") - .tasks( - doTask -> - doTask.tryCatch( - "try-catch-task", - tryBuilder -> - tryBuilder - .tryHandler( - tryBlock -> - tryBlock.raise( - "raise-error-task", - raiseBlock -> - raiseBlock.error( - error -> - error - .type( - URI.create( - "http://example.com/error")) - .status(500)))) - .catchHandler( - catchBlock -> - catchBlock - .errorsWith( - errs -> errs.type("http://example.com/error")) - .doTasks( - catchTasks -> - catchTasks.set( - "catchHandled", - setBlock -> - setBlock.expr( - Map.of("handled", true))))))) - .build(); - - WorkflowInstance instance = - app.workflowDefinition(TestSerializationUtils.writeAndReadInMemory(workflow)) - .instance(Map.of()); - - CompletableFuture future = instance.start(); - WorkflowModel result = future.join(); - - assertThat(instance.status()).isEqualTo(WorkflowStatus.COMPLETED); - assertThat(result.as(Map.class).orElseThrow()) - .containsEntry("handled", true) - .containsKey("handled"); - } - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncEventFilterTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncEventFilterTest.java deleted file mode 100644 index 645373c05..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncEventFilterTest.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consume; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.consumed; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.emitJson; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.listen; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.switchWhenOrElse; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.to; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.toOne; -import static io.serverlessworkflow.fluent.test.TestSerializationUtils.writeAndReadInMemory; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.fluent.func.dsl.ListenStep; -import io.serverlessworkflow.impl.TaskContextData; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowContextData; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowInstance; -import io.serverlessworkflow.impl.WorkflowModel; -import io.serverlessworkflow.impl.WorkflowModelCollection; -import io.serverlessworkflow.impl.WorkflowStatus; -import io.serverlessworkflow.impl.events.EventPublisher; -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import org.junit.jupiter.api.Test; - -/** - * Tests for the Event Filter DSL specification. Verifies that the fluent builder correctly wires - * the payload parsing and contextual lambdas into the final Workflow definitions, and ensures the - * ModelCollection adapters seamlessly convert between types. - */ -class FuncEventFilterTest { - - @Test - void testListenToOneCollection() throws IOException { - runIt( - FuncWorkflowBuilder.workflow("listenToOneReviewCol") - .tasks( - listen("waitReview", toOne("org.acme.test.review")) - .outputAs((Collection node) -> node.iterator().next())) - .build()); - } - - @Test - void testListenToOneArrayNode() throws IOException { - runIt( - FuncWorkflowBuilder.workflow("listenToOneReviewNode") - .tasks( - listen("waitReview", toOne("org.acme.test.review")) - .outputAs((ArrayNode node) -> node.get(0))) - .build()); - } - - @Test - void testListenToOneList() throws IOException { - runIt( - FuncWorkflowBuilder.workflow("listenToOneReviewList") - .tasks( - listen("waitReview", toOne("org.acme.test.review")) - .outputAs((List list) -> list.get(0))) - .build()); - } - - @Test - void testListenToOneSet() throws IOException { - runIt( - FuncWorkflowBuilder.workflow("listenToOneReviewSet") - .tasks( - listen("waitReview", toOne("org.acme.test.review")) - .outputAs((Set set) -> set.iterator().next())) - .build()); - } - - @Test - void testListenToOneArray() throws IOException { - runIt( - FuncWorkflowBuilder.workflow("listenToOneReviewArray") - .tasks( - listen("waitReview", toOne("org.acme.test.review")) - .outputAs((JsonNode[] array) -> array[0])) - .build()); - } - - @Test - void testPrimitiveArray() { - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - Workflow workflow = - FuncWorkflowBuilder.workflow("doubleArray") - .tasks(function(FuncEventFilterTest::doubleArray)) - .build(); - WorkflowModelCollection col = app.modelFactory().createCollection(); - col.add(app.modelFactory().from(1)); - col.add(app.modelFactory().from(2)); - col.add(app.modelFactory().from(3)); - assertThat( - app.workflowDefinition(workflow) - .instance(col) - .start() - .join() - .as(int[].class) - .orElseThrow()) - .isEqualTo(new int[] {2, 4, 6}); - } - } - - private static int[] doubleArray(int[] input) { - int[] output = new int[input.length]; - for (int i = 0; i < input.length; i++) { - output[i] = input[i] << 1; - } - return output; - } - - private Workflow reviewEmitter() { - return FuncWorkflowBuilder.workflow("emitReview") - .tasks(emitJson("draftReady", "org.acme.test.review", Review.class)) - .build(); - } - - private void runIt(Workflow listen) throws IOException { - Review review = new Review("Torrente", "espectacular", 5); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - - CompletableFuture waiting = - app.workflowDefinition(writeAndReadInMemory(listen)).instance(Map.of()).start(); - - app.workflowDefinition(reviewEmitter()).instance(review).start().join(); - - assertThat(waiting.join().as(Review.class).orElseThrow()).isEqualTo(review); - } - } - - // --- Mock Service Methods --- - NewsletterDraft writeDraft(NewsletterRequest req) { - return new NewsletterDraft("Draft: " + req.topic(), "Initial body..."); - } - - NewsletterDraft editDraft(HumanReview review) { - return new NewsletterDraft("Edited Draft", "Fixed based on: " + review.notes()); - } - - void sendEmail(NewsletterDraft draft) { - // Simulates MailService.send - } - - @Test - void testAutomaticConversion() throws Exception { - testConversionWorkflow( - listen( - "waitHumanReview", - to().one( - consumed("org.acme.newsletter.review.done") - .extensionByInstanceId("instanceid")))); - } - - @Test - void testCollectionConversion() throws Exception { - testConversionWorkflow( - listen( - to().one( - consumed("org.acme.newsletter.review.done") - .extensionByInstanceId("instanceid"))) - .outputAs((Collection col) -> col.iterator().next())); - } - - @Test - void testNodeConversion() throws Exception { - testConversionWorkflow( - listen( - "waitHumanReview", - to().one( - consumed("org.acme.newsletter.review.done") - .extensionByInstanceId("instanceid"))) - .outputAs((ArrayNode col) -> col.get(0))); - } - - private void testConversionWorkflow(ListenStep listen) throws Exception { - Workflow workflow = - FuncWorkflowBuilder.workflow("intelligent-newsletter") - .tasks( - function("draftAgent", this::writeDraft).exportAsTaskOutput(), - emitJson("draftReady", "org.acme.email.review.required", NewsletterDraft.class), - listen, - switchWhenOrElse( - h -> HumanReview.NEEDS_REVISION.equals(h.status()), - "humanEditorAgent", - "sendNewsletter", - HumanReview.class), - function("humanEditorAgent", this::editDraft) - .exportAsTaskOutput() - .then("draftReady"), - consume("sendNewsletter", this::sendEmail) - // Because we are in Jackson, the payload at this evaluation stage can be a - // Map. - // We simply check for the "status" field to know if it's the review payload. - .inputFrom( - (Map payload, - WorkflowContextData wfc, - TaskContextData tfc) -> - payload.containsKey("status") ? wfc.context() : payload)) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - WorkflowDefinition definition = app.workflowDefinition(workflow); - WorkflowInstance instance = definition.instance(new NewsletterRequest("Tech Stocks")); - CompletableFuture future = instance.start(); - - await() - .atMost(Duration.ofSeconds(5)) - .until(() -> instance.status() == WorkflowStatus.WAITING); - - CloudEvent humanReviewEvent = - CloudEventBuilder.v1() - .withId("event-123") - .withSource(URI.create("test:/human-editor")) - .withType("org.acme.newsletter.review.done") - .withExtension("instanceid", instance.id()) - .withData( - "application/json", - "{\"status\":\"APPROVED\", \"notes\":\"Looks good\"}" - .getBytes(StandardCharsets.UTF_8)) - .build(); - - EventPublisher publisher = app.eventPublishers().iterator().next(); - publisher.publish(humanReviewEvent).toCompletableFuture().join(); - - future.join(); - - assertThat(instance.status()).isEqualTo(WorkflowStatus.COMPLETED); - } - } - - record Review(String author, String text, int rating) {} - - record NewsletterRequest(String topic) {} - - record NewsletterDraft(String title, String body) {} - - record HumanReview(String status, String notes) { - public static final String NEEDS_REVISION = "NEEDS_REVISION"; - public static final String APPROVED = "APPROVED"; - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncHttpTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncHttpTest.java deleted file mode 100644 index d6ff8766a..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncHttpTest.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.http; -import static io.serverlessworkflow.fluent.test.TestSerializationUtils.writeAndReadInMemory; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowInstance; -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import mockwebserver3.MockResponse; -import mockwebserver3.MockWebServer; -import mockwebserver3.RecordedRequest; -import okhttp3.Headers; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -public class FuncHttpTest { - - private WorkflowApplication app; - private MockWebServer mockServer; - - @BeforeEach - void setup() throws IOException { - app = WorkflowApplication.builder().build(); - mockServer = new MockWebServer(); - mockServer.start(0); - mockServer.enqueue(new MockResponse(204, Headers.of("Content-Type", "application/json"), "")); - } - - @AfterEach - void cleanup() { - mockServer.close(); - app.close(); - } - - private RecordedRequest takeRequestOrFail() throws Exception { - RecordedRequest request = mockServer.takeRequest(150, TimeUnit.MILLISECONDS); - assertThat(request) - .as("Expected an HTTP request to be received by MockWebServer within 300 ms") - .isNotNull(); - return request; - } - - @Test - @DisplayName("Query method with single key-value pair") - void test_query_with_single_key_value() throws Exception { - var workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("test-query-single") - .tasks( - http("callHttp") - .GET() - .uri(mockServer.url("/api/endpoint").toString()) - .query("param1", "value1")) - .build()); - - WorkflowInstance instance = app.workflowDefinition(workflow).instance(Map.of()); - - instance.start().join(); - - RecordedRequest request = takeRequestOrFail(); - - assertSoftly( - softly -> { - softly.assertThat(request.getUrl().toString()).contains("param1=value1"); - softly.assertThat(request.getMethod()).isEqualTo("GET"); - }); - } - - @Test - @DisplayName("Query method with multiple single key-value pairs (individually tested)") - void test_query_with_multiple_single_values() throws Exception { - var workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("test-query-single-multi") - .tasks( - http("callHttp") - .GET() - .uri(mockServer.url("/api/endpoint").toString()) - .query("param1", "value1") - .query("param2", "value2") - .query("param3", "value3")) - .build()); - - WorkflowInstance instance = app.workflowDefinition(workflow).instance(Map.of()); - instance.start().join(); - - RecordedRequest request = takeRequestOrFail(); - String url = request.getUrl().toString(); - - assertSoftly( - softly -> { - softly.assertThat(url).contains("param1=value1").isNotEmpty(); - softly.assertThat(url).contains("param2=value2").isNotEmpty(); - softly.assertThat(url).contains("param3=value3").isNotEmpty(); - }); - } - - @Test - @DisplayName("Query method with Map of parameters") - void test_query_with_map() throws Exception { - - var workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("test-query-map") - .tasks( - http("callHttp") - .GET() - .uri(mockServer.url("/api/endpoint").toString()) - .query(Map.of("userId", "123", "userName", "john", "status", "active"))) - .build()); - - WorkflowInstance instance = app.workflowDefinition(workflow).instance(Map.of()); - instance.start().join(); - - RecordedRequest request = takeRequestOrFail(); - String url = request.getUrl().toString(); - - assertSoftly( - softly -> { - softly.assertThat(url).contains("userId=123"); - softly.assertThat(url).contains("userName=john"); - softly.assertThat(url).contains("status=active"); - }); - } - - @Test - @DisplayName("Query method with expression string") - void test_query_with_expression() throws Exception { - var workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("test-query-expression") - .tasks( - http("callHttp") - .GET() - .uri(mockServer.url("/api/endpoint").toString()) - .query("enabled", "${ .enabled }")) - .build()); - - WorkflowInstance instance = app.workflowDefinition(workflow).instance(Map.of("enabled", true)); - instance.start().join(); - - RecordedRequest request = takeRequestOrFail(); - - assertThat(request.getUrl().query()).contains("enabled=true"); - } - - @Test - @DisplayName("Query method with empty Map") - void test_query_with_empty_map() throws Exception { - var workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("test-query-empty-map") - .tasks( - http("callHttp") - .GET() - .uri(mockServer.url("/api/endpoint").toString()) - .query(Map.of())) - .build()); - - WorkflowInstance instance = app.workflowDefinition(workflow).instance(Map.of()); - instance.start().join(); - - RecordedRequest request = takeRequestOrFail(); - - assertSoftly( - softly -> { - softly.assertThat(request.getUrl().encodedPath()).isEqualTo("/api/endpoint"); - softly.assertThat(request.getUrl().encodedQuery()).isNull(); - }); - } - - @Test - @DisplayName("Query method with special characters in values") - void test_query_with_special_characters() throws Exception { - var workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("test-query-special-chars") - .tasks( - http("callHttp") - .GET() - .uri(mockServer.url("/api/endpoint").toString()) - .query("email", "user@example.com")) - .build()); - - WorkflowInstance instance = app.workflowDefinition(workflow).instance(Map.of()); - instance.start().join(); - - RecordedRequest request = takeRequestOrFail(); - - assertSoftly( - softly -> { - softly.assertThat(request.getUrl().queryParameter("email")).isEqualTo("user@example.com"); - softly.assertThat(request.getUrl().encodedQuery()).contains("email=user%40example.com"); - }); - } - - @Test - @DisplayName("Query method overload - Map with multiple values") - void test_query_map_multiple_values() throws Exception { - var workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("test-query-map-multi") - .tasks( - http("callHttp") - .GET() - .uri(mockServer.url("/api/endpoint").toString()) - .query(Map.of("limit", "50", "offset", "0", "sort", "name"))) - .build()); - - WorkflowInstance instance = app.workflowDefinition(workflow).instance(Map.of()); - instance.start().join(); - - RecordedRequest request = takeRequestOrFail(); - String url = request.getUrl().toString(); - - assertSoftly( - softly -> { - softly.assertThat(url).contains("limit=50"); - softly.assertThat(url).contains("offset=0"); - softly.assertThat(url).contains("sort=name"); - }); - } - - @Test - @DisplayName("Query method with headers and query parameters") - void test_query_with_headers_and_query() throws Exception { - var workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow("test-query-with-headers") - .tasks( - http("callHttp") - .GET() - .uri(mockServer.url("/api/endpoint").toString()) - .header("Authorization", "Bearer token123") - .header("Accept", "application/json") - .query("userId", "123")) - .build()); - - WorkflowInstance instance = app.workflowDefinition(workflow).instance(Map.of()); - instance.start().join(); - - RecordedRequest request = takeRequestOrFail(); - String url = request.getUrl().toString(); - assertThat(url).contains("userId=123"); - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncOAuth2HttpTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncOAuth2HttpTest.java deleted file mode 100644 index e6c06be75..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncOAuth2HttpTest.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.serverlessworkflow.api.types.OAuth2AuthenticationData; -import io.serverlessworkflow.api.types.OAuth2AuthenticationDataClient; -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.fluent.func.dsl.FuncDSL; -import io.serverlessworkflow.impl.WorkflowApplication; -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.util.Base64; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import mockwebserver3.Dispatcher; -import mockwebserver3.MockResponse; -import mockwebserver3.MockWebServer; -import mockwebserver3.RecordedRequest; -import okhttp3.Headers; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -public class FuncOAuth2HttpTest { - - private static final ObjectMapper MAPPER = new ObjectMapper(); - - private record OAuth2Client(String clientId, String clientSecret, String baseUrl) {} - - private WorkflowApplication app; - private MockWebServer mockServer; - - // Recorded token-request bodies, keyed by the request path. - private final Map tokenRequestBodies = new ConcurrentHashMap<>(); - // Recorded Authorization headers of the downstream API calls, keyed by the request path. - private final Map apiAuthHeaders = new ConcurrentHashMap<>(); - - @BeforeEach - void setup() throws IOException { - app = WorkflowApplication.builder().build(); - mockServer = new MockWebServer(); - mockServer.setDispatcher( - new Dispatcher() { - @Override - public MockResponse dispatch(RecordedRequest request) { - String path = request.getUrl().encodedPath(); - if (path.endsWith("/token")) { - tokenRequestBodies.put(path, request.getBody().utf8()); - return new MockResponse( - 200, Headers.of("Content-Type", "application/json"), tokenResponse(fakeJwt())); - } - // The downstream API call ("/joogle" or "/jahoo"). - apiAuthHeaders.put(path, request.getHeaders().get("Authorization")); - return new MockResponse( - 200, - Headers.of("Content-Type", "application/json"), - "{\"email\":\"" + path + "@example.com\"}"); - } - }); - mockServer.start(0); - } - - @AfterEach - void cleanup() { - mockServer.close(); - app.close(); - } - - @Test - @DisplayName( - "Two named OAuth2 client-credentials authentications, each used by a forked HTTP call") - void test_multiple_oauth2_clients() throws Exception { - String base = mockServer.url("/").toString(); - base = base.substring(0, base.length() - 1); // strip trailing slash - - OAuth2Client joogle = - new OAuth2Client("joogle-client-id", "joogle-client-secret", base + "/joogle-auth"); - OAuth2Client jahoo = - new OAuth2Client("jahoo-client-id", "jahoo-client-secret", base + "/jahoo-auth"); - String wireMock = base; - - Workflow workflow = - FuncWorkflowBuilder.workflow("multiple-oauth2-clients", "quarkus-flow") - .use( - use -> - use.authentications( - auth -> { - auth.authentication( - "joogle", - a -> - a.oauth2( - oauth2 -> - oauth2 - .client( - client -> - client - .id(joogle.clientId()) - .secret(joogle.clientSecret()) - .authentication( - OAuth2AuthenticationDataClient - .ClientAuthentication - .CLIENT_SECRET_POST)) - .authority(joogle.baseUrl()) - .grant( - OAuth2AuthenticationData - .OAuth2AuthenticationDataGrant - .CLIENT_CREDENTIALS) - .build())); - auth.authentication( - "jahoo", - a -> - a.oauth2( - oauth2 -> - oauth2 - .client( - client -> - client - .id(jahoo.clientId()) - .secret(jahoo.clientSecret())) - .authority(jahoo.baseUrl()) - .grant( - OAuth2AuthenticationData - .OAuth2AuthenticationDataGrant - .CLIENT_CREDENTIALS) - .build())); - })) - .tasks( - FuncDSL.fork( - FuncDSL.http() - .GET() - .uri(URI.create(wireMock + "/joogle"), FuncDSL.use("joogle")), - FuncDSL.http() - .GET() - .uri(URI.create(wireMock + "/jahoo"), FuncDSL.use("jahoo"))), - FuncDSL.function("merge", o -> o)) - .build(); - - app.workflowDefinition(workflow).instance(Map.of()).start().join(); - - String joogleTokenBody = tokenRequestBodies.get("/joogle-auth/oauth2/token"); - String jahooTokenBody = tokenRequestBodies.get("/jahoo-auth/oauth2/token"); - - assertThat(joogleTokenBody) - .as("joogle token request body") - .isNotNull() - .contains("grant_type=client_credentials") - .contains("client_id=joogle-client-id") - .contains("client_secret=joogle-client-secret"); - - assertThat(jahooTokenBody) - .as("jahoo token request body") - .isNotNull() - .contains("grant_type=client_credentials") - .contains("client_id=jahoo-client-id") - .contains("client_secret=jahoo-client-secret"); - - // The token obtained from each authority is forwarded as a Bearer token on the API call. - assertThat(apiAuthHeaders.get("/joogle")).as("joogle bearer").startsWith("Bearer "); - assertThat(apiAuthHeaders.get("/jahoo")).as("jahoo bearer").startsWith("Bearer "); - } - - @Test - @DisplayName("Custom endpoints.token overrides the default /oauth2/token path") - void test_custom_token_endpoint() throws Exception { - String base = mockServer.url("/").toString(); - base = base.substring(0, base.length() - 1); // strip trailing slash - - OAuth2Client joogle = - new OAuth2Client("joogle-client-id", "joogle-client-secret", base + "/joogle-auth"); - String wireMock = base; - String customTokenPath = "/auth/realms/joogle/protocol/openid-connect/token"; - - // Same configuration as above, expressed with the FuncDSL auth helpers: - // FuncDSL.auth(name, configurer) returns a chainable UseSpec (a Consumer), - // and FuncDSL.oauth2(...) builds the policy (no explicit .build() needed). - Workflow workflow = - FuncWorkflowBuilder.workflow("custom-token-endpoint", "quarkus-flow") - .use( - FuncDSL.auth( - "joogle", - FuncDSL.oauth2( - oauth2 -> - oauth2 - .endpoints(e -> e.token(customTokenPath)) - .client( - client -> - client - .id(joogle.clientId()) - .secret(joogle.clientSecret()) - .authentication( - OAuth2AuthenticationDataClient.ClientAuthentication - .CLIENT_SECRET_POST)) - .authority(joogle.baseUrl()) - .grant( - OAuth2AuthenticationData.OAuth2AuthenticationDataGrant - .CLIENT_CREDENTIALS)))) - .tasks( - FuncDSL.http().GET().uri(URI.create(wireMock + "/joogle"), FuncDSL.use("joogle"))) - .build(); - - app.workflowDefinition(workflow).instance(Map.of()).start().join(); - - // The token path is resolved relative to the authority, so the default "/oauth2/token" is - // replaced by the custom path. - assertThat(tokenRequestBodies.get("/joogle-auth" + customTokenPath)) - .as("token request hit the custom endpoint") - .isNotNull() - .contains("client_id=joogle-client-id"); - assertThat(tokenRequestBodies).doesNotContainKey("/joogle-auth/oauth2/token"); - } - - private static String tokenResponse(String jwt) { - return """ - { - "access_token": "%s", - "token_type": "Bearer", - "expires_in": 3600 - } - """ - .formatted(jwt); - } - - private static String fakeJwt() { - try { - long now = Instant.now().getEpochSecond(); - String header = - MAPPER.writeValueAsString(Map.of("alg", "RS256", "typ", "Bearer", "kid", "test")); - String payload = - MAPPER.writeValueAsString(Map.of("sub", "test-subject", "exp", now + 3600, "iat", now)); - return b64Url(header) + "." + b64Url(payload) + ".sig"; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static String b64Url(String s) { - return Base64.getUrlEncoder() - .withoutPadding() - .encodeToString(s.getBytes(StandardCharsets.UTF_8)); - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncOpenAPITest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncOpenAPITest.java deleted file mode 100644 index dbcdd2073..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncOpenAPITest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.openapi; - -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowInstance; -import io.serverlessworkflow.impl.WorkflowModel; -import java.io.IOException; -import java.net.URI; -import java.util.Map; -import mockwebserver3.MockResponse; -import mockwebserver3.MockWebServer; -import okhttp3.Headers; -import org.assertj.core.api.SoftAssertions; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class FuncOpenAPITest { - - private static MockWebServer mockWebServer; - - @BeforeEach - public void setup() throws IOException { - mockWebServer = new MockWebServer(); - mockWebServer.start(0); - } - - @AfterEach - public void tearDown() { - mockWebServer.close(); - } - - @Test - void test_openapi_document_with_non_jq_uri_string() { - String mockedSwaggerDoc = - """ - { - "swagger": "2.0", - "info": { "version": "1.0.0", "title": "Mock Petstore" }, - "host": "localhost:%d", - "basePath": "/v2", - "schemes": [ "http" ], - "paths": { - "/pet/findByStatus": { - "get": { - "operationId": "findPetsByStatus", - "parameters": [ - { - "name": "status", - "in": "query", - "required": true, - "type": "string" - } - ], - "responses": { "200": { "description": "OK" } } - } - } - } - } - """ - .formatted(mockWebServer.getPort()); - - mockWebServer.enqueue( - new MockResponse(200, Headers.of("Content-Type", "application/json"), mockedSwaggerDoc)); - mockWebServer.enqueue( - new MockResponse( - 200, - Headers.of("Content-Type", "application/json"), - """ - { "description": "OK" } - """)); - var w = - FuncWorkflowBuilder.workflow("openapi-call-workflow") - .tasks( - openapi() - .document(URI.create(mockWebServer.url("/v2/swagger.json").toString())) - .operation("findPetsByStatus") - .parameters(Map.of("status", "available"))) - .build(); - - try (WorkflowApplication app = WorkflowApplication.builder().build()) { - - WorkflowDefinition def = app.workflowDefinition(w); - WorkflowInstance instance = def.instance(Map.of()); - WorkflowModel model = instance.start().join(); - - SoftAssertions.assertSoftly( - softly -> { - softly.assertThat(model).isNotNull(); - softly.assertThat(model.asMap()).contains(Map.of("description", "OK")); - }); - } - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncTryCatchTest.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncTryCatchTest.java deleted file mode 100644 index 686c90fda..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/FuncTryCatchTest.java +++ /dev/null @@ -1,648 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.function; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.tasks; -import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.tryCatch; -import static io.serverlessworkflow.fluent.test.TestSerializationUtils.writeAndReadInMemory; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import io.serverlessworkflow.api.types.Workflow; -import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowDefinition; -import io.serverlessworkflow.impl.WorkflowError; -import io.serverlessworkflow.impl.WorkflowException; -import io.serverlessworkflow.impl.WorkflowModel; -import java.io.IOException; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class FuncTryCatchTest { - - private static final Logger log = LoggerFactory.getLogger(FuncTryCatchTest.class); - - private static final String STOCK_ORDER_ERROR = "ERR_001"; - private static final String PAYMENT_PROCESSING_ERROR = "ERR_002"; - private static final String SHIPPING_ERROR = "ERR_003"; - - private static final String ORDER_001 = "ORDER#001"; - private static final String ORDER_002 = "ORDER#002"; - private static final String ORDER_003 = "ORDER#003"; - - private static final String TRANSIENT_ERROR = "ERR_TRANSIENT"; - - @Test - void booking_compensation_dsl() throws IOException { - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryStockReservation", - t -> - t.tryCatch(function("stockReservation", this::reserveStock)) - .catchError( - err -> err.type(STOCK_ORDER_ERROR), - function("cancelStockReservation", this::cancelReservation) - .then("endFlow"))), - tryCatch( - "tryPaymentProcessing", - t -> - t.tryCatch(function("paymentProcessing", this::processPayment)) - .catchWhen( - "${ .status == 503 }", - function("cancelPayment", this::cancelPayment) - .then("endFlow"))), - tryCatch( - "tryShipping", - t -> - t.tryCatch(function("scheduleShipping", this::scheduleShipping)) - .catchType( - SHIPPING_ERROR, - function("cancelPayment", this::cancelShipping))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_003).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_003, "endFlow"); - } - } - - @Test - void testStockReservationError_CatchByType() throws IOException { - log.info("Testing stock reservation error with catch by type"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryStockReservation", - t -> - t.tryCatch(function("stockReservation", this::reserveStock)) - .catchError( - err -> err.type(STOCK_ORDER_ERROR), - function("cancelStockReservation", this::cancelReservation) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_001).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_001, "endFlow"); - } - } - - @Test - void testStockReservationError_CatchByStatus() throws IOException { - log.info("Testing stock reservation error with catch by status code"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryStockReservation", - t -> - t.tryCatch(function("stockReservation", this::reserveStock)) - .catchWhen( - "${ .status == 409 }", - function("cancelStockReservation", this::cancelReservation) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_001).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_001, "endFlow"); - } - } - - @Test - void testStockReservationError_CatchType() throws IOException { - log.info("Testing stock reservation error with catchType"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryStockReservation", - t -> - t.tryCatch(function("stockReservation", this::reserveStock)) - .catchType( - STOCK_ORDER_ERROR, - function("cancelStockReservation", this::cancelReservation) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_001).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_001, "endFlow"); - } - } - - @Test - void testPaymentProcessingError_CatchByType() throws IOException { - log.info("Testing payment processing error with catch by type"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryPaymentProcessing", - t -> - t.tryCatch(function("paymentProcessing", this::processPayment)) - .catchError( - err -> err.type(PAYMENT_PROCESSING_ERROR), - function("cancelPayment", this::cancelPayment) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_002).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_002, "endFlow"); - } - } - - @Test - void testPaymentProcessingError_CatchByStatus() throws IOException { - log.info("Testing payment processing error with catch by status code"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryPaymentProcessing", - t -> - t.tryCatch(function("paymentProcessing", this::processPayment)) - .catchWhen( - "${ .status == 503 }", - function("cancelPayment", this::cancelPayment) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_002).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_002, "endFlow"); - } - } - - @Test - void testPaymentProcessingError_CatchType() throws IOException { - log.info("Testing payment processing error with catchType"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryPaymentProcessing", - t -> - t.tryCatch(function("paymentProcessing", this::processPayment)) - .catchType( - PAYMENT_PROCESSING_ERROR, - function("cancelPayment", this::cancelPayment) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_002).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_002, "endFlow"); - } - } - - @Test - void testShippingError_CatchByType() throws IOException { - log.info("Testing shipping error with catch by type"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryShipping", - t -> - t.tryCatch(function("scheduleShipping", this::scheduleShipping)) - .catchError( - err -> err.type(SHIPPING_ERROR), - function("cancelShipping", this::cancelShipping) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_003).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_003, "endFlow"); - } - } - - @Test - void testShippingError_CatchByStatus() throws IOException { - log.info("Testing shipping error with catch by status code"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryShipping", - t -> - t.tryCatch(function("scheduleShipping", this::scheduleShipping)) - .catchWhen( - "${ .status == 500 }", - function("cancelShipping", this::cancelShipping) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_003).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_003, "endFlow"); - } - } - - @Test - void testShippingError_CatchType() throws IOException { - log.info("Testing shipping error with catchType"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryShipping", - t -> - t.tryCatch(function("scheduleShipping", this::scheduleShipping)) - .catchType( - SHIPPING_ERROR, - function("cancelShipping", this::cancelShipping) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_003).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_003, "endFlow"); - } - } - - @Test - void testSuccessfulFlow_NoErrors() throws IOException { - log.info("Testing successful flow without any errors"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryStockReservation", - t -> - t.tryCatch(function("stockReservation", this::reserveStock)) - .catchError( - err -> err.type(STOCK_ORDER_ERROR), - function("cancelStockReservation", this::cancelReservation) - .then("endFlow"))), - tryCatch( - "tryPaymentProcessing", - t -> - t.tryCatch(function("paymentProcessing", this::processPayment)) - .catchWhen( - "${ .status == 503 }", - function("cancelPayment", this::cancelPayment) - .then("endFlow"))), - tryCatch( - "tryShipping", - t -> - t.tryCatch(function("scheduleShipping", this::scheduleShipping)) - .catchType( - SHIPPING_ERROR, - function("cancelShipping", this::cancelShipping))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - // Using a different order ID that doesn't trigger any errors - WorkflowModel workflowModel = workflowDefinition.instance("ORDER#999").start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains("ORDER#999", "endFlow"); - } - } - - @Test - void testMultipleCatchHandlers_FirstMatches() throws IOException { - log.info("Testing multiple catch handlers where first one matches"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryStockReservation", - t -> - t.tryCatch(function("stockReservation", this::reserveStock)) - .catchError( - err -> err.type(STOCK_ORDER_ERROR), - function("cancelStockReservation", this::cancelReservation) - .then("endFlow")) - .catchWhen( - "${ .status == 409 }", - function("alternativeCancellation", this::cancelReservation) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_001).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_001, "endFlow"); - } - } - - @Test - void testCatchAll_WithAnyError() throws IOException { - log.info("Testing catch-all handler for any error"); - - Workflow workflow = - writeAndReadInMemory( - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryStockReservation", - t -> - t.tryCatch(function("stockReservation", this::reserveStock)) - .catchWhen( - "${ true }", - function("genericErrorHandler", this::cancelReservation) - .then("endFlow"))), - function("endFlow", this::endFlow)) - .build()); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition workflowDefinition = application.workflowDefinition(workflow); - WorkflowModel workflowModel = workflowDefinition.instance(ORDER_001).start().join(); - - assertThat(workflowModel.asCollection()) - .map(w -> w.asText().orElseThrow()) - .contains(ORDER_001, "endFlow"); - } - } - - @Test - void testRetryWithoutBackoff() { - AtomicInteger attempts = new AtomicInteger(); - Workflow workflow = - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryTask", - t -> - t.tryCatch( - tasks( - function( - "riskyTask", - (String input) -> { - if (attempts.incrementAndGet() <= 2) { - throw new WorkflowException( - WorkflowError.error(TRANSIENT_ERROR, 503).build()); - } - return "success"; - }, - String.class))) - .catchHandler( - handler -> - handler - .errorsWith(err -> err.type(TRANSIENT_ERROR)) - .retry( - retry -> - retry - .delay(d -> d.milliseconds(10)) - .limit( - limit -> limit.attempt(a -> a.count(3))))))) - .build(); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition definition = application.workflowDefinition(workflow); - WorkflowModel result = definition.instance("input").start().join(); - Assertions.assertThat(result.asText()).hasValue("success"); - Assertions.assertThat(attempts.get()).isEqualTo(3); - } - } - - @Test - void testRetryWithoutLimit() { - AtomicInteger attempts = new AtomicInteger(); - Workflow workflow = - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryTask", - t -> - t.tryCatch( - tasks( - function( - "riskyTask", - (String input) -> { - if (attempts.incrementAndGet() <= 2) { - throw new WorkflowException( - WorkflowError.error(TRANSIENT_ERROR, 503).build()); - } - return "success"; - }, - String.class))) - .catchHandler( - handler -> - handler - .errorsWith(err -> err.type(TRANSIENT_ERROR)) - .retry( - retry -> - retry - .delay(d -> d.milliseconds(10)) - .backoff(b -> b.constant("c", "10")))))) - .build(); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition definition = application.workflowDefinition(workflow); - WorkflowModel result = definition.instance("input").start().join(); - Assertions.assertThat(result.asText()).hasValue("success"); - Assertions.assertThat(attempts.get()).isEqualTo(3); - } - } - - @Test - void testRetryWithoutDelay() { - AtomicInteger attempts = new AtomicInteger(); - - Workflow workflow = - FuncWorkflowBuilder.workflow() - .tasks( - tryCatch( - "tryTask", - t -> - t.tryCatch( - tasks( - function( - "riskyTask", - (String input) -> { - if (attempts.incrementAndGet() <= 2) { - throw new WorkflowException( - WorkflowError.error(TRANSIENT_ERROR, 503).build()); - } - return "success"; - }, - String.class))) - .catchHandler( - handler -> - handler - .errorsWith(err -> err.type(TRANSIENT_ERROR)) - .retry( - retry -> - retry - .backoff(b -> b.constant("c", "10")) - .limit( - limit -> limit.attempt(a -> a.count(3))))))) - .build(); - - try (WorkflowApplication application = WorkflowApplication.builder().build()) { - WorkflowDefinition definition = application.workflowDefinition(workflow); - WorkflowModel result = definition.instance("input").start().join(); - Assertions.assertThat(result.asText()).hasValue("success"); - Assertions.assertThat(attempts.get()).isEqualTo(3); - } - } - - public String reserveStock(String order) { - log.info("Reserving stock for order: {}", order); - if (order.equals(ORDER_001)) { - throw new WorkflowException(WorkflowError.error(STOCK_ORDER_ERROR, 409).build()); - } - return order; - } - - public String cancelReservation(String order) { - log.info("Cancelling reservation for order: {}", order); - return order; - } - - public String processPayment(String order) { - log.info("Processing payment for order: {}", order); - if (order.equals(ORDER_002)) { - throw new WorkflowException(WorkflowError.error(PAYMENT_PROCESSING_ERROR, 503).build()); - } - return order; - } - - public String cancelPayment(String order) { - log.info("Cancel payment for order: {}", order); - cancelReservation(order); - return order; - } - - public String scheduleShipping(String order) { - log.info("Scheduling shipping for order: {}", order); - if (order.equals(ORDER_003)) { - throw new WorkflowException(WorkflowError.error(SHIPPING_ERROR, 500).build()); - } - return order; - } - - public String cancelShipping(String order) { - log.info("Cancel shipping for order: {}", order); - cancelReservation(order); - return order; - } - - public List endFlow(String order) { - log.info("End flow for order: {}", order); - return List.of(order, "endFlow"); - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/LaggedInMemoryEvents.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/LaggedInMemoryEvents.java deleted file mode 100644 index d2e4151ed..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/LaggedInMemoryEvents.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import io.cloudevents.CloudEvent; -import io.serverlessworkflow.impl.events.InMemoryEvents; -import java.util.concurrent.CompletableFuture; - -public class LaggedInMemoryEvents extends InMemoryEvents { - - @Override - public CompletableFuture publish(CloudEvent ce) { - - return super.publish(ce) - .thenRun( - () -> { - try { - Thread.sleep(50); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - }); - } -} diff --git a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/TestSerializationUtils.java b/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/TestSerializationUtils.java deleted file mode 100644 index b0dc16b0b..000000000 --- a/experimental/test/src/test/java/io/serverlessworkflow/fluent/test/TestSerializationUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.fluent.test; - -import static io.serverlessworkflow.api.WorkflowReader.readWorkflow; -import static io.serverlessworkflow.api.WorkflowWriter.writeWorkflow; - -import io.serverlessworkflow.api.WorkflowFormat; -import io.serverlessworkflow.api.types.Workflow; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class TestSerializationUtils { - - private static final Logger logger = LoggerFactory.getLogger(TestSerializationUtils.class); - - private TestSerializationUtils() {} - - static Workflow writeAndReadInMemory(Workflow workflow) throws IOException { - byte[] bytes; - try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { - writeWorkflow(out, workflow, WorkflowFormat.YAML); - bytes = out.toByteArray(); - } - if (logger.isDebugEnabled()) { - logger.debug("Workflow string representation is {}", new String(bytes)); - } - try (ByteArrayInputStream in = new ByteArrayInputStream(bytes)) { - return readWorkflow(in, WorkflowFormat.YAML); - } - } -} diff --git a/experimental/test/src/test/resources/logback.xml b/experimental/test/src/test/resources/logback.xml deleted file mode 100644 index 355a1df3e..000000000 --- a/experimental/test/src/test/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/experimental/types/pom.xml b/experimental/types/pom.xml deleted file mode 100644 index 197c5097c..000000000 --- a/experimental/types/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental - 8.0.0-SNAPSHOT - - serverlessworkflow-experimental-types - Serverless Workflow :: Experimental:: Types - - - io.serverlessworkflow - serverlessworkflow-types - - - io.serverlessworkflow - serverlessworkflow-impl-core - - - \ No newline at end of file diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/CallJava.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/CallJava.java deleted file mode 100644 index 8e6f88a55..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/CallJava.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.api.types.CallFunction; -import io.serverlessworkflow.api.types.FunctionArguments; -import io.serverlessworkflow.api.types.utils.ReflectionUtils; -import java.lang.invoke.MethodType; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Function; - -public abstract class CallJava { - - private CallJava() {} - - public static final String JAVA_CALL_KEY = "Java"; - public static final String FUNCTION_NAME_KEY = "function"; - public static final String INPUT_CLASS_KEY = "inputClass"; - public static final String OUTPUT_CLASS_KEY = "outputClass"; - public static final String VAR_NAME_KEY = "varName"; - public static final String INDEX_NAME_KEY = "index"; - - private static CallFunction buildFunction( - Object function, Optional> inputClass, Optional> outputClass) { - CallFunction result = new CallFunction(); - result.setCall(JAVA_CALL_KEY); - result.withWith( - new FunctionArguments() - .withAdditionalProperty(FUNCTION_NAME_KEY, function) - .withAdditionalProperty(INPUT_CLASS_KEY, inputClass) - .withAdditionalProperty(OUTPUT_CLASS_KEY, outputClass)); - return result; - } - - public static CallFunction consumer(Consumer consumer) { - return buildFunction( - consumer, - ReflectionUtils.methodType(consumer).map(m -> m.parameterType(0)), - Optional.empty()); - } - - public static CallFunction consumer(Consumer consumer, Class inputClass) { - return buildFunction(consumer, Optional.ofNullable(inputClass), Optional.empty()); - } - - public static CallFunction function(Function function) { - return buildFunction(function, Optional.empty(), Optional.empty()); - } - - public static CallFunction function(Function function, Class inputClass) { - return buildFunction( - function, - Optional.ofNullable(inputClass), - ReflectionUtils.methodType(function).map(MethodType::returnType)); - } - - public static CallFunction function( - Function function, Class inputClass, Class outputClass) { - return buildFunction( - function, Optional.ofNullable(inputClass), Optional.ofNullable(outputClass)); - } - - public static CallFunction loopFunction( - LoopFunctionIndex function, String varName, String indexName) { - Optional methodType = ReflectionUtils.methodType(function); - CallFunction result = - buildFunction( - function, - methodType.map(m -> m.parameterType(0)), - methodType.map(MethodType::returnType)); - result - .getWith() - .withAdditionalProperty(VAR_NAME_KEY, varName) - .withAdditionalProperty(INDEX_NAME_KEY, indexName); - return result; - } - - public static CallFunction loopFunction( - LoopFunction function, String varName) { - Optional methodType = ReflectionUtils.methodType(function); - CallFunction result = - buildFunction( - function, - methodType.map(m -> m.parameterType(0)), - methodType.map(MethodType::returnType)); - result.getWith().withAdditionalProperty(VAR_NAME_KEY, varName); - return result; - } - - public static CallFunction function(ContextFunction function, Class inputClass) { - return buildFunction( - function, - Optional.ofNullable(inputClass), - ReflectionUtils.methodType(function).map(MethodType::returnType)); - } - - public static CallFunction function( - ContextFunction function, Class inputClass, Class outputClass) { - return buildFunction( - function, Optional.ofNullable(inputClass), Optional.ofNullable(outputClass)); - } - - public static CallFunction function(FilterFunction function, Class inputClass) { - return buildFunction( - function, - Optional.ofNullable(inputClass), - ReflectionUtils.methodType(function).map(MethodType::returnType)); - } - - public static CallFunction function( - FilterFunction function, Class inputClass, Class outputClass) { - return buildFunction( - function, Optional.ofNullable(inputClass), Optional.ofNullable(outputClass)); - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextFunction.java deleted file mode 100644 index c2f87ebda..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextFunction.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.impl.WorkflowContextData; - -@FunctionalInterface -public interface ContextFunction extends FunctionObject { - R apply(T object, WorkflowContextData workflowContext); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextPredicate.java deleted file mode 100644 index 0dd0c7dc9..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/ContextPredicate.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.impl.WorkflowContextData; - -@FunctionalInterface -public interface ContextPredicate extends FunctionObject { - boolean test(T value, WorkflowContextData context); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataFunction.java deleted file mode 100644 index b7fea24ef..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataFunction.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.api.types.EventData; -import java.util.Objects; -import java.util.function.Function; - -public class EventDataFunction extends EventData { - - public EventData withFunction(Function value) { - setObject(value); - return this; - } - - public EventData withFunction(Function value, Class argClass) { - Objects.requireNonNull(argClass); - setObject(new TypedFunction<>(value, argClass)); - return this; - } - - public EventData withFunction(FilterFunction value) { - setObject(value); - return this; - } - - public EventData withFunction(FilterFunction value, Class argClass) { - setObject(new TypedFilterFunction<>(value, argClass)); - return this; - } - - public EventData withFunction(ContextFunction value) { - setObject(value); - return this; - } - - public EventData withFunction(ContextFunction value, Class argClass) { - setObject(new TypedContextFunction<>(value, argClass)); - return this; - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataPredicate.java deleted file mode 100644 index 1e6865eac..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventDataPredicate.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.api.types.EventData; -import java.util.Objects; -import java.util.function.Predicate; - -public class EventDataPredicate extends EventData { - - public EventDataPredicate withPredicate(Predicate predicate) { - setObject(predicate); - return this; - } - - public EventDataPredicate withPredicate(Predicate predicate, Class clazz) { - Objects.requireNonNull(clazz); - setObject(new TypedPredicate<>(predicate, clazz)); - return this; - } - - public EventDataPredicate withPredicate(ContextPredicate predicate) { - setObject(predicate); - return this; - } - - public EventDataPredicate withPredicate(ContextPredicate predicate, Class clazz) { - Objects.requireNonNull(clazz); - setObject(new TypedContextPredicate<>(predicate, clazz)); - return this; - } - - public EventDataPredicate withPredicate(FilterPredicate predicate) { - setObject(predicate); - return this; - } - - public EventDataPredicate withPredicate(FilterPredicate predicate, Class clazz) { - Objects.requireNonNull(clazz); - setObject(new TypedFilterPredicate<>(predicate, clazz)); - return this; - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventPropertiesPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventPropertiesPredicate.java deleted file mode 100644 index 4c1b774d3..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/EventPropertiesPredicate.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.api.types.EventProperties; -import java.util.Objects; -import java.util.function.Predicate; - -public class EventPropertiesPredicate extends EventProperties { - - private Object filterPredicate; - - public Object getFilterPredicate() { - return filterPredicate; - } - - public EventPropertiesPredicate withPredicate(Predicate predicate) { - this.filterPredicate = predicate; - return this; - } - - public EventPropertiesPredicate withPredicate(Predicate predicate, Class clazz) { - Objects.requireNonNull(clazz); - this.filterPredicate = new TypedPredicate<>(predicate, clazz); - return this; - } - - public EventPropertiesPredicate withPredicate(ContextPredicate predicate) { - this.filterPredicate = predicate; - return this; - } - - public EventPropertiesPredicate withPredicate(ContextPredicate predicate, Class clazz) { - Objects.requireNonNull(clazz); - this.filterPredicate = new TypedContextPredicate<>(predicate, clazz); - return this; - } - - public EventPropertiesPredicate withPredicate(FilterPredicate predicate) { - this.filterPredicate = predicate; - return this; - } - - public EventPropertiesPredicate withPredicate(FilterPredicate predicate, Class clazz) { - Objects.requireNonNull(clazz); - this.filterPredicate = new TypedFilterPredicate<>(predicate, clazz); - return this; - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterFunction.java deleted file mode 100644 index 916ae9eed..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterFunction.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.impl.TaskContextData; -import io.serverlessworkflow.impl.WorkflowContextData; - -@FunctionalInterface -public interface FilterFunction extends FunctionObject { - R apply(T object, WorkflowContextData workflowContext, TaskContextData taskContext); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterPredicate.java deleted file mode 100644 index e09b98b06..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterPredicate.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.impl.TaskContextData; -import io.serverlessworkflow.impl.WorkflowContextData; - -@FunctionalInterface -public interface FilterPredicate extends FunctionObject { - boolean test(T value, WorkflowContextData workflow, TaskContextData task); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterSerializable.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterSerializable.java deleted file mode 100644 index cdec9f30a..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FilterSerializable.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -/** Marker interfaces for types that might be serialized with ExportAs, OutputAs and InputFrom */ -public interface FilterSerializable {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FuncCloudEventPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FuncCloudEventPredicate.java deleted file mode 100644 index 995129350..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FuncCloudEventPredicate.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.cloudevents.CloudEvent; -import io.serverlessworkflow.impl.TaskContext; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.WorkflowContext; -import io.serverlessworkflow.impl.WorkflowModelFactory; -import io.serverlessworkflow.impl.WorkflowPredicate; -import io.serverlessworkflow.impl.events.CloudEventAttrPredicate; -import io.serverlessworkflow.impl.events.DefaultCloudEventPredicate; -import io.serverlessworkflow.impl.expressions.ExpressionDescriptor; - -public class FuncCloudEventPredicate extends DefaultCloudEventPredicate { - - private final CloudEventAttrPredicate envelopePredicate; - - public FuncCloudEventPredicate(EventPropertiesPredicate properties, WorkflowApplication app) { - super(properties, app); - Object envelopePredObj = properties.getFilterPredicate(); - this.envelopePredicate = - envelopePredObj == null - ? isTrue() - : fromCloudEvent( - app.modelFactory(), - app.expressionFactory() - .buildPredicate(new ExpressionDescriptor(null, envelopePredObj))); - } - - private CloudEventAttrPredicate fromCloudEvent( - WorkflowModelFactory workflowModelFactory, WorkflowPredicate filter) { - return (e, w, t) -> filter.test(w, t, workflowModelFactory.from(e)); - } - - @Override - public boolean test(CloudEvent event, WorkflowContext workflow, TaskContext task) { - return envelopePredicate.test(event, workflow, task) && super.test(event, workflow, task); - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FuncCloudEventPredicateFactory.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FuncCloudEventPredicateFactory.java deleted file mode 100644 index 13ec465c9..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FuncCloudEventPredicateFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.api.types.EventProperties; -import io.serverlessworkflow.impl.WorkflowApplication; -import io.serverlessworkflow.impl.events.CloudEventPredicate; -import io.serverlessworkflow.impl.events.CloudEventPredicateFactory; -import io.serverlessworkflow.impl.events.DefaultCloudEventPredicate; - -public class FuncCloudEventPredicateFactory implements CloudEventPredicateFactory { - - @Override - public CloudEventPredicate build(WorkflowApplication appl, EventProperties props) { - return props instanceof EventPropertiesPredicate funcProps - ? new FuncCloudEventPredicate(funcProps, appl) - : new DefaultCloudEventPredicate(props, appl); - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FunctionObject.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FunctionObject.java deleted file mode 100644 index f6647a2f8..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/FunctionObject.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.io.Serializable; - -/** - * Marked interface for objects that represent a function, predicate or consumer invoked by the - * runtime - */ -public interface FunctionObject extends Serializable, FilterSerializable {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/InstanceIdFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/InstanceIdFunction.java deleted file mode 100644 index 9af0d1d12..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/InstanceIdFunction.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -/** - * Functions that expect a workflow instance ID injection in runtime - * - * @param The task payload input - * @param The task result output - */ -@FunctionalInterface -public interface InstanceIdFunction extends FunctionObject { - R apply(String instanceId, T payload); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopFunction.java deleted file mode 100644 index a7cac96be..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopFunction.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.util.function.BiFunction; - -@FunctionalInterface -public interface LoopFunction extends FunctionObject, BiFunction {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopFunctionIndex.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopFunctionIndex.java deleted file mode 100644 index 38ec773cb..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopFunctionIndex.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -@FunctionalInterface -public interface LoopFunctionIndex extends FunctionObject { - R apply(T model, V item, Integer index); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicate.java deleted file mode 100644 index 0007ce1b2..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicate.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.util.function.BiPredicate; - -@FunctionalInterface -public interface LoopPredicate extends FunctionObject, BiPredicate {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndex.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndex.java deleted file mode 100644 index d4904721a..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndex.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -@FunctionalInterface -public interface LoopPredicateIndex extends FunctionObject { - boolean test(T model, V item, Integer index); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexContext.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexContext.java deleted file mode 100644 index 6c17fe98c..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexContext.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.impl.WorkflowContextData; - -@FunctionalInterface -public interface LoopPredicateIndexContext extends FunctionObject { - boolean test(T model, V item, Integer index, WorkflowContextData context); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexFilter.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexFilter.java deleted file mode 100644 index b25b00537..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/LoopPredicateIndexFilter.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import io.serverlessworkflow.impl.TaskContextData; -import io.serverlessworkflow.impl.WorkflowContextData; - -@FunctionalInterface -public interface LoopPredicateIndexFilter extends FunctionObject { - boolean test(T model, V item, Integer index, WorkflowContextData workflow, TaskContextData task); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializableConsumer.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializableConsumer.java deleted file mode 100644 index 430cdaf75..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializableConsumer.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.util.function.Consumer; - -@FunctionalInterface -public interface SerializableConsumer extends Consumer, FunctionObject {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializableFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializableFunction.java deleted file mode 100644 index 9daf11216..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializableFunction.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.util.function.Function; - -/** - * Alternative to Function for our DSL to discover the input parameter class in runtime via - * reflection. - * - * @param - * @param - */ -@FunctionalInterface -public interface SerializableFunction extends Function, FunctionObject {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializablePredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializablePredicate.java deleted file mode 100644 index 82f2159b9..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/SerializablePredicate.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.util.function.Predicate; - -@FunctionalInterface -public interface SerializablePredicate extends Predicate, FunctionObject {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextFunction.java deleted file mode 100644 index fd8d10bd3..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextFunction.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -public record TypedContextFunction(ContextFunction function, Class argClass) - implements FilterSerializable {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextPredicate.java deleted file mode 100644 index 4b9142588..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedContextPredicate.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -public record TypedContextPredicate(ContextPredicate predicate, Class argClass) - implements FilterSerializable {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterFunction.java deleted file mode 100644 index 71ee2d2c4..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterFunction.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -public record TypedFilterFunction(FilterFunction function, Class argClass) - implements FilterSerializable {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterPredicate.java deleted file mode 100644 index 462952dc7..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFilterPredicate.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -public record TypedFilterPredicate(FilterPredicate predicate, Class argClass) - implements FilterSerializable {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFunction.java deleted file mode 100644 index a17267c16..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedFunction.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.util.function.Function; - -public record TypedFunction(Function function, Class argClass) - implements FilterSerializable {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedPredicate.java deleted file mode 100644 index 762e9d3d7..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/TypedPredicate.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.util.function.Predicate; - -public record TypedPredicate(Predicate pred, Class argClass) - implements FilterSerializable {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/UniqueIdBiFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/UniqueIdBiFunction.java deleted file mode 100644 index 94c1347ce..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/func/UniqueIdBiFunction.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.func; - -import java.util.function.BiFunction; - -/** - * Functions that expect a unique ID injection in runtime, typically an idempotent generated unique - * id based on the workflow instance id and task name. - * - * @param The task payload input - * @param The task result output - */ -@FunctionalInterface -public interface UniqueIdBiFunction extends BiFunction, FunctionObject { - R apply(String uniqueId, T object); -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/ForTaskFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/ForTaskFunction.java deleted file mode 100644 index 4c185f655..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/ForTaskFunction.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.utils; - -import io.serverlessworkflow.api.types.ForTask; -import io.serverlessworkflow.api.types.ForTaskConfiguration; -import io.serverlessworkflow.api.types.TaskMetadata; -import io.serverlessworkflow.api.types.func.LoopPredicate; -import io.serverlessworkflow.api.types.func.LoopPredicateIndex; -import io.serverlessworkflow.api.types.func.LoopPredicateIndexContext; -import io.serverlessworkflow.api.types.func.LoopPredicateIndexFilter; -import java.lang.invoke.MethodType; -import java.util.Collection; -import java.util.Optional; -import java.util.function.Function; - -public class ForTaskFunction { - - private ForTaskFunction() {} - - public static final String WHILE_PREDICATE = "whilePredicate"; - public static final String WHILE_CLASS = "whileClass"; - public static final String ITEM_CLASS = "itemClass"; - public static final String FOR_CLASS = "forClass"; - public static final String COLLECTION = "inCollection"; - - public static ForTask withWhile(ForTask task, LoopPredicate whilePredicate) { - return withWhile(task, whilePredicate, Optional.empty(), Optional.empty()); - } - - public static ForTask withWhile( - ForTask task, LoopPredicate whilePredicate, Class modelClass) { - return withWhile(task, whilePredicate, Optional.ofNullable(modelClass), Optional.empty()); - } - - public static ForTask withWhile( - ForTask task, LoopPredicate whilePredicate, Class modelClass, Class itemClass) { - return withWhile( - task, whilePredicate, Optional.ofNullable(modelClass), Optional.ofNullable(itemClass)); - } - - public static ForTask withWhile(ForTask task, LoopPredicateIndex whilePredicate) { - return withWhile(task, whilePredicate, Optional.empty(), Optional.empty()); - } - - public static ForTask withWhile( - ForTask task, LoopPredicateIndex whilePredicate, Class modelClass) { - return withWhile(task, whilePredicate, Optional.ofNullable(modelClass), Optional.empty()); - } - - public static ForTask withWhile( - ForTask task, - LoopPredicateIndex whilePredicate, - Class modelClass, - Class itemClass) { - return withWhile( - task, whilePredicate, Optional.ofNullable(modelClass), Optional.ofNullable(itemClass)); - } - - public static ForTask withWhile( - ForTask task, LoopPredicateIndexContext whilePredicate) { - Optional methodType = ReflectionUtils.methodType(whilePredicate); - return withWhile( - task, - whilePredicate, - methodType.map(m -> m.parameterType(0)), - methodType.map(m -> m.parameterType(1))); - } - - public static ForTask withWhile( - ForTask task, LoopPredicateIndexContext whilePredicate, Class modelClass) { - return withWhile( - task, - whilePredicate, - Optional.ofNullable(modelClass), - ReflectionUtils.methodType(whilePredicate).map(m -> m.parameterType(1))); - } - - public static ForTask withWhile( - ForTask task, - LoopPredicateIndexContext whilePredicate, - Class modelClass, - Class itemClass) { - return withWhile( - task, whilePredicate, Optional.ofNullable(modelClass), Optional.ofNullable(itemClass)); - } - - public static ForTask withWhile( - ForTask task, LoopPredicateIndexFilter whilePredicate) { - Optional methodType = ReflectionUtils.methodType(whilePredicate); - return withWhile( - task, - whilePredicate, - methodType.map(m -> m.parameterType(0)), - methodType.map(m -> m.parameterType(1))); - } - - public static ForTask withWhile( - ForTask task, LoopPredicateIndexFilter whilePredicate, Class modelClass) { - return withWhile( - task, - whilePredicate, - Optional.ofNullable(modelClass), - ReflectionUtils.methodType(whilePredicate).map(m -> m.parameterType(1))); - } - - public static ForTask withWhile( - ForTask task, - LoopPredicateIndexFilter whilePredicate, - Class modelClass, - Class itemClass) { - return withWhile( - task, whilePredicate, Optional.ofNullable(modelClass), Optional.ofNullable(itemClass)); - } - - private static ForTask withWhile( - ForTask forTask, - Object whilePredicate, - Optional> modelClass, - Optional> itemClass) { - TypesUtils.initMetadata(forTask) - .withAdditionalProperty(WHILE_PREDICATE, whilePredicate) - .withAdditionalProperty(WHILE_CLASS, modelClass) - .withAdditionalProperty(ITEM_CLASS, itemClass); - return forTask; - } - - public static ForTask withCollection( - ForTask forTask, Function> collection) { - return withCollection(forTask, collection, null); - } - - public static ForTask withCollection( - ForTask forTask, Function> collection, Class colArgClass) { - TaskMetadata metadata = TypesUtils.initMetadata(forTask); - metadata.withAdditionalProperty(COLLECTION, collection); - metadata.withAdditionalProperty(FOR_CLASS, Optional.ofNullable(colArgClass)); - ForTaskConfiguration forConfig = forTask.getFor(); - if (forConfig == null) { - forConfig = new ForTaskConfiguration(); - forTask.setFor(forConfig); - } - if (forConfig.getIn() == null) { - forConfig.setIn("Handling item collection with metadata key " + ForTaskFunction.COLLECTION); - } - return forTask; - } - - public static Object getWhilePredicate(ForTask task) { - return task.getMetadata() == null - ? null - : task.getMetadata().getAdditionalProperties().get(WHILE_PREDICATE); - } - - public static Optional> getWhileClass(ForTask task) { - return task.getMetadata() == null - ? Optional.empty() - : (Optional>) - task.getMetadata() - .getAdditionalProperties() - .getOrDefault(WHILE_CLASS, Optional.empty()); - } - - public static Optional> getForClass(ForTask task) { - return task.getMetadata() == null - ? Optional.empty() - : (Optional>) - task.getMetadata().getAdditionalProperties().getOrDefault(FOR_CLASS, Optional.empty()); - } - - public static Optional> getItemClass(ForTask task) { - return task.getMetadata() == null - ? Optional.empty() - : (Optional>) - task.getMetadata().getAdditionalProperties().getOrDefault(ITEM_CLASS, Optional.empty()); - } - - public static Function> getInCollection(ForTask task) { - return task.getMetadata() == null - ? null - : (Function>) task.getMetadata().getAdditionalProperties().get(COLLECTION); - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/MapSetTaskConfiguration.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/MapSetTaskConfiguration.java deleted file mode 100644 index 4baa13286..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/MapSetTaskConfiguration.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.utils; - -import io.serverlessworkflow.api.types.SetTaskConfiguration; -import java.util.Map; - -public class MapSetTaskConfiguration { - - private MapSetTaskConfiguration() {} - - public static SetTaskConfiguration map(Map map) { - SetTaskConfiguration config = new SetTaskConfiguration(); - for (Map.Entry entry : map.entrySet()) { - config.withAdditionalProperty(entry.getKey(), entry.getValue()); - } - return config; - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/ReflectionUtils.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/ReflectionUtils.java deleted file mode 100644 index 2e1529a92..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/ReflectionUtils.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.utils; - -import io.serverlessworkflow.api.types.func.ContextFunction; -import io.serverlessworkflow.api.types.func.FilterFunction; -import io.serverlessworkflow.api.types.func.InstanceIdFunction; -import io.serverlessworkflow.api.types.func.SerializableConsumer; -import io.serverlessworkflow.api.types.func.SerializableFunction; -import io.serverlessworkflow.api.types.func.SerializablePredicate; -import io.serverlessworkflow.api.types.func.UniqueIdBiFunction; -import java.lang.invoke.MethodType; -import java.lang.invoke.SerializedLambda; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Optional; -import java.util.function.Function; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Specially used by {@link Function} parameters in the Java Function. - * - * @see Serialize a Lambda in Java - */ -public final class ReflectionUtils { - - private static final Logger logger = LoggerFactory.getLogger(ReflectionUtils.class); - - private ReflectionUtils() {} - - @SuppressWarnings("unchecked") - public static Class inferInputType(ContextFunction fn) { - return (Class) inferInputTypeFromAny(fn, 0); - } - - @SuppressWarnings("unchecked") - public static Class inferInputType(FilterFunction fn) { - return (Class) inferInputTypeFromAny(fn, 0); - } - - @SuppressWarnings("unchecked") - public static Class inferInputType(SerializableFunction fn) { - return (Class) inferInputTypeFromAny(fn, 0); - } - - @SuppressWarnings("unchecked") - public static Class inferInputType(SerializablePredicate fn) { - return (Class) inferInputTypeFromAny(fn, 0); - } - - @SuppressWarnings("unchecked") - public static Class inferInputType(InstanceIdFunction fn) { - return (Class) inferInputTypeFromAny(fn, 1); - } - - @SuppressWarnings("unchecked") - public static Class inferInputType(UniqueIdBiFunction fn) { - return (Class) inferInputTypeFromAny(fn, 1); - } - - @SuppressWarnings("unchecked") - public static Class inferInputType(SerializableConsumer fn) { - return (Class) inferInputTypeFromAny(fn, 0); - } - - @SuppressWarnings("unchecked") - public static Class inferResultType(Object fn) { - return (Class) inferOutputType(inferMethodType(fn)); - } - - public static Class inferInputTypeFromAny(Object fn, int lambdaParamIndex) { - return inferInputType(inferMethodType(fn), lambdaParamIndex); - } - - public static Optional serializedFromFunction(Object fn) { - try { - return Optional.of(serializedLambda(fn)); - } catch (ReflectiveOperationException ex) { - logger.debug("Error resolving serialized lambda for {}", fn, ex); - return Optional.empty(); - } - } - - public static Class loadCapturingClass(String capturingClass) throws ClassNotFoundException { - return loadClass(capturingClass.replace('/', '.')); - } - - public static Class loadClass(String className) throws ClassNotFoundException { - return Class.forName(className, false, getClassLoader()); - } - - private static ClassLoader getClassLoader() { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (cl == null) { - cl = ReflectionUtils.class.getClassLoader(); - if (cl == null) { - cl = ClassLoader.getSystemClassLoader(); - } - } - return cl; - } - - public static Object functionFromSerialized(SerializedLambda sl) - throws ReflectiveOperationException { - Method deserializeMethod = - loadCapturingClass(sl.getCapturingClass()) - .getDeclaredMethod("$deserializeLambda$", SerializedLambda.class); - deserializeMethod.setAccessible(true); - return deserializeMethod.invoke(null, sl); - } - - public static Optional methodType(Object fn) { - return serializedFromFunction(fn).map(ReflectionUtils::inferMethodType); - } - - public static MethodType inferMethodType(SerializedLambda sl) { - // getInstantiatedMethodType() provides the exact generic signature resolved - // by the compiler, completely bypassing captured variables and method kind switches! - return MethodType.fromMethodDescriptorString(sl.getInstantiatedMethodType(), getClassLoader()); - } - - public static SerializedLambda serializedLambda(Object fn) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - Method m = fn.getClass().getDeclaredMethod("writeReplace"); - m.setAccessible(true); - return (SerializedLambda) m.invoke(fn); - } - - private static Class inferInputType(MethodType type, int index) { - return type.parameterType(index); - } - - private static Class inferOutputType(MethodType type) { - return type.returnType(); - } - - private static MethodType inferMethodType(Object fn) { - try { - SerializedLambda sl = serializedLambda(fn); - return inferMethodType(sl); - } catch (ReflectiveOperationException ex) { - throw new IllegalStateException( - "Cannot infer type from lambda. Pass Class or use a method reference.", ex); - } - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TaskMetadataKeys.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TaskMetadataKeys.java deleted file mode 100644 index b0a4c3a16..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TaskMetadataKeys.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.utils; - -public final class TaskMetadataKeys {} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TaskPredicate.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TaskPredicate.java deleted file mode 100644 index 0d3062c95..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TaskPredicate.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.utils; - -import io.serverlessworkflow.api.types.TaskBase; -import io.serverlessworkflow.api.types.TaskMetadata; -import io.serverlessworkflow.api.types.func.ContextPredicate; -import io.serverlessworkflow.api.types.func.FilterPredicate; -import io.serverlessworkflow.api.types.func.TypedContextPredicate; -import io.serverlessworkflow.api.types.func.TypedFilterPredicate; -import io.serverlessworkflow.api.types.func.TypedPredicate; -import java.util.function.Predicate; - -public class TaskPredicate { - - private static final String PREDICATE_KEY_PREFIX = "predicate-"; - - private TaskPredicate() {} - - public static TaskMetadata withPredicate( - V task, String name, Predicate predicate) { - return TypesUtils.initMetadata(task).withAdditionalProperty(concat(name), predicate); - } - - public static V withPredicate( - V task, String name, Predicate predicate, Class predicateClass) { - TypesUtils.initMetadata(task) - .withAdditionalProperty( - concat(name), - predicateClass == null ? predicate : new TypedPredicate<>(predicate, predicateClass)); - return task; - } - - public static V withPredicate( - V task, String name, ContextPredicate predicate) { - TypesUtils.initMetadata(task).withAdditionalProperty(concat(name), predicate); - return task; - } - - public static V withPredicate( - V task, String name, ContextPredicate predicate, Class predicateClass) { - TypesUtils.initMetadata(task) - .withAdditionalProperty( - concat(name), - predicateClass == null - ? predicate - : new TypedContextPredicate<>(predicate, predicateClass)); - return task; - } - - public static V withPredicate( - V task, String name, FilterPredicate predicate) { - TypesUtils.initMetadata(task).withAdditionalProperty(concat(name), predicate); - return task; - } - - public static V withPredicate( - V task, String name, FilterPredicate predicate, Class predicateClass) { - TypesUtils.initMetadata(task) - .withAdditionalProperty( - concat(name), - predicateClass == null - ? predicate - : new TypedFilterPredicate<>(predicate, predicateClass)); - return task; - } - - public static Object predicate(TaskBase task, String name) { - return task.getMetadata() != null - ? task.getMetadata().getAdditionalProperties().get(concat(name)) - : null; - } - - private static String concat(String name) { - return PREDICATE_KEY_PREFIX + name; - } -} diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TypesUtils.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TypesUtils.java deleted file mode 100644 index 825c21762..000000000 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/utils/TypesUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2020-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.serverlessworkflow.api.types.utils; - -import io.serverlessworkflow.api.types.TaskBase; -import io.serverlessworkflow.api.types.TaskMetadata; - -public class TypesUtils { - - private TypesUtils() {} - - /** Metadata entry name for the DSL’s “when”/“if” predicate. */ - public static final String IF_PREDICATE = "if_predicate"; - - /** Metadata entry name for event until predicate */ - public static final String UNTIL_PRED_NAME = "until"; - - public static TaskMetadata initMetadata(TaskBase task) { - TaskMetadata metadata = task.getMetadata(); - if (metadata == null) { - metadata = new TaskMetadata(); - task.setMetadata(metadata); - } - return metadata; - } -} diff --git a/experimental/types/src/main/resources/META-INF/services/io.serverlessworkflow.impl.events.CloudEventPredicateFactory b/experimental/types/src/main/resources/META-INF/services/io.serverlessworkflow.impl.events.CloudEventPredicateFactory deleted file mode 100644 index 4e2a7f991..000000000 --- a/experimental/types/src/main/resources/META-INF/services/io.serverlessworkflow.impl.events.CloudEventPredicateFactory +++ /dev/null @@ -1 +0,0 @@ -io.serverlessworkflow.api.types.func.FuncCloudEventPredicateFactory \ No newline at end of file diff --git a/pom.xml b/pom.xml index b7efc6616..7edb100a2 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,6 @@ annotations generators serialization - experimental fluent mermaid bom