diff --git a/experimental/lambda/pom.xml b/experimental/lambda/pom.xml index 72e4c0b2..5c20338c 100644 --- a/experimental/lambda/pom.xml +++ b/experimental/lambda/pom.xml @@ -1,22 +1,27 @@ - - 4.0.0 - - io.serverlessworkflow - serverlessworkflow-experimental - 8.0.0-SNAPSHOT - - serverlessworkflow-experimental-lambda - ServelessWorkflow:: Experimental:: lambda - - - io.serverlessworkflow - serverlessworkflow-experimental-types - - - io.serverlessworkflow - serverlessworkflow-impl-core - - + + 4.0.0 + + io.serverlessworkflow + serverlessworkflow-experimental + 8.0.0-SNAPSHOT + + serverlessworkflow-experimental-lambda + ServelessWorkflow:: Experimental:: lambda + + + io.serverlessworkflow + serverlessworkflow-experimental-types + + + io.serverlessworkflow + serverlessworkflow-impl-core + + + io.serverlessworkflow + serverlessworkflow-fluent-java + + org.junit.jupiter junit-jupiter-api test @@ -41,5 +46,5 @@ logback-classic test - + \ No newline at end of file diff --git a/experimental/lambda/src/test/java/io/serverless/workflow/impl/CallTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/CallTest.java index 9118ec06..7d95410b 100644 --- a/experimental/lambda/src/test/java/io/serverless/workflow/impl/CallTest.java +++ b/experimental/lambda/src/test/java/io/serverless/workflow/impl/CallTest.java @@ -80,7 +80,7 @@ void testForLoop() throws InterruptedException, ExecutionException { new Task() .withForTask( new ForTaskFunction() - .withWhile(this::isEven) + .withWhile(CallTest::isEven) .withCollection(v -> (Collection) v) .withFor(forConfig) .withDo( @@ -91,7 +91,7 @@ void testForLoop() throws InterruptedException, ExecutionException { .withCallTask( new CallTaskJava( CallJava.loopFunction( - this::sum, + CallTest::sum, forConfig.getEach())))))))))); assertThat( @@ -124,7 +124,7 @@ void testSwitch() throws InterruptedException, ExecutionException { new SwitchItem( "odd", new SwitchCaseFunction() - .withPredicate(this::isOdd) + .withPredicate(CallTest::isOdd) .withThen( new FlowDirective() .withFlowDirectiveEnum( @@ -132,7 +132,7 @@ void testSwitch() throws InterruptedException, ExecutionException { new TaskItem( "java", new Task() - .withCallTask(new CallTaskJava(CallJava.function(this::zero)))))); + .withCallTask(new CallTaskJava(CallJava.function(CallTest::zero)))))); WorkflowDefinition definition = app.workflowDefinition(workflow); assertThat(definition.instance(3).start().get().asNumber().orElseThrow()).isEqualTo(3); @@ -140,19 +140,19 @@ void testSwitch() throws InterruptedException, ExecutionException { } } - private boolean isEven(Object model, Integer number) { + public static boolean isEven(Object model, Integer number) { return !isOdd(number); } - private boolean isOdd(Integer number) { + public static boolean isOdd(Integer number) { return number % 2 != 0; } - private int zero(Integer value) { + public static int zero(Integer value) { return 0; } - private Integer sum(Object model, Integer item) { + 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/FluentDSLCallTest.java b/experimental/lambda/src/test/java/io/serverless/workflow/impl/FluentDSLCallTest.java new file mode 100644 index 00000000..dd4f9a29 --- /dev/null +++ b/experimental/lambda/src/test/java/io/serverless/workflow/impl/FluentDSLCallTest.java @@ -0,0 +1,96 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.serverlessworkflow.api.types.FlowDirectiveEnum; +import io.serverlessworkflow.api.types.Workflow; +import io.serverlessworkflow.fluent.java.JavaWorkflowBuilder; +import io.serverlessworkflow.impl.WorkflowApplication; +import io.serverlessworkflow.impl.WorkflowDefinition; +import java.util.Collection; +import java.util.List; +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 = + JavaWorkflowBuilder.workflow("testJavaCall") + .tasks(tasks -> tasks.callFn(f -> f.fn(JavaFunctions::getName))) + .build(); + 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()) { + Workflow workflow = + JavaWorkflowBuilder.workflow() + .tasks( + t -> + t.forFn( + 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 = + JavaWorkflowBuilder.workflow() + .tasks( + tasks -> + tasks + .switchFn( + switchOdd -> + switchOdd.items( + item -> + item.when(CallTest::isOdd).then(FlowDirectiveEnum.END))) + .callFn(callJava -> callJava.fn(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); + } + } +} diff --git a/experimental/pom.xml b/experimental/pom.xml index 409e68c2..e269b7b0 100644 --- a/experimental/pom.xml +++ b/experimental/pom.xml @@ -30,6 +30,11 @@ serverlessworkflow-experimental-types ${project.version} + + io.serverlessworkflow + serverlessworkflow-fluent-java + ${project.version} + diff --git a/experimental/types/src/main/java/io/serverlessworkflow/api/types/SwitchCaseFunction.java b/experimental/types/src/main/java/io/serverlessworkflow/api/types/SwitchCaseFunction.java index 027ab178..51b4175a 100644 --- a/experimental/types/src/main/java/io/serverlessworkflow/api/types/SwitchCaseFunction.java +++ b/experimental/types/src/main/java/io/serverlessworkflow/api/types/SwitchCaseFunction.java @@ -27,6 +27,10 @@ public SwitchCaseFunction withPredicate(Predicate predicate) { return this; } + public void setPredicate(Predicate predicate) { + this.predicate = predicate; + } + public Predicate predicate() { return predicate; } diff --git a/fluent/java/pom.xml b/fluent/java/pom.xml new file mode 100644 index 00000000..aa12ec97 --- /dev/null +++ b/fluent/java/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + io.serverlessworkflow + serverlessworkflow-fluent + 8.0.0-SNAPSHOT + + + Serverless Workflow :: Fluent :: Java + serverlessworkflow-fluent-java + + + 17 + 17 + UTF-8 + + + + + io.serverlessworkflow + serverlessworkflow-experimental-types + + + io.serverlessworkflow + serverlessworkflow-types + + + io.serverlessworkflow + serverlessworkflow-fluent-standard + + + + org.junit.jupiter + junit-jupiter-api + test + + + + \ No newline at end of file diff --git a/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/CallTaskJavaBuilder.java b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/CallTaskJavaBuilder.java new file mode 100644 index 00000000..8149ebba --- /dev/null +++ b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/CallTaskJavaBuilder.java @@ -0,0 +1,47 @@ +/* + * 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.java; + +import io.serverlessworkflow.api.types.CallJava; +import io.serverlessworkflow.api.types.CallTaskJava; +import io.serverlessworkflow.fluent.standard.TaskBaseBuilder; +import java.util.function.Function; + +public class CallTaskJavaBuilder extends TaskBaseBuilder + implements JavaTransformationHandlers { + + private CallTaskJava callTaskJava; + + CallTaskJavaBuilder() { + callTaskJava = new CallTaskJava(new CallJava() {}); + super.setTask(callTaskJava.getCallJava()); + } + + @Override + protected CallTaskJavaBuilder self() { + return this; + } + + public CallTaskJavaBuilder fn(Function function) { + this.callTaskJava = new CallTaskJava(CallJava.function(function)); + super.setTask(this.callTaskJava.getCallJava()); + return this; + } + + public CallTaskJava build() { + return this.callTaskJava; + } +} diff --git a/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/DoTaskJavaBuilder.java b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/DoTaskJavaBuilder.java new file mode 100644 index 00000000..b17cf643 --- /dev/null +++ b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/DoTaskJavaBuilder.java @@ -0,0 +1,62 @@ +/* + * 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.java; + +import io.serverlessworkflow.fluent.standard.BaseDoTaskBuilder; +import java.util.function.Consumer; + +public class DoTaskJavaBuilder extends BaseDoTaskBuilder + implements JavaTransformationHandlers { + + DoTaskJavaBuilder() { + super(new TaskItemListJavaBuilder()); + } + + @Override + protected DoTaskJavaBuilder self() { + return this; + } + + public DoTaskJavaBuilder callFn(String name, Consumer consumer) { + this.innerListBuilder().callJava(name, consumer); + return this; + } + + public DoTaskJavaBuilder callFn(Consumer consumer) { + this.innerListBuilder().callJava(consumer); + return this; + } + + public DoTaskJavaBuilder forFn(String name, Consumer consumer) { + this.innerListBuilder().forFn(name, consumer); + return this; + } + + public DoTaskJavaBuilder forFn(Consumer consumer) { + this.innerListBuilder().forFn(consumer); + return this; + } + + public DoTaskJavaBuilder switchFn(String name, Consumer consumer) { + this.innerListBuilder().switchFn(name, consumer); + return this; + } + + public DoTaskJavaBuilder switchFn(Consumer consumer) { + this.innerListBuilder().switchFn(consumer); + return this; + } +} diff --git a/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/ForTaskJavaBuilder.java b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/ForTaskJavaBuilder.java new file mode 100644 index 00000000..241272f0 --- /dev/null +++ b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/ForTaskJavaBuilder.java @@ -0,0 +1,95 @@ +/* + * 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.java; + +import io.serverlessworkflow.api.types.CallJava; +import io.serverlessworkflow.api.types.CallTaskJava; +import io.serverlessworkflow.api.types.ForTaskConfiguration; +import io.serverlessworkflow.api.types.ForTaskFunction; +import io.serverlessworkflow.api.types.Task; +import io.serverlessworkflow.api.types.TaskItem; +import io.serverlessworkflow.fluent.standard.TaskBaseBuilder; +import io.serverlessworkflow.impl.expressions.LoopFunction; +import io.serverlessworkflow.impl.expressions.LoopPredicate; +import io.serverlessworkflow.impl.expressions.LoopPredicateIndex; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.function.Consumer; +import java.util.function.Function; + +public class ForTaskJavaBuilder extends TaskBaseBuilder + implements JavaTransformationHandlers { + + private final ForTaskFunction forTaskFunction; + private final List items; + + ForTaskJavaBuilder() { + this.forTaskFunction = new ForTaskFunction(); + this.forTaskFunction.withFor(new ForTaskConfiguration()); + this.items = new ArrayList<>(); + super.setTask(forTaskFunction); + } + + @Override + protected ForTaskJavaBuilder self() { + return this; + } + + public ForTaskJavaBuilder whileC(LoopPredicate predicate) { + this.forTaskFunction.withWhile(predicate); + return this; + } + + public ForTaskJavaBuilder whileC(LoopPredicateIndex predicate) { + this.forTaskFunction.withWhile(predicate); + return this; + } + + public ForTaskJavaBuilder collection(Function> collectionF) { + this.forTaskFunction.withCollection(collectionF); + return this; + } + + public ForTaskJavaBuilder tasks(String name, LoopFunction function) { + this.items.add( + new TaskItem( + name, + new Task() + .withCallTask( + new CallTaskJava( + CallJava.loopFunction( + function, this.forTaskFunction.getFor().getEach()))))); + return this; + } + + public ForTaskJavaBuilder tasks(LoopFunction function) { + return this.tasks(UUID.randomUUID().toString(), function); + } + + public ForTaskJavaBuilder tasks(Consumer consumer) { + final TaskItemListJavaBuilder builder = new TaskItemListJavaBuilder(); + consumer.accept(builder); + this.items.addAll(builder.build()); + return this; + } + + public ForTaskFunction build() { + this.forTaskFunction.setDo(this.items); + return this.forTaskFunction; + } +} diff --git a/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/JavaTransformationHandlers.java b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/JavaTransformationHandlers.java new file mode 100644 index 00000000..c8651b83 --- /dev/null +++ b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/JavaTransformationHandlers.java @@ -0,0 +1,44 @@ +/* + * 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.java; + +import io.serverlessworkflow.api.types.Export; +import io.serverlessworkflow.api.types.ExportAsFunction; +import io.serverlessworkflow.api.types.Input; +import io.serverlessworkflow.api.types.InputFromFunction; +import io.serverlessworkflow.api.types.Output; +import io.serverlessworkflow.api.types.OutputAsFunction; +import io.serverlessworkflow.fluent.standard.TransformationHandlers; +import java.util.function.Function; + +public interface JavaTransformationHandlers> + extends TransformationHandlers { + + default B exportAsFn(Function function) { + setExport(new Export().withAs(new ExportAsFunction().withFunction(function))); + return (B) this; + } + + default B inputFrom(Function function) { + setInput(new Input().withFrom(new InputFromFunction().withFunction(function))); + return (B) this; + } + + default B outputAs(Function function) { + setOutput(new Output().withAs(new OutputAsFunction().withFunction(function))); + return (B) this; + } +} diff --git a/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/JavaWorkflowBuilder.java b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/JavaWorkflowBuilder.java new file mode 100644 index 00000000..5d90b598 --- /dev/null +++ b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/JavaWorkflowBuilder.java @@ -0,0 +1,51 @@ +/* + * 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.java; + +import io.serverlessworkflow.fluent.standard.BaseWorkflowBuilder; +import java.util.UUID; + +public class JavaWorkflowBuilder + extends BaseWorkflowBuilder + implements JavaTransformationHandlers { + + private JavaWorkflowBuilder(final String name, final String namespace, final String version) { + super(name, namespace, version); + } + + public static JavaWorkflowBuilder workflow(final String name, final String namespace) { + return new JavaWorkflowBuilder(name, namespace, DEFAULT_VERSION); + } + + public static JavaWorkflowBuilder workflow(final String name) { + return new JavaWorkflowBuilder(name, DEFAULT_NAMESPACE, DEFAULT_VERSION); + } + + public static JavaWorkflowBuilder workflow() { + return new JavaWorkflowBuilder( + UUID.randomUUID().toString(), DEFAULT_NAMESPACE, DEFAULT_VERSION); + } + + @Override + protected DoTaskJavaBuilder newDo() { + return new DoTaskJavaBuilder(); + } + + @Override + protected JavaWorkflowBuilder self() { + return this; + } +} diff --git a/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/SwitchTaskJavaBuilder.java b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/SwitchTaskJavaBuilder.java new file mode 100644 index 00000000..8b9d98e6 --- /dev/null +++ b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/SwitchTaskJavaBuilder.java @@ -0,0 +1,90 @@ +/* + * 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.java; + +import io.serverlessworkflow.api.types.FlowDirective; +import io.serverlessworkflow.api.types.FlowDirectiveEnum; +import io.serverlessworkflow.api.types.SwitchCase; +import io.serverlessworkflow.api.types.SwitchCaseFunction; +import io.serverlessworkflow.api.types.SwitchItem; +import io.serverlessworkflow.api.types.SwitchTask; +import io.serverlessworkflow.fluent.standard.TaskBaseBuilder; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class SwitchTaskJavaBuilder extends TaskBaseBuilder + implements JavaTransformationHandlers { + + private final SwitchTask switchTask; + private final List switchItems; + + SwitchTaskJavaBuilder() { + this.switchTask = new SwitchTask(); + this.switchItems = new ArrayList<>(); + super.setTask(switchTask); + } + + @Override + protected SwitchTaskJavaBuilder self() { + return this; + } + + public SwitchTaskJavaBuilder items(Consumer consumer) { + return this.items(UUID.randomUUID().toString(), consumer); + } + + public SwitchTaskJavaBuilder items(String name, Consumer consumer) { + final SwitchCaseJavaBuilder switchCase = new SwitchCaseJavaBuilder(); + consumer.accept(switchCase); + this.switchItems.add(new SwitchItem(name, switchCase.build())); + return this; + } + + public SwitchTask build() { + this.switchTask.setSwitch(this.switchItems); + return switchTask; + } + + public static final class SwitchCaseJavaBuilder { + private final SwitchCaseFunction switchCase; + + SwitchCaseJavaBuilder() { + this.switchCase = new SwitchCaseFunction(); + } + + public SwitchCaseJavaBuilder when(Predicate when) { + this.switchCase.setPredicate(when); + return this; + } + + public SwitchCaseJavaBuilder then(FlowDirective then) { + this.switchCase.setThen(then); + return this; + } + + public SwitchCaseJavaBuilder then(FlowDirectiveEnum then) { + this.switchCase.setThen(new FlowDirective().withFlowDirectiveEnum(then)); + return this; + } + + public SwitchCase build() { + return this.switchCase; + } + } +} diff --git a/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/TaskItemListJavaBuilder.java b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/TaskItemListJavaBuilder.java new file mode 100644 index 00000000..40fa250b --- /dev/null +++ b/fluent/java/src/main/java/io/serverlessworkflow/fluent/java/TaskItemListJavaBuilder.java @@ -0,0 +1,73 @@ +/* + * 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.java; + +import io.serverlessworkflow.api.types.Task; +import io.serverlessworkflow.api.types.TaskItem; +import io.serverlessworkflow.fluent.standard.BaseTaskItemListBuilder; +import java.util.UUID; +import java.util.function.Consumer; + +public class TaskItemListJavaBuilder extends BaseTaskItemListBuilder { + + TaskItemListJavaBuilder() { + super(); + } + + @Override + protected TaskItemListJavaBuilder self() { + return this; + } + + @Override + protected TaskItemListJavaBuilder newItemListBuilder() { + return new TaskItemListJavaBuilder(); + } + + public TaskItemListJavaBuilder callJava(String name, Consumer consumer) { + this.requireNameAndConfig(name, consumer); + final CallTaskJavaBuilder callTaskJavaBuilder = new CallTaskJavaBuilder(); + consumer.accept(callTaskJavaBuilder); + return addTaskItem(new TaskItem(name, new Task().withCallTask(callTaskJavaBuilder.build()))); + } + + public TaskItemListJavaBuilder callJava(Consumer consumer) { + return this.callJava(UUID.randomUUID().toString(), consumer); + } + + public TaskItemListJavaBuilder forFn(String name, Consumer consumer) { + this.requireNameAndConfig(name, consumer); + final ForTaskJavaBuilder forTaskJavaBuilder = new ForTaskJavaBuilder(); + consumer.accept(forTaskJavaBuilder); + return this.addTaskItem(new TaskItem(name, new Task().withForTask(forTaskJavaBuilder.build()))); + } + + public TaskItemListJavaBuilder forFn(Consumer consumer) { + return this.forFn(UUID.randomUUID().toString(), consumer); + } + + public TaskItemListJavaBuilder switchFn(String name, Consumer consumer) { + this.requireNameAndConfig(name, consumer); + final SwitchTaskJavaBuilder switchTaskJavaBuilder = new SwitchTaskJavaBuilder(); + consumer.accept(switchTaskJavaBuilder); + return this.addTaskItem( + new TaskItem(name, new Task().withSwitchTask(switchTaskJavaBuilder.build()))); + } + + public TaskItemListJavaBuilder switchFn(Consumer consumer) { + return this.switchFn(UUID.randomUUID().toString(), consumer); + } +} diff --git a/fluent/java/src/test/java/io/serverlessworkflow/fluent/java/JavaWorkflowBuilderTest.java b/fluent/java/src/test/java/io/serverlessworkflow/fluent/java/JavaWorkflowBuilderTest.java new file mode 100644 index 00000000..ef037cad --- /dev/null +++ b/fluent/java/src/test/java/io/serverlessworkflow/fluent/java/JavaWorkflowBuilderTest.java @@ -0,0 +1,274 @@ +/* + * 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.java; + +import static org.junit.jupiter.api.Assertions.*; + +import io.serverlessworkflow.api.types.*; +import io.serverlessworkflow.fluent.standard.BaseWorkflowBuilder; +// if you reuse anything +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** Tests for JavaWorkflowBuilder + Java DSL extensions. */ +class JavaWorkflowBuilderTest { + + @Test + @DisplayName("Default Java workflow has auto-generated name and default namespace/version") + void testDefaults() { + Workflow wf = JavaWorkflowBuilder.workflow().build(); + assertNotNull(wf); + Document doc = wf.getDocument(); + assertNotNull(doc); + assertEquals(BaseWorkflowBuilder.DEFAULT_NAMESPACE, doc.getNamespace()); + assertEquals(BaseWorkflowBuilder.DEFAULT_VERSION, doc.getVersion()); + assertEquals(BaseWorkflowBuilder.DSL, doc.getDsl()); + assertNotNull(doc.getName()); + } + + @Test + @DisplayName("Spec style forE still works inside Java workflow") + void testSpecForEachInJavaWorkflow() { + Workflow wf = + JavaWorkflowBuilder.workflow("specLoopFlow") + .tasks( + d -> + d.forEach(f -> f.each("pet").in("$.pets")) + .set("markDone", s -> s.expr("$.done = true"))) + .build(); + + List items = wf.getDo(); + assertEquals(2, items.size()); + + TaskItem loopItem = items.get(0); + assertNotNull(loopItem.getTask().getForTask(), "Spec ForTask should be present"); + + TaskItem setItem = items.get(1); + assertNotNull(setItem.getTask().getSetTask()); + SetTask st = setItem.getTask().getSetTask(); + assertEquals("$.done = true", st.getSet().getString()); + } + + @Test + @DisplayName("Java style forE with collection + whileC builds ForTaskFunction") + void testJavaForEach() { + Workflow wf = + JavaWorkflowBuilder.workflow("javaLoopFlow") + .tasks( + d -> + d.forFn( + j -> + j.collection(ctx -> List.of("a", "b", "c")) + .whileC((String val, Object ctx) -> !val.equals("c")) + .tasks( + inner -> inner.set("loopFlag", s -> s.expr("$.flag = true"))))) + .build(); + + List items = wf.getDo(); + assertEquals(1, items.size()); + + TaskItem loopItem = items.get(0); + Task task = loopItem.getTask(); + + assertNotNull(task.getForTask(), "Java ForTaskFunction should be present"); + + // Basic structural checks on nested do inside the function loop + ForTaskFunction fn = (ForTaskFunction) task.getForTask(); + assertNotNull(fn.getDo(), "Nested 'do' list inside ForTaskFunction should be populated"); + assertEquals(1, fn.getDo().size()); + Task nested = fn.getDo().get(0).getTask(); + assertNotNull(nested.getSetTask()); + } + + @Test + @DisplayName("Mixed spec and Java loops in one workflow") + void testMixedLoops() { + Workflow wf = + JavaWorkflowBuilder.workflow("mixed") + .tasks( + d -> + d.forEach(f -> f.each("item").in("$.array")) // spec + .forFn(j -> j.collection(ctx -> List.of(1, 2, 3))) // java + ) + .build(); + + List items = wf.getDo(); + assertEquals(2, items.size()); + + Task specLoop = items.get(0).getTask(); + Task javaLoop = items.get(1).getTask(); + + assertNotNull(specLoop.getForTask()); + assertNotNull(javaLoop.getForTask()); + } + + @Test + @DisplayName("Java functional exportAsFn/inputFrom/outputAs set function wrappers (not literals)") + void testJavaFunctionalIO() { + AtomicBoolean exportCalled = new AtomicBoolean(false); + AtomicBoolean inputCalled = new AtomicBoolean(false); + AtomicBoolean outputCalled = new AtomicBoolean(false); + + Workflow wf = + JavaWorkflowBuilder.workflow("fnIO") + .tasks( + d -> + d.set("init", s -> s.expr("$.x = 1")) + .forFn( + j -> + j.collection( + ctx -> { + inputCalled.set(true); + return List.of("x", "y"); + }) + .tasks(inner -> inner.set("calc", s -> s.expr("$.y = $.x + 1"))) + .exportAsFn( + item -> { + exportCalled.set(true); + return Map.of("computed", 42); + }) + .outputAs( + item -> { + outputCalled.set(true); + return Map.of("out", true); + }))) + .build(); + + // Top-level 'do' structure + assertEquals(2, wf.getDo().size()); + + // Find nested forTaskFunction + Task forTaskFnHolder = wf.getDo().get(1).getTask(); + ForTaskFunction fn = (ForTaskFunction) forTaskFnHolder.getForTask(); + assertNotNull(fn); + + // Inspect nested tasks inside the function loop + List nested = fn.getDo(); + assertEquals(1, nested.size()); + TaskBase nestedTask = nested.get(0).getTask().getSetTask(); + assertNotNull(nestedTask); + + // Because functions are likely stored as opaque objects, we check that + // export / output structures exist and are not expression-based. + Export export = fn.getExport(); + assertNotNull(export, "Export should be set via functional variant"); + assertNull( + export.getAs() != null ? export.getAs().getString() : null, + "Export 'as' should not be a plain string when using function variant"); + + Output out = fn.getOutput(); + // If functional output maps to an OutputAsFunction wrapper, adapt the checks: + if (out != null && out.getAs() != null) { + // Expect no literal string if function used + assertNull(out.getAs().getString(), "Output 'as' should not be a literal string"); + } + + // We can't *invoke* lambdas here (unless your runtime exposes them), + // but we verified structural placement. Flipping AtomicBooleans in creation lambdas + // (collection) at least shows one function executed during build (if it is executed now; + // if they are deferred, remove those assertions.) + } + + @Test + @DisplayName("callJava task added and retains name + CallTask union") + void testCallJavaTask() { + Workflow wf = + JavaWorkflowBuilder.workflow("callJavaFlow") + .tasks( + d -> + d.callFn( + "invokeHandler", + cj -> { + // configure your CallTaskJavaBuilder here + // e.g., cj.className("com.acme.Handler").arg("key", "value"); + })) + .build(); + + List items = wf.getDo(); + assertEquals(1, items.size()); + TaskItem ti = items.get(0); + + assertEquals("invokeHandler", ti.getName()); + Task task = ti.getTask(); + assertNotNull(task.getCallTask(), "CallTask should be present for callJava"); + // Additional assertions if CallTaskJavaBuilder populates fields + // e.g., assertEquals("com.acme.Handler", task.getCallTask().getCallJava().getClassName()); + } + + @Test + @DisplayName("switchCaseFn (Java variant) coexists with spec tasks") + void testSwitchCaseJava() { + Workflow wf = + JavaWorkflowBuilder.workflow("switchJava") + .tasks( + d -> + d.set("prepare", s -> s.expr("$.ready = true")) + .switchC( + sw -> { + // configure Java switch builder (cases / predicates) + })) + .build(); + + List items = wf.getDo(); + assertEquals(2, items.size()); + + Task specSet = items.get(0).getTask(); + Task switchTask = items.get(1).getTask(); + + assertNotNull(specSet.getSetTask()); + assertNotNull(switchTask.getSwitchTask(), "SwitchTask union should be present"); + } + + @Test + @DisplayName("Combined: spec set + java forE + callJava inside nested do") + void testCompositeScenario() { + Workflow wf = + JavaWorkflowBuilder.workflow("composite") + .tasks( + d -> + d.set("init", s -> s.expr("$.val = 0")) + .forFn( + j -> + j.collection(ctx -> List.of("a", "b")) + .tasks( + inner -> + inner + .callJava( + cj -> { + // customizing Java call + }) + .set("flag", s -> s.expr("$.flag = true"))))) + .build(); + + assertEquals(2, wf.getDo().size()); + + Task loopHolder = wf.getDo().get(1).getTask(); + ForTaskFunction fn = (ForTaskFunction) loopHolder.getForTask(); + assertNotNull(fn); + + List nested = fn.getDo(); + assertEquals(2, nested.size()); + + Task nestedCall = nested.get(0).getTask(); + Task nestedSet = nested.get(1).getTask(); + + assertNotNull(nestedCall.getCallTask()); + assertNotNull(nestedSet.getSetTask()); + } +} diff --git a/fluent/pom.xml b/fluent/pom.xml index 71d54a64..1af30562 100644 --- a/fluent/pom.xml +++ b/fluent/pom.xml @@ -25,11 +25,22 @@ serverlessworkflow-types ${project.version} + + io.serverlessworkflow + serverlessworkflow-experimental-types + ${project.version} + + + io.serverlessworkflow + serverlessworkflow-fluent-standard + ${project.version} + standard + java \ No newline at end of file diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseDoTaskBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseDoTaskBuilder.java new file mode 100644 index 00000000..fab86cdd --- /dev/null +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseDoTaskBuilder.java @@ -0,0 +1,143 @@ +/* + * 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.standard; + +import io.serverlessworkflow.api.types.DoTask; +import java.util.function.Consumer; + +public abstract class BaseDoTaskBuilder< + TASK extends TaskBaseBuilder, LIST extends BaseTaskItemListBuilder> + extends TaskBaseBuilder { + private final DoTask doTask; + private final BaseTaskItemListBuilder taskItemListBuilder; + + protected BaseDoTaskBuilder(BaseTaskItemListBuilder taskItemListBuilder) { + this.doTask = new DoTask(); + this.taskItemListBuilder = taskItemListBuilder; + this.setTask(doTask); + } + + protected abstract TASK self(); + + protected LIST innerListBuilder() { + return (LIST) taskItemListBuilder; + } + + public TASK set(String name, Consumer itemsConfigurer) { + taskItemListBuilder.set(name, itemsConfigurer); + return self(); + } + + public TASK set(Consumer itemsConfigurer) { + taskItemListBuilder.set(itemsConfigurer); + return self(); + } + + public TASK set(String name, final String expr) { + taskItemListBuilder.set(name, s -> s.expr(expr)); + return self(); + } + + public TASK set(final String expr) { + taskItemListBuilder.set(expr); + return self(); + } + + public TASK forEach(String name, Consumer> itemsConfigurer) { + taskItemListBuilder.forEach(name, itemsConfigurer); + return self(); + } + + public TASK forEach(Consumer> itemsConfigurer) { + taskItemListBuilder.forEach(itemsConfigurer); + return self(); + } + + public TASK switchC(String name, Consumer itemsConfigurer) { + taskItemListBuilder.switchC(name, itemsConfigurer); + return self(); + } + + public TASK switchC(Consumer itemsConfigurer) { + taskItemListBuilder.switchC(itemsConfigurer); + return self(); + } + + public TASK raise(String name, Consumer itemsConfigurer) { + taskItemListBuilder.raise(name, itemsConfigurer); + return self(); + } + + public TASK raise(Consumer itemsConfigurer) { + taskItemListBuilder.raise(itemsConfigurer); + return self(); + } + + public TASK fork(String name, Consumer itemsConfigurer) { + taskItemListBuilder.fork(name, itemsConfigurer); + return self(); + } + + public TASK fork(Consumer itemsConfigurer) { + taskItemListBuilder.fork(itemsConfigurer); + return self(); + } + + public TASK listen(String name, Consumer itemsConfigurer) { + taskItemListBuilder.listen(name, itemsConfigurer); + return self(); + } + + public TASK listen(Consumer itemsConfigurer) { + taskItemListBuilder.listen(itemsConfigurer); + return self(); + } + + public TASK emit(String name, Consumer itemsConfigurer) { + taskItemListBuilder.emit(name, itemsConfigurer); + return self(); + } + + public TASK emit(Consumer itemsConfigurer) { + taskItemListBuilder.emit(itemsConfigurer); + return self(); + } + + public TASK tryC(String name, Consumer> itemsConfigurer) { + taskItemListBuilder.tryC(name, itemsConfigurer); + return self(); + } + + public TASK tryC(Consumer> itemsConfigurer) { + taskItemListBuilder.tryC(itemsConfigurer); + return self(); + } + + public TASK callHTTP(String name, Consumer itemsConfigurer) { + taskItemListBuilder.callHTTP(name, itemsConfigurer); + return self(); + } + + public TASK callHTTP(Consumer itemsConfigurer) { + taskItemListBuilder.callHTTP(itemsConfigurer); + return self(); + } + + public DoTask build() { + this.doTask.setDo(this.taskItemListBuilder.build()); + return this.doTask; + } +} diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseTaskItemListBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseTaskItemListBuilder.java new file mode 100644 index 00000000..566b493a --- /dev/null +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseTaskItemListBuilder.java @@ -0,0 +1,176 @@ +/* + * 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.standard; + +import io.serverlessworkflow.api.types.CallTask; +import io.serverlessworkflow.api.types.Task; +import io.serverlessworkflow.api.types.TaskBase; +import io.serverlessworkflow.api.types.TaskItem; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.function.Consumer; + +/** + * A builder for an ordered {@link TaskItem} list. + * + *

This builder only knows how to append new TaskItems of various flavors, but does NOT expose + * {@link TaskBase}‑level methods like export(), input(), etc. Those belong on {@link + * TaskBaseBuilder} subclasses. + * + * @param the concrete builder type + */ +public abstract class BaseTaskItemListBuilder> { + + private final List list; + + public BaseTaskItemListBuilder() { + this.list = new ArrayList<>(); + } + + protected abstract SELF self(); + + protected abstract SELF newItemListBuilder(); + + protected SELF addTaskItem(TaskItem taskItem) { + Objects.requireNonNull(taskItem, "taskItem must not be null"); + list.add(taskItem); + return self(); + } + + protected void requireNameAndConfig(String name, Consumer cfg) { + Objects.requireNonNull(name, "Task name must not be null"); + Objects.requireNonNull(cfg, "Configurer must not be null"); + } + + public SELF set(String name, Consumer itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final SetTaskBuilder setBuilder = new SetTaskBuilder(); + itemsConfigurer.accept(setBuilder); + return addTaskItem(new TaskItem(name, new Task().withSetTask(setBuilder.build()))); + } + + public SELF set(Consumer itemsConfigurer) { + return this.set(UUID.randomUUID().toString(), itemsConfigurer); + } + + public SELF set(String name, final String expr) { + return this.set(name, s -> s.expr(expr)); + } + + public SELF set(final String expr) { + return this.set(UUID.randomUUID().toString(), s -> s.expr(expr)); + } + + public SELF forEach(String name, Consumer> itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final ForTaskBuilder forBuilder = new ForTaskBuilder<>(newItemListBuilder()); + itemsConfigurer.accept(forBuilder); + return addTaskItem(new TaskItem(name, new Task().withForTask(forBuilder.build()))); + } + + public SELF forEach(Consumer> itemsConfigurer) { + return this.forEach(UUID.randomUUID().toString(), itemsConfigurer); + } + + public SELF switchC(String name, Consumer itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final SwitchTaskBuilder switchBuilder = new SwitchTaskBuilder(); + itemsConfigurer.accept(switchBuilder); + return addTaskItem(new TaskItem(name, new Task().withSwitchTask(switchBuilder.build()))); + } + + public SELF switchC(Consumer itemsConfigurer) { + return this.switchC(UUID.randomUUID().toString(), itemsConfigurer); + } + + public SELF raise(String name, Consumer itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final RaiseTaskBuilder raiseBuilder = new RaiseTaskBuilder(); + itemsConfigurer.accept(raiseBuilder); + return addTaskItem(new TaskItem(name, new Task().withRaiseTask(raiseBuilder.build()))); + } + + public SELF raise(Consumer itemsConfigurer) { + return this.raise(UUID.randomUUID().toString(), itemsConfigurer); + } + + public SELF fork(String name, Consumer itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final ForkTaskBuilder forkBuilder = new ForkTaskBuilder(); + itemsConfigurer.accept(forkBuilder); + return addTaskItem(new TaskItem(name, new Task().withForkTask(forkBuilder.build()))); + } + + public SELF fork(Consumer itemsConfigurer) { + return this.fork(UUID.randomUUID().toString(), itemsConfigurer); + } + + public SELF listen(String name, Consumer itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final ListenTaskBuilder listenBuilder = new ListenTaskBuilder(); + itemsConfigurer.accept(listenBuilder); + return addTaskItem(new TaskItem(name, new Task().withListenTask(listenBuilder.build()))); + } + + public SELF listen(Consumer itemsConfigurer) { + return this.listen(UUID.randomUUID().toString(), itemsConfigurer); + } + + public SELF emit(String name, Consumer itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final EmitTaskBuilder emitBuilder = new EmitTaskBuilder(); + itemsConfigurer.accept(emitBuilder); + return addTaskItem(new TaskItem(name, new Task().withEmitTask(emitBuilder.build()))); + } + + public SELF emit(Consumer itemsConfigurer) { + return this.emit(UUID.randomUUID().toString(), itemsConfigurer); + } + + public SELF tryC(String name, Consumer> itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final TryTaskBuilder tryBuilder = new TryTaskBuilder<>(this.newItemListBuilder()); + itemsConfigurer.accept(tryBuilder); + return addTaskItem(new TaskItem(name, new Task().withTryTask(tryBuilder.build()))); + } + + public SELF tryC(Consumer> itemsConfigurer) { + return this.tryC(UUID.randomUUID().toString(), itemsConfigurer); + } + + public SELF callHTTP(String name, Consumer itemsConfigurer) { + requireNameAndConfig(name, itemsConfigurer); + final CallHTTPTaskBuilder callHTTPBuilder = new CallHTTPTaskBuilder(); + itemsConfigurer.accept(callHTTPBuilder); + return addTaskItem( + new TaskItem( + name, new Task().withCallTask(new CallTask().withCallHTTP(callHTTPBuilder.build())))); + } + + public SELF callHTTP(Consumer itemsConfigurer) { + return this.callHTTP(UUID.randomUUID().toString(), itemsConfigurer); + } + + /** + * @return an immutable snapshot of all {@link TaskItem}s added so far + */ + public List build() { + return Collections.unmodifiableList(list); + } +} diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseWorkflowBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseWorkflowBuilder.java new file mode 100644 index 00000000..b93bdda0 --- /dev/null +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/BaseWorkflowBuilder.java @@ -0,0 +1,106 @@ +/* + * 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.standard; + +import io.serverlessworkflow.api.types.Document; +import io.serverlessworkflow.api.types.Export; +import io.serverlessworkflow.api.types.Input; +import io.serverlessworkflow.api.types.Output; +import io.serverlessworkflow.api.types.Workflow; +import java.util.function.Consumer; + +public abstract class BaseWorkflowBuilder< + SELF extends BaseWorkflowBuilder, + DO extends BaseDoTaskBuilder, + LIST extends BaseTaskItemListBuilder> + implements TransformationHandlers { + + public static final String DSL = "1.0.0"; + public static final String DEFAULT_VERSION = "0.0.1"; + public static final String DEFAULT_NAMESPACE = "org.acme"; + + private final Workflow workflow; + private final Document document; + + protected BaseWorkflowBuilder(final String name, final String namespace, final String version) { + this.document = new Document(); + this.document.setName(name); + this.document.setNamespace(namespace); + this.document.setVersion(version); + this.document.setDsl(DSL); + this.workflow = new Workflow(); + this.workflow.setDocument(this.document); + } + + protected abstract DO newDo(); + + protected abstract SELF self(); + + @Override + public void setOutput(Output output) { + this.workflow.setOutput(output); + } + + @Override + public void setExport(Export export) { + // TODO: build another interface with only Output and Input + throw new UnsupportedOperationException( + "export() is not supported on the workflow root; only tasks may export"); + } + + @Override + public void setInput(Input input) { + this.workflow.setInput(input); + } + + public SELF document(Consumer documentBuilderConsumer) { + final DocumentBuilder documentBuilder = new DocumentBuilder(this.document); + documentBuilderConsumer.accept(documentBuilder); + return self(); + } + + public SELF use(Consumer useBuilderConsumer) { + final UseBuilder builder = new UseBuilder(); + useBuilderConsumer.accept(builder); + this.workflow.setUse(builder.build()); + return self(); + } + + public SELF tasks(Consumer doTaskConsumer) { + final DO doTaskBuilder = newDo(); + doTaskConsumer.accept(doTaskBuilder); + this.workflow.setDo(doTaskBuilder.build().getDo()); + return self(); + } + + public SELF input(Consumer inputBuilderConsumer) { + final InputBuilder inputBuilder = new InputBuilder(); + inputBuilderConsumer.accept(inputBuilder); + this.workflow.setInput(inputBuilder.build()); + return self(); + } + + public SELF output(Consumer outputBuilderConsumer) { + final OutputBuilder outputBuilder = new OutputBuilder(); + outputBuilderConsumer.accept(outputBuilder); + this.workflow.setOutput(outputBuilder.build()); + return self(); + } + + public Workflow build() { + return this.workflow; + } +} diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/DoTaskBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/DoTaskBuilder.java index 3de5cfe7..dee523b3 100644 --- a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/DoTaskBuilder.java +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/DoTaskBuilder.java @@ -15,142 +15,14 @@ */ package io.serverlessworkflow.fluent.standard; -import io.serverlessworkflow.api.types.CallTask; -import io.serverlessworkflow.api.types.DoTask; -import io.serverlessworkflow.api.types.Task; -import io.serverlessworkflow.api.types.TaskItem; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import java.util.function.Consumer; - -public class DoTaskBuilder extends TaskBaseBuilder { - - private final DoTask doTask; - private final List list; +public class DoTaskBuilder extends BaseDoTaskBuilder { DoTaskBuilder() { - this.doTask = new DoTask(); - this.list = new ArrayList<>(); - this.setTask(doTask); + super(new TaskItemListBuilder()); } @Override protected DoTaskBuilder self() { return this; } - - public DoTaskBuilder set(String name, Consumer itemsConfigurer) { - final SetTaskBuilder setBuilder = new SetTaskBuilder(); - itemsConfigurer.accept(setBuilder); - this.list.add(new TaskItem(name, new Task().withSetTask(setBuilder.build()))); - return this; - } - - public DoTaskBuilder set(Consumer itemsConfigurer) { - return this.set(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTaskBuilder set(String name, final String expr) { - return this.set(name, s -> s.expr(expr)); - } - - public DoTaskBuilder set(final String expr) { - return this.set(UUID.randomUUID().toString(), s -> s.expr(expr)); - } - - public DoTaskBuilder forEach(String name, Consumer itemsConfigurer) { - final ForTaskBuilder forBuilder = new ForTaskBuilder(); - itemsConfigurer.accept(forBuilder); - this.list.add(new TaskItem(name, new Task().withForTask(forBuilder.build()))); - return this; - } - - public DoTaskBuilder forEach(Consumer itemsConfigurer) { - return this.forEach(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTaskBuilder switchTask(String name, Consumer itemsConfigurer) { - final SwitchTaskBuilder switchBuilder = new SwitchTaskBuilder(); - itemsConfigurer.accept(switchBuilder); - this.list.add(new TaskItem(name, new Task().withSwitchTask(switchBuilder.build()))); - return this; - } - - public DoTaskBuilder switchTask(Consumer itemsConfigurer) { - return this.switchTask(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTaskBuilder raise(String name, Consumer itemsConfigurer) { - final RaiseTaskBuilder raiseBuilder = new RaiseTaskBuilder(); - itemsConfigurer.accept(raiseBuilder); - this.list.add(new TaskItem(name, new Task().withRaiseTask(raiseBuilder.build()))); - return this; - } - - public DoTaskBuilder raise(Consumer itemsConfigurer) { - return this.raise(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTaskBuilder fork(String name, Consumer itemsConfigurer) { - final ForkTaskBuilder forkBuilder = new ForkTaskBuilder(); - itemsConfigurer.accept(forkBuilder); - this.list.add(new TaskItem(name, new Task().withForkTask(forkBuilder.build()))); - return this; - } - - public DoTaskBuilder fork(Consumer itemsConfigurer) { - return this.fork(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTaskBuilder listen(String name, Consumer itemsConfigurer) { - final ListenTaskBuilder listenBuilder = new ListenTaskBuilder(); - itemsConfigurer.accept(listenBuilder); - this.list.add(new TaskItem(name, new Task().withListenTask(listenBuilder.build()))); - return this; - } - - public DoTaskBuilder listen(Consumer itemsConfigurer) { - return this.listen(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTaskBuilder emit(String name, Consumer itemsConfigurer) { - final EmitTaskBuilder emitBuilder = new EmitTaskBuilder(); - itemsConfigurer.accept(emitBuilder); - this.list.add(new TaskItem(name, new Task().withEmitTask(emitBuilder.build()))); - return this; - } - - public DoTaskBuilder emit(Consumer itemsConfigurer) { - return this.emit(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTaskBuilder tryTask(String name, Consumer itemsConfigurer) { - final TryTaskBuilder tryBuilder = new TryTaskBuilder(); - itemsConfigurer.accept(tryBuilder); - this.list.add(new TaskItem(name, new Task().withTryTask(tryBuilder.build()))); - return this; - } - - public DoTaskBuilder tryTask(Consumer itemsConfigurer) { - return this.tryTask(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTaskBuilder callHTTP(String name, Consumer itemsConfigurer) { - final CallHTTPTaskBuilder callHTTPBuilder = new CallHTTPTaskBuilder(); - itemsConfigurer.accept(callHTTPBuilder); - this.list.add( - new TaskItem( - name, new Task().withCallTask(new CallTask().withCallHTTP(callHTTPBuilder.build())))); - return this; - } - - public DoTaskBuilder callHTTP(Consumer itemsConfigurer) { - return this.callHTTP(UUID.randomUUID().toString(), itemsConfigurer); - } - - public DoTask build() { - this.doTask.setDo(this.list); - return this.doTask; - } } diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/ForTaskBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/ForTaskBuilder.java index e755eebd..ba0cec7c 100644 --- a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/ForTaskBuilder.java +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/ForTaskBuilder.java @@ -19,46 +19,49 @@ import io.serverlessworkflow.api.types.ForTaskConfiguration; import java.util.function.Consumer; -public class ForTaskBuilder extends TaskBaseBuilder { +public class ForTaskBuilder> + extends TaskBaseBuilder> { private final ForTask forTask; private final ForTaskConfiguration forTaskConfiguration; + private final T taskItemListBuilder; - ForTaskBuilder() { + ForTaskBuilder(T taskItemListBuilder) { super(); forTask = new ForTask(); forTaskConfiguration = new ForTaskConfiguration(); + this.taskItemListBuilder = taskItemListBuilder; super.setTask(forTask); } - protected ForTaskBuilder self() { + protected ForTaskBuilder self() { return this; } - public ForTaskBuilder each(String each) { + public ForTaskBuilder each(String each) { forTaskConfiguration.setEach(each); return this; } - public ForTaskBuilder in(String in) { + public ForTaskBuilder in(String in) { this.forTaskConfiguration.setIn(in); return this; } - public ForTaskBuilder at(String at) { + public ForTaskBuilder at(String at) { this.forTaskConfiguration.setAt(at); return this; } - public ForTaskBuilder whileCondition(final String expression) { + public ForTaskBuilder whileC(final String expression) { this.forTask.setWhile(expression); return this; } - public ForTaskBuilder doTasks(Consumer doBuilderConsumer) { - final DoTaskBuilder doTaskBuilder = new DoTaskBuilder(); - doBuilderConsumer.accept(doTaskBuilder); - this.forTask.setDo(doTaskBuilder.build().getDo()); + public ForTaskBuilder tasks(Consumer doBuilderConsumer) { + final T taskItemListBuilder = this.taskItemListBuilder.newItemListBuilder(); + doBuilderConsumer.accept(taskItemListBuilder); + this.forTask.setDo(taskItemListBuilder.build()); return this; } diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/SwitchTaskBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/SwitchTaskBuilder.java index 12e027ee..fca04cdf 100644 --- a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/SwitchTaskBuilder.java +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/SwitchTaskBuilder.java @@ -15,11 +15,14 @@ */ package io.serverlessworkflow.fluent.standard; +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 java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.function.Consumer; public class SwitchTaskBuilder extends TaskBaseBuilder { @@ -39,7 +42,11 @@ protected SwitchTaskBuilder self() { return this; } - public SwitchTaskBuilder switchTask( + public SwitchTaskBuilder items(Consumer switchCaseConsumer) { + return this.items(UUID.randomUUID().toString(), switchCaseConsumer); + } + + public SwitchTaskBuilder items( final String name, Consumer switchCaseConsumer) { final SwitchCaseBuilder switchCaseBuilder = new SwitchCaseBuilder(); switchCaseConsumer.accept(switchCaseBuilder); @@ -64,8 +71,13 @@ public SwitchCaseBuilder when(String when) { return this; } - public SwitchCaseBuilder then(String then) { - this.switchCase.setWhen(then); + public SwitchCaseBuilder then(FlowDirective then) { + this.switchCase.setThen(then); + return this; + } + + public SwitchCaseBuilder then(FlowDirectiveEnum then) { + this.switchCase.setThen(new FlowDirective().withFlowDirectiveEnum(then)); return this; } diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TaskBaseBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TaskBaseBuilder.java index 31d30b3f..e4b9a623 100644 --- a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TaskBaseBuilder.java +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TaskBaseBuilder.java @@ -21,24 +21,42 @@ import io.serverlessworkflow.api.types.ExternalResource; import io.serverlessworkflow.api.types.FlowDirective; import io.serverlessworkflow.api.types.FlowDirectiveEnum; +import io.serverlessworkflow.api.types.Input; +import io.serverlessworkflow.api.types.Output; import io.serverlessworkflow.api.types.SchemaExternal; import io.serverlessworkflow.api.types.SchemaInline; import io.serverlessworkflow.api.types.SchemaUnion; import io.serverlessworkflow.api.types.TaskBase; import java.util.function.Consumer; -public abstract class TaskBaseBuilder> { - protected abstract T self(); - +public abstract class TaskBaseBuilder> + implements TransformationHandlers { private TaskBase task; protected TaskBaseBuilder() {} + protected abstract T self(); + protected void setTask(TaskBase task) { this.task = task; } - public T _if(String id) { + @Override + public void setInput(Input input) { + this.task.setInput(input); + } + + @Override + public void setExport(Export export) { + this.task.setExport(export); + } + + @Override + public void setOutput(Output output) { + this.task.setOutput(output); + } + + public T ifClause(String id) { this.task.setIf(id); return self(); } diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TaskItemListBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TaskItemListBuilder.java new file mode 100644 index 00000000..ebc3353c --- /dev/null +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TaskItemListBuilder.java @@ -0,0 +1,33 @@ +/* + * 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.standard; + +public class TaskItemListBuilder extends BaseTaskItemListBuilder { + + TaskItemListBuilder() { + super(); + } + + @Override + protected TaskItemListBuilder self() { + return this; + } + + @Override + protected TaskItemListBuilder newItemListBuilder() { + return new TaskItemListBuilder(); + } +} diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TransformationHandlers.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TransformationHandlers.java new file mode 100644 index 00000000..298f2fbe --- /dev/null +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TransformationHandlers.java @@ -0,0 +1,29 @@ +/* + * 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.standard; + +import io.serverlessworkflow.api.types.Export; +import io.serverlessworkflow.api.types.Input; +import io.serverlessworkflow.api.types.Output; + +public interface TransformationHandlers { + + void setOutput(final Output output); + + void setExport(final Export export); + + void setInput(final Input input); +} diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TryTaskBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TryTaskBuilder.java index 2e022503..677a36f0 100644 --- a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TryTaskBuilder.java +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TryTaskBuilder.java @@ -34,27 +34,30 @@ import io.serverlessworkflow.api.types.TryTaskCatch; import java.util.function.Consumer; -public class TryTaskBuilder extends TaskBaseBuilder { +public class TryTaskBuilder> + extends TaskBaseBuilder> { private final TryTask tryTask; + private final T doTaskBuilderFactory; - TryTaskBuilder() { + TryTaskBuilder(T doTaskBuilderFactory) { this.tryTask = new TryTask(); + this.doTaskBuilderFactory = doTaskBuilderFactory; } @Override - protected TryTaskBuilder self() { + protected TryTaskBuilder self() { return this; } - public TryTaskBuilder tryHandler(Consumer consumer) { - final DoTaskBuilder doTaskBuilder = new DoTaskBuilder(); - consumer.accept(doTaskBuilder); - this.tryTask.setTry(doTaskBuilder.build().getDo()); + public TryTaskBuilder tryHandler(Consumer consumer) { + final T taskItemListBuilder = this.doTaskBuilderFactory.newItemListBuilder(); + consumer.accept(taskItemListBuilder); + this.tryTask.setTry(taskItemListBuilder.build()); return this; } - public TryTaskBuilder catchHandler(Consumer consumer) { + public TryTaskBuilder catchHandler(Consumer consumer) { final TryTaskCatchBuilder catchBuilder = new TryTaskCatchBuilder(); consumer.accept(catchBuilder); this.tryTask.setCatch(catchBuilder.build()); diff --git a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/WorkflowBuilder.java b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/WorkflowBuilder.java index 742b5761..278e1df8 100644 --- a/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/WorkflowBuilder.java +++ b/fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/WorkflowBuilder.java @@ -15,28 +15,18 @@ */ package io.serverlessworkflow.fluent.standard; -import io.serverlessworkflow.api.types.Document; -import io.serverlessworkflow.api.types.Workflow; import java.util.UUID; -import java.util.function.Consumer; -public class WorkflowBuilder { - - private static final String DSL = "1.0.0"; - private static final String DEFAULT_VERSION = "0.0.1"; - private static final String DEFAULT_NAMESPACE = "org.acme"; - - private final Workflow workflow; - private final Document document; +public class WorkflowBuilder + extends BaseWorkflowBuilder { private WorkflowBuilder(final String name, final String namespace, final String version) { - this.document = new Document(); - this.document.setName(name); - this.document.setNamespace(namespace); - this.document.setVersion(version); - this.document.setDsl(DSL); - this.workflow = new Workflow(); - this.workflow.setDocument(this.document); + super(name, namespace, version); + } + + @Override + protected DoTaskBuilder newDo() { + return new DoTaskBuilder(); } public static WorkflowBuilder workflow( @@ -56,41 +46,8 @@ public static WorkflowBuilder workflow() { return new WorkflowBuilder(UUID.randomUUID().toString(), DEFAULT_NAMESPACE, DEFAULT_VERSION); } - public WorkflowBuilder document(Consumer documentBuilderConsumer) { - final DocumentBuilder documentBuilder = new DocumentBuilder(this.document); - documentBuilderConsumer.accept(documentBuilder); - return this; - } - - public WorkflowBuilder use(Consumer useBuilderConsumer) { - final UseBuilder builder = new UseBuilder(); - useBuilderConsumer.accept(builder); - this.workflow.setUse(builder.build()); - return this; - } - - public WorkflowBuilder doTasks(Consumer doTaskConsumer) { - final DoTaskBuilder doTaskBuilder = new DoTaskBuilder(); - doTaskConsumer.accept(doTaskBuilder); - this.workflow.setDo(doTaskBuilder.build().getDo()); + @Override + protected WorkflowBuilder self() { return this; } - - public WorkflowBuilder input(Consumer inputBuilderConsumer) { - final InputBuilder inputBuilder = new InputBuilder(); - inputBuilderConsumer.accept(inputBuilder); - this.workflow.setInput(inputBuilder.build()); - return this; - } - - public WorkflowBuilder output(Consumer outputBuilderConsumer) { - final OutputBuilder outputBuilder = new OutputBuilder(); - outputBuilderConsumer.accept(outputBuilder); - this.workflow.setOutput(outputBuilder.build()); - return this; - } - - public Workflow build() { - return this.workflow; - } } diff --git a/fluent/standard/src/test/java/io/serverlessworkflow/fluent/standard/WorkflowBuilderTest.java b/fluent/standard/src/test/java/io/serverlessworkflow/fluent/standard/WorkflowBuilderTest.java index e29a27b9..cdf1c3ba 100644 --- a/fluent/standard/src/test/java/io/serverlessworkflow/fluent/standard/WorkflowBuilderTest.java +++ b/fluent/standard/src/test/java/io/serverlessworkflow/fluent/standard/WorkflowBuilderTest.java @@ -99,7 +99,7 @@ void testUseAuthenticationsBasic() { void testDoTaskSetAndForEach() { Workflow wf = WorkflowBuilder.workflow("flowDo") - .doTasks( + .tasks( d -> d.set("initCtx", "$.foo = 'bar'") .forEach("item", f -> f.each("item").at("$.list"))) @@ -124,11 +124,11 @@ void testDoTaskSetAndForEach() { void testDoTaskMultipleTypes() { Workflow wf = WorkflowBuilder.workflow("flowMixed") - .doTasks( + .tasks( d -> d.set("init", s -> s.expr("$.init = true")) .forEach("items", f -> f.each("item").in("$.list")) - .switchTask( + .switchC( "choice", sw -> { // no-op configuration @@ -154,7 +154,7 @@ void testDoTaskMultipleTypes() { assertEquals("init", setItem.getName()); assertNotNull(setItem.getTask().getSetTask(), "SetTask should be present"); - // forEach task + // forE task TaskItem forItem = items.get(1); assertEquals("items", forItem.getName()); assertNotNull(forItem.getTask().getForTask(), "ForTask should be present"); @@ -179,7 +179,7 @@ void testDoTaskMultipleTypes() { void testDoTaskListenOne() { Workflow wf = WorkflowBuilder.workflow("flowListen") - .doTasks( + .tasks( d -> d.listen( "waitCheck", @@ -205,7 +205,7 @@ void testDoTaskListenOne() { void testDoTaskEmitEvent() { Workflow wf = WorkflowBuilder.workflow("flowEmit") - .doTasks( + .tasks( d -> d.emit( "emitEvent", @@ -256,9 +256,9 @@ void testDoTaskEmitEvent() { void testDoTaskTryCatchWithRetry() { Workflow wf = WorkflowBuilder.workflow("flowTry") - .doTasks( + .tasks( d -> - d.tryTask( + d.tryC( "tryBlock", t -> t.tryHandler(tb -> tb.set("init", s -> s.expr("$.start = true"))) @@ -304,9 +304,9 @@ void testDoTaskTryCatchWithRetry() { void testDoTaskTryCatchErrorsFiltering() { Workflow wf = WorkflowBuilder.workflow("flowCatch") - .doTasks( + .tasks( d -> - d.tryTask( + d.tryC( "tryBlock", t -> t.tryHandler(tb -> tb.set("foo", s -> s.expr("$.foo = 'bar'"))) @@ -402,7 +402,7 @@ void testWorkflowInputInlineSchemaAndFromObject() { void testDoTaskCallHTTPBasic() { Workflow wf = WorkflowBuilder.workflow("flowCallBasic") - .doTasks( + .tasks( d -> d.callHTTP( "basicCall", @@ -428,7 +428,7 @@ void testDoTaskCallHTTPBasic() { void testDoTaskCallHTTPHeadersConsumerAndMap() { Workflow wf = WorkflowBuilder.workflow("flowCallHeaders") - .doTasks( + .tasks( d -> d.callHTTP( "hdrCall", @@ -444,7 +444,7 @@ void testDoTaskCallHTTPHeadersConsumerAndMap() { Workflow wf2 = WorkflowBuilder.workflow() - .doTasks( + .tasks( d -> d.callHTTP( c -> @@ -460,7 +460,7 @@ void testDoTaskCallHTTPHeadersConsumerAndMap() { void testDoTaskCallHTTPQueryConsumerAndMap() { Workflow wf = WorkflowBuilder.workflow("flowCallQuery") - .doTasks( + .tasks( d -> d.callHTTP( "qryCall", @@ -476,7 +476,7 @@ void testDoTaskCallHTTPQueryConsumerAndMap() { Workflow wf2 = WorkflowBuilder.workflow() - .doTasks( + .tasks( d -> d.callHTTP( c -> c.method("GET").endpoint("uri").query(Map.of("q1", "x", "q2", "y")))) @@ -498,7 +498,7 @@ void testDoTaskCallHTTPQueryConsumerAndMap() { void testDoTaskCallHTTPRedirectAndOutput() { Workflow wf = WorkflowBuilder.workflow("flowCallOpts") - .doTasks( + .tasks( d -> d.callHTTP( "optCall",