Skip to content

Commit 8fff347

Browse files
committed
Adding java lambda support
Signed-off-by: fjtirado <ftirados@redhat.com>
1 parent 14d25e9 commit 8fff347

37 files changed

+1580
-79
lines changed

experimental/lambda/pom.xml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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-experimental</artifactId>
6+
<version>8.0.0-SNAPSHOT</version>
7+
</parent>
8+
<artifactId>serverlessworkflow-experimental-lambda</artifactId>
9+
<name>ServelessWorkflow:: Experimental:: lambda</name>
10+
<dependencies>
11+
<dependency>
12+
<groupId>io.serverlessworkflow</groupId>
13+
<artifactId>serverlessworkflow-experimental-types</artifactId>
14+
</dependency>
15+
<dependency>
16+
<groupId>io.serverlessworkflow</groupId>
17+
<artifactId>serverlessworkflow-impl-core</artifactId>
18+
</dependency>
19+
<dependency>
20+
<groupId>org.junit.jupiter</groupId>
21+
<artifactId>junit-jupiter-api</artifactId>
22+
<scope>test</scope>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.junit.jupiter</groupId>
26+
<artifactId>junit-jupiter-engine</artifactId>
27+
<scope>test</scope>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.junit.jupiter</groupId>
31+
<artifactId>junit-jupiter-params</artifactId>
32+
<scope>test</scope>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.assertj</groupId>
36+
<artifactId>assertj-core</artifactId>
37+
<scope>test</scope>
38+
</dependency>
39+
<dependency>
40+
<groupId>ch.qos.logback</groupId>
41+
<artifactId>logback-classic</artifactId>
42+
<scope>test</scope>
43+
</dependency>
44+
</dependencies>
45+
</project>
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.impl.executors;
17+
18+
import io.serverlessworkflow.api.types.CallJava;
19+
import io.serverlessworkflow.api.types.TaskBase;
20+
import io.serverlessworkflow.impl.TaskContext;
21+
import io.serverlessworkflow.impl.WorkflowApplication;
22+
import io.serverlessworkflow.impl.WorkflowContext;
23+
import io.serverlessworkflow.impl.WorkflowModel;
24+
import io.serverlessworkflow.impl.WorkflowModelFactory;
25+
import io.serverlessworkflow.impl.resources.ResourceLoader;
26+
import java.util.concurrent.CompletableFuture;
27+
28+
public class JavaCallExecutor implements CallableTask<CallJava> {
29+
30+
@Override
31+
public void init(CallJava task, WorkflowApplication application, ResourceLoader loader) {}
32+
33+
@Override
34+
public CompletableFuture<WorkflowModel> apply(
35+
WorkflowContext workflowContext, TaskContext taskContext, WorkflowModel input) {
36+
WorkflowModelFactory modelFactory = workflowContext.definition().application().modelFactory();
37+
if (taskContext.task() instanceof CallJava.CallJavaFunction function) {
38+
return CompletableFuture.completedFuture(
39+
modelFactory.fromAny(function.function().apply(input.asJavaObject())));
40+
} else if (taskContext.task() instanceof CallJava.CallJavaLoopFunction function) {
41+
return CompletableFuture.completedFuture(
42+
modelFactory.fromAny(
43+
function
44+
.function()
45+
.apply(
46+
input.asJavaObject(),
47+
safeObject(taskContext.variables().get(function.varName())))));
48+
} else if (taskContext.task() instanceof CallJava.CallJavaLoopFunctionIndex function) {
49+
return CompletableFuture.completedFuture(
50+
modelFactory.fromAny(
51+
function
52+
.function()
53+
.apply(
54+
input.asJavaObject(),
55+
safeObject(taskContext.variables().get(function.varName())),
56+
(Integer) safeObject(taskContext.variables().get(function.indexName())))));
57+
} else if (taskContext.task() instanceof CallJava.CallJavaConsumer consumer) {
58+
consumer.consumer().accept(input.asJavaObject());
59+
}
60+
return CompletableFuture.completedFuture(input);
61+
}
62+
63+
@Override
64+
public boolean accept(Class<? extends TaskBase> clazz) {
65+
return CallJava.class.isAssignableFrom(clazz);
66+
}
67+
68+
static Object safeObject(Object obj) {
69+
return obj instanceof WorkflowModel model ? model.asJavaObject() : obj;
70+
}
71+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
17+
package io.serverlessworkflow.impl.executors;
18+
19+
import static io.serverlessworkflow.impl.executors.JavaCallExecutor.safeObject;
20+
21+
import io.serverlessworkflow.api.types.ForTask;
22+
import io.serverlessworkflow.api.types.ForTaskFunction;
23+
import io.serverlessworkflow.api.types.Workflow;
24+
import io.serverlessworkflow.impl.WorkflowApplication;
25+
import io.serverlessworkflow.impl.WorkflowFilter;
26+
import io.serverlessworkflow.impl.WorkflowPosition;
27+
import io.serverlessworkflow.impl.WorkflowUtils;
28+
import io.serverlessworkflow.impl.executors.ForExecutor.ForExecutorBuilder;
29+
import io.serverlessworkflow.impl.expressions.LoopPredicateIndex;
30+
import io.serverlessworkflow.impl.resources.ResourceLoader;
31+
import java.util.Optional;
32+
33+
public class JavaForExecutorBuilder extends ForExecutorBuilder {
34+
35+
protected JavaForExecutorBuilder(
36+
WorkflowPosition position,
37+
ForTask task,
38+
Workflow workflow,
39+
WorkflowApplication application,
40+
ResourceLoader resourceLoader) {
41+
super(position, task, workflow, application, resourceLoader);
42+
if (task instanceof ForTaskFunction taskFunctions) {}
43+
}
44+
45+
protected Optional<WorkflowFilter> buildWhileFilter() {
46+
if (task instanceof ForTaskFunction taskFunctions) {
47+
LoopPredicateIndex whilePred = taskFunctions.getWhilePredicate();
48+
String varName = task.getFor().getEach();
49+
String indexName = task.getFor().getAt();
50+
if (whilePred != null) {
51+
return Optional.of(
52+
(w, t, n) -> {
53+
Object item = safeObject(t.variables().get(varName));
54+
return application
55+
.modelFactory()
56+
.from(
57+
item == null
58+
|| whilePred.test(
59+
n.asJavaObject(),
60+
item,
61+
(Integer) safeObject(t.variables().get(indexName))));
62+
});
63+
}
64+
}
65+
return super.buildWhileFilter();
66+
}
67+
68+
protected WorkflowFilter buildCollectionFilter() {
69+
return task instanceof ForTaskFunction taskFunctions
70+
? WorkflowUtils.buildWorkflowFilter(application, null, taskFunctions.getCollection())
71+
: super.buildCollectionFilter();
72+
}
73+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
17+
package io.serverlessworkflow.impl.executors;
18+
19+
import io.serverlessworkflow.api.types.SwitchCase;
20+
import io.serverlessworkflow.api.types.SwitchCaseFunction;
21+
import io.serverlessworkflow.api.types.SwitchTask;
22+
import io.serverlessworkflow.api.types.Workflow;
23+
import io.serverlessworkflow.impl.WorkflowApplication;
24+
import io.serverlessworkflow.impl.WorkflowFilter;
25+
import io.serverlessworkflow.impl.WorkflowPosition;
26+
import io.serverlessworkflow.impl.WorkflowUtils;
27+
import io.serverlessworkflow.impl.executors.SwitchExecutor.SwitchExecutorBuilder;
28+
import io.serverlessworkflow.impl.resources.ResourceLoader;
29+
import java.util.Optional;
30+
31+
public class JavaSwitchExecutorBuilder extends SwitchExecutorBuilder {
32+
33+
protected JavaSwitchExecutorBuilder(
34+
WorkflowPosition position,
35+
SwitchTask task,
36+
Workflow workflow,
37+
WorkflowApplication application,
38+
ResourceLoader resourceLoader) {
39+
super(position, task, workflow, application, resourceLoader);
40+
}
41+
42+
@Override
43+
protected Optional<WorkflowFilter> buildFilter(SwitchCase switchCase) {
44+
return switchCase instanceof SwitchCaseFunction function
45+
? Optional.of(WorkflowUtils.buildWorkflowFilter(application, null, function.predicate()))
46+
: super.buildFilter(switchCase);
47+
}
48+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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.executors;
17+
18+
import io.serverlessworkflow.api.types.Task;
19+
import io.serverlessworkflow.api.types.TaskBase;
20+
import io.serverlessworkflow.api.types.Workflow;
21+
import io.serverlessworkflow.impl.WorkflowApplication;
22+
import io.serverlessworkflow.impl.WorkflowPosition;
23+
import io.serverlessworkflow.impl.resources.ResourceLoader;
24+
25+
public class JavaTaskExecutorFactory extends DefaultTaskExecutorFactory {
26+
27+
public TaskExecutorBuilder<? extends TaskBase> getTaskExecutor(
28+
WorkflowPosition position,
29+
Task task,
30+
Workflow workflow,
31+
WorkflowApplication application,
32+
ResourceLoader resourceLoader) {
33+
if (task.getForTask() != null) {
34+
return new JavaForExecutorBuilder(
35+
position, task.getForTask(), workflow, application, resourceLoader);
36+
} else if (task.getSwitchTask() != null) {
37+
return new JavaSwitchExecutorBuilder(
38+
position, task.getSwitchTask(), workflow, application, resourceLoader);
39+
} else {
40+
return super.getTaskExecutor(position, task, workflow, application, resourceLoader);
41+
}
42+
}
43+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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.expressions;
17+
18+
import io.serverlessworkflow.impl.TaskContext;
19+
import io.serverlessworkflow.impl.WorkflowContext;
20+
import io.serverlessworkflow.impl.WorkflowFilter;
21+
import io.serverlessworkflow.impl.WorkflowModel;
22+
import io.serverlessworkflow.impl.WorkflowModelFactory;
23+
import java.util.function.BiFunction;
24+
import java.util.function.BiPredicate;
25+
import java.util.function.Function;
26+
import java.util.function.Predicate;
27+
28+
public class JavaExpressionFactory implements ExpressionFactory {
29+
30+
private final WorkflowModelFactory modelFactory = new JavaModelFactory();
31+
private final Expression dummyExpression =
32+
new Expression() {
33+
@Override
34+
public WorkflowModel eval(
35+
WorkflowContext workflowContext, TaskContext context, WorkflowModel model) {
36+
return model;
37+
}
38+
};
39+
40+
@Override
41+
public Expression buildExpression(String expression) {
42+
return dummyExpression;
43+
}
44+
45+
@Override
46+
public WorkflowFilter buildFilter(String expr, Object value) {
47+
if (value instanceof Function func) {
48+
return (w, t, n) -> modelFactory.fromAny(func.apply(n.asJavaObject()));
49+
} else if (value instanceof Predicate pred) {
50+
return (w, t, n) -> modelFactory.from(pred.test(n.asJavaObject()));
51+
} else if (value instanceof BiPredicate pred) {
52+
return (w, t, n) -> modelFactory.from(pred.test(w, t));
53+
} else if (value instanceof BiFunction func) {
54+
return (w, t, n) -> modelFactory.fromAny(func.apply(w, t));
55+
} else if (value instanceof WorkflowFilter filter) {
56+
return filter;
57+
} else {
58+
return (w, t, n) -> modelFactory.fromAny(value);
59+
}
60+
}
61+
62+
@Override
63+
public WorkflowModelFactory modelFactory() {
64+
return modelFactory;
65+
}
66+
}

0 commit comments

Comments
 (0)