Skip to content

Commit 43fe833

Browse files
committed
Add input/output to workflow/tasks
Signed-off-by: Ricardo Zanini <[email protected]>
1 parent 3a08287 commit 43fe833

File tree

5 files changed

+258
-17
lines changed

5 files changed

+258
-17
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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.standard;
17+
18+
import io.serverlessworkflow.api.types.Endpoint;
19+
import io.serverlessworkflow.api.types.ExternalResource;
20+
import io.serverlessworkflow.api.types.Input;
21+
import io.serverlessworkflow.api.types.InputFrom;
22+
import io.serverlessworkflow.api.types.SchemaExternal;
23+
import io.serverlessworkflow.api.types.SchemaInline;
24+
import io.serverlessworkflow.api.types.SchemaUnion;
25+
26+
public class InputBuilder {
27+
28+
private final Input input;
29+
30+
InputBuilder() {
31+
this.input = new Input();
32+
this.input.setFrom(new InputFrom());
33+
this.input.setSchema(new SchemaUnion());
34+
}
35+
36+
public InputBuilder from(String expr) {
37+
this.input.getFrom().setString(expr);
38+
return this;
39+
}
40+
41+
public InputBuilder from(Object object) {
42+
this.input.getFrom().setObject(object);
43+
return this;
44+
}
45+
46+
public InputBuilder schema(Object schema) {
47+
this.input.getSchema().setSchemaInline(new SchemaInline(schema));
48+
return this;
49+
}
50+
51+
public InputBuilder schema(String schema) {
52+
this.input
53+
.getSchema()
54+
.setSchemaExternal(
55+
new SchemaExternal()
56+
.withResource(
57+
new ExternalResource()
58+
.withEndpoint(
59+
new Endpoint()
60+
.withUriTemplate(UriTemplateBuilder.newUriTemplate(schema)))));
61+
return this;
62+
}
63+
64+
public Input build() {
65+
return this.input;
66+
}
67+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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.standard;
17+
18+
import io.serverlessworkflow.api.types.Endpoint;
19+
import io.serverlessworkflow.api.types.ExternalResource;
20+
import io.serverlessworkflow.api.types.Output;
21+
import io.serverlessworkflow.api.types.OutputAs;
22+
import io.serverlessworkflow.api.types.SchemaExternal;
23+
import io.serverlessworkflow.api.types.SchemaInline;
24+
import io.serverlessworkflow.api.types.SchemaUnion;
25+
26+
public class OutputBuilder {
27+
28+
private final Output output;
29+
30+
OutputBuilder() {
31+
this.output = new Output();
32+
this.output.setAs(new OutputAs());
33+
this.output.setSchema(new SchemaUnion());
34+
}
35+
36+
public OutputBuilder as(final String expr) {
37+
this.output.getAs().setString(expr);
38+
return this;
39+
}
40+
41+
public OutputBuilder as(final Object object) {
42+
this.output.getAs().setObject(object);
43+
return this;
44+
}
45+
46+
public OutputBuilder schema(final String schema) {
47+
this.output
48+
.getSchema()
49+
.setSchemaExternal(
50+
new SchemaExternal()
51+
.withResource(
52+
new ExternalResource()
53+
.withEndpoint(
54+
new Endpoint()
55+
.withUriTemplate(UriTemplateBuilder.newUriTemplate(schema)))));
56+
return this;
57+
}
58+
59+
public OutputBuilder schema(final Object schema) {
60+
this.output.getSchema().setSchemaInline(new SchemaInline(schema));
61+
return this;
62+
}
63+
64+
public Output build() {
65+
return this.output;
66+
}
67+
}

fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/TaskBaseBuilder.java

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@
1515
*/
1616
package io.serverlessworkflow.fluent.standard;
1717

18+
import io.serverlessworkflow.api.types.Endpoint;
1819
import io.serverlessworkflow.api.types.Export;
1920
import io.serverlessworkflow.api.types.ExportAs;
21+
import io.serverlessworkflow.api.types.ExternalResource;
2022
import io.serverlessworkflow.api.types.FlowDirective;
2123
import io.serverlessworkflow.api.types.FlowDirectiveEnum;
24+
import io.serverlessworkflow.api.types.SchemaExternal;
25+
import io.serverlessworkflow.api.types.SchemaInline;
26+
import io.serverlessworkflow.api.types.SchemaUnion;
2227
import io.serverlessworkflow.api.types.TaskBase;
2328
import java.util.function.Consumer;
2429

@@ -55,24 +60,56 @@ public T export(Consumer<ExportBuilder> exportConsumer) {
5560
return self();
5661
}
5762

63+
public T input(Consumer<InputBuilder> inputConsumer) {
64+
final InputBuilder inputBuilder = new InputBuilder();
65+
inputConsumer.accept(inputBuilder);
66+
this.task.setInput(inputBuilder.build());
67+
return self();
68+
}
69+
70+
public T output(Consumer<OutputBuilder> outputConsumer) {
71+
final OutputBuilder outputBuilder = new OutputBuilder();
72+
outputConsumer.accept(outputBuilder);
73+
this.task.setOutput(outputBuilder.build());
74+
return self();
75+
}
76+
5877
// TODO: add timeout, metadata
5978

6079
public static final class ExportBuilder {
6180
private final Export export;
6281

63-
// TODO: add schema
64-
6582
public ExportBuilder() {
6683
this.export = new Export();
84+
this.export.setAs(new ExportAs());
85+
this.export.setSchema(new SchemaUnion());
6786
}
6887

6988
public ExportBuilder as(Object as) {
70-
this.export.setAs(new ExportAs().withObject(as));
89+
this.export.getAs().withObject(as);
7190
return this;
7291
}
7392

7493
public ExportBuilder as(String as) {
75-
this.export.setAs(new ExportAs().withString(as));
94+
this.export.getAs().withString(as);
95+
return this;
96+
}
97+
98+
public ExportBuilder schema(String schema) {
99+
this.export
100+
.getSchema()
101+
.setSchemaExternal(
102+
new SchemaExternal()
103+
.withResource(
104+
new ExternalResource()
105+
.withEndpoint(
106+
new Endpoint()
107+
.withUriTemplate(UriTemplateBuilder.newUriTemplate(schema)))));
108+
return this;
109+
}
110+
111+
public ExportBuilder schema(Object schema) {
112+
this.export.getSchema().setSchemaInline(new SchemaInline(schema));
76113
return this;
77114
}
78115

fluent/standard/src/main/java/io/serverlessworkflow/fluent/standard/WorkflowBuilder.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ public WorkflowBuilder doTasks(Consumer<DoTaskBuilder> doTaskConsumer) {
7676
return this;
7777
}
7878

79+
public WorkflowBuilder input(Consumer<InputBuilder> inputBuilderConsumer) {
80+
final InputBuilder inputBuilder = new InputBuilder();
81+
inputBuilderConsumer.accept(inputBuilder);
82+
this.workflow.setInput(inputBuilder.build());
83+
return this;
84+
}
85+
86+
public WorkflowBuilder output(Consumer<OutputBuilder> outputBuilderConsumer) {
87+
final OutputBuilder outputBuilder = new OutputBuilder();
88+
outputBuilderConsumer.accept(outputBuilder);
89+
this.workflow.setOutput(outputBuilder.build());
90+
return this;
91+
}
92+
7993
public Workflow build() {
8094
return this.workflow;
8195
}

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

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ void testUseAuthenticationsBasic() {
8686
assertNotNull(use, "Use must not be null");
8787
UseAuthentications auths = use.getAuthentications();
8888
assertNotNull(auths, "Authentications map must not be null");
89-
AuthenticationPolicyUnion union =
90-
(AuthenticationPolicyUnion) auths.getAdditionalProperties().get("basicAuth");
89+
AuthenticationPolicyUnion union = auths.getAdditionalProperties().get("basicAuth");
9190
assertNotNull(union, "basicAuth policy should be present");
9291
assertNotNull(union.getBasicAuthenticationPolicy(), "BasicAuthenticationPolicy should be set");
9392
}
@@ -214,18 +213,12 @@ void testDoTaskEmitEvent() {
214213
.data(
215214
Map.of(
216215
"client",
217-
Map.of(
218-
"firstName",
219-
"Cruella",
220-
"lastName",
221-
"de Vil"),
216+
Map.of(
217+
"firstName", "Cruella", "lastName", "de Vil"),
222218
"items",
223-
List.of(
224-
Map.of(
225-
"breed",
226-
"dalmatian",
227-
"quantity",
228-
101)))))))
219+
List.of(
220+
Map.of(
221+
"breed", "dalmatian", "quantity", 101)))))))
229222
.build();
230223

231224
List<TaskItem> items = wf.getDo();
@@ -337,4 +330,67 @@ void testDoTaskTryCatchErrorsFiltering() {
337330
assertEquals(500, filter.getStatus());
338331
assertEquals("http://errors/5xx", filter.getInstance());
339332
}
333+
334+
@Test
335+
void testWorkflowInputExternalSchema() {
336+
String uri = "http://example.com/schema";
337+
Workflow wf =
338+
WorkflowBuilder.workflow("wfInput").input(i -> i.from("$.data").schema(uri)).build();
339+
340+
assertNotNull(wf.getInput(), "Input must be set");
341+
assertEquals("$.data", wf.getInput().getFrom().getString());
342+
assertNotNull(wf.getInput().getSchema().getSchemaExternal(), "External schema must be set");
343+
String resolved =
344+
wf.getInput()
345+
.getSchema()
346+
.getSchemaExternal()
347+
.getResource()
348+
.getEndpoint()
349+
.getUriTemplate()
350+
.getLiteralUri()
351+
.toString();
352+
assertEquals(uri, resolved, "Schema URI should match");
353+
}
354+
355+
@Test
356+
void testWorkflowOutputExternalSchemaAndAs() {
357+
String uri = "http://example.org/output-schema";
358+
Workflow wf =
359+
WorkflowBuilder.workflow("wfOutput").output(o -> o.as("$.result").schema(uri)).build();
360+
361+
assertNotNull(wf.getOutput(), "Output must be set");
362+
assertEquals("$.result", wf.getOutput().getAs().getString());
363+
assertNotNull(wf.getOutput().getSchema().getSchemaExternal(), "External schema must be set");
364+
String resolved =
365+
wf.getOutput()
366+
.getSchema()
367+
.getSchemaExternal()
368+
.getResource()
369+
.getEndpoint()
370+
.getUriTemplate()
371+
.getLiteralUri()
372+
.toString();
373+
assertEquals(uri, resolved, "Schema URI should match");
374+
}
375+
376+
@Test
377+
void testWorkflowOutputInlineSchemaAndAsObject() {
378+
Map<String, Object> inline = Map.of("foo", "bar");
379+
Workflow wf =
380+
WorkflowBuilder.workflow().output(o -> o.as(Map.of("ok", true)).schema(inline)).build();
381+
382+
assertNotNull(wf.getOutput(), "Output must be set");
383+
assertInstanceOf(Map.class, wf.getOutput().getAs().getObject(), "As object must be a Map");
384+
assertNotNull(wf.getOutput().getSchema().getSchemaInline(), "Inline schema must be set");
385+
}
386+
387+
@Test
388+
void testWorkflowInputInlineSchemaAndFromObject() {
389+
Map<String, Object> inline = Map.of("nested", List.of(1, 2, 3));
390+
Workflow wf = WorkflowBuilder.workflow().input(i -> i.from(inline).schema(inline)).build();
391+
392+
assertNotNull(wf.getInput(), "Input must be set");
393+
assertInstanceOf(Map.class, wf.getInput().getFrom().getObject(), "From object must be a Map");
394+
assertNotNull(wf.getInput().getSchema().getSchemaInline(), "Inline schema must be set");
395+
}
340396
}

0 commit comments

Comments
 (0)