Skip to content

Commit b6ae245

Browse files
author
Tihomir Surdilovic
authored
Merge pull request #50 from tsurdilo/subflowrepeat
add switch state repeat
2 parents b9ed27c + e07e9e9 commit b6ae245

File tree

7 files changed

+204
-1
lines changed

7 files changed

+204
-1
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"type": "object",
3+
"javaType": "io.serverlessworkflow.api.repeat.Repeat",
4+
"properties": {
5+
"expression": {
6+
"type": "string",
7+
"description": "Expression evaluated against SubFlow state data. SubFlow will repeat execution as long as this expression is true or until the max property count is reached",
8+
"minLength": 1
9+
},
10+
"checkBefore": {
11+
"type": "boolean",
12+
"description": "If true, the expression is evaluated before each repeat execution, if false the expression is evaluated after each repeat execution",
13+
"default": true
14+
},
15+
"max": {
16+
"type": "integer",
17+
"description": "Sets the maximum amount of repeat executions",
18+
"minimum": 0
19+
},
20+
"continueOnError": {
21+
"type": "boolean",
22+
"description": "If true, repeats executions in a case unhandled errors propagate from the sub-workflow to this state",
23+
"default": false
24+
},
25+
"stopOnEvents": {
26+
"type" : "array",
27+
"description": "List referencing defined consumed workflow events. SubFlow will repeat execution until one of the defined events is consumed, or until the max property count is reached",
28+
"items": {
29+
"type": "object",
30+
"existingJavaType": "java.lang.String"
31+
}
32+
}
33+
},
34+
"required": [
35+
"nextState"
36+
]
37+
}

api/src/main/resources/schema/states/subflowstate.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
"type": "boolean",
2323
"default": false,
2424
"description": "If true, this state is used to compensate another state. Default is false"
25+
},
26+
"repeat": {
27+
"$ref": "../repeat/repeat.json",
28+
"description": "SubFlow state repeat exec definition"
2529
}
2630
},
2731
"required": [

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import io.serverlessworkflow.api.interfaces.State;
2626
import io.serverlessworkflow.api.states.EventState;
2727
import io.serverlessworkflow.api.states.OperationState;
28+
import io.serverlessworkflow.api.states.SubflowState;
2829
import io.serverlessworkflow.api.states.SwitchState;
2930
import io.serverlessworkflow.api.switchconditions.DataCondition;
3031
import io.serverlessworkflow.api.test.utils.WorkflowTestUtils;
@@ -55,7 +56,8 @@ public class MarkupToWorkflowTest {
5556
"/examples/periodicinboxcheck.json", "/examples/periodicinboxcheck.yml",
5657
"/examples/vetappointmentservice.json", "/examples/vetappointmentservice.yml",
5758
"/examples/eventbasedtransition.json", "/examples/eventbasedtransition.yml",
58-
"/examples/roomreadings.json", "/examples/roomreadings.yml"
59+
"/examples/roomreadings.json", "/examples/roomreadings.yml",
60+
"/examples/checkcarvitals.json", "/examples/checkcarvitals.yml"
5961
})
6062
public void testSpecExamplesParsing(String workflowLocation) {
6163
Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation));
@@ -256,4 +258,29 @@ public void testKeepActiveExecTimeout(String workflowLocation) {
256258
assertEquals("PT1H", execTimeout.getInterval());
257259
assertEquals("GenerateReport", execTimeout.getRunBefore());
258260
}
261+
262+
@ParameterizedTest
263+
@ValueSource(strings = {"/features/checkcarvitals.json", "/features/checkcarvitals.yml"})
264+
public void testSubflowStateRepeat(String workflowLocation) {
265+
Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation));
266+
267+
assertNotNull(workflow);
268+
assertNotNull(workflow.getId());
269+
assertNotNull(workflow.getName());
270+
assertNotNull(workflow.getStates());
271+
272+
assertNotNull(workflow.getStates());
273+
assertTrue(workflow.getStates().size() == 2);
274+
275+
State state = workflow.getStates().get(1);
276+
assertTrue(state instanceof SubflowState);
277+
278+
SubflowState subflowState = (SubflowState) workflow.getStates().get(1);
279+
assertNotNull(subflowState.getRepeat());
280+
assertEquals(10, subflowState.getRepeat().getMax());
281+
assertTrue(subflowState.getRepeat().isContinueOnError());
282+
assertNotNull(subflowState.getRepeat().getStopOnEvents());
283+
assertEquals(1, subflowState.getRepeat().getStopOnEvents().size());
284+
assertEquals("CarTurnedOffEvent", subflowState.getRepeat().getStopOnEvents().get(0));
285+
}
259286
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"id": "checkcarvitals",
3+
"name": "Check Car Vitals Workflow",
4+
"version": "1.0",
5+
"states": [
6+
{
7+
"name": "WhenCarIsOn",
8+
"type": "event",
9+
"start": true,
10+
"onEvents": [
11+
{
12+
"eventRefs": ["CarTurnedOnEvent"]
13+
}
14+
],
15+
"transition": "DoCarVitalsChecks"
16+
},
17+
{
18+
"name": "DoCarVitalsChecks",
19+
"type": "subflow",
20+
"workflowId": "vitalscheck",
21+
"repeat": {
22+
"stopOnEvents": ["CarTurnedOffEvent"]
23+
},
24+
"end": true
25+
}
26+
],
27+
"events": [
28+
{
29+
"name": "CarTurnedOnEvent",
30+
"type": "car.events",
31+
"source": "my/car/start"
32+
},
33+
{
34+
"name": "CarTurnedOffEvent",
35+
"type": "car.events",
36+
"source": "my/car/start"
37+
}
38+
]
39+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
id: checkcarvitals
2+
name: Check Car Vitals Workflow
3+
version: '1.0'
4+
states:
5+
- name: WhenCarIsOn
6+
type: event
7+
start: true
8+
onEvents:
9+
- eventRefs:
10+
- CarTurnedOnEvent
11+
transition: DoCarVitalsChecks
12+
- name: DoCarVitalsChecks
13+
type: subflow
14+
workflowId: vitalscheck
15+
repeat:
16+
max: 10
17+
continueOnError: true
18+
stopOnEvents:
19+
- CarTurnedOffEvent
20+
end: true
21+
events:
22+
- name: CarTurnedOnEvent
23+
type: car.events
24+
source: my/car/start
25+
- name: CarTurnedOffEvent
26+
type: car.events
27+
source: my/car/start
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"id": "checkcarvitals",
3+
"name": "Check Car Vitals Workflow",
4+
"version": "1.0",
5+
"states": [
6+
{
7+
"name": "WhenCarIsOn",
8+
"type": "event",
9+
"start": true,
10+
"onEvents": [
11+
{
12+
"eventRefs": ["CarTurnedOnEvent"]
13+
}
14+
],
15+
"transition": "DoCarVitalsChecks"
16+
},
17+
{
18+
"name": "DoCarVitalsChecks",
19+
"type": "subflow",
20+
"workflowId": "vitalscheck",
21+
"repeat": {
22+
"max": 10,
23+
"continueOnError": true,
24+
"stopOnEvents": ["CarTurnedOffEvent"]
25+
},
26+
"end": true
27+
}
28+
],
29+
"events": [
30+
{
31+
"name": "CarTurnedOnEvent",
32+
"type": "car.events",
33+
"source": "my/car/start"
34+
},
35+
{
36+
"name": "CarTurnedOffEvent",
37+
"type": "car.events",
38+
"source": "my/car/start"
39+
}
40+
]
41+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
id: checkcarvitals
3+
name: Check Car Vitals Workflow
4+
version: '1.0'
5+
states:
6+
- name: WhenCarIsOn
7+
type: event
8+
start: true
9+
onEvents:
10+
- eventRefs:
11+
- CarTurnedOnEvent
12+
transition: DoCarVitalsChecks
13+
- name: DoCarVitalsChecks
14+
type: subflow
15+
workflowId: vitalscheck
16+
repeat:
17+
max: 10
18+
continueOnError: true
19+
stopOnEvents:
20+
- CarTurnedOffEvent
21+
end: true
22+
events:
23+
- name: CarTurnedOnEvent
24+
type: car.events
25+
source: my/car/start
26+
- name: CarTurnedOffEvent
27+
type: car.events
28+
source: my/car/start

0 commit comments

Comments
 (0)