Skip to content

Commit 04a3563

Browse files
feat: add sub worflows run on FuncDSL (#1299)
Signed-off-by: Matheus Andre <matheusandr2@gmail.com> Signed-off-by: Matheus André <matheusandr2@gmail.com>
1 parent 37b3f39 commit 04a3563

6 files changed

Lines changed: 265 additions & 130 deletions

File tree

‎experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncDoTaskBuilder.java‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.serverlessworkflow.fluent.func.spi.FuncDoFluent;
2020
import io.serverlessworkflow.fluent.func.spi.FuncTaskTransformations;
2121
import io.serverlessworkflow.fluent.spec.BaseDoTaskBuilder;
22+
import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder;
2223
import java.util.function.Consumer;
2324

2425
public class FuncDoTaskBuilder extends BaseDoTaskBuilder<FuncDoTaskBuilder, FuncTaskItemListBuilder>
@@ -103,6 +104,24 @@ public FuncDoTaskBuilder openapi(
103104
return this;
104105
}
105106

107+
@Override
108+
public FuncDoTaskBuilder workflow(String name, Consumer<WorkflowTaskBuilder> itemsConfigurer) {
109+
this.listBuilder().workflow(name, itemsConfigurer);
110+
return this;
111+
}
112+
113+
@Override
114+
public FuncDoTaskBuilder subflow(String name, Consumer<WorkflowTaskBuilder> itemsConfigurer) {
115+
this.listBuilder().subflow(name, itemsConfigurer);
116+
return this;
117+
}
118+
119+
@Override
120+
public FuncDoTaskBuilder subflow(Consumer<WorkflowTaskBuilder> itemsConfigurer) {
121+
this.listBuilder().subflow(itemsConfigurer);
122+
return this;
123+
}
124+
106125
@Override
107126
public FuncDoTaskBuilder tryCatch(String name, Consumer<FuncTryTaskBuilder> itemsConfigurer) {
108127
this.listBuilder().tryCatch(name, itemsConfigurer);

‎experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/FuncTaskItemListBuilder.java‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import io.serverlessworkflow.api.types.TaskItem;
2323
import io.serverlessworkflow.fluent.func.spi.FuncDoFluent;
2424
import io.serverlessworkflow.fluent.spec.BaseTaskItemListBuilder;
25+
import io.serverlessworkflow.fluent.spec.TaskItemListBuilder;
26+
import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder;
2527
import java.util.List;
2628
import java.util.function.Consumer;
2729

@@ -165,6 +167,46 @@ public FuncTaskItemListBuilder openapi(
165167
return this.addTaskItem(new TaskItem(name, task));
166168
}
167169

170+
@Override
171+
public FuncTaskItemListBuilder workflow(
172+
String name, Consumer<WorkflowTaskBuilder> itemsConfigurer) {
173+
return this.addDelegatedWorkflow(name, itemsConfigurer, TYPE_WORKFLOW);
174+
}
175+
176+
@Override
177+
public FuncTaskItemListBuilder workflow(Consumer<WorkflowTaskBuilder> itemsConfigurer) {
178+
return this.workflow(null, itemsConfigurer);
179+
}
180+
181+
@Override
182+
public FuncTaskItemListBuilder subflow(
183+
String name, Consumer<WorkflowTaskBuilder> itemsConfigurer) {
184+
return this.addDelegatedWorkflow(name, itemsConfigurer, TYPE_WORKFLOW);
185+
}
186+
187+
@Override
188+
public FuncTaskItemListBuilder subflow(Consumer<WorkflowTaskBuilder> itemsConfigurer) {
189+
return this.subflow(null, itemsConfigurer);
190+
}
191+
192+
private FuncTaskItemListBuilder addDelegatedWorkflow(
193+
String name, Consumer<WorkflowTaskBuilder> itemsConfigurer, String delegateType) {
194+
name = this.defaultNameAndRequireConfig(name, itemsConfigurer, delegateType);
195+
// Preserve the original offset when delegating to avoid duplicate task names
196+
// across appended .tasks(...) blocks
197+
final int effectiveOffset = this.getOffset() + this.mutableList().size();
198+
final TaskItemListBuilder delegate = new TaskItemListBuilder(effectiveOffset);
199+
delegate.workflow(name, itemsConfigurer);
200+
final List<TaskItem> taskItems = delegate.build();
201+
if (taskItems.size() != 1) {
202+
throw new IllegalStateException(
203+
String.format(
204+
"Expected %s delegate '%s' to build exactly 1 TaskItem, but got %d",
205+
delegateType, name, taskItems.size()));
206+
}
207+
return addTaskItem(taskItems.get(0));
208+
}
209+
168210
@Override
169211
public FuncTaskItemListBuilder tryCatch(
170212
String name, Consumer<FuncTryTaskBuilder> itemsConfigurer) {

‎experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/dsl/FuncDSL.java‎

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@
4141
import io.serverlessworkflow.fluent.spec.EventFilterBuilder;
4242
import io.serverlessworkflow.fluent.spec.ScheduleBuilder;
4343
import io.serverlessworkflow.fluent.spec.TimeoutBuilder;
44+
import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder;
4445
import io.serverlessworkflow.fluent.spec.configurers.AuthenticationConfigurer;
46+
import io.serverlessworkflow.fluent.spec.configurers.WorkflowConfigurer;
4547
import io.serverlessworkflow.fluent.spec.dsl.DSL;
4648
import io.serverlessworkflow.fluent.spec.dsl.UseSpec;
49+
import io.serverlessworkflow.fluent.spec.dsl.WorkflowSpec;
4750
import io.serverlessworkflow.impl.TaskContextData;
4851
import io.serverlessworkflow.impl.WorkflowContextData;
4952
import java.net.URI;
@@ -1133,6 +1136,107 @@ public static FuncTaskConfigurer set(Map<String, Object> map) {
11331136
return list -> list.set(s -> s.expr(map));
11341137
}
11351138

1139+
/**
1140+
* Create a {@link FuncTaskConfigurer} that adds a sub-workflow call task using a {@link
1141+
* WorkflowConfigurer}.
1142+
*
1143+
* <pre>{@code
1144+
* tasks(
1145+
* subflow(
1146+
* workflow("org.acme", "sub-workflow", "0.1.0")
1147+
* .input("id", 99)
1148+
* .await(false)
1149+
* )
1150+
* );
1151+
* }</pre>
1152+
*
1153+
* @param configurer nested workflow configurer
1154+
* @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list
1155+
*/
1156+
public static FuncTaskConfigurer subflow(WorkflowConfigurer configurer) {
1157+
Objects.requireNonNull(configurer, "configurer");
1158+
return list -> list.subflow(configurer);
1159+
}
1160+
1161+
/**
1162+
* Create a {@link FuncTaskConfigurer} that adds a named sub-workflow call task.
1163+
*
1164+
* @param name task name
1165+
* @param configurer nested workflow configurer
1166+
* @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list
1167+
*/
1168+
public static FuncTaskConfigurer subflow(String name, Consumer<WorkflowTaskBuilder> configurer) {
1169+
Objects.requireNonNull(name, "name");
1170+
Objects.requireNonNull(configurer, "configurer");
1171+
return list -> list.subflow(name, configurer);
1172+
}
1173+
1174+
/**
1175+
* Create a {@link FuncTaskConfigurer} that adds an unnamed sub-workflow call task.
1176+
*
1177+
* @param configurer nested workflow configurer
1178+
* @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list
1179+
*/
1180+
public static FuncTaskConfigurer subflow(Consumer<WorkflowTaskBuilder> configurer) {
1181+
Objects.requireNonNull(configurer, "configurer");
1182+
return list -> list.subflow(configurer);
1183+
}
1184+
1185+
/**
1186+
* Alias for {@link #subflow(WorkflowConfigurer)}.
1187+
*
1188+
* @param configurer nested workflow configurer
1189+
* @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list
1190+
*/
1191+
public static FuncTaskConfigurer workflowTask(WorkflowConfigurer configurer) {
1192+
return subflow(configurer);
1193+
}
1194+
1195+
/**
1196+
* Create a {@link FuncTaskConfigurer} that adds a workflow subflow task.
1197+
*
1198+
* @param configurer configurer for the nested workflow task
1199+
* @return a {@link FuncTaskConfigurer} that adds a workflow task to the tasks list
1200+
* @deprecated use {@link #subflow(WorkflowConfigurer)} to avoid ambiguity with spec-side factory
1201+
* methods
1202+
*/
1203+
@Deprecated
1204+
public static FuncTaskConfigurer workflow(WorkflowConfigurer configurer) {
1205+
return subflow(configurer);
1206+
}
1207+
1208+
/**
1209+
* Create a new {@link WorkflowSpec} to be used as a factory for workflow definitions.
1210+
*
1211+
* @param namespace workflow namespace
1212+
* @param name workflow name
1213+
* @param version workflow version
1214+
* @return a new {@link WorkflowSpec} instance
1215+
*/
1216+
public static WorkflowSpec workflow(String namespace, String name, String version) {
1217+
return DSL.workflow(namespace, name, version);
1218+
}
1219+
1220+
/**
1221+
* Create a new {@link WorkflowSpec} to be used as a factory for workflow definitions.
1222+
*
1223+
* @param namespace workflow namespace
1224+
* @param name workflow name
1225+
* @return a new {@link WorkflowSpec} instance
1226+
*/
1227+
public static WorkflowSpec workflow(String namespace, String name) {
1228+
return DSL.workflow(namespace, name);
1229+
}
1230+
1231+
/**
1232+
* Create a new {@link WorkflowSpec} to be used as a factory for workflow definitions.
1233+
*
1234+
* @return a new {@link WorkflowSpec} instance
1235+
*/
1236+
public static WorkflowSpec workflow() {
1237+
return DSL.workflow();
1238+
}
1239+
11361240
// ---------------------------------------------------------------------------
11371241
// HTTP / OpenAPI
11381242
// ---------------------------------------------------------------------------

‎experimental/fluent/func/src/main/java/io/serverlessworkflow/fluent/func/spi/FuncDoFluent.java‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.serverlessworkflow.fluent.func.FuncSetTaskBuilder;
2727
import io.serverlessworkflow.fluent.func.FuncSwitchTaskBuilder;
2828
import io.serverlessworkflow.fluent.func.FuncTryTaskBuilder;
29+
import io.serverlessworkflow.fluent.spec.WorkflowTaskBuilder;
2930
import io.serverlessworkflow.fluent.spec.spi.CallHttpFluent;
3031
import io.serverlessworkflow.fluent.spec.spi.CallOpenAPIFluent;
3132
import io.serverlessworkflow.fluent.spec.spi.EmitFluent;
@@ -36,6 +37,8 @@
3637
import io.serverlessworkflow.fluent.spec.spi.SetFluent;
3738
import io.serverlessworkflow.fluent.spec.spi.SwitchFluent;
3839
import io.serverlessworkflow.fluent.spec.spi.TryCatchFluent;
40+
import io.serverlessworkflow.fluent.spec.spi.WorkflowFluent;
41+
import java.util.function.Consumer;
3942

4043
public interface FuncDoFluent<SELF extends FuncDoFluent<SELF>>
4144
extends SetFluent<FuncSetTaskBuilder, SELF>,
@@ -48,4 +51,14 @@ public interface FuncDoFluent<SELF extends FuncDoFluent<SELF>>
4851
TryCatchFluent<FuncTryTaskBuilder, SELF>,
4952
CallFnFluent<FuncCallTaskBuilder, SELF>,
5053
CallHttpFluent<FuncCallHttpTaskBuilder, SELF>,
51-
CallOpenAPIFluent<FuncCallOpenAPITaskBuilder, SELF> {}
54+
CallOpenAPIFluent<FuncCallOpenAPITaskBuilder, SELF>,
55+
WorkflowFluent<WorkflowTaskBuilder, SELF> {
56+
57+
default SELF subflow(String name, Consumer<WorkflowTaskBuilder> itemsConfigurer) {
58+
return this.workflow(name, itemsConfigurer);
59+
}
60+
61+
default SELF subflow(Consumer<WorkflowTaskBuilder> itemsConfigurer) {
62+
return this.workflow(itemsConfigurer);
63+
}
64+
}

0 commit comments

Comments
 (0)