Skip to content

Commit 98a4bf7

Browse files
committed
feat: support to subflows on the Java DSL
Signed-off-by: Matheus André <92062874+matheusandre1@users.noreply.github.com>
1 parent 29ed45e commit 98a4bf7

File tree

11 files changed

+357
-1
lines changed

11 files changed

+357
-1
lines changed

fluent/spec/src/main/java/io/serverlessworkflow/fluent/spec/DoTaskBuilder.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,10 @@ public DoTaskBuilder openapi(String name, Consumer<CallOpenAPITaskBuilder> items
9797
this.listBuilder().openapi(name, itemsConfigurer);
9898
return this;
9999
}
100+
101+
@Override
102+
public DoTaskBuilder workflow(String name, Consumer<WorkflowTaskBuilder> itemsConfigurer) {
103+
this.listBuilder().workflow(name, itemsConfigurer);
104+
return this;
105+
}
100106
}

fluent/spec/src/main/java/io/serverlessworkflow/fluent/spec/TaskItemListBuilder.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,17 @@ public TaskItemListBuilder openapi(
146146

147147
return addTaskItem(new TaskItem(name, task));
148148
}
149+
150+
@Override
151+
public TaskItemListBuilder workflow(String name, Consumer<WorkflowTaskBuilder> itemsConfigurer) {
152+
name = defaultNameAndRequireConfig(name, itemsConfigurer);
153+
154+
final WorkflowTaskBuilder workflowTaskBuilder = new WorkflowTaskBuilder();
155+
itemsConfigurer.accept(workflowTaskBuilder);
156+
157+
final Task task = new Task();
158+
task.setRunTask(workflowTaskBuilder.build());
159+
160+
return addTaskItem(new TaskItem(name, task));
161+
}
149162
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.spec;
17+
18+
import io.serverlessworkflow.api.types.RunTask;
19+
import io.serverlessworkflow.api.types.RunTaskConfigurationUnion;
20+
import io.serverlessworkflow.api.types.RunWorkflow;
21+
import io.serverlessworkflow.api.types.SubflowConfiguration;
22+
import io.serverlessworkflow.fluent.spec.spi.WorkflowTaskFluent;
23+
24+
public class WorkflowTaskBuilder extends TaskBaseBuilder<WorkflowTaskBuilder>
25+
implements WorkflowTaskFluent<WorkflowTaskBuilder> {
26+
27+
private final RunTask task;
28+
private final RunWorkflow configuration;
29+
private final SubflowConfiguration workflow;
30+
31+
WorkflowTaskBuilder() {
32+
this.task = new RunTask();
33+
this.configuration = new RunWorkflow();
34+
this.workflow = new SubflowConfiguration();
35+
this.configuration.setWorkflow(this.workflow);
36+
this.task.setRun(new RunTaskConfigurationUnion().withRunWorkflow(this.configuration));
37+
this.setTask(task);
38+
}
39+
40+
@Override
41+
public WorkflowTaskBuilder self() {
42+
return this;
43+
}
44+
45+
public RunWorkflow config() {
46+
return this.configuration;
47+
}
48+
49+
public SubflowConfiguration workflow() {
50+
return this.workflow;
51+
}
52+
53+
public RunTask build() {
54+
return this.task;
55+
}
56+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.spec.configurers;
17+
18+
import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder;
19+
import java.util.function.Consumer;
20+
21+
@FunctionalInterface
22+
public interface WorkflowConfigurer extends Consumer<WorkflowTaskBuilder> {}

fluent/spec/src/main/java/io/serverlessworkflow/fluent/spec/dsl/DSL.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import io.serverlessworkflow.fluent.spec.configurers.TasksConfigurer;
3434
import io.serverlessworkflow.fluent.spec.configurers.TryCatchConfigurer;
3535
import io.serverlessworkflow.fluent.spec.configurers.TryConfigurer;
36+
import io.serverlessworkflow.fluent.spec.configurers.WorkflowConfigurer;
3637
import io.serverlessworkflow.types.Errors;
3738
import java.net.URI;
3839
import java.util.List;
@@ -102,6 +103,18 @@ public static CallOpenAPISpec openapi() {
102103
return new CallOpenAPISpec();
103104
}
104105

106+
public static WorkflowSpec workflow(String namespace, String name, String version) {
107+
return new WorkflowSpec().namespace(namespace).name(name).version(version);
108+
}
109+
110+
public static WorkflowSpec workflow(String namespace, String name) {
111+
return new WorkflowSpec().namespace(namespace).name(name);
112+
}
113+
114+
public static WorkflowSpec workflow() {
115+
return new WorkflowSpec();
116+
}
117+
105118
/**
106119
* Convenience for defining a {@code use} block with a single secret.
107120
*
@@ -623,6 +636,10 @@ public static TasksConfigurer call(CallOpenAPIConfigurer configurer) {
623636
return list -> list.openapi(configurer);
624637
}
625638

639+
public static TasksConfigurer workflow(WorkflowConfigurer configurer) {
640+
return list -> list.workflow(configurer);
641+
}
642+
626643
/**
627644
* Create a {@link TasksConfigurer} that adds a {@code set} task using a low-level configurer.
628645
*
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.spec.dsl;
17+
18+
import io.serverlessworkflow.api.types.RunTaskConfiguration;
19+
import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder;
20+
import io.serverlessworkflow.fluent.spec.configurers.WorkflowConfigurer;
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
import java.util.Map;
24+
import java.util.function.Consumer;
25+
26+
public final class WorkflowSpec implements WorkflowConfigurer {
27+
28+
private final List<Consumer<WorkflowTaskBuilder>> steps = new ArrayList<>();
29+
30+
public WorkflowSpec namespace(String namespace) {
31+
steps.add(b -> b.namespace(namespace));
32+
return this;
33+
}
34+
35+
public WorkflowSpec name(String name) {
36+
steps.add(b -> b.name(name));
37+
return this;
38+
}
39+
40+
public WorkflowSpec version(String version) {
41+
steps.add(b -> b.version(version));
42+
return this;
43+
}
44+
45+
public WorkflowSpec input(Map<String, Object> input) {
46+
steps.add(b -> b.input(input));
47+
return this;
48+
}
49+
50+
public WorkflowSpec input(String key, Object value) {
51+
steps.add(b -> b.input(key, value));
52+
return this;
53+
}
54+
55+
public WorkflowSpec await(boolean await) {
56+
steps.add(b -> b.await(await));
57+
return this;
58+
}
59+
60+
public WorkflowSpec returnType(RunTaskConfiguration.ProcessReturnType returnType) {
61+
steps.add(b -> b.returnType(returnType));
62+
return this;
63+
}
64+
65+
@Override
66+
public void accept(WorkflowTaskBuilder builder) {
67+
for (var s : steps) {
68+
s.accept(builder);
69+
}
70+
}
71+
}

fluent/spec/src/main/java/io/serverlessworkflow/fluent/spec/spi/DoFluent.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.serverlessworkflow.fluent.spec.SwitchTaskBuilder;
2727
import io.serverlessworkflow.fluent.spec.TaskItemListBuilder;
2828
import io.serverlessworkflow.fluent.spec.TryTaskBuilder;
29+
import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder;
2930

3031
/**
3132
* Documents the exposed fluent `do` DSL.
@@ -44,4 +45,5 @@ public interface DoFluent<T>
4445
ForkFluent<ForkTaskBuilder, T>,
4546
ListenFluent<ListenTaskBuilder, T>,
4647
RaiseFluent<RaiseTaskBuilder, T>,
47-
CallOpenAPIFluent<CallOpenAPITaskBuilder, T> {}
48+
CallOpenAPIFluent<CallOpenAPITaskBuilder, T>,
49+
WorkflowFluent<WorkflowTaskBuilder, T> {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.spec.spi;
17+
18+
import io.serverlessworkflow.fluent.spec.TaskBaseBuilder;
19+
import java.util.UUID;
20+
import java.util.function.Consumer;
21+
22+
public interface WorkflowFluent<SELF extends TaskBaseBuilder<SELF>, LIST> {
23+
24+
LIST workflow(String name, Consumer<SELF> itemsConfigurer);
25+
26+
default LIST workflow(Consumer<SELF> itemsConfigurer) {
27+
return this.workflow(UUID.randomUUID().toString(), itemsConfigurer);
28+
}
29+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.serverlessworkflow.fluent.spec.spi;
17+
18+
import io.serverlessworkflow.api.types.RunTaskConfiguration;
19+
import io.serverlessworkflow.api.types.SubflowInput;
20+
import io.serverlessworkflow.fluent.spec.TaskBaseBuilder;
21+
import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder;
22+
import java.util.Map;
23+
24+
public interface WorkflowTaskFluent<SELF extends TaskBaseBuilder<SELF>> {
25+
26+
SELF self();
27+
28+
default SELF namespace(String namespace) {
29+
((WorkflowTaskBuilder) this.self()).workflow().setNamespace(namespace);
30+
return self();
31+
}
32+
33+
default SELF name(String name) {
34+
((WorkflowTaskBuilder) this.self()).workflow().setName(name);
35+
return self();
36+
}
37+
38+
default SELF version(String version) {
39+
((WorkflowTaskBuilder) this.self()).workflow().setVersion(version);
40+
return self();
41+
}
42+
43+
default SELF input(Map<String, Object> input) {
44+
final SubflowInput subflowInput = new SubflowInput();
45+
input.forEach(subflowInput::setAdditionalProperty);
46+
((WorkflowTaskBuilder) this.self()).workflow().setInput(subflowInput);
47+
return self();
48+
}
49+
50+
default SELF input(String key, Object value) {
51+
final WorkflowTaskBuilder builder = (WorkflowTaskBuilder) this.self();
52+
if (builder.workflow().getInput() == null) {
53+
builder.workflow().setInput(new SubflowInput());
54+
}
55+
builder.workflow().getInput().setAdditionalProperty(key, value);
56+
return self();
57+
}
58+
59+
default SELF await(boolean await) {
60+
((WorkflowTaskBuilder) this.self()).config().setAwait(await);
61+
return self();
62+
}
63+
64+
default SELF returnType(RunTaskConfiguration.ProcessReturnType returnType) {
65+
((WorkflowTaskBuilder) this.self()).config().setReturn(returnType);
66+
return self();
67+
}
68+
}

fluent/spec/src/test/java/io/serverlessworkflow/fluent/spec/WorkflowBuilderTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import io.serverlessworkflow.api.types.OneEventConsumptionStrategy;
3939
import io.serverlessworkflow.api.types.RetryLimitAttempt;
4040
import io.serverlessworkflow.api.types.RetryPolicy;
41+
import io.serverlessworkflow.api.types.RunTaskConfiguration;
4142
import io.serverlessworkflow.api.types.SetTask;
4243
import io.serverlessworkflow.api.types.TaskItem;
4344
import io.serverlessworkflow.api.types.TryTask;
@@ -517,4 +518,51 @@ void testDoTaskCallHTTPRedirectAndOutput() {
517518
call.getWith().getOutput(),
518519
"Output should be overridden");
519520
}
521+
522+
@Test
523+
void testDoTaskRunWorkflow() {
524+
Workflow wf =
525+
WorkflowBuilder.workflow("parentFlow")
526+
.tasks(
527+
d ->
528+
d.workflow(
529+
"runChild",
530+
w ->
531+
w.namespace("org.acme")
532+
.name("childFlow")
533+
.version("1.0.0")
534+
.input(Map.of("id", 42, "region", "us-east"))
535+
.await(false)
536+
.returnType(RunTaskConfiguration.ProcessReturnType.NONE)))
537+
.build();
538+
539+
var runTask = wf.getDo().get(0).getTask().getRunTask();
540+
assertNotNull(runTask, "RunTask should be present");
541+
assertNotNull(runTask.getRun(), "RunTask configuration should be present");
542+
assertNotNull(runTask.getRun().getRunWorkflow(), "RunWorkflow should be selected");
543+
assertEquals("org.acme", runTask.getRun().getRunWorkflow().getWorkflow().getNamespace());
544+
assertEquals("childFlow", runTask.getRun().getRunWorkflow().getWorkflow().getName());
545+
assertEquals("1.0.0", runTask.getRun().getRunWorkflow().getWorkflow().getVersion());
546+
assertEquals(
547+
42,
548+
runTask
549+
.getRun()
550+
.getRunWorkflow()
551+
.getWorkflow()
552+
.getInput()
553+
.getAdditionalProperties()
554+
.get("id"));
555+
assertEquals(
556+
"us-east",
557+
runTask
558+
.getRun()
559+
.getRunWorkflow()
560+
.getWorkflow()
561+
.getInput()
562+
.getAdditionalProperties()
563+
.get("region"));
564+
assertEquals(
565+
RunTaskConfiguration.ProcessReturnType.NONE, runTask.getRun().getRunWorkflow().getReturn());
566+
assertEquals(false, runTask.getRun().getRunWorkflow().isAwait());
567+
}
520568
}

0 commit comments

Comments
 (0)