Skip to content

Commit 8bf2dfb

Browse files
authored
Merge pull request #80 from tsurdilo/adddatainputschema
Adding workflow dataInputSchema property
2 parents 8a778aa + 665fcb2 commit 8bf2dfb

File tree

10 files changed

+231
-0
lines changed

10 files changed

+231
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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.deser.std.StdDeserializer;
23+
import io.serverlessworkflow.api.datainputschema.DataInputSchema;
24+
import io.serverlessworkflow.api.interfaces.WorkflowPropertySource;
25+
import java.io.IOException;
26+
27+
public class DataInputSchemaDeserializer extends StdDeserializer<DataInputSchema> {
28+
29+
private static final long serialVersionUID = 510l;
30+
31+
public DataInputSchemaDeserializer() {
32+
this(DataInputSchema.class);
33+
}
34+
35+
public DataInputSchemaDeserializer(Class<?> vc) {
36+
super(vc);
37+
}
38+
39+
public DataInputSchemaDeserializer(WorkflowPropertySource context) {
40+
this(DataInputSchema.class);
41+
}
42+
43+
@Override
44+
public DataInputSchema deserialize(JsonParser jp,
45+
DeserializationContext ctxt) throws IOException {
46+
47+
JsonNode node = jp.getCodec().readTree(jp);
48+
49+
DataInputSchema dataInputSchema = new DataInputSchema();
50+
51+
if (!node.isObject()) {
52+
dataInputSchema.setSchema(node.asText());
53+
dataInputSchema.setFailOnValidationErrors(true); // default
54+
55+
return dataInputSchema;
56+
} else {
57+
dataInputSchema.setSchema(node.get("schema").asText());
58+
dataInputSchema.setFailOnValidationErrors(node.get("failOnValidationErrors").asBoolean());
59+
60+
return dataInputSchema;
61+
}
62+
}
63+
}
64+

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.fasterxml.jackson.databind.module.SimpleModule;
2020
import io.serverlessworkflow.api.cron.Cron;
21+
import io.serverlessworkflow.api.datainputschema.DataInputSchema;
2122
import io.serverlessworkflow.api.deserializers.*;
2223
import io.serverlessworkflow.api.end.End;
2324
import io.serverlessworkflow.api.events.EventDefinition;
@@ -103,6 +104,7 @@ private void addDefaultDeserializers() {
103104
addDeserializer(FunctionRef.class, new FunctionRefDeserializer(workflowPropertySource));
104105
addDeserializer(Cron.class, new CronDeserializer(workflowPropertySource));
105106
addDeserializer(Schedule.class, new ScheduleDeserializer(workflowPropertySource));
107+
addDeserializer(DataInputSchema.class, new DataInputSchemaDeserializer(workflowPropertySource));
106108
}
107109

108110
public ExtensionSerializer getExtensionSerializer() {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ public void serialize(Workflow workflow,
7070
workflow.getVersion());
7171
}
7272

73+
if (workflow.getDataInputSchema() != null) {
74+
if (workflow.getDataInputSchema().getSchema() != null
75+
&& workflow.getDataInputSchema().getSchema().length() > 0
76+
&& workflow.getDataInputSchema().isFailOnValidationErrors()) {
77+
gen.writeStringField("dataInputSchema",
78+
workflow.getDataInputSchema().getSchema());
79+
80+
} else if (workflow.getDataInputSchema().getSchema() != null
81+
&& workflow.getDataInputSchema().getSchema().length() > 0
82+
&& !workflow.getDataInputSchema().isFailOnValidationErrors()) {
83+
gen.writeObjectField("dataInputSchema", workflow.getDataInputSchema());
84+
}
85+
}
86+
7387
if (workflow.getStart() != null) {
7488
gen.writeObjectField("start", workflow.getStart());
7589
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"type": "object",
3+
"javaType": "io.serverlessworkflow.api.datainputschema.DataInputSchema",
4+
"description": "Workflow data input schema",
5+
"properties": {
6+
"schema": {
7+
"type": "string",
8+
"description": "URI of the JSON Schema used to validate the workflow data input",
9+
"minLength": 1
10+
},
11+
"failOnValidationErrors": {
12+
"type": "boolean",
13+
"default": true,
14+
"description": "Determines if workfow execution should continue if there are validation errors"
15+
}
16+
},
17+
"required": [
18+
"schema",
19+
"failOnValidationErrors"
20+
]
21+
}

api/src/main/resources/schema/workflow.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
"type": "string",
2828
"description": "Workflow version"
2929
},
30+
"dataInputSchema": {
31+
"$ref": "datainputschema/datainputschema.json",
32+
"description": "Workflow data input schema"
33+
},
3034
"start": {
3135
"$ref": "start/start.json",
3236
"description": "Defines workflow start"

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.fasterxml.jackson.databind.JsonNode;
2020
import io.serverlessworkflow.api.Workflow;
2121
import io.serverlessworkflow.api.actions.Action;
22+
import io.serverlessworkflow.api.datainputschema.DataInputSchema;
2223
import io.serverlessworkflow.api.defaultdef.DefaultDefinition;
2324
import io.serverlessworkflow.api.exectimeout.ExecTimeout;
2425
import io.serverlessworkflow.api.functions.FunctionDefinition;
@@ -462,4 +463,36 @@ public void testRetriesProps(String workflowLocation) {
462463
assertEquals("0.4", retryDefinition.getJitter());
463464

464465
}
466+
467+
@ParameterizedTest
468+
@ValueSource(strings = {"/features/datainputschemastring.json", "/features/datainputschemastring.yml"})
469+
public void testDataInputSchemaFromString(String workflowLocation) {
470+
Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation));
471+
472+
assertNotNull(workflow);
473+
assertNotNull(workflow.getId());
474+
assertNotNull(workflow.getName());
475+
assertNotNull(workflow.getStates());
476+
477+
DataInputSchema dataInputSchema = workflow.getDataInputSchema();
478+
assertNotNull(dataInputSchema);
479+
assertEquals("somejsonschema.json", dataInputSchema.getSchema());
480+
assertTrue(dataInputSchema.isFailOnValidationErrors());
481+
}
482+
483+
@ParameterizedTest
484+
@ValueSource(strings = {"/features/datainputschemaobj.json", "/features/datainputschemaobj.yml"})
485+
public void testDataInputSchemaFromObject(String workflowLocation) {
486+
Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation));
487+
488+
assertNotNull(workflow);
489+
assertNotNull(workflow.getId());
490+
assertNotNull(workflow.getName());
491+
assertNotNull(workflow.getStates());
492+
493+
DataInputSchema dataInputSchema = workflow.getDataInputSchema();
494+
assertNotNull(dataInputSchema);
495+
assertEquals("somejsonschema.json", dataInputSchema.getSchema());
496+
assertFalse(dataInputSchema.isFailOnValidationErrors());
497+
}
465498
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"id": "datainputschemaobj",
3+
"version": "1.0",
4+
"name": "Data Input Schema test",
5+
"dataInputSchema": {
6+
"schema": "somejsonschema.json",
7+
"failOnValidationErrors": false
8+
},
9+
"start": "TestFunctionRefs",
10+
"states": [
11+
{
12+
"name": "TestFunctionRefs",
13+
"type": "operation",
14+
"actionMode": "sequential",
15+
"actions": [
16+
{
17+
"functionRef": "creditCheckFunction"
18+
},
19+
{
20+
"functionRef": {
21+
"refName": "sendRejectionEmailFunction",
22+
"arguments": {
23+
"applicant": "${ .customer }"
24+
}
25+
}
26+
}
27+
],
28+
"end": true
29+
}
30+
]
31+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
id: datainputschemaobj
2+
version: '1.0'
3+
name: Data Input Schema test
4+
dataInputSchema:
5+
schema: somejsonschema.json
6+
failOnValidationErrors: false
7+
start: TestFunctionRefs
8+
states:
9+
- name: TestFunctionRefs
10+
type: operation
11+
actionMode: sequential
12+
actions:
13+
- functionRef: creditCheckFunction
14+
- functionRef:
15+
refName: sendRejectionEmailFunction
16+
arguments:
17+
applicant: "${ .customer }"
18+
end: true
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"id": "datainputschemaobj",
3+
"version": "1.0",
4+
"name": "Data Input Schema test",
5+
"dataInputSchema": "somejsonschema.json",
6+
"start": "TestFunctionRefs",
7+
"states": [
8+
{
9+
"name": "TestFunctionRefs",
10+
"type": "operation",
11+
"actionMode": "sequential",
12+
"actions": [
13+
{
14+
"functionRef": "creditCheckFunction"
15+
},
16+
{
17+
"functionRef": {
18+
"refName": "sendRejectionEmailFunction",
19+
"arguments": {
20+
"applicant": "${ .customer }"
21+
}
22+
}
23+
}
24+
],
25+
"end": true
26+
}
27+
]
28+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
id: datainputschemaobj
2+
version: '1.0'
3+
name: Data Input Schema test
4+
dataInputSchema: somejsonschema.json
5+
start: TestFunctionRefs
6+
states:
7+
- name: TestFunctionRefs
8+
type: operation
9+
actionMode: sequential
10+
actions:
11+
- functionRef: creditCheckFunction
12+
- functionRef:
13+
refName: sendRejectionEmailFunction
14+
arguments:
15+
applicant: "${ .customer }"
16+
end: true

0 commit comments

Comments
 (0)