From 0012d2a1eed521bea3ca92f436a167e9fe6b7456 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 11:23:37 -0500 Subject: [PATCH 01/22] Bump org.sonatype.plugins:nexus-staging-maven-plugin (#533) Bumps org.sonatype.plugins:nexus-staging-maven-plugin from 1.6.13 to 1.7.0. --- updated-dependencies: - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e054f843..2096ad4c 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ 3.1.1 3.3.1 3.5.2 - 1.6.13 + 1.7.0 From 491c2dc26108c77b7d69413fdf0d542c52a0d907 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:17:04 -0500 Subject: [PATCH 02/22] Bump version.org.junit.jupiter from 5.11.4 to 5.12.0 (#536) Bumps `version.org.junit.jupiter` from 5.11.4 to 5.12.0. Updates `org.junit.jupiter:junit-jupiter-api` from 5.11.4 to 5.12.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.4 to 5.12.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0) Updates `org.junit.jupiter:junit-jupiter-params` from 5.11.4 to 5.12.0 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.junit.jupiter:junit-jupiter-params dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2096ad4c..f446c562 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 3.1.1 1.5.2 3.27.3 - 5.11.4 + 5.12.0 5.15.2 2.0.16 8.0.2.Final From bc7e0c37f8aaaafce7e3f08364b759c92b1e2996 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:17:19 -0500 Subject: [PATCH 03/22] Bump org.apache.maven.plugins:maven-compiler-plugin (#534) Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.13.0 to 3.14.0. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.13.0...maven-compiler-plugin-3.14.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f446c562..f151cc11 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 3.2.1 3.6.0 - 3.13.0 + 3.14.0 3.1.3 3.5.0 3.5.2 From 75ce0d19e0c6245e747e0547ba893645a138df06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:17:40 -0500 Subject: [PATCH 04/22] Bump com.networknt:json-schema-validator from 1.5.5 to 1.5.6 (#535) Bumps [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) from 1.5.5 to 1.5.6. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/1.5.5...1.5.6) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f151cc11..3e8349ec 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ 1.5.16 2.18.2 - 1.5.5 + 1.5.6 3.1.1 1.5.2 3.27.3 From 9452cc2f4526f973d97ef5146aefc9f08c084319 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 13:53:45 +0000 Subject: [PATCH 05/22] Bump org.apache.maven.plugins:maven-deploy-plugin from 3.1.3 to 3.1.4 Bumps [org.apache.maven.plugins:maven-deploy-plugin](https://github.com/apache/maven-deploy-plugin) from 3.1.3 to 3.1.4. - [Release notes](https://github.com/apache/maven-deploy-plugin/releases) - [Commits](https://github.com/apache/maven-deploy-plugin/compare/maven-deploy-plugin-3.1.3...maven-deploy-plugin-3.1.4) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-deploy-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3e8349ec..0495b073 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 3.2.1 3.6.0 3.14.0 - 3.1.3 + 3.1.4 3.5.0 3.5.2 2.25 From b609cbd1233a470f8411d0855acd8d62437d7ebc Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Mon, 3 Mar 2025 16:08:05 +0100 Subject: [PATCH 06/22] Fixing tests problems with swagger pet api and post call Signed-off-by: Francisco Javier Tirado Sarti --- impl/http/pom.xml | 5 +++++ .../impl/HTTPWorkflowDefinitionTest.java | 2 +- .../http/src/test/resources/callPostHttp.yaml | 19 ++++--------------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/impl/http/pom.xml b/impl/http/pom.xml index fdf2a168..0df48fb3 100644 --- a/impl/http/pom.xml +++ b/impl/http/pom.xml @@ -41,5 +41,10 @@ assertj-core test + + ch.qos.logback + logback-classic + test + \ No newline at end of file diff --git a/impl/http/src/test/java/io/serverlessworkflow/impl/HTTPWorkflowDefinitionTest.java b/impl/http/src/test/java/io/serverlessworkflow/impl/HTTPWorkflowDefinitionTest.java index 7492be53..badb6403 100644 --- a/impl/http/src/test/java/io/serverlessworkflow/impl/HTTPWorkflowDefinitionTest.java +++ b/impl/http/src/test/java/io/serverlessworkflow/impl/HTTPWorkflowDefinitionTest.java @@ -98,7 +98,7 @@ private static Stream provideParameters() { "call-http-query-parameters-external-schema.yaml", starTrekInput, starTrekCondition), Arguments.of( "callPostHttp.yaml", - Map.of("name", "Javierito", "status", "available"), + Map.of("name", "Javierito", "surname", "Unknown"), new Condition<>(o -> o.equals("Javierito"), "CallHttpPostCondition"))); } } diff --git a/impl/http/src/test/resources/callPostHttp.yaml b/impl/http/src/test/resources/callPostHttp.yaml index d66dcfaa..f12fec42 100644 --- a/impl/http/src/test/resources/callPostHttp.yaml +++ b/impl/http/src/test/resources/callPostHttp.yaml @@ -9,20 +9,9 @@ do: with: method: post endpoint: - uri: https://petstore.swagger.io/v2/pet + uri: https://fakerestapi.azurewebsites.net/api/v1/Authors body: - name: ${.name} - status: ${.status} + firstName: ${.name} + lastName: ${.surname } output: - as: .id - - getPet: - call: http - with: - method: get - endpoint: - uri: https://petstore.swagger.io/v2/pet/{petId} - input: - from: - petId: ${.} - output: - as: .name \ No newline at end of file + as: .firstName \ No newline at end of file From e723607efa10c6df3ffbc66051ab2be91045589a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:00:22 -0500 Subject: [PATCH 07/22] Bump ch.qos.logback:logback-classic from 1.5.16 to 1.5.17 (#537) Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.5.16 to 1.5.17. - [Release notes](https://github.com/qos-ch/logback/releases) - [Commits](https://github.com/qos-ch/logback/compare/v_1.5.16...v_1.5.17) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0495b073..62554713 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,7 @@ - 1.5.16 + 1.5.17 2.18.2 1.5.6 3.1.1 From 72991f47af3b05c447a25f41c86bb9a03d7ed110 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:01:01 -0500 Subject: [PATCH 08/22] Bump org.slf4j:slf4j-api from 2.0.16 to 2.0.17 (#538) Bumps org.slf4j:slf4j-api from 2.0.16 to 2.0.17. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 62554713..8a3596ea 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.27.3 5.12.0 5.15.2 - 2.0.16 + 2.0.17 8.0.2.Final 5.0.0 From 60c017ce8b297e63fde80beacb97997c3f906553 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:05:22 -0500 Subject: [PATCH 09/22] Bump org.mockito:mockito-core from 5.15.2 to 5.16.0 (#541) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.15.2 to 5.16.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.15.2...v5.16.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8a3596ea..60a839da 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 1.5.2 3.27.3 5.12.0 - 5.15.2 + 5.16.0 2.0.17 8.0.2.Final 5.0.0 From 3d51906d6a85b3f94dcc3126e272bbb1df348942 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:05:35 -0500 Subject: [PATCH 10/22] Bump version.com.fasterxml.jackson from 2.18.2 to 2.18.3 (#540) Bumps `version.com.fasterxml.jackson` from 2.18.2 to 2.18.3. Updates `com.fasterxml.jackson.core:jackson-core` from 2.18.2 to 2.18.3 - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.18.2...jackson-core-2.18.3) Updates `com.fasterxml.jackson.core:jackson-databind` from 2.18.2 to 2.18.3 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `com.fasterxml.jackson.dataformat:jackson-dataformat-yaml` from 2.18.2 to 2.18.3 - [Commits](https://github.com/FasterXML/jackson-dataformats-text/compare/jackson-dataformats-text-2.18.2...jackson-dataformats-text-2.18.3) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 60a839da..fd359fa9 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,7 @@ 1.5.17 - 2.18.2 + 2.18.3 1.5.6 3.1.1 1.5.2 From 982f2d189c3516f6af65945ab742133cd6859f03 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Wed, 5 Mar 2025 12:57:21 +0100 Subject: [PATCH 11/22] [Fix #543] Not compiled dependencies should be runtime Signed-off-by: Francisco Javier Tirado Sarti --- api/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/pom.xml b/api/pom.xml index 69f8c2f5..2b08c827 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -40,10 +40,12 @@ org.hibernate.validator hibernate-validator + runtime org.glassfish.expressly expressly + runtime From 18b84453103e61f225e8f240a68f5bc0fca4440a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 14:33:13 -0400 Subject: [PATCH 12/22] Bump org.mockito:mockito-core from 5.16.0 to 5.16.1 (#547) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.16.0 to 5.16.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.16.0...v5.16.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fd359fa9..9002f235 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 1.5.2 3.27.3 5.12.0 - 5.16.0 + 5.16.1 2.0.17 8.0.2.Final 5.0.0 From 9129e9285d600497ab24b7904c7a1bb49056f7a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 14:38:08 -0400 Subject: [PATCH 13/22] Bump version.org.junit.jupiter from 5.12.0 to 5.12.1 (#546) Bumps `version.org.junit.jupiter` from 5.12.0 to 5.12.1. Updates `org.junit.jupiter:junit-jupiter-api` from 5.12.0 to 5.12.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.12.0 to 5.12.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1) Updates `org.junit.jupiter:junit-jupiter-params` from 5.12.0 to 5.12.1 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit.jupiter:junit-jupiter-params dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9002f235..b17f0895 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 3.1.1 1.5.2 3.27.3 - 5.12.0 + 5.12.1 5.16.1 2.0.17 8.0.2.Final From bc15319752ace9e584448ed337e7be5885870414 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 13:23:16 -0400 Subject: [PATCH 14/22] Bump ch.qos.logback:logback-classic from 1.5.17 to 1.5.18 (#548) Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.5.17 to 1.5.18. - [Release notes](https://github.com/qos-ch/logback/releases) - [Commits](https://github.com/qos-ch/logback/compare/v_1.5.17...v_1.5.18) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b17f0895..7a55c21a 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,7 @@ - 1.5.17 + 1.5.18 2.18.3 1.5.6 3.1.1 From bab05ebe3a81138b7b38e566d8e2325b65f6f7ee Mon Sep 17 00:00:00 2001 From: fjtirado Date: Thu, 27 Mar 2025 17:24:52 +0100 Subject: [PATCH 15/22] [Fix_#549] Implement if for all task Signed-off-by: fjtirado --- .../impl/executors/AbstractTaskExecutor.java | 77 +++++++++++-------- .../impl/executors/RegularTaskExecutor.java | 5 ++ .../impl/executors/SwitchExecutor.java | 5 ++ .../impl/WorkflowDefinitionTest.java | 18 +++++ .../src/test/resources/conditional-set.yaml | 10 +++ 5 files changed, 83 insertions(+), 32 deletions(-) create mode 100644 impl/core/src/test/resources/conditional-set.yaml diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/AbstractTaskExecutor.java b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/AbstractTaskExecutor.java index f51b7a01..23ca9a22 100644 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/AbstractTaskExecutor.java +++ b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/AbstractTaskExecutor.java @@ -49,12 +49,14 @@ public abstract class AbstractTaskExecutor implements TaskEx private final Optional inputSchemaValidator; private final Optional outputSchemaValidator; private final Optional contextSchemaValidator; + private final Optional ifFilter; public abstract static class AbstractTaskExecutorBuilder implements TaskExecutorBuilder { private Optional inputProcessor = Optional.empty(); private Optional outputProcessor = Optional.empty(); private Optional contextProcessor = Optional.empty(); + private Optional ifFilter = Optional.empty(); private Optional inputSchemaValidator = Optional.empty(); private Optional outputSchemaValidator = Optional.empty(); private Optional contextSchemaValidator = Optional.empty(); @@ -100,6 +102,7 @@ protected AbstractTaskExecutorBuilder( this.contextSchemaValidator = getSchemaValidator(application.validatorFactory(), resourceLoader, export.getSchema()); } + this.ifFilter = optionalFilter(application.expressionFactory(), task.getIf()); } protected final TransitionInfoBuilder next( @@ -153,6 +156,7 @@ protected AbstractTaskExecutor(AbstractTaskExecutorBuilder builder) { this.inputSchemaValidator = builder.inputSchemaValidator; this.outputSchemaValidator = builder.outputSchemaValidator; this.contextSchemaValidator = builder.contextSchemaValidator; + this.ifFilter = builder.ifFilter; } protected final CompletableFuture executeNext( @@ -177,40 +181,49 @@ public CompletableFuture apply( if (!TaskExecutorHelper.isActive(workflowContext)) { return completable; } - return executeNext( - completable - .thenApply( - t -> { - workflowContext - .definition() - .listeners() - .forEach(l -> l.onTaskStarted(position, task)); - inputSchemaValidator.ifPresent(s -> s.validate(t.rawInput())); - inputProcessor.ifPresent( - p -> taskContext.input(p.apply(workflowContext, t, t.rawInput()))); - return t; - }) - .thenCompose(t -> execute(workflowContext, t)) - .thenApply( - t -> { - outputProcessor.ifPresent( - p -> t.output(p.apply(workflowContext, t, t.rawOutput()))); - outputSchemaValidator.ifPresent(s -> s.validate(t.output())); - contextProcessor.ifPresent( - p -> - workflowContext.context( - p.apply(workflowContext, t, workflowContext.context()))); - contextSchemaValidator.ifPresent(s -> s.validate(workflowContext.context())); - t.completedAt(Instant.now()); - workflowContext - .definition() - .listeners() - .forEach(l -> l.onTaskEnded(position, task)); - return t; - }), - workflowContext); + if (ifFilter + .map(f -> f.apply(workflowContext, taskContext, input).asBoolean(true)) + .orElse(true)) { + return executeNext( + completable + .thenApply( + t -> { + workflowContext + .definition() + .listeners() + .forEach(l -> l.onTaskStarted(position, task)); + inputSchemaValidator.ifPresent(s -> s.validate(t.rawInput())); + inputProcessor.ifPresent( + p -> taskContext.input(p.apply(workflowContext, t, t.rawInput()))); + return t; + }) + .thenCompose(t -> execute(workflowContext, t)) + .thenApply( + t -> { + outputProcessor.ifPresent( + p -> t.output(p.apply(workflowContext, t, t.rawOutput()))); + outputSchemaValidator.ifPresent(s -> s.validate(t.output())); + contextProcessor.ifPresent( + p -> + workflowContext.context( + p.apply(workflowContext, t, workflowContext.context()))); + contextSchemaValidator.ifPresent(s -> s.validate(workflowContext.context())); + t.completedAt(Instant.now()); + workflowContext + .definition() + .listeners() + .forEach(l -> l.onTaskEnded(position, task)); + return t; + }), + workflowContext); + } else { + taskContext.transition(getSkipTransition()); + return executeNext(completable, workflowContext); + } } + protected abstract TransitionInfo getSkipTransition(); + protected abstract CompletableFuture execute( WorkflowContext workflow, TaskContext taskContext); } diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RegularTaskExecutor.java b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RegularTaskExecutor.java index 24c1e841..7cac9a8e 100644 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RegularTaskExecutor.java +++ b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RegularTaskExecutor.java @@ -54,6 +54,11 @@ public void connect(Map> connections) { } } + @Override + protected TransitionInfo getSkipTransition() { + return transition; + } + protected CompletableFuture execute( WorkflowContext workflow, TaskContext taskContext) { CompletableFuture future = diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/SwitchExecutor.java b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/SwitchExecutor.java index 70b127c4..9bd3a74a 100644 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/SwitchExecutor.java +++ b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/SwitchExecutor.java @@ -79,6 +79,11 @@ protected TaskExecutor buildInstance() { } } + @Override + protected TransitionInfo getSkipTransition() { + return defaultTask; + } + private SwitchExecutor(SwitchExecutorBuilder builder) { super(builder); this.defaultTask = TransitionInfo.build(builder.defaultTask); diff --git a/impl/core/src/test/java/io/serverlessworkflow/impl/WorkflowDefinitionTest.java b/impl/core/src/test/java/io/serverlessworkflow/impl/WorkflowDefinitionTest.java index 4ea87283..4a0a073f 100644 --- a/impl/core/src/test/java/io/serverlessworkflow/impl/WorkflowDefinitionTest.java +++ b/impl/core/src/test/java/io/serverlessworkflow/impl/WorkflowDefinitionTest.java @@ -81,6 +81,14 @@ private static Stream provideParameters() { "simple-expression.yaml", Map.of("input", Arrays.asList(1, 2, 3)), WorkflowDefinitionTest::checkSpecialKeywords), + args( + "conditional-set.yaml", + Map.of("enabled", true), + WorkflowDefinitionTest::checkEnableCondition), + args( + "conditional-set.yaml", + Map.of("enabled", false), + WorkflowDefinitionTest::checkDisableCondition), args( "raise-inline copy.yaml", WorkflowDefinitionTest::checkWorkflowException, @@ -166,4 +174,14 @@ private static void checkSpecialKeywords(Object obj) { assertThat(result.get("id").toString()).hasSize(26); assertThat(result.get("version").toString()).contains("alpha"); } + + private static void checkEnableCondition(Object obj) { + Map result = (Map) obj; + assertThat(result.get("name")).isEqualTo("javierito"); + } + + private static void checkDisableCondition(Object obj) { + Map result = (Map) obj; + assertThat(result.get("enabled")).isEqualTo(false); + } } diff --git a/impl/core/src/test/resources/conditional-set.yaml b/impl/core/src/test/resources/conditional-set.yaml new file mode 100644 index 00000000..5e06622d --- /dev/null +++ b/impl/core/src/test/resources/conditional-set.yaml @@ -0,0 +1,10 @@ +document: + dsl: '1.0.0-alpha5' + namespace: test + name: conditional-set + version: '0.1.0' +do: + - conditionalExpression: + if: .enabled + set: + name: javierito \ No newline at end of file From 9772676e989d2181f906000fa29e1da6c9de5fb4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:13:16 +0000 Subject: [PATCH 16/22] Bump org.apache.maven.plugins:maven-failsafe-plugin from 3.5.2 to 3.5.3 Bumps [org.apache.maven.plugins:maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.5.2 to 3.5.3. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.2...surefire-3.5.3) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7a55c21a..ad04fe6e 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 3.14.0 3.1.4 3.5.0 - 3.5.2 + 3.5.3 2.25 3.2.7 3.4.2 From bc06196affd6b77e0eb6c9d590d0df8505eaefab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:13:24 +0000 Subject: [PATCH 17/22] Bump org.apache.maven.plugins:maven-surefire-plugin from 3.5.2 to 3.5.3 Bumps [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.5.2 to 3.5.3. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.2...surefire-3.5.3) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7a55c21a..0beab9dd 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,7 @@ 3.11.2 3.1.1 3.3.1 - 3.5.2 + 3.5.3 1.7.0 From 145295040a9d9215cd0c849127dc0908a859f88f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 14:11:22 +0000 Subject: [PATCH 18/22] Bump org.mockito:mockito-core from 5.16.1 to 5.17.0 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.16.1 to 5.17.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.16.1...v5.17.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-version: 5.17.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ca410bef..317b5b8c 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 1.5.2 3.27.3 5.12.1 - 5.16.1 + 5.17.0 2.0.17 8.0.2.Final 5.0.0 From 53ee8ab53afcab9d0c1f33e28705ca14fc681385 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 11:40:09 -0400 Subject: [PATCH 19/22] Bump version.org.junit.jupiter from 5.12.1 to 5.12.2 (#556) Bumps `version.org.junit.jupiter` from 5.12.1 to 5.12.2. Updates `org.junit.jupiter:junit-jupiter-api` from 5.12.1 to 5.12.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.12.1 to 5.12.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2) Updates `org.junit.jupiter:junit-jupiter-params` from 5.12.1 to 5.12.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-version: 5.12.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-version: 5.12.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit.jupiter:junit-jupiter-params dependency-version: 5.12.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 317b5b8c..2f623e9a 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 3.1.1 1.5.2 3.27.3 - 5.12.1 + 5.12.2 5.17.0 2.0.17 8.0.2.Final From 53ee49ef621fc5b204119ae44e07f669da5c3944 Mon Sep 17 00:00:00 2001 From: fjtirado Date: Tue, 29 Apr 2025 13:24:47 +0200 Subject: [PATCH 20/22] [Fix_#555] New inheritance approach in schema Signed-off-by: fjtirado --- api/src/main/resources/schema/workflow.yaml | 1126 +++++++++-------- .../generator/AllAnyOneOfSchemaRule.java | 195 ++- .../impl/executors/RaiseExecutor.java | 11 +- .../impl/executors/SetExecutor.java | 27 +- .../impl/executors/HttpExecutor.java | 49 +- 5 files changed, 790 insertions(+), 618 deletions(-) diff --git a/api/src/main/resources/schema/workflow.yaml b/api/src/main/resources/schema/workflow.yaml index b59e2f3a..73bda7ee 100644 --- a/api/src/main/resources/schema/workflow.yaml +++ b/api/src/main/resources/schema/workflow.yaml @@ -1,4 +1,4 @@ -$id: https://serverlessworkflow.io/schemas/1.0.0-alpha5/workflow.yaml +$id: https://serverlessworkflow.io/schemas/1.0.1/workflow.yaml $schema: https://json-schema.org/draft/2020-12/schema description: Serverless Workflow DSL - Workflow Schema. type: object @@ -226,638 +226,664 @@ $defs: oneOf: - title: CallAsyncAPI description: Defines the AsyncAPI call to perform. - $ref: '#/$defs/taskBase' type: object required: [ call, with ] unevaluatedProperties: false - properties: - call: - type: string - const: asyncapi - with: - type: object - title: AsyncApiArguments - description: The Async API call arguments. - properties: - document: - $ref: '#/$defs/externalResource' - title: AsyncAPIDocument - description: The document that defines the AsyncAPI operation to call. - channel: - type: string - title: With - description: The name of the channel on which to perform the operation. Used only in case the referenced document uses AsyncAPI v2.6.0. - operation: - type: string - title: AsyncAPIOperation - description: A reference to the AsyncAPI operation to call. - server: - $ref: '#/$defs/asyncApiServer' - title: AsyncAPIServer - description: An object used to configure to the server to call the specified AsyncAPI operation on. - protocol: - type: string - title: AsyncApiProtocol - description: The protocol to use to select the target server. - enum: [ amqp, amqp1, anypointmq, googlepubsub, http, ibmmq, jms, kafka, mercure, mqtt, mqtt5, nats, pulsar, redis, sns, solace, sqs, stomp, ws ] - message: - $ref: '#/$defs/asyncApiOutboundMessage' - title: AsyncApiMessage - description: An object used to configure the message to publish using the target operation. - subscription: - $ref: '#/$defs/asyncApiSubscription' - title: AsyncApiSubscription - description: An object used to configure the subscription to messages consumed using the target operation. - authentication: - $ref: '#/$defs/referenceableAuthenticationPolicy' - title: AsyncAPIAuthentication - description: The authentication policy, if any, to use when calling the AsyncAPI operation. - oneOf: - - required: [ document, operation, message ] - - required: [ document, operation, subscription ] - - required: [ document, channel, message ] - - required: [ document, channel, subscription ] - unevaluatedProperties: false + allOf: + - $ref: '#/$defs/taskBase' + - properties: + call: + type: string + const: asyncapi + with: + type: object + title: AsyncApiArguments + description: The Async API call arguments. + properties: + document: + $ref: '#/$defs/externalResource' + title: AsyncAPIDocument + description: The document that defines the AsyncAPI operation to call. + channel: + type: string + title: With + description: The name of the channel on which to perform the operation. Used only in case the referenced document uses AsyncAPI v2.6.0. + operation: + type: string + title: AsyncAPIOperation + description: A reference to the AsyncAPI operation to call. + server: + $ref: '#/$defs/asyncApiServer' + title: AsyncAPIServer + description: An object used to configure to the server to call the specified AsyncAPI operation on. + protocol: + type: string + title: AsyncApiProtocol + description: The protocol to use to select the target server. + enum: [ amqp, amqp1, anypointmq, googlepubsub, http, ibmmq, jms, kafka, mercure, mqtt, mqtt5, nats, pulsar, redis, sns, solace, sqs, stomp, ws ] + message: + $ref: '#/$defs/asyncApiOutboundMessage' + title: AsyncApiMessage + description: An object used to configure the message to publish using the target operation. + subscription: + $ref: '#/$defs/asyncApiSubscription' + title: AsyncApiSubscription + description: An object used to configure the subscription to messages consumed using the target operation. + authentication: + $ref: '#/$defs/referenceableAuthenticationPolicy' + title: AsyncAPIAuthentication + description: The authentication policy, if any, to use when calling the AsyncAPI operation. + oneOf: + - required: [ document, operation, message ] + - required: [ document, operation, subscription ] + - required: [ document, channel, message ] + - required: [ document, channel, subscription ] + unevaluatedProperties: false - title: CallGRPC description: Defines the GRPC call to perform. - $ref: '#/$defs/taskBase' type: object unevaluatedProperties: false required: [ call, with ] - properties: - call: - type: string - const: grpc - with: - type: object - title: GRPCArguments - description: The GRPC call arguments. - properties: - proto: - $ref: '#/$defs/externalResource' - title: WithGRPCProto - description: The proto resource that describes the GRPC service to call. - service: - type: object - title: WithGRPCService - unevaluatedProperties: false - properties: - name: - type: string - title: WithGRPCServiceName - description: The name of the GRPC service to call. - host: - type: string - title: WithGRPCServiceHost - description: The hostname of the GRPC service to call. - pattern: ^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$ - port: - type: integer - title: WithGRPCServicePost - description: The port number of the GRPC service to call. - minimum: 0 - maximum: 65535 - authentication: - $ref: '#/$defs/referenceableAuthenticationPolicy' - title: WithGRPCServiceAuthentication - description: The endpoint's authentication policy, if any. - required: [ name, host ] - method: - type: string - title: WithGRPCMethod - description: The name of the method to call on the defined GRPC service. - arguments: - type: object - title: WithGRPCArguments - description: The arguments, if any, to call the method with. - additionalProperties: true - required: [ proto, service, method ] - unevaluatedProperties: false + allOf: + - $ref: '#/$defs/taskBase' + - properties: + call: + type: string + const: grpc + with: + type: object + title: GRPCArguments + description: The GRPC call arguments. + properties: + proto: + $ref: '#/$defs/externalResource' + title: WithGRPCProto + description: The proto resource that describes the GRPC service to call. + service: + type: object + title: WithGRPCService + unevaluatedProperties: false + properties: + name: + type: string + title: WithGRPCServiceName + description: The name of the GRPC service to call. + host: + type: string + title: WithGRPCServiceHost + description: The hostname of the GRPC service to call. + pattern: ^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$ + port: + type: integer + title: WithGRPCServicePost + description: The port number of the GRPC service to call. + minimum: 0 + maximum: 65535 + authentication: + $ref: '#/$defs/referenceableAuthenticationPolicy' + title: WithGRPCServiceAuthentication + description: The endpoint's authentication policy, if any. + required: [ name, host ] + method: + type: string + title: WithGRPCMethod + description: The name of the method to call on the defined GRPC service. + arguments: + type: object + title: WithGRPCArguments + description: The arguments, if any, to call the method with. + additionalProperties: true + required: [ proto, service, method ] + unevaluatedProperties: false - title: CallHTTP description: Defines the HTTP call to perform. - $ref: '#/$defs/taskBase' type: object unevaluatedProperties: false required: [ call, with ] - properties: - call: - type: string - const: http - with: - type: object - title: HTTPArguments - description: The HTTP call arguments. - properties: - method: - type: string - title: HTTPMethod - description: The HTTP method of the HTTP request to perform. - endpoint: - title: HTTPEndpoint - description: The HTTP endpoint to send the request to. - $ref: '#/$defs/endpoint' - headers: - type: object - title: HTTPHeaders - description: A name/value mapping of the headers, if any, of the HTTP request to perform. - body: - title: HTTPBody - description: The body, if any, of the HTTP request to perform. - query: - type: object - title: HTTPQuery - description: A name/value mapping of the query parameters, if any, of the HTTP request to perform. - additionalProperties: true - output: - type: string - title: HTTPOutput - description: The http call output format. Defaults to 'content'. - enum: [ raw, content, response ] - redirect: - type: boolean - title: HttpRedirect - description: Specifies whether redirection status codes (`300–399`) should be treated as errors. - required: [ method, endpoint ] - unevaluatedProperties: false + allOf: + - $ref: '#/$defs/taskBase' + - properties: + call: + type: string + const: http + with: + type: object + title: HTTPArguments + description: The HTTP call arguments. + properties: + method: + type: string + title: HTTPMethod + description: The HTTP method of the HTTP request to perform. + endpoint: + title: HTTPEndpoint + description: The HTTP endpoint to send the request to. + $ref: '#/$defs/endpoint' + headers: + oneOf: + - type: object + additionalProperties: + type: string + - $ref: '#/$defs/runtimeExpression' + title: HTTPHeaders + description: A name/value mapping of the headers, if any, of the HTTP request to perform. + body: + title: HTTPBody + description: The body, if any, of the HTTP request to perform. + query: + oneOf: + - type: object + additionalProperties: + type: string + - $ref: '#/$defs/runtimeExpression' + title: HTTPQuery + description: A name/value mapping of the query parameters, if any, of the HTTP request to perform. + additionalProperties: true + output: + type: string + title: HTTPOutput + description: The http call output format. Defaults to 'content'. + enum: [ raw, content, response ] + redirect: + type: boolean + title: HttpRedirect + description: Specifies whether redirection status codes (`300–399`) should be treated as errors. + required: [ method, endpoint ] + unevaluatedProperties: false - title: CallOpenAPI description: Defines the OpenAPI call to perform. - $ref: '#/$defs/taskBase' type: object unevaluatedProperties: false required: [ call, with ] - properties: - call: - type: string - const: openapi - with: - type: object - title: OpenAPIArguments - description: The OpenAPI call arguments. - properties: - document: - $ref: '#/$defs/externalResource' - title: WithOpenAPIDocument - description: The document that defines the OpenAPI operation to call. - operationId: - type: string - title: WithOpenAPIOperation - description: The id of the OpenAPI operation to call. - parameters: - type: object - title: WithOpenAPIParameters - description: A name/value mapping of the parameters of the OpenAPI operation to call. - additionalProperties: true - authentication: - $ref: '#/$defs/referenceableAuthenticationPolicy' - title: WithOpenAPIAuthentication - description: The authentication policy, if any, to use when calling the OpenAPI operation. - output: - type: string - enum: [ raw, content, response ] - title: WithOpenAPIOutput - description: The http call output format. Defaults to 'content'. - redirect: - type: boolean - title: HttpRedirect - description: Specifies whether redirection status codes (`300–399`) should be treated as errors. - required: [ document, operationId ] - unevaluatedProperties: false + allOf: + - $ref: '#/$defs/taskBase' + - properties: + call: + type: string + const: openapi + with: + type: object + title: OpenAPIArguments + description: The OpenAPI call arguments. + properties: + document: + $ref: '#/$defs/externalResource' + title: WithOpenAPIDocument + description: The document that defines the OpenAPI operation to call. + operationId: + type: string + title: WithOpenAPIOperation + description: The id of the OpenAPI operation to call. + parameters: + type: object + title: WithOpenAPIParameters + description: A name/value mapping of the parameters of the OpenAPI operation to call. + additionalProperties: true + authentication: + $ref: '#/$defs/referenceableAuthenticationPolicy' + title: WithOpenAPIAuthentication + description: The authentication policy, if any, to use when calling the OpenAPI operation. + output: + type: string + enum: [ raw, content, response ] + title: WithOpenAPIOutput + description: The http call output format. Defaults to 'content'. + redirect: + type: boolean + title: HttpRedirect + description: Specifies whether redirection status codes (`300–399`) should be treated as errors. + required: [ document, operationId ] + unevaluatedProperties: false - title: CallFunction description: Defines the function call to perform. - $ref: '#/$defs/taskBase' type: object unevaluatedProperties: false required: [ call ] - properties: - call: - type: string - not: - enum: ["asyncapi", "grpc", "http", "openapi"] - description: The name of the function to call. - with: - type: object - title: FunctionArguments - description: A name/value mapping of the parameters, if any, to call the function with. - additionalProperties: true + allOf: + - $ref: '#/$defs/taskBase' + - properties: + call: + type: string + not: + enum: ["asyncapi", "grpc", "http", "openapi"] + description: The name of the function to call. + with: + type: object + title: FunctionArguments + description: A name/value mapping of the parameters, if any, to call the function with. + additionalProperties: true forkTask: type: object - $ref: '#/$defs/taskBase' title: ForkTask description: Allows workflows to execute multiple tasks concurrently and optionally race them against each other, with a single possible winner, which sets the task's output. unevaluatedProperties: false required: [ fork ] - properties: - fork: - type: object - title: ForkTaskConfiguration - description: The configuration of the branches to perform concurrently. - unevaluatedProperties: false - required: [ branches ] - properties: - branches: - $ref: '#/$defs/taskList' - title: ForkBranches - compete: - type: boolean - title: ForkCompete - description: Indicates whether or not the concurrent tasks are racing against each other, with a single possible winner, which sets the composite task's output. - default: false + allOf: + - $ref: '#/$defs/taskBase' + - properties: + fork: + type: object + title: ForkTaskConfiguration + description: The configuration of the branches to perform concurrently. + unevaluatedProperties: false + required: [ branches ] + properties: + branches: + $ref: '#/$defs/taskList' + title: ForkBranches + compete: + type: boolean + title: ForkCompete + description: Indicates whether or not the concurrent tasks are racing against each other, with a single possible winner, which sets the composite task's output. + default: false doTask: type: object - $ref: '#/$defs/taskBase' title: DoTask description: Allows to execute a list of tasks in sequence. unevaluatedProperties: false required: [ do ] - properties: - do: - $ref: '#/$defs/taskList' - title: DoTaskConfiguration - description: The configuration of the tasks to perform sequentially. + allOf: + - $ref: '#/$defs/taskBase' + - properties: + do: + $ref: '#/$defs/taskList' + title: DoTaskConfiguration + description: The configuration of the tasks to perform sequentially. emitTask: type: object - $ref: '#/$defs/taskBase' title: EmitTask description: Allows workflows to publish events to event brokers or messaging systems, facilitating communication and coordination between different components and services. required: [ emit ] unevaluatedProperties: false - properties: - emit: - type: object - title: EmitTaskConfiguration - description: The configuration of an event's emission. - unevaluatedProperties: false - properties: - event: - type: object - title: EmitEventDefinition - description: The definition of the event to emit. - properties: - with: - $ref: '#/$defs/eventProperties' - title: EmitEventWith - description: Defines the properties of event to emit. - required: [ source, type ] - additionalProperties: true - required: [ event ] + allOf: + - $ref: '#/$defs/taskBase' + - properties: + emit: + type: object + title: EmitTaskConfiguration + description: The configuration of an event's emission. + unevaluatedProperties: false + properties: + event: + type: object + title: EmitEventDefinition + description: The definition of the event to emit. + properties: + with: + $ref: '#/$defs/eventProperties' + title: EmitEventWith + description: Defines the properties of event to emit. + required: [ source, type ] + additionalProperties: true + required: [ event ] forTask: type: object - $ref: '#/$defs/taskBase' title: ForTask description: Allows workflows to iterate over a collection of items, executing a defined set of subtasks for each item in the collection. This task type is instrumental in handling scenarios such as batch processing, data transformation, and repetitive operations across datasets. required: [ for, do ] unevaluatedProperties: false - properties: - for: - type: object - title: ForTaskConfiguration - description: The definition of the loop that iterates over a range of values. - unevaluatedProperties: false - properties: - each: - type: string - title: ForEach - description: The name of the variable used to store the current item being enumerated. - default: item - in: - type: string - title: ForIn - description: A runtime expression used to get the collection to enumerate. - at: - type: string - title: ForAt - description: The name of the variable used to store the index of the current item being enumerated. - default: index - required: [ in ] - while: - type: string - title: While - description: A runtime expression that represents the condition, if any, that must be met for the iteration to continue. - do: - $ref: '#/$defs/taskList' - title: ForTaskDo + allOf: + - $ref: '#/$defs/taskBase' + - properties: + for: + type: object + title: ForTaskConfiguration + description: The definition of the loop that iterates over a range of values. + unevaluatedProperties: false + properties: + each: + type: string + title: ForEach + description: The name of the variable used to store the current item being enumerated. + default: item + in: + type: string + title: ForIn + description: A runtime expression used to get the collection to enumerate. + at: + type: string + title: ForAt + description: The name of the variable used to store the index of the current item being enumerated. + default: index + required: [ in ] + while: + type: string + title: While + description: A runtime expression that represents the condition, if any, that must be met for the iteration to continue. + do: + $ref: '#/$defs/taskList' + title: ForTaskDo listenTask: type: object - $ref: '#/$defs/taskBase' title: ListenTask description: Provides a mechanism for workflows to await and react to external events, enabling event-driven behavior within workflow systems. required: [ listen ] unevaluatedProperties: false - properties: - listen: - type: object - title: ListenTaskConfiguration - description: The configuration of the listener to use. - unevaluatedProperties: false - properties: - to: - $ref: '#/$defs/eventConsumptionStrategy' - title: ListenTo - description: Defines the event(s) to listen to. - read: - type: string - enum: [ data, envelope, raw ] - default: data - title: ListenAndReadAs - description: Specifies how events are read during the listen operation. - required: [ to ] - foreach: - $ref: '#/$defs/subscriptionIterator' - title: ListenIterator - description: Configures the iterator, if any, for processing consumed event(s). + allOf: + - $ref: '#/$defs/taskBase' + - properties: + listen: + type: object + title: ListenTaskConfiguration + description: The configuration of the listener to use. + unevaluatedProperties: false + properties: + to: + $ref: '#/$defs/eventConsumptionStrategy' + title: ListenTo + description: Defines the event(s) to listen to. + read: + type: string + enum: [ data, envelope, raw ] + default: data + title: ListenAndReadAs + description: Specifies how events are read during the listen operation. + required: [ to ] + foreach: + $ref: '#/$defs/subscriptionIterator' + title: ListenIterator + description: Configures the iterator, if any, for processing consumed event(s). raiseTask: type: object - $ref: '#/$defs/taskBase' title: RaiseTask description: Intentionally triggers and propagates errors. required: [ raise ] unevaluatedProperties: false - properties: - raise: - type: object - title: RaiseTaskConfiguration - description: The definition of the error to raise. - unevaluatedProperties: false - properties: - error: - title: RaiseTaskError - oneOf: - - $ref: '#/$defs/error' - title: RaiseErrorDefinition - description: Defines the error to raise. - - type: string - title: RaiseErrorReference - description: The name of the error to raise - required: [ error ] + allOf: + - $ref: '#/$defs/taskBase' + - properties: + raise: + type: object + title: RaiseTaskConfiguration + description: The definition of the error to raise. + unevaluatedProperties: false + properties: + error: + title: RaiseTaskError + oneOf: + - $ref: '#/$defs/error' + title: RaiseErrorDefinition + description: Defines the error to raise. + - type: string + title: RaiseErrorReference + description: The name of the error to raise + required: [ error ] runTask: type: object - $ref: '#/$defs/taskBase' title: RunTask description: Provides the capability to execute external containers, shell commands, scripts, or workflows. required: [ run ] unevaluatedProperties: false - properties: - run: - type: object - title: RunTaskConfiguration - description: The configuration of the process to execute. - unevaluatedProperties: false - properties: - await: - type: boolean - default: true - title: AwaitProcessCompletion - description: Whether to await the process completion before continuing. - return: - type: string - title: ProcessReturnType - description: Configures the output of the process. - enum: [ stdout, stderr, code, all, none ] - default: stdout - oneOf: - - title: RunContainer - description: Enables the execution of external processes encapsulated within a containerized environment. - properties: - container: - type: object - title: Container - description: The configuration of the container to run. - unevaluatedProperties: false - properties: - image: - type: string - title: ContainerImage - description: The name of the container image to run. - name: - type: string - title: ContainerName - description: A runtime expression, if any, used to give specific name to the container. - command: - type: string - title: ContainerCommand - description: The command, if any, to execute on the container. - ports: - type: object - title: ContainerPorts - description: The container's port mappings, if any. - volumes: - type: object - title: ContainerVolumes - description: The container's volume mappings, if any. - environment: - type: object - title: ContainerEnvironment - description: A key/value mapping of the environment variables, if any, to use when running the configured process. - lifetime: - $ref: '#/$defs/containerLifetime' - title: ContainerLifetime - description: An object, if any, used to configure the container's lifetime - required: [ image ] - required: [ container ] - - title: RunScript - description: Enables the execution of custom scripts or code within a workflow, empowering workflows to perform specialized logic, data processing, or integration tasks by executing user-defined scripts written in various programming languages. - properties: - script: - type: object - title: Script - description: The configuration of the script to run. - unevaluatedProperties: false - properties: - language: - type: string - title: ScriptLanguage - description: The language of the script to run. - arguments: - type: object - title: ScriptArguments - description: A key/value mapping of the arguments, if any, to use when running the configured script. - additionalProperties: true - environment: - type: object - title: ScriptEnvironment - description: A key/value mapping of the environment variables, if any, to use when running the configured script process. - additionalProperties: true - oneOf: - - title: InlineScript - type: object - description: The script's code. - properties: - code: - type: string - title: InlineScriptCode - required: [ code ] - - title: ExternalScript - type: object - description: The script's resource. - properties: - source: - $ref: '#/$defs/externalResource' - title: ExternalScriptResource - required: [ source ] - required: [ language ] - required: [ script ] - - title: RunShell - description: Enables the execution of shell commands within a workflow, enabling workflows to interact with the underlying operating system and perform system-level operations, such as file manipulation, environment configuration, or system administration tasks. - properties: - shell: - type: object - title: Shell - description: The configuration of the shell command to run. - unevaluatedProperties: false - properties: - command: - type: string - title: ShellCommand - description: The shell command to run. - arguments: - type: object - title: ShellArguments - description: A list of the arguments of the shell command to run. - additionalProperties: true - environment: - type: object - title: ShellEnvironment - description: A key/value mapping of the environment variables, if any, to use when running the configured process. - additionalProperties: true - required: [ command ] - required: [ shell ] - - title: RunWorkflow - description: Enables the invocation and execution of nested workflows within a parent workflow, facilitating modularization, reusability, and abstraction of complex logic or business processes by encapsulating them into standalone workflow units. - properties: - workflow: - type: object - title: SubflowConfiguration - description: The configuration of the workflow to run. - unevaluatedProperties: false - properties: - namespace: - type: string - title: SubflowNamespace - description: The namespace the workflow to run belongs to. - name: - type: string - title: SubflowName - description: The name of the workflow to run. - version: - type: string - default: latest - title: SubflowVersion - description: The version of the workflow to run. Defaults to latest. - input: - type: object - title: SubflowInput - description: The data, if any, to pass as input to the workflow to execute. The value should be validated against the target workflow's input schema, if specified. - additionalProperties: true - required: [ namespace, name, version ] - required: [ workflow ] + allOf: + - $ref: '#/$defs/taskBase' + - properties: + run: + type: object + title: RunTaskConfiguration + description: The configuration of the process to execute. + unevaluatedProperties: false + properties: + await: + type: boolean + default: true + title: AwaitProcessCompletion + description: Whether to await the process completion before continuing. + return: + type: string + title: ProcessReturnType + description: Configures the output of the process. + enum: [ stdout, stderr, code, all, none ] + default: stdout + oneOf: + - title: RunContainer + description: Enables the execution of external processes encapsulated within a containerized environment. + properties: + container: + type: object + title: Container + description: The configuration of the container to run. + unevaluatedProperties: false + properties: + image: + type: string + title: ContainerImage + description: The name of the container image to run. + name: + type: string + title: ContainerName + description: A runtime expression, if any, used to give specific name to the container. + command: + type: string + title: ContainerCommand + description: The command, if any, to execute on the container. + ports: + type: object + title: ContainerPorts + description: The container's port mappings, if any. + volumes: + type: object + title: ContainerVolumes + description: The container's volume mappings, if any. + environment: + type: object + title: ContainerEnvironment + description: A key/value mapping of the environment variables, if any, to use when running the configured process. + lifetime: + $ref: '#/$defs/containerLifetime' + title: ContainerLifetime + description: An object, if any, used to configure the container's lifetime + required: [ image ] + required: [ container ] + - title: RunScript + description: Enables the execution of custom scripts or code within a workflow, empowering workflows to perform specialized logic, data processing, or integration tasks by executing user-defined scripts written in various programming languages. + properties: + script: + type: object + title: Script + description: The configuration of the script to run. + unevaluatedProperties: false + properties: + language: + type: string + title: ScriptLanguage + description: The language of the script to run. + arguments: + type: object + title: ScriptArguments + description: A key/value mapping of the arguments, if any, to use when running the configured script. + additionalProperties: true + environment: + type: object + title: ScriptEnvironment + description: A key/value mapping of the environment variables, if any, to use when running the configured script process. + additionalProperties: true + oneOf: + - title: InlineScript + type: object + description: The script's code. + properties: + code: + type: string + title: InlineScriptCode + required: [ code ] + - title: ExternalScript + type: object + description: The script's resource. + properties: + source: + $ref: '#/$defs/externalResource' + title: ExternalScriptResource + required: [ source ] + required: [ language ] + required: [ script ] + - title: RunShell + description: Enables the execution of shell commands within a workflow, enabling workflows to interact with the underlying operating system and perform system-level operations, such as file manipulation, environment configuration, or system administration tasks. + properties: + shell: + type: object + title: Shell + description: The configuration of the shell command to run. + unevaluatedProperties: false + properties: + command: + type: string + title: ShellCommand + description: The shell command to run. + arguments: + type: object + title: ShellArguments + description: A list of the arguments of the shell command to run. + additionalProperties: true + environment: + type: object + title: ShellEnvironment + description: A key/value mapping of the environment variables, if any, to use when running the configured process. + additionalProperties: true + required: [ command ] + required: [ shell ] + - title: RunWorkflow + description: Enables the invocation and execution of nested workflows within a parent workflow, facilitating modularization, reusability, and abstraction of complex logic or business processes by encapsulating them into standalone workflow units. + properties: + workflow: + type: object + title: SubflowConfiguration + description: The configuration of the workflow to run. + unevaluatedProperties: false + properties: + namespace: + type: string + title: SubflowNamespace + description: The namespace the workflow to run belongs to. + name: + type: string + title: SubflowName + description: The name of the workflow to run. + version: + type: string + default: latest + title: SubflowVersion + description: The version of the workflow to run. Defaults to latest. + input: + type: object + title: SubflowInput + description: The data, if any, to pass as input to the workflow to execute. The value should be validated against the target workflow's input schema, if specified. + additionalProperties: true + required: [ namespace, name, version ] + required: [ workflow ] setTask: type: object - $ref: '#/$defs/taskBase' title: SetTask description: A task used to set data. required: [ set ] unevaluatedProperties: false - properties: - set: - type: object - title: SetTaskConfiguration - description: The data to set. - minProperties: 1 - additionalProperties: true + allOf: + - $ref: '#/$defs/taskBase' + - properties: + set: + oneOf: + - type: object + minProperties: 1 + additionalProperties: true + - type: string + title: SetTaskConfiguration + description: The data to set. switchTask: type: object - $ref: '#/$defs/taskBase' title: SwitchTask description: Enables conditional branching within workflows, allowing them to dynamically select different paths based on specified conditions or criteria. required: [ switch ] unevaluatedProperties: false - properties: - switch: - type: array - title: SwitchTaskConfiguration - description: The definition of the switch to use. - minItems: 1 - items: - type: object - title: SwitchItem - minProperties: 1 - maxProperties: 1 - additionalProperties: + allOf: + - $ref: '#/$defs/taskBase' + - properties: + switch: + type: array + title: SwitchTaskConfiguration + description: The definition of the switch to use. + minItems: 1 + items: type: object - title: SwitchCase - description: The definition of a case within a switch task, defining a condition and corresponding tasks to execute if the condition is met. - unevaluatedProperties: false - required: [ then ] - properties: - when: - type: string - title: SwitchCaseCondition - description: A runtime expression used to determine whether or not the case matches. - then: - $ref: '#/$defs/flowDirective' - title: SwitchCaseOutcome - description: The flow directive to execute when the case matches. + title: SwitchItem + minProperties: 1 + maxProperties: 1 + additionalProperties: + type: object + title: SwitchCase + description: The definition of a case within a switch task, defining a condition and corresponding tasks to execute if the condition is met. + unevaluatedProperties: false + required: [ then ] + properties: + when: + type: string + title: SwitchCaseCondition + description: A runtime expression used to determine whether or not the case matches. + then: + $ref: '#/$defs/flowDirective' + title: SwitchCaseOutcome + description: The flow directive to execute when the case matches. tryTask: type: object - $ref: '#/$defs/taskBase' title: TryTask description: Serves as a mechanism within workflows to handle errors gracefully, potentially retrying failed tasks before proceeding with alternate ones. required: [ try, catch ] unevaluatedProperties: false - properties: - try: - $ref: '#/$defs/taskList' - title: TryTaskConfiguration - description: The task(s) to perform. - catch: - type: object - title: TryTaskCatch - description: The object used to define the errors to catch. - unevaluatedProperties: false - properties: - errors: - type: object - title: CatchErrors - properties: - with: - $ref: '#/$defs/errorFilter' - description: static error filter - as: - type: string - title: CatchAs - description: The name of the runtime expression variable to save the error as. Defaults to 'error'. - when: - type: string - title: CatchWhen - description: A runtime expression used to determine whether to catch the filtered error. - exceptWhen: - type: string - title: CatchExceptWhen - description: A runtime expression used to determine whether not to catch the filtered error. - retry: - oneOf: - - $ref: '#/$defs/retryPolicy' - title: RetryPolicyDefinition - description: The retry policy to use, if any, when catching errors. - - type: string - title: RetryPolicyReference - description: The name of the retry policy to use, if any, when catching errors. - do: - $ref: '#/$defs/taskList' - title: TryTaskCatchDo - description: The definition of the task(s) to run when catching an error. + allOf: + - $ref: '#/$defs/taskBase' + - properties: + try: + $ref: '#/$defs/taskList' + title: TryTaskConfiguration + description: The task(s) to perform. + catch: + type: object + title: TryTaskCatch + description: The object used to define the errors to catch. + unevaluatedProperties: false + properties: + errors: + type: object + title: CatchErrors + properties: + with: + $ref: '#/$defs/errorFilter' + description: static error filter + as: + type: string + title: CatchAs + description: The name of the runtime expression variable to save the error as. Defaults to 'error'. + when: + type: string + title: CatchWhen + description: A runtime expression used to determine whether to catch the filtered error. + exceptWhen: + type: string + title: CatchExceptWhen + description: A runtime expression used to determine whether not to catch the filtered error. + retry: + oneOf: + - $ref: '#/$defs/retryPolicy' + title: RetryPolicyDefinition + description: The retry policy to use, if any, when catching errors. + - type: string + title: RetryPolicyReference + description: The name of the retry policy to use, if any, when catching errors. + do: + $ref: '#/$defs/taskList' + title: TryTaskCatchDo + description: The definition of the task(s) to run when catching an error. waitTask: type: object - $ref: '#/$defs/taskBase' title: WaitTask description: Allows workflows to pause or delay their execution for a specified period of time. required: [ wait ] unevaluatedProperties: false - properties: - wait: - $ref: '#/$defs/duration' - title: WaitTaskConfiguration - description: The amount of time to wait. + allOf: + - $ref: '#/$defs/taskBase' + - properties: + wait: + $ref: '#/$defs/duration' + title: WaitTaskConfiguration + description: The amount of time to wait. flowDirective: title: FlowDirective description: Represents different transition options for a workflow. @@ -1188,13 +1214,21 @@ $defs: title: ExpressionErrorInstance description: An expression based error instance. title: - type: string - title: ErrorTitle description: A short, human-readable summary of the error. + title: ErrorTitle + anyOf: + - $ref: '#/$defs/runtimeExpression' + title: ExpressionErrorTitle + - type: string + title: LiteralErrorTitle detail: - type: string title: ErrorDetails description: A human-readable explanation specific to this occurrence of the error. + anyOf: + - $ref: '#/$defs/runtimeExpression' + title: ExpressionErrorDetails + - type: string + title: LiteralErrorDetails required: [ type, status ] errorFilter: type: object diff --git a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java index 622efcbb..28a611cb 100644 --- a/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java +++ b/custom-generator/src/main/java/io/serverlessworkflow/generator/AllAnyOneOfSchemaRule.java @@ -52,6 +52,7 @@ class AllAnyOneOfSchemaRule extends SchemaRule { + private static final String ALL_OF = "allOf"; private RuleFactory ruleFactory; AllAnyOneOfSchemaRule(RuleFactory ruleFactory) { @@ -142,7 +143,7 @@ public JType apply( unionType("oneOf", nodeName, schemaNode, parent, generatableType, schema, oneOfTypes); unionType("anyOf", nodeName, schemaNode, parent, generatableType, schema, oneOfTypes); - unionType("allOf", nodeName, schemaNode, parent, generatableType, schema, allOfTypes); + allOfType(nodeName, schemaNode, parent, generatableType, schema, allOfTypes); Collections.sort(oneOfTypes); @@ -204,6 +205,100 @@ public JType apply( return javaType; } + private void allOfType( + String nodeName, + JsonNode schemaNode, + JsonNode parent, + JClassContainer generatableType, + Schema schema, + List allOfTypes) { + if (schemaNode.has(ALL_OF)) { + ArrayNode array = (ArrayNode) schemaNode.get(ALL_OF); + if (array.size() == 2) { + JsonNode refNode = null; + JsonNode propsNode = null; + int refNodePos = 0; + int propsNodePos = 0; + int pos = 0; + for (JsonNode node : array) { + if (node.isObject() && node.size() == 1) { + if (node.has(REF)) { + refNode = node; + refNodePos = pos++; + } else if (node.has("properties")) { + propsNode = node; + propsNodePos = pos++; + } else { + pos++; + break; + } + } + } + if (refNode != null && propsNode != null) { + allOfTypes.add( + new JTypeWrapper( + inheritanceNode( + nodeName, + schemaNode, + generatableType, + schema, + refNode, + refNodePos, + propsNode, + propsNodePos), + array)); + return; + } + } + unionType(ALL_OF, nodeName, schemaNode, parent, generatableType, schema, allOfTypes); + } + } + + private JType inheritanceNode( + String nodeName, + JsonNode schemaNode, + JClassContainer container, + Schema schema, + JsonNode refNode, + int refNodePos, + JsonNode propsNode, + int propsNodePos) { + try { + JDefinedClass javaType = + container._class( + ruleFactory + .getNameHelper() + .getUniqueClassName(nodeName, schemaNode, container.getPackage())); + javaType._extends( + (JClass) + refType( + refNode.get(REF).asText(), + nodeName, + refNode, + schemaNode, + container, + childSchema(schema, ALL_OF, refNodePos))); + ruleFactory + .getPropertiesRule() + .apply( + nodeName, + propsNode.get("properties"), + propsNode, + javaType, + childSchema(schema, ALL_OF, propsNodePos)); + return javaType; + } catch (JClassAlreadyExistsException e) { + throw new IllegalStateException(e); + } + } + + private Schema childSchema(Schema parentSchema, String prefix, int pos) { + String ref = parentSchema.getId().toString() + '/' + prefix + '/' + pos; + return ruleFactory + .getSchemaStore() + .create(URI.create(ref), ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters()); + } + private JDefinedClass populateAllOf( Schema parentSchema, JDefinedClass definedClass, Collection allOfTypes) { return wrapAll(parentSchema, definedClass, Optional.empty(), allOfTypes, Optional.empty()); @@ -344,8 +439,10 @@ private void wrapIt( Optional valueField, JType unionType, JsonNode node) { - JFieldVar instanceField = getInstanceField(parentSchema, definedClass, unionType, node); - JMethod method = getSetterMethod(definedClass, instanceField, node); + String typeName = getTypeName(node, unionType, parentSchema); + JFieldVar instanceField = + getInstanceField(typeName, parentSchema, definedClass, unionType, node); + JMethod method = getSetterMethod(typeName, definedClass, instanceField, node); method .body() .assign( @@ -370,8 +467,8 @@ private JVar setupMethod( } private JMethod getSetterMethod( - JDefinedClass definedClass, JFieldVar instanceField, JsonNode node) { - String setterName = ruleFactory.getNameHelper().getSetterName(instanceField.name(), node); + String fieldName, JDefinedClass definedClass, JFieldVar instanceField, JsonNode node) { + String setterName = ruleFactory.getNameHelper().getSetterName(fieldName, node); JMethod fluentMethod = definedClass.method(JMod.PUBLIC, definedClass, setterName.replaceFirst("set", "with")); JBlock body = fluentMethod.body(); @@ -391,9 +488,10 @@ private void wrapStrings( if (pattern == null && iter.hasNext()) { pattern = ".*"; } + String typeName = getTypeName(first.getNode(), first.getType(), parentSchema); JFieldVar instanceField = - getInstanceField(parentSchema, definedClass, first.getType(), first.getNode()); - JMethod setterMethod = getSetterMethod(definedClass, instanceField, first.getNode()); + getInstanceField(typeName, parentSchema, definedClass, first.getType(), first.getNode()); + JMethod setterMethod = getSetterMethod(typeName, definedClass, instanceField, first.getNode()); JVar methodParam = setupMethod(definedClass, setterMethod, valueField, instanceField); JBlock body = setterMethod.body(); if (pattern != null) { @@ -403,7 +501,12 @@ private void wrapStrings( while (iter.hasNext()) { JTypeWrapper item = iter.next(); instanceField = - getInstanceField(parentSchema, definedClass, item.getType(), item.getNode()); + getInstanceField( + getTypeName(item.getNode(), item.getType(), parentSchema), + parentSchema, + definedClass, + item.getType(), + item.getNode()); pattern = pattern(item.getNode(), parentSchema); if (pattern == null) { pattern = ".*"; @@ -431,16 +534,16 @@ private void wrapStrings( } private JFieldVar getInstanceField( - Schema parentSchema, JDefinedClass definedClass, JType type, JsonNode node) { + String fieldName, + Schema parentSchema, + JDefinedClass definedClass, + JType type, + JsonNode node) { JFieldVar instanceField = definedClass.field( - JMod.PRIVATE, - type, - ruleFactory - .getNameHelper() - .getPropertyName(getTypeName(node, type, parentSchema), node)); + JMod.PRIVATE, type, ruleFactory.getNameHelper().getPropertyName(fieldName, node)); GeneratorUtils.getterMethod( - definedClass, instanceField, ruleFactory.getNameHelper(), instanceField.name()); + definedClass, instanceField, ruleFactory.getNameHelper(), fieldName); return instanceField; } @@ -486,13 +589,7 @@ private void unionType( int i = 0; for (JsonNode oneOf : array) { if (!ignoreNode(oneOf)) { - String ref = parentSchema.getId().toString() + '/' + prefix + '/' + i++; - Schema schema = - ruleFactory - .getSchemaStore() - .create( - URI.create(ref), - ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters()); + Schema schema = childSchema(parentSchema, prefix, i++); types.add( new JTypeWrapper( schema.isGenerated() @@ -529,29 +626,39 @@ private Optional refType( String nodeName, JsonNode schemaNode, JsonNode parent, - JClassContainer generatableType, + JClassContainer container, Schema parentSchema) { - if (schemaNode.has(REF)) { - String ref = schemaNode.get(REF).asText(); - Schema schema = - ruleFactory - .getSchemaStore() - .create( - parentSchema, - ref, - ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters()); - - return Optional.of( - schema.isGenerated() - ? schema.getJavaType() - : apply( - nameFromRef(ref, nodeName, schemaNode), - schema.getContent(), - parent, - generatableType, - schema)); - } - return Optional.empty(); + return schemaNode.has(REF) + ? Optional.of( + refType( + schemaNode.get(REF).asText(), + nodeName, + schemaNode, + parent, + container, + parentSchema)) + : Optional.empty(); + } + + private JType refType( + String ref, + String nodeName, + JsonNode schemaNode, + JsonNode parent, + JClassContainer container, + Schema parentSchema) { + Schema schema = + ruleFactory + .getSchemaStore() + .create( + parentSchema, + ref, + ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters()); + + return schema.isGenerated() + ? schema.getJavaType() + : apply( + nameFromRef(ref, nodeName, schemaNode), schema.getContent(), parent, container, schema); } private JsonNode schemaRef(JsonNode schemaNode, Schema parentSchema) { diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RaiseExecutor.java b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RaiseExecutor.java index 6dd43c2b..7a2c4025 100644 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RaiseExecutor.java +++ b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/RaiseExecutor.java @@ -30,7 +30,6 @@ import io.serverlessworkflow.impl.WorkflowException; import io.serverlessworkflow.impl.WorkflowPosition; import io.serverlessworkflow.impl.WorkflowUtils; -import io.serverlessworkflow.impl.executors.RegularTaskExecutor.RegularTaskExecutorBuilder; import io.serverlessworkflow.impl.expressions.ExpressionFactory; import io.serverlessworkflow.impl.resources.ResourceLoader; import java.util.Map; @@ -66,9 +65,15 @@ protected RaiseExecutorBuilder( this.instanceFilter = getInstanceFunction(application.expressionFactory(), error.getInstance()); this.titleFilter = - WorkflowUtils.buildStringFilter(application.expressionFactory(), error.getTitle()); + WorkflowUtils.buildStringFilter( + application.expressionFactory(), + error.getTitle().getExpressionErrorTitle(), + error.getTitle().getLiteralErrorTitle()); this.detailFilter = - WorkflowUtils.buildStringFilter(application.expressionFactory(), error.getDetail()); + WorkflowUtils.buildStringFilter( + application.expressionFactory(), + error.getDetail().getExpressionErrorDetails(), + error.getTitle().getExpressionErrorTitle()); this.errorBuilder = (w, t) -> buildError(error, w, t); } diff --git a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/SetExecutor.java b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/SetExecutor.java index c5600891..f8373d39 100644 --- a/impl/core/src/main/java/io/serverlessworkflow/impl/executors/SetExecutor.java +++ b/impl/core/src/main/java/io/serverlessworkflow/impl/executors/SetExecutor.java @@ -16,25 +16,26 @@ package io.serverlessworkflow.impl.executors; import com.fasterxml.jackson.databind.JsonNode; +import io.serverlessworkflow.api.types.Set; import io.serverlessworkflow.api.types.SetTask; +import io.serverlessworkflow.api.types.SetTaskConfiguration; import io.serverlessworkflow.api.types.Workflow; import io.serverlessworkflow.impl.TaskContext; import io.serverlessworkflow.impl.WorkflowApplication; import io.serverlessworkflow.impl.WorkflowContext; +import io.serverlessworkflow.impl.WorkflowFilter; import io.serverlessworkflow.impl.WorkflowPosition; -import io.serverlessworkflow.impl.expressions.ExpressionUtils; -import io.serverlessworkflow.impl.json.JsonUtils; +import io.serverlessworkflow.impl.WorkflowUtils; import io.serverlessworkflow.impl.resources.ResourceLoader; -import java.util.Map; import java.util.concurrent.CompletableFuture; public class SetExecutor extends RegularTaskExecutor { - private final Map toBeSet; + private final WorkflowFilter setFilter; public static class SetExecutorBuilder extends RegularTaskExecutorBuilder { - private final Map toBeSet; + private final WorkflowFilter setFilter; protected SetExecutorBuilder( WorkflowPosition position, @@ -43,9 +44,13 @@ protected SetExecutorBuilder( WorkflowApplication application, ResourceLoader resourceLoader) { super(position, task, workflow, application, resourceLoader); - this.toBeSet = - ExpressionUtils.buildExpressionMap( - task.getSet().getAdditionalProperties(), application.expressionFactory()); + Set setInfo = task.getSet(); + SetTaskConfiguration setConfig = setInfo.getSetTaskConfiguration(); + this.setFilter = + WorkflowUtils.buildWorkflowFilter( + application.expressionFactory(), + setInfo.getString(), + setConfig != null ? setConfig.getAdditionalProperties() : null); } @Override @@ -56,15 +61,13 @@ public TaskExecutor buildInstance() { private SetExecutor(SetExecutorBuilder builder) { super(builder); - this.toBeSet = builder.toBeSet; + this.setFilter = builder.setFilter; } @Override protected CompletableFuture internalExecute( WorkflowContext workflow, TaskContext taskContext) { return CompletableFuture.completedFuture( - JsonUtils.fromValue( - ExpressionUtils.evaluateExpressionMap( - toBeSet, workflow, taskContext, taskContext.input()))); + setFilter.apply(workflow, taskContext, taskContext.input())); } } diff --git a/impl/http/src/main/java/io/serverlessworkflow/impl/executors/HttpExecutor.java b/impl/http/src/main/java/io/serverlessworkflow/impl/executors/HttpExecutor.java index 3c078309..d60c4655 100644 --- a/impl/http/src/main/java/io/serverlessworkflow/impl/executors/HttpExecutor.java +++ b/impl/http/src/main/java/io/serverlessworkflow/impl/executors/HttpExecutor.java @@ -28,6 +28,8 @@ import io.serverlessworkflow.impl.WorkflowContext; import io.serverlessworkflow.impl.WorkflowError; import io.serverlessworkflow.impl.WorkflowException; +import io.serverlessworkflow.impl.WorkflowFilter; +import io.serverlessworkflow.impl.WorkflowUtils; import io.serverlessworkflow.impl.expressions.Expression; import io.serverlessworkflow.impl.expressions.ExpressionFactory; import io.serverlessworkflow.impl.expressions.ExpressionUtils; @@ -40,8 +42,10 @@ import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.Invocation.Builder; import jakarta.ws.rs.client.WebTarget; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.concurrent.CompletableFuture; public class HttpExecutor implements CallableTask { @@ -49,8 +53,8 @@ public class HttpExecutor implements CallableTask { private static final Client client = ClientBuilder.newClient(); private TargetSupplier targetSupplier; - private Map headersMap; - private Map queryMap; + private Optional headersMap; + private Optional queryMap; private RequestSupplier requestFunction; @FunctionalInterface @@ -70,14 +74,24 @@ public void init(CallHTTP task, WorkflowApplication application, ResourceLoader getTargetSupplier(httpArgs.getEndpoint(), application.expressionFactory()); this.headersMap = httpArgs.getHeaders() != null - ? ExpressionUtils.buildExpressionMap( - httpArgs.getHeaders().getAdditionalProperties(), application.expressionFactory()) - : Map.of(); + ? Optional.of( + WorkflowUtils.buildWorkflowFilter( + application.expressionFactory(), + httpArgs.getHeaders().getRuntimeExpression(), + httpArgs.getHeaders().getHTTPHeaders() != null + ? httpArgs.getHeaders().getHTTPHeaders().getAdditionalProperties() + : null)) + : Optional.empty(); this.queryMap = httpArgs.getQuery() != null - ? ExpressionUtils.buildExpressionMap( - httpArgs.getQuery().getAdditionalProperties(), application.expressionFactory()) - : Map.of(); + ? Optional.of( + WorkflowUtils.buildWorkflowFilter( + application.expressionFactory(), + httpArgs.getQuery().getRuntimeExpression(), + httpArgs.getQuery().getHTTPQuery() != null + ? httpArgs.getQuery().getHTTPQuery().getAdditionalProperties() + : null)) + : Optional.empty(); switch (httpArgs.getMethod().toUpperCase()) { case HttpMethod.POST: Object body = @@ -100,13 +114,22 @@ public void init(CallHTTP task, WorkflowApplication application, ResourceLoader public CompletableFuture apply( WorkflowContext workflow, TaskContext taskContext, JsonNode input) { WebTarget target = targetSupplier.apply(workflow, taskContext, input); - for (Entry entry : - ExpressionUtils.evaluateExpressionMap(queryMap, workflow, taskContext, input).entrySet()) { - target = target.queryParam(entry.getKey(), entry.getValue()); + Optional queryJson = queryMap.map(q -> q.apply(workflow, taskContext, input)); + if (queryJson.isPresent()) { + Iterator> iter = queryJson.orElseThrow().fields(); + while (iter.hasNext()) { + Entry item = iter.next(); + target = target.queryParam(item.getKey(), JsonUtils.toJavaValue(item.getValue())); + } } + Builder request = target.request(); - ExpressionUtils.evaluateExpressionMap(headersMap, workflow, taskContext, input) - .forEach(request::header); + headersMap.ifPresent( + h -> + h.apply(workflow, taskContext, input) + .fields() + .forEachRemaining( + e -> request.header(e.getKey(), JsonUtils.toJavaValue(e.getValue())))); return CompletableFuture.supplyAsync( () -> { try { From 27304a28a7173f21c298f72c5b1839ef228e9ae8 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti <65240126+fjtirado@users.noreply.github.com> Date: Tue, 29 Apr 2025 15:37:04 +0200 Subject: [PATCH 21/22] Release 7.1.0.Final (#567) Include these schema changes (not backward compatible) - https://github.com/serverlessworkflow/specification/issues/1087 - https://github.com/serverlessworkflow/specification/issues/1076 - https://github.com/serverlessworkflow/specification/issues/1079 Signed-off-by: fjtirado --- .github/project.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/project.yml b/.github/project.yml index e787d911..1d03de1c 100644 --- a/.github/project.yml +++ b/.github/project.yml @@ -1,4 +1,4 @@ # Retriggering release again release: - current-version: 7.0.0.Final + current-version: 7.1.0.Final next-version: 8.0.0-SNAPSHOT From e22a3b14fa84625960f5d6e8195075fecd603117 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 29 Apr 2025 13:38:04 +0000 Subject: [PATCH 22/22] [maven-release-plugin] prepare release 7.1.0.Final --- api/pom.xml | 2 +- custom-generator/pom.xml | 5 ++--- impl/core/pom.xml | 5 ++--- impl/http/pom.xml | 5 ++--- impl/pom.xml | 5 ++--- pom.xml | 15 +++++++-------- 6 files changed, 16 insertions(+), 21 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 2b08c827..9f0802fe 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ io.serverlessworkflow serverlessworkflow-parent - 8.0.0-SNAPSHOT + 7.1.0.Final serverlessworkflow-api diff --git a/custom-generator/pom.xml b/custom-generator/pom.xml index 3660e286..6313203e 100644 --- a/custom-generator/pom.xml +++ b/custom-generator/pom.xml @@ -1,10 +1,9 @@ - + 4.0.0 io.serverlessworkflow serverlessworkflow-parent - 8.0.0-SNAPSHOT + 7.1.0.Final serverless-workflow-custom-generator Serverless Workflow :: Custom Generator diff --git a/impl/core/pom.xml b/impl/core/pom.xml index a5fac29a..e8f808b1 100644 --- a/impl/core/pom.xml +++ b/impl/core/pom.xml @@ -1,10 +1,9 @@ - + 4.0.0 io.serverlessworkflow serverlessworkflow-impl - 8.0.0-SNAPSHOT + 7.1.0.Final serverlessworkflow-impl-core Serverless Workflow :: Impl :: Core diff --git a/impl/http/pom.xml b/impl/http/pom.xml index 0df48fb3..14e7126e 100644 --- a/impl/http/pom.xml +++ b/impl/http/pom.xml @@ -1,10 +1,9 @@ - + 4.0.0 io.serverlessworkflow serverlessworkflow-impl - 8.0.0-SNAPSHOT + 7.1.0.Final serverlessworkflow-impl-http Serverless Workflow :: Impl :: HTTP diff --git a/impl/pom.xml b/impl/pom.xml index 65fa9095..a8297955 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -1,10 +1,9 @@ - + 4.0.0 io.serverlessworkflow serverlessworkflow-parent - 8.0.0-SNAPSHOT + 7.1.0.Final serverlessworkflow-impl Serverless Workflow :: Impl diff --git a/pom.xml b/pom.xml index 2f623e9a..54ef626d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,10 @@ - + 4.0.0 io.serverlessworkflow serverlessworkflow-parent - 8.0.0-SNAPSHOT + 7.1.0.Final pom Serverless Workflow :: Parent @@ -34,7 +33,7 @@ scm:git:git@github.com:serverlessworkflow/sdk-java.git scm:git:git@github.com:serverlessworkflow/sdk-java.git https://github.com/serverlessworkflow/sdk-java - HEAD + 7.1.0.Final @@ -241,13 +240,13 @@ - - + + - - + +