Skip to content

Commit 71a5947

Browse files
author
Tihomir Surdilovic
authored
Merge pull request #56 from tsurdilo/simplifyscheduleandcron
Simplified cron and schedule definitions
2 parents df94ca5 + 6945384 commit 71a5947

File tree

18 files changed

+502
-19
lines changed

18 files changed

+502
-19
lines changed
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+
* <p>
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+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
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.api.deserializers;
18+
19+
import com.fasterxml.jackson.core.JsonParser;
20+
import com.fasterxml.jackson.databind.DeserializationContext;
21+
import com.fasterxml.jackson.databind.JsonNode;
22+
import com.fasterxml.jackson.databind.ObjectMapper;
23+
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
24+
import io.serverlessworkflow.api.cron.Cron;
25+
import io.serverlessworkflow.api.interfaces.WorkflowPropertySource;
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
import java.io.IOException;
30+
31+
public class CronDeserializer extends StdDeserializer<Cron> {
32+
33+
private static final long serialVersionUID = 510l;
34+
private static Logger logger = LoggerFactory.getLogger(CronDeserializer.class);
35+
36+
private WorkflowPropertySource context;
37+
38+
public CronDeserializer() {
39+
this(Cron.class);
40+
}
41+
42+
public CronDeserializer(Class<?> vc) {
43+
super(vc);
44+
}
45+
46+
public CronDeserializer(WorkflowPropertySource context) {
47+
this(Cron.class);
48+
this.context = context;
49+
}
50+
51+
@Override
52+
public Cron deserialize(JsonParser jp,
53+
DeserializationContext ctxt) throws IOException {
54+
55+
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
56+
JsonNode node = jp.getCodec().readTree(jp);
57+
58+
Cron cron = new Cron();
59+
60+
if (!node.isObject()) {
61+
cron.setExpression(node.asText());
62+
return cron;
63+
} else {
64+
if(node.get("expression") != null) {
65+
cron.setExpression(node.get("expression").asText());
66+
}
67+
68+
if(node.get("validUntil") != null) {
69+
cron.setValidUntil(node.get("validUntil").asText());
70+
}
71+
72+
return cron;
73+
}
74+
}
75+
}
76+

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.slf4j.LoggerFactory;
2828

2929
import java.io.IOException;
30-
import java.util.HashMap;
3130

3231
public class FunctionRefDeserializer extends StdDeserializer<FunctionRef> {
3332

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
* <p>
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+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
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.api.deserializers;
18+
19+
import com.fasterxml.jackson.core.JsonParser;
20+
import com.fasterxml.jackson.databind.DeserializationContext;
21+
import com.fasterxml.jackson.databind.JsonNode;
22+
import com.fasterxml.jackson.databind.ObjectMapper;
23+
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
24+
import io.serverlessworkflow.api.cron.Cron;
25+
import io.serverlessworkflow.api.interfaces.WorkflowPropertySource;
26+
import io.serverlessworkflow.api.schedule.Schedule;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
29+
30+
import java.io.IOException;
31+
32+
public class ScheduleDeserializer extends StdDeserializer<Schedule> {
33+
34+
private static final long serialVersionUID = 510l;
35+
private static Logger logger = LoggerFactory.getLogger(ScheduleDeserializer.class);
36+
37+
private WorkflowPropertySource context;
38+
39+
public ScheduleDeserializer() {
40+
this(Schedule.class);
41+
}
42+
43+
public ScheduleDeserializer(Class<?> vc) {
44+
super(vc);
45+
}
46+
47+
public ScheduleDeserializer(WorkflowPropertySource context) {
48+
this(Schedule.class);
49+
this.context = context;
50+
}
51+
52+
@Override
53+
public Schedule deserialize(JsonParser jp,
54+
DeserializationContext ctxt) throws IOException {
55+
56+
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
57+
JsonNode node = jp.getCodec().readTree(jp);
58+
59+
Schedule schedule = new Schedule();
60+
61+
if (!node.isObject()) {
62+
schedule.setInterval(node.asText());
63+
return schedule;
64+
} else {
65+
if(node.get("interval") != null) {
66+
schedule.setInterval(node.get("interval").asText());
67+
}
68+
69+
if(node.get("cron") != null) {
70+
schedule.setCron(mapper.treeToValue(node.get("cron"), Cron.class));
71+
}
72+
73+
if(node.get("directInvoke") != null) {
74+
schedule.setDirectInvoke(mapper.treeToValue(node.get("directInvoke"), Schedule.DirectInvoke.class));
75+
}
76+
77+
if(node.get("timezone") != null) {
78+
schedule.setTimezone(node.get("timezone").asText());
79+
}
80+
81+
return schedule;
82+
}
83+
}
84+
}

api/src/main/java/io/serverlessworkflow/api/mapper/WorkflowModule.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.serverlessworkflow.api.mapper;
1818

1919
import com.fasterxml.jackson.databind.module.SimpleModule;
20+
import io.serverlessworkflow.api.cron.Cron;
2021
import io.serverlessworkflow.api.deserializers.*;
2122
import io.serverlessworkflow.api.end.End;
2223
import io.serverlessworkflow.api.events.EventDefinition;
@@ -73,6 +74,8 @@ private void addDefaultSerializers() {
7374
addSerializer(new EndDefinitionSerializer());
7475
addSerializer(new TransitionSerializer());
7576
addSerializer(new FunctionRefSerializer());
77+
addSerializer(new CronSerializer());
78+
addSerializer(new ScheduleSerializer());
7679
addSerializer(extensionSerializer);
7780
}
7881

@@ -99,6 +102,8 @@ private void addDefaultDeserializers() {
99102
addDeserializer(FunctionDefinition.Type.class, new FunctionDefinitionTypeDeserializer(workflowPropertySource));
100103
addDeserializer(Transition.class, new TransitionDeserializer(workflowPropertySource));
101104
addDeserializer(FunctionRef.class, new FunctionRefDeserializer(workflowPropertySource));
105+
addDeserializer(Cron.class, new CronDeserializer(workflowPropertySource));
106+
addDeserializer(Schedule.class, new ScheduleDeserializer(workflowPropertySource));
102107
}
103108

104109
public ExtensionSerializer getExtensionSerializer() {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
* <p>
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+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
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.api.serializers;
18+
19+
import com.fasterxml.jackson.core.JsonGenerator;
20+
import com.fasterxml.jackson.databind.SerializerProvider;
21+
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
22+
import io.serverlessworkflow.api.cron.Cron;
23+
24+
import java.io.IOException;
25+
26+
public class CronSerializer extends StdSerializer<Cron> {
27+
28+
public CronSerializer() {
29+
this(Cron.class);
30+
}
31+
32+
protected CronSerializer(Class<Cron> t) {
33+
super(t);
34+
}
35+
36+
@Override
37+
public void serialize(Cron cron,
38+
JsonGenerator gen,
39+
SerializerProvider provider) throws IOException {
40+
41+
if(cron != null) {
42+
if((cron.getValidUntil() == null || cron.getValidUntil().isEmpty())
43+
&& cron.getExpression() != null
44+
&& cron.getExpression().length() > 0) {
45+
gen.writeString(cron.getExpression());
46+
} else {
47+
gen.writeStartObject();
48+
49+
if(cron.getExpression() != null && cron.getExpression().length() > 0) {
50+
gen.writeStringField("expression", cron.getExpression());
51+
}
52+
53+
if (cron.getValidUntil() != null && cron.getValidUntil().length() > 0) {
54+
gen.writeStringField("validUntil", cron.getValidUntil());
55+
}
56+
57+
gen.writeEndObject();
58+
}
59+
}
60+
}
61+
}
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+
* <p>
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+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
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.api.serializers;
18+
19+
import com.fasterxml.jackson.core.JsonGenerator;
20+
import com.fasterxml.jackson.databind.SerializerProvider;
21+
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
22+
import io.serverlessworkflow.api.schedule.Schedule;
23+
24+
import java.io.IOException;
25+
26+
public class ScheduleSerializer extends StdSerializer<Schedule> {
27+
28+
public ScheduleSerializer() {
29+
this(Schedule.class);
30+
}
31+
32+
protected ScheduleSerializer(Class<Schedule> t) {
33+
super(t);
34+
}
35+
36+
@Override
37+
public void serialize(Schedule schedule,
38+
JsonGenerator gen,
39+
SerializerProvider provider) throws IOException {
40+
41+
if(schedule != null) {
42+
if(schedule.getCron() == null
43+
&& schedule.getDirectInvoke() == null
44+
&& (schedule.getTimezone() == null || schedule.getTimezone().isEmpty())
45+
&& schedule.getInterval() != null
46+
&& schedule.getInterval().length() > 0) {
47+
gen.writeString(schedule.getInterval());
48+
} else {
49+
gen.writeStartObject();
50+
51+
if(schedule.getInterval() != null && schedule.getInterval().length() > 0) {
52+
gen.writeStringField("interval", schedule.getInterval());
53+
}
54+
55+
if(schedule.getCron() != null) {
56+
gen.writeObjectField("cron", schedule.getCron());
57+
}
58+
59+
if (schedule.getDirectInvoke() != null) {
60+
gen.writeStringField("directInvoke", schedule.getDirectInvoke().value());
61+
}
62+
63+
if(schedule.getTimezone() != null && schedule.getTimezone().length() > 0) {
64+
gen.writeStringField("timezone", schedule.getTimezone());
65+
}
66+
67+
gen.writeEndObject();
68+
}
69+
}
70+
}
71+
}

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,4 +345,46 @@ public void testFunctionRefNoParams(String workflowLocation) {
345345
JsonNode params2 = actions.get(1).getFunctionRef().getArguments();
346346
assertNull(params);
347347
}
348+
349+
@ParameterizedTest
350+
@ValueSource(strings = {"/features/simpleschedule.json", "/features/simpleschedule.yml"})
351+
public void testSimplifiedSchedule(String workflowLocation) {
352+
Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation));
353+
354+
assertNotNull(workflow);
355+
assertNotNull(workflow.getId());
356+
assertNotNull(workflow.getName());
357+
assertNotNull(workflow.getStates());
358+
359+
assertNotNull(workflow.getStates());
360+
assertTrue(workflow.getStates().size() == 1);
361+
assertTrue(workflow.getStates().get(0) instanceof EventState);
362+
363+
EventState eventState = (EventState) workflow.getStates().get(0);
364+
assertNotNull(eventState.getStart());
365+
assertNotNull(eventState.getStart().getSchedule());
366+
367+
assertEquals("2020-03-20T09:00:00Z/2020-03-20T15:00:00Z", eventState.getStart().getSchedule().getInterval());
368+
}
369+
370+
@ParameterizedTest
371+
@ValueSource(strings = {"/features/simplecron.json", "/features/simplecron.yml"})
372+
public void testSimplifiedCron(String workflowLocation) {
373+
Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation));
374+
375+
assertNotNull(workflow);
376+
assertNotNull(workflow.getId());
377+
assertNotNull(workflow.getName());
378+
assertNotNull(workflow.getStates());
379+
380+
assertNotNull(workflow.getStates());
381+
assertTrue(workflow.getStates().size() == 2);
382+
assertTrue(workflow.getStates().get(0) instanceof OperationState);
383+
384+
OperationState operationState = (OperationState) workflow.getStates().get(0);
385+
assertNotNull(operationState.getStart());
386+
assertNotNull(operationState.getStart().getSchedule());
387+
388+
assertEquals("0 0/15 * * * ?", operationState.getStart().getSchedule().getCron().getExpression());
389+
}
348390
}

api/src/test/resources/examples/carauctionbids.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@
2121
"name": "StoreCarAuctionBid",
2222
"type": "event",
2323
"start": {
24-
"schedule": {
25-
"interval": "2020-03-20T09:00:00Z/2020-03-20T15:00:00Z"
26-
}
24+
"schedule": "2020-03-20T09:00:00Z/2020-03-20T15:00:00Z"
2725
},
2826
"exclusive": true,
2927
"onEvents": [

0 commit comments

Comments
 (0)