Skip to content

Commit dc153e7

Browse files
committed
Add initial asyncapi implementation + asyncapi DSL
Signed-off-by: Matheus Cruz <matheuscruz.dev@gmail.com>
1 parent 90ead3c commit dc153e7

42 files changed

Lines changed: 2491 additions & 51 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

asyncapi-call-plan.md

Lines changed: 488 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public abstract class BaseTaskItemListBuilder<SELF extends BaseTaskItemListBuild
4646
protected final String TYPE_HTTP = "http";
4747
protected final String TYPE_OPENAPI = "openapi";
4848
protected final String TYPE_GRPC = "grpc";
49+
protected final String TYPE_ASYNCAPI = "asyncapi";
4950
protected final String TYPE_WORKFLOW = "workflow";
5051

5152
private final List<TaskItem> list;

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,11 @@ private SELF appendDo(Consumer<DBuilder> configurer) {
136136
configurer.accept(doBuilder);
137137

138138
final List<TaskItem> newItems = doBuilder.build().getDo();
139-
if (newItems == null || newItems.isEmpty()) return self();
139+
if (newItems == null || newItems.isEmpty()) {
140+
throw new IllegalStateException(
141+
"Task list must contain at least one task. "
142+
+ "Use .tasks(d -> d.set(...)) or similar to define tasks.");
143+
}
140144

141145
final List<TaskItem> merged =
142146
new ArrayList<>(this.workflow.getDo() != null ? this.workflow.getDo() : List.of());
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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.AsyncApiArguments;
19+
import io.serverlessworkflow.api.types.CallAsyncAPI;
20+
import io.serverlessworkflow.fluent.spec.spi.CallAsyncAPITaskFluent;
21+
22+
public class CallAsyncAPITaskBuilder extends TaskBaseBuilder<CallAsyncAPITaskBuilder>
23+
implements CallAsyncAPITaskFluent<CallAsyncAPITaskBuilder> {
24+
25+
CallAsyncAPITaskBuilder() {
26+
final CallAsyncAPI callAsyncAPI = new CallAsyncAPI();
27+
callAsyncAPI.setWith(new AsyncApiArguments());
28+
super.setTask(callAsyncAPI);
29+
}
30+
31+
@Override
32+
public CallAsyncAPITaskBuilder self() {
33+
return this;
34+
}
35+
}

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
@@ -104,6 +104,12 @@ public DoTaskBuilder openapi(String name, Consumer<CallOpenAPITaskBuilder> items
104104
return this;
105105
}
106106

107+
@Override
108+
public DoTaskBuilder asyncapi(String name, Consumer<CallAsyncAPITaskBuilder> itemsConfigurer) {
109+
this.listBuilder().asyncapi(name, itemsConfigurer);
110+
return this;
111+
}
112+
107113
@Override
108114
public DoTaskBuilder grpc(String name, Consumer<CallGrpcTaskBuilder> itemsConfigurer) {
109115
this.listBuilder().grpc(name, itemsConfigurer);

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,22 @@ public TaskItemListBuilder openapi(
154154
return addTaskItem(new TaskItem(name, task));
155155
}
156156

157+
@Override
158+
public TaskItemListBuilder asyncapi(
159+
String name, Consumer<CallAsyncAPITaskBuilder> itemsConfigurer) {
160+
name = defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_ASYNCAPI);
161+
162+
final CallAsyncAPITaskBuilder callAsyncAPIBuilder = new CallAsyncAPITaskBuilder();
163+
itemsConfigurer.accept(callAsyncAPIBuilder);
164+
165+
final CallTask callTask = new CallTask();
166+
callTask.setCallAsyncAPI(callAsyncAPIBuilder.build());
167+
final Task task = new Task();
168+
task.setCallTask(callTask);
169+
170+
return addTaskItem(new TaskItem(name, task));
171+
}
172+
157173
@Override
158174
public TaskItemListBuilder grpc(String name, Consumer<CallGrpcTaskBuilder> itemsConfigurer) {
159175
name = defaultNameAndRequireConfig(name, itemsConfigurer, TYPE_GRPC);
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.CallAsyncAPITaskBuilder;
19+
import java.util.function.Consumer;
20+
21+
@FunctionalInterface
22+
public interface CallAsyncAPIConfigurer extends Consumer<CallAsyncAPITaskBuilder> {}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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.AsyncApiArguments;
19+
import io.serverlessworkflow.fluent.spec.CallAsyncAPITaskBuilder;
20+
import io.serverlessworkflow.fluent.spec.SubscriptionIteratorBuilder;
21+
import io.serverlessworkflow.fluent.spec.TaskItemListBuilder;
22+
import io.serverlessworkflow.fluent.spec.configurers.AuthenticationConfigurer;
23+
import io.serverlessworkflow.fluent.spec.configurers.CallAsyncAPIConfigurer;
24+
import io.serverlessworkflow.fluent.spec.spi.CallAsyncAPITaskFluent;
25+
import java.net.URI;
26+
import java.util.ArrayList;
27+
import java.util.List;
28+
import java.util.Map;
29+
import java.util.function.Consumer;
30+
31+
public final class CallAsyncAPISpec implements CallAsyncAPIConfigurer {
32+
33+
private final List<Consumer<CallAsyncAPITaskFluent<?>>> steps = new ArrayList<>();
34+
35+
public CallAsyncAPISpec document(String uri) {
36+
steps.add(b -> b.document(uri));
37+
return this;
38+
}
39+
40+
public CallAsyncAPISpec document(String uri, AuthenticationConfigurer authenticationConfigurer) {
41+
steps.add(b -> b.document(uri, authenticationConfigurer));
42+
return this;
43+
}
44+
45+
public CallAsyncAPISpec document(URI uri) {
46+
steps.add(b -> b.document(uri));
47+
return this;
48+
}
49+
50+
public CallAsyncAPISpec document(URI uri, AuthenticationConfigurer authenticationConfigurer) {
51+
steps.add(b -> b.document(uri, authenticationConfigurer));
52+
return this;
53+
}
54+
55+
public CallAsyncAPISpec channel(String channel) {
56+
steps.add(b -> b.channel(channel));
57+
return this;
58+
}
59+
60+
public CallAsyncAPISpec operation(String operation) {
61+
steps.add(b -> b.operation(operation));
62+
return this;
63+
}
64+
65+
public CallAsyncAPISpec server(String name) {
66+
steps.add(b -> b.server(name));
67+
return this;
68+
}
69+
70+
public CallAsyncAPISpec server(String name, Map<String, Object> variables) {
71+
steps.add(b -> b.server(name, variables));
72+
return this;
73+
}
74+
75+
public CallAsyncAPISpec protocol(AsyncApiArguments.AsyncApiProtocol protocol) {
76+
steps.add(b -> b.protocol(protocol));
77+
return this;
78+
}
79+
80+
public CallAsyncAPISpec message(Map<String, Object> payload) {
81+
steps.add(b -> b.message(payload));
82+
return this;
83+
}
84+
85+
public CallAsyncAPISpec message(Map<String, Object> payload, Map<String, Object> headers) {
86+
steps.add(b -> b.message(payload, headers));
87+
return this;
88+
}
89+
90+
public CallAsyncAPISpec payload(Map<String, Object> payload) {
91+
steps.add(b -> b.payload(payload));
92+
return this;
93+
}
94+
95+
public CallAsyncAPISpec headers(Map<String, Object> headers) {
96+
steps.add(b -> b.headers(headers));
97+
return this;
98+
}
99+
100+
public CallAsyncAPISpec consumeAmount(int amount) {
101+
steps.add(b -> b.consumeAmount(amount));
102+
return this;
103+
}
104+
105+
public CallAsyncAPISpec consumeWhile(String expression) {
106+
steps.add(b -> b.consumeWhile(expression));
107+
return this;
108+
}
109+
110+
public CallAsyncAPISpec consumeUntil(String expression) {
111+
steps.add(b -> b.consumeUntil(expression));
112+
return this;
113+
}
114+
115+
public CallAsyncAPISpec filter(String filterExpression) {
116+
steps.add(b -> b.filter(filterExpression));
117+
return this;
118+
}
119+
120+
public CallAsyncAPISpec subscription(
121+
Consumer<SubscriptionIteratorBuilder<TaskItemListBuilder>> foreachConfigurer) {
122+
steps.add(b -> b.subscription(foreachConfigurer));
123+
return this;
124+
}
125+
126+
public CallAsyncAPISpec authentication(AuthenticationConfigurer authenticationConfigurer) {
127+
steps.add(b -> b.authentication(authenticationConfigurer));
128+
return this;
129+
}
130+
131+
@Override
132+
public void accept(CallAsyncAPITaskBuilder builder) {
133+
for (var s : steps) {
134+
s.accept(builder);
135+
}
136+
}
137+
}

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.serverlessworkflow.fluent.spec.TimeoutBuilder;
2929
import io.serverlessworkflow.fluent.spec.TryTaskBuilder;
3030
import io.serverlessworkflow.fluent.spec.configurers.AuthenticationConfigurer;
31+
import io.serverlessworkflow.fluent.spec.configurers.CallAsyncAPIConfigurer;
3132
import io.serverlessworkflow.fluent.spec.configurers.CallGrpcConfigurer;
3233
import io.serverlessworkflow.fluent.spec.configurers.CallHttpConfigurer;
3334
import io.serverlessworkflow.fluent.spec.configurers.CallOpenAPIConfigurer;
@@ -114,6 +115,28 @@ public static CallGrpcSpec grpc() {
114115
return new CallGrpcSpec();
115116
}
116117

118+
/**
119+
* Create a new AsyncAPI call specification to be used with {@link #call(CallAsyncAPIConfigurer)}.
120+
*
121+
* <p>Typical usage:
122+
*
123+
* <pre>{@code
124+
* tasks(
125+
* call(
126+
* asyncapi()
127+
* .document("http://acme.org/asyncapi.yaml")
128+
* .operation("greet")
129+
* .message(Map.of("greeting", "hello"))
130+
* )
131+
* );
132+
* }</pre>
133+
*
134+
* @return a new {@link CallAsyncAPISpec} instance
135+
*/
136+
public static CallAsyncAPISpec asyncapi() {
137+
return new CallAsyncAPISpec();
138+
}
139+
117140
public static WorkflowSpec workflow(String namespace, String name, String version) {
118141
return new WorkflowSpec().namespace(namespace).name(name).version(version);
119142
}
@@ -760,6 +783,27 @@ public static TasksConfigurer call(String name, CallOpenAPIConfigurer configurer
760783
return list -> list.openapi(name, configurer);
761784
}
762785

786+
/**
787+
* Create a {@link TasksConfigurer} that adds an AsyncAPI call task.
788+
*
789+
* @param configurer AsyncAPI configurer
790+
* @return a {@link TasksConfigurer} that adds a CallAsyncAPI task
791+
*/
792+
public static TasksConfigurer call(CallAsyncAPIConfigurer configurer) {
793+
return list -> list.asyncapi(configurer);
794+
}
795+
796+
/**
797+
* Create a {@link TasksConfigurer} that adds an AsyncAPI call task with an explicit name.
798+
*
799+
* @param name the task name
800+
* @param configurer AsyncAPI configurer
801+
* @return a {@link TasksConfigurer} that adds a CallAsyncAPI task
802+
*/
803+
public static TasksConfigurer call(String name, CallAsyncAPIConfigurer configurer) {
804+
return list -> list.asyncapi(name, configurer);
805+
}
806+
763807
public static TasksConfigurer call(CallGrpcConfigurer configurer) {
764808
return list -> list.grpc(configurer);
765809
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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.function.Consumer;
20+
21+
public interface CallAsyncAPIFluent<SELF extends TaskBaseBuilder<SELF>, LIST> {
22+
23+
LIST asyncapi(String name, Consumer<SELF> itemsConfigurer);
24+
25+
default LIST asyncapi(Consumer<SELF> itemsConfigurer) {
26+
return this.asyncapi(null, itemsConfigurer);
27+
}
28+
}

0 commit comments

Comments
 (0)