Skip to content

Commit d955ffa

Browse files
committed
adding async function invoke
Signed-off-by: Tihomir Surdilovic <[email protected]>
1 parent 8d67d42 commit d955ffa

File tree

10 files changed

+169
-1
lines changed

10 files changed

+169
-1
lines changed

api/src/main/java/io/serverlessworkflow/api/deserializers/FunctionRefDeserializer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public FunctionRef deserialize(JsonParser jp, DeserializationContext ctxt) throw
5555
if (!node.isObject()) {
5656
functionRef.setRefName(node.asText());
5757
functionRef.setArguments(null);
58+
functionRef.setInvoke(FunctionRef.Invoke.SYNC);
5859
return functionRef;
5960
} else {
6061
if (node.get("arguments") != null) {
@@ -69,6 +70,10 @@ public FunctionRef deserialize(JsonParser jp, DeserializationContext ctxt) throw
6970
functionRef.setSelectionSet(node.get("selectionSet").asText());
7071
}
7172

73+
if (node.get("invoke") != null) {
74+
functionRef.setInvoke(FunctionRef.Invoke.fromValue(node.get("invoke").asText()));
75+
}
76+
7277
return functionRef;
7378
}
7479
}

api/src/main/java/io/serverlessworkflow/api/deserializers/SubFlowRefDeserializer.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ public SubFlowRef deserialize(JsonParser jp, DeserializationContext ctxt) throws
6262
subflowRef.setVersion(node.get("version").asText());
6363
}
6464

65+
if (node.get("onParentComplete") != null) {
66+
subflowRef.setOnParentComplete(
67+
SubFlowRef.OnParentComplete.fromValue(node.get("onParentComplete").asText()));
68+
}
69+
70+
if (node.get("invoke") != null) {
71+
subflowRef.setInvoke(SubFlowRef.Invoke.fromValue(node.get("invoke").asText()));
72+
}
73+
6574
return subflowRef;
6675
}
6776
}

api/src/main/java/io/serverlessworkflow/api/serializers/FunctionRefSerializer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public void serialize(FunctionRef functionRef, JsonGenerator gen, SerializerProv
3838
if (functionRef != null) {
3939
if ((functionRef.getArguments() == null || functionRef.getArguments().isEmpty())
4040
&& (functionRef.getSelectionSet() == null || functionRef.getSelectionSet().isEmpty())
41+
&& (functionRef.getInvoke() == null
42+
|| functionRef.getInvoke().equals(FunctionRef.Invoke.SYNC))
4143
&& functionRef.getRefName() != null
4244
&& functionRef.getRefName().length() > 0) {
4345
gen.writeString(functionRef.getRefName());
@@ -56,6 +58,10 @@ public void serialize(FunctionRef functionRef, JsonGenerator gen, SerializerProv
5658
gen.writeStringField("selectionSet", functionRef.getSelectionSet());
5759
}
5860

61+
if (functionRef.getInvoke() != null) {
62+
gen.writeStringField("invoke", functionRef.getInvoke().value());
63+
}
64+
5965
gen.writeEndObject();
6066
}
6167
}

api/src/main/java/io/serverlessworkflow/api/serializers/SubFlowRefSerializer.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.fasterxml.jackson.core.JsonGenerator;
1919
import com.fasterxml.jackson.databind.SerializerProvider;
2020
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
21+
import io.serverlessworkflow.api.functions.FunctionRef;
2122
import io.serverlessworkflow.api.functions.SubFlowRef;
2223
import java.io.IOException;
2324

@@ -37,7 +38,9 @@ public void serialize(SubFlowRef subflowRef, JsonGenerator gen, SerializerProvid
3738

3839
if (subflowRef != null) {
3940
if ((subflowRef.getWorkflowId() == null || subflowRef.getWorkflowId().isEmpty())
40-
&& (subflowRef.getVersion() == null || subflowRef.getVersion().isEmpty())) {
41+
&& (subflowRef.getVersion() == null || subflowRef.getVersion().isEmpty())
42+
&& (subflowRef.getInvoke() == null
43+
|| subflowRef.getInvoke().equals(FunctionRef.Invoke.SYNC))) {
4144
gen.writeString(subflowRef.getWorkflowId());
4245
} else {
4346
gen.writeStartObject();
@@ -50,6 +53,14 @@ public void serialize(SubFlowRef subflowRef, JsonGenerator gen, SerializerProvid
5053
gen.writeStringField("version", subflowRef.getVersion());
5154
}
5255

56+
if (subflowRef.getOnParentComplete() != null) {
57+
gen.writeStringField("onParentComplete", subflowRef.getOnParentComplete().value());
58+
}
59+
60+
if (subflowRef.getInvoke() != null) {
61+
gen.writeStringField("invoke", subflowRef.getInvoke().value());
62+
}
63+
5364
gen.writeEndObject();
5465
}
5566
}

api/src/main/resources/schema/events/eventref.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323
"existingJavaType": "java.util.Map<String, String>",
2424
"type": "object",
2525
"description": "Add additional extension context attributes to the produced event"
26+
},
27+
"invoke": {
28+
"type": "string",
29+
"enum": [
30+
"sync",
31+
"async"
32+
],
33+
"description": "Specifies if the function should be invoked sync or async. Default is sync.",
34+
"default": "sync"
2635
}
2736
},
2837
"required": [

api/src/main/resources/schema/functions/functionref.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@
1515
"selectionSet": {
1616
"type": "string",
1717
"description": "Only used if function type is 'graphql'. A string containing a valid GraphQL selection set"
18+
},
19+
"invoke": {
20+
"type": "string",
21+
"enum": [
22+
"sync",
23+
"async"
24+
],
25+
"description": "Specifies if the function should be invoked sync or async. Default is sync.",
26+
"default": "sync"
1827
}
1928
},
2029
"required": [

api/src/main/resources/schema/functions/subflowref.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@
1010
"type": "string",
1111
"description": "Version of the sub-workflow to be invoked",
1212
"minLength": 1
13+
},
14+
"onParentComplete": {
15+
"type": "string",
16+
"enum": [
17+
"continue",
18+
"terminate"
19+
],
20+
"description": "If invoke is 'async', specifies how subflow execution should behave when parent workflow completes. Default is 'terminate'",
21+
"default": "terminate"
22+
},
23+
"invoke": {
24+
"type": "string",
25+
"enum": [
26+
"sync",
27+
"async"
28+
],
29+
"description": "Specifies if the function should be invoked sync or async. Default is sync.",
30+
"default": "sync"
1331
}
1432
},
1533
"required": [

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import io.serverlessworkflow.api.datainputschema.DataInputSchema;
2626
import io.serverlessworkflow.api.defaultdef.DefaultConditionDefinition;
2727
import io.serverlessworkflow.api.end.End;
28+
import io.serverlessworkflow.api.events.EventRef;
2829
import io.serverlessworkflow.api.functions.FunctionDefinition;
2930
import io.serverlessworkflow.api.functions.FunctionRef;
3031
import io.serverlessworkflow.api.functions.SubFlowRef;
@@ -798,4 +799,41 @@ public void testContinueAsObject(String workflowLocation) {
798799
assertNotNull(end.getContinueAs().getWorkflowExecTimeout());
799800
assertEquals("PT1M", end.getContinueAs().getWorkflowExecTimeout().getDuration());
800801
}
802+
803+
@ParameterizedTest
804+
@ValueSource(strings = {"/features/invoke.json", "/features/invoke.yml"})
805+
public void testFunctionInvoke(String workflowLocation) {
806+
Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation));
807+
808+
assertNotNull(workflow);
809+
assertNotNull(workflow.getId());
810+
assertNotNull(workflow.getName());
811+
assertNotNull(workflow.getStates());
812+
813+
assertNotNull(workflow.getStates());
814+
assertEquals(1, workflow.getStates().size());
815+
816+
OperationState operationState = (OperationState) workflow.getStates().get(0);
817+
assertNotNull(operationState.getEnd());
818+
assertNotNull(operationState.getActions());
819+
assertEquals(3, operationState.getActions().size());
820+
821+
Action action1 = operationState.getActions().get(0);
822+
assertNotNull(action1.getFunctionRef());
823+
assertNotNull(action1.getFunctionRef().getInvoke());
824+
assertEquals(FunctionRef.Invoke.ASYNC, action1.getFunctionRef().getInvoke());
825+
826+
Action action2 = operationState.getActions().get(1);
827+
assertNotNull(action2.getSubFlowRef());
828+
assertNotNull(action2.getSubFlowRef().getOnParentComplete());
829+
assertEquals(
830+
SubFlowRef.OnParentComplete.CONTINUE, action2.getSubFlowRef().getOnParentComplete());
831+
assertNotNull(action2.getSubFlowRef().getInvoke());
832+
assertEquals(SubFlowRef.Invoke.ASYNC, action2.getSubFlowRef().getInvoke());
833+
834+
Action action3 = operationState.getActions().get(2);
835+
assertNotNull(action3.getEventRef());
836+
assertNotNull(action3.getEventRef().getInvoke());
837+
assertEquals(EventRef.Invoke.ASYNC, action3.getEventRef().getInvoke());
838+
}
801839
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"id": "invoketest",
3+
"version": "1.0",
4+
"specVersion": "0.7",
5+
"name": "Invoke Test",
6+
"description": "Invoke Test",
7+
"start": "TestInvoke",
8+
"states": [
9+
{
10+
"name": "TestInvoke",
11+
"type": "operation",
12+
"actionMode": "sequential",
13+
"actions": [
14+
{
15+
"functionRef": {
16+
"refName": "sendRejectionEmailFunction",
17+
"invoke": "async"
18+
}
19+
},
20+
{
21+
"subFlowRef": {
22+
"workflowId": "subflowrefworkflowid",
23+
"version": "1.0",
24+
"invoke": "async",
25+
"onParentComplete": "continue"
26+
}
27+
},
28+
{
29+
"eventRef": {
30+
"triggerEventRef": "abc",
31+
"resultEventRef": "123",
32+
"invoke": "async"
33+
}
34+
}
35+
],
36+
"end": true
37+
}
38+
]
39+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
id: invoketest
2+
version: '1.0'
3+
specVersion: '0.7'
4+
name: Invoke Test
5+
description: Invoke Test
6+
start: TestInvoke
7+
states:
8+
- name: TestInvoke
9+
type: operation
10+
actionMode: sequential
11+
actions:
12+
- functionRef:
13+
refName: sendRejectionEmailFunction
14+
invoke: async
15+
- subFlowRef:
16+
workflowId: subflowrefworkflowid
17+
version: '1.0'
18+
invoke: async
19+
onParentComplete: continue
20+
- eventRef:
21+
triggerEventRef: abc
22+
resultEventRef: '123'
23+
invoke: async
24+
end: true

0 commit comments

Comments
 (0)