Skip to content

Commit e31e486

Browse files
authored
Merge pull request #450 from fjtirado/ref-impl
Serverless Workflow reference implementation (skeleton)
2 parents d6dbdcd + f13ec22 commit e31e486

File tree

14 files changed

+816
-1
lines changed

14 files changed

+816
-1
lines changed

api/src/test/java/io/serverlessworkflow/api/FeaturesTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ public class FeaturesTest {
4444
"features/switch.yaml",
4545
"features/try.yaml",
4646
"features/listen.yaml",
47-
"features/callFunction.yaml"
47+
"features/callFunction.yaml",
48+
"features/callCustomFunction.yaml"
4849
})
4950
public void testSpecFeaturesParsing(String workflowLocation) throws IOException {
5051
Workflow workflow = readWorkflowFromClasspath(workflowLocation);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
document:
2+
dsl: 1.0.0-alpha5
3+
namespace: test
4+
name: call-example
5+
version: 0.1.0
6+
schedule:
7+
cron: 0 8 * * *
8+
do:
9+
- getData:
10+
call: http
11+
with:
12+
method: get
13+
endpoint: https://api.agify.io?name=meelad
14+
output:
15+
as: ".data.reading"
16+
- filterData:
17+
for:
18+
in: ".data.reading"
19+
each: reading
20+
do:
21+
- log:
22+
call: https://raw.githubusercontent.com/serverlessworkflow/catalog/main/functions/log/1.0.0/function.yaml
23+
with:
24+
level: information
25+
format: "{TIMESTAMP} [{LEVEL}] ({CONTEXT}): {MESSAGE}"
26+
message: Hello, world!
27+
timestamp: true

impl/pom.xml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<parent>
4+
<groupId>io.serverlessworkflow</groupId>
5+
<artifactId>serverlessworkflow-parent</artifactId>
6+
<version>7.0.0-SNAPSHOT</version>
7+
</parent>
8+
<artifactId>serverlessworkflow-impl</artifactId>
9+
<properties>
10+
<version.org.glassfish.jersey>3.1.9</version.org.glassfish.jersey>
11+
</properties>
12+
<dependencies>
13+
<dependency>
14+
<groupId>io.serverlessworkflow</groupId>
15+
<artifactId>serverlessworkflow-api</artifactId>
16+
<version>7.0.0-SNAPSHOT</version>
17+
</dependency>
18+
<dependency>
19+
<groupId>org.glassfish.jersey.core</groupId>
20+
<artifactId>jersey-client</artifactId>
21+
<version>${version.org.glassfish.jersey}</version>
22+
</dependency>
23+
<dependency>
24+
<groupId>org.glassfish.jersey.media</groupId>
25+
<artifactId>jersey-media-json-jackson</artifactId>
26+
<version>${version.org.glassfish.jersey}</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.junit.jupiter</groupId>
30+
<artifactId>junit-jupiter-api</artifactId>
31+
<scope>test</scope>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.junit.jupiter</groupId>
35+
<artifactId>junit-jupiter-engine</artifactId>
36+
<scope>test</scope>
37+
</dependency>
38+
<dependency>
39+
<groupId>org.junit.jupiter</groupId>
40+
<artifactId>junit-jupiter-params</artifactId>
41+
<scope>test</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.assertj</groupId>
45+
<artifactId>assertj-core</artifactId>
46+
<scope>test</scope>
47+
</dependency>
48+
</dependencies>
49+
<build>
50+
<plugins>
51+
<plugin>
52+
<groupId>com.spotify.fmt</groupId>
53+
<artifactId>fmt-maven-plugin</artifactId>
54+
<configuration>
55+
<sourceDirectory>src/main/java</sourceDirectory>
56+
<testSourceDirectory>src/test/java</testSourceDirectory>
57+
<verbose>false</verbose>
58+
<filesNamePattern>.*\.java</filesNamePattern>
59+
<skip>false</skip>
60+
<skipSortingImports>false</skipSortingImports>
61+
<style>google</style>
62+
</configuration>
63+
<executions>
64+
<execution>
65+
<goals>
66+
<goal>format</goal>
67+
</goals>
68+
</execution>
69+
</executions>
70+
</plugin>
71+
</plugins>
72+
</build>
73+
</project>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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.impl;
17+
18+
import com.fasterxml.jackson.databind.JsonNode;
19+
import io.serverlessworkflow.api.types.TaskBase;
20+
21+
public abstract class AbstractTaskExecutor<T extends TaskBase> implements TaskExecutor<T> {
22+
23+
protected final T task;
24+
25+
protected AbstractTaskExecutor(T task) {
26+
this.task = task;
27+
}
28+
29+
@Override
30+
public JsonNode apply(JsonNode node) {
31+
32+
// do input filtering
33+
return internalExecute(node);
34+
// do output filtering
35+
36+
}
37+
38+
protected abstract JsonNode internalExecute(JsonNode node);
39+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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.impl;
17+
18+
import com.fasterxml.jackson.core.type.TypeReference;
19+
import com.fasterxml.jackson.databind.JsonNode;
20+
import io.serverlessworkflow.api.types.CallHTTP;
21+
import io.serverlessworkflow.api.types.HTTPArguments;
22+
import io.serverlessworkflow.api.types.WithHTTPHeaders;
23+
import io.serverlessworkflow.api.types.WithHTTPQuery;
24+
import jakarta.ws.rs.client.Client;
25+
import jakarta.ws.rs.client.ClientBuilder;
26+
import jakarta.ws.rs.client.Entity;
27+
import jakarta.ws.rs.client.Invocation.Builder;
28+
import jakarta.ws.rs.client.WebTarget;
29+
import jakarta.ws.rs.core.MediaType;
30+
import java.util.Map;
31+
import java.util.Map.Entry;
32+
33+
public class HttpExecutor extends AbstractTaskExecutor<CallHTTP> {
34+
35+
private static final Client client = ClientBuilder.newClient();
36+
37+
public HttpExecutor(CallHTTP task) {
38+
super(task);
39+
}
40+
41+
@Override
42+
protected JsonNode internalExecute(JsonNode node) {
43+
HTTPArguments httpArgs = task.getWith();
44+
// missing checks
45+
String uri =
46+
httpArgs
47+
.getEndpoint()
48+
.getEndpointConfiguration()
49+
.getUri()
50+
.getLiteralEndpointURI()
51+
.getLiteralUriTemplate();
52+
WebTarget target = client.target(uri);
53+
WithHTTPQuery query = httpArgs.getQuery();
54+
if (query != null) {
55+
for (Entry<String, Object> entry : query.getAdditionalProperties().entrySet()) {
56+
target = target.queryParam(entry.getKey(), entry.getValue());
57+
}
58+
}
59+
Builder request =
60+
target
61+
.resolveTemplates(
62+
JsonUtils.mapper().convertValue(node, new TypeReference<Map<String, Object>>() {}))
63+
.request(MediaType.APPLICATION_JSON);
64+
WithHTTPHeaders headers = httpArgs.getHeaders();
65+
if (headers != null) {
66+
headers.getAdditionalProperties().forEach(request::header);
67+
}
68+
switch (httpArgs.getMethod().toLowerCase()) {
69+
case "get":
70+
default:
71+
return request.get(JsonNode.class);
72+
case "post":
73+
return request.post(Entity.json(httpArgs.getBody()), JsonNode.class);
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)