Skip to content

Commit f8dbe54

Browse files
authored
Merge pull request #419 from fjtirado/Fix_#418
[Fix #418] Adding const support
2 parents 3823d60 + 3b65612 commit f8dbe54

File tree

22 files changed

+210
-11
lines changed

22 files changed

+210
-11
lines changed

api/pom.xml

+9-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@
3333
<groupId>jakarta.validation</groupId>
3434
<artifactId>jakarta.validation-api</artifactId>
3535
</dependency>
36-
36+
<dependency>
37+
<groupId>org.hibernate.validator</groupId>
38+
<artifactId>hibernate-validator</artifactId>
39+
</dependency>
40+
<dependency>
41+
<groupId>org.glassfish.expressly</groupId>
42+
<artifactId>expressly</artifactId>
43+
</dependency>
3744
<!-- test -->
3845
<dependency>
3946
<groupId>org.junit.jupiter</groupId>
@@ -65,11 +72,6 @@
6572
<artifactId>logback-classic</artifactId>
6673
<scope>test</scope>
6774
</dependency>
68-
<dependency>
69-
<groupId>org.assertj</groupId>
70-
<artifactId>assertj-core</artifactId>
71-
<scope>test</scope>
72-
</dependency>
7375
</dependencies>
7476

7577

@@ -101,6 +103,7 @@
101103
<usePrimitives>true</usePrimitives>
102104
<useJakartaValidation>true</useJakartaValidation>
103105
<customRuleFactory>io.serverlessworkflow.generator.UnreferencedFactory</customRuleFactory>
106+
<customAnnotator>io.serverlessworkflow.generator.ConstAnnotator</customAnnotator>
104107
</configuration>
105108
<dependencies>
106109
<dependency>

api/src/main/java/io/serverlessworkflow/api/ObjectMapperFactory.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717

1818
import com.fasterxml.jackson.databind.ObjectMapper;
1919
import com.fasterxml.jackson.databind.SerializationFeature;
20+
import com.fasterxml.jackson.databind.module.SimpleModule;
2021
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
2122
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature;
23+
import io.serverlessworkflow.serialization.BeanDeserializerModifierWithValidation;
2224

2325
class ObjectMapperFactory {
2426

@@ -36,10 +38,13 @@ public static final ObjectMapper yamlMapper() {
3638
}
3739

3840
private static ObjectMapper configure(ObjectMapper mapper) {
41+
SimpleModule validationModule = new SimpleModule();
42+
validationModule.setDeserializerModifier(new BeanDeserializerModifierWithValidation());
3943
return mapper
4044
.configure(SerializationFeature.INDENT_OUTPUT, true)
4145
.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false)
42-
.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
46+
.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false)
47+
.registerModule(validationModule);
4348
}
4449

4550
private ObjectMapperFactory() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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.serialization;
17+
18+
import com.fasterxml.jackson.databind.BeanDescription;
19+
import com.fasterxml.jackson.databind.DeserializationConfig;
20+
import com.fasterxml.jackson.databind.JsonDeserializer;
21+
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
22+
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
23+
24+
public class BeanDeserializerModifierWithValidation extends BeanDeserializerModifier {
25+
26+
private static final long serialVersionUID = 1L;
27+
28+
@Override
29+
public JsonDeserializer<?> modifyDeserializer(
30+
DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
31+
return deserializer instanceof BeanDeserializer
32+
? new BeanDeserializerWithValidation((BeanDeserializer) deserializer)
33+
: deserializer;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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.serialization;
17+
18+
import com.fasterxml.jackson.core.JsonParser;
19+
import com.fasterxml.jackson.databind.DeserializationContext;
20+
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
21+
import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
22+
import jakarta.validation.ConstraintViolation;
23+
import jakarta.validation.ConstraintViolationException;
24+
import jakarta.validation.Validation;
25+
import jakarta.validation.Validator;
26+
import java.io.IOException;
27+
import java.util.Set;
28+
29+
public class BeanDeserializerWithValidation extends BeanDeserializer {
30+
private static final long serialVersionUID = 1L;
31+
private static final Validator validator =
32+
Validation.buildDefaultValidatorFactory().getValidator();
33+
34+
protected BeanDeserializerWithValidation(BeanDeserializerBase src) {
35+
super(src);
36+
}
37+
38+
private <T> void validate(T t) throws IOException {
39+
Set<ConstraintViolation<T>> violations = validator.validate(t);
40+
if (!violations.isEmpty()) {
41+
throw new ConstraintViolationException(violations);
42+
}
43+
}
44+
45+
@Override
46+
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
47+
Object instance = super.deserialize(p, ctxt);
48+
validate(instance);
49+
return instance;
50+
}
51+
}

api/src/main/java/io/serverlessworkflow/serialization/DeserializeHelper.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.fasterxml.jackson.core.JsonProcessingException;
2020
import com.fasterxml.jackson.core.TreeNode;
2121
import com.fasterxml.jackson.databind.JsonMappingException;
22+
import jakarta.validation.ConstraintViolationException;
2223
import java.io.IOException;
2324
import java.util.Collection;
2425

@@ -33,7 +34,7 @@ public static <T> T deserializeOneOf(
3334
try {
3435
Object object = p.getCodec().treeToValue(node, unionType);
3536
return targetClass.getConstructor(unionType).newInstance(object);
36-
} catch (IOException | ReflectiveOperationException io) {
37+
} catch (IOException | ReflectiveOperationException | ConstraintViolationException io) {
3738
ex.addSuppressed(io);
3839
}
3940
}

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

+19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static io.serverlessworkflow.api.WorkflowReader.readWorkflowFromClasspath;
1919
import static org.assertj.core.api.Assertions.assertThat;
2020

21+
import io.serverlessworkflow.api.types.CallFunction;
2122
import io.serverlessworkflow.api.types.CallHTTP;
2223
import io.serverlessworkflow.api.types.CallTask;
2324
import io.serverlessworkflow.api.types.Task;
@@ -44,4 +45,22 @@ void testCallHTTPAPI() throws IOException {
4445
assertThat(httpCall.getWith().getMethod()).isEqualTo("get");
4546
}
4647
}
48+
49+
@Test
50+
void testCallFunctionAPIWithoutArguments() throws IOException {
51+
Workflow workflow = readWorkflowFromClasspath("features/callFunction.yaml");
52+
assertThat(workflow.getDo()).isNotEmpty();
53+
assertThat(workflow.getDo().get(0).getName()).isNotNull();
54+
assertThat(workflow.getDo().get(0).getTask()).isNotNull();
55+
Task task = workflow.getDo().get(0).getTask();
56+
CallTask callTask = task.getCallTask();
57+
assertThat(callTask).isNotNull();
58+
assertThat(callTask.get()).isInstanceOf(CallFunction.class);
59+
if (callTask.get() instanceof CallFunction) {
60+
CallFunction functionCall = callTask.getCallFunction();
61+
assertThat(functionCall).isNotNull();
62+
assertThat(callTask.getCallAsyncAPI()).isNull();
63+
assertThat(functionCall.getWith()).isNull();
64+
}
65+
}
4766
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ public class FeaturesTest {
4343
"features/set.yaml",
4444
"features/switch.yaml",
4545
"features/try.yaml",
46-
"features/listen.yaml"
46+
"features/listen.yaml",
47+
"features/callFunction.yaml"
4748
})
4849
public void testSpecFeaturesParsing(String workflowLocation) throws IOException {
4950
Workflow workflow = readWorkflowFromClasspath(workflowLocation);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
document:
2+
dsl: 1.0.0-alpha1
3+
namespace: default
4+
name: http-call-with-response-output
5+
version: 1.0.0
6+
7+
use:
8+
functions:
9+
getPet:
10+
call: http
11+
with:
12+
method: get
13+
endpoint:
14+
uri: https://petstore.swagger.io/v2/pet/{petId}
15+
output: response
16+
17+
do:
18+
- getPetFunctionCall:
19+
call: getPet

api/src/test/resources/features/callHttp.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: http-call-with-response-output
5+
version: 1.0.0
56
do:
67
- getPet:
78
call: http

api/src/test/resources/features/callOpenAPI.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: openapi-call-with-content-output
5+
version: 1.0.0
56
do:
67
- findPet:
78
call: openapi

api/src/test/resources/features/composite.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: do
5+
version: 1.0.0
56
do:
67
- compositeExample:
78
do:

api/src/test/resources/features/data-flow.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: output-filtering
5+
version: 1.0.0
56
do:
67
- getPet:
78
call: http

api/src/test/resources/features/emit.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: emit
5+
version: 1.0.0
56
do:
67
- emitEvent:
78
emit:

api/src/test/resources/features/flow.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: implicit-sequence
5+
version: 1.0.0
56
do:
67
- setRed:
78
set:

api/src/test/resources/features/for.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: for
5+
version: 1.0.0
56
do:
67
- loopColors:
78
for:

api/src/test/resources/features/listen.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: listen-task
5+
version: 1.0.0
56
do:
67
- listenToSomething:
78
listen:

api/src/test/resources/features/raise.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: raise-custom-error
5+
version: 1.0.0
56
do:
67
- raiseError:
78
raise:
89
error:
910
status: 400
1011
type: https://serverlessworkflow.io/errors/types/compliance
11-
title: Compliance Error
12+
title: Compliance Error
13+
instance: raiseError

api/src/test/resources/features/set.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: set
5+
version: 1.0.0
56
do:
67
- setShape:
78
set:

api/src/test/resources/features/switch.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: switch-match
5+
version: 1.0.0
56
do:
67
- switchColor:
78
switch:

api/src/test/resources/features/try.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ document:
22
dsl: 1.0.0-alpha1
33
namespace: default
44
name: try-catch-404
5+
version: 1.0.0
56
do:
67
- tryGetPet:
78
try:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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.generator;
17+
18+
import com.fasterxml.jackson.databind.JsonNode;
19+
import com.sun.codemodel.JDefinedClass;
20+
import com.sun.codemodel.JFieldVar;
21+
import jakarta.validation.constraints.Pattern;
22+
import org.jsonschema2pojo.AbstractAnnotator;
23+
import org.jsonschema2pojo.GenerationConfig;
24+
25+
public class ConstAnnotator extends AbstractAnnotator {
26+
27+
private static final String CONST = "const";
28+
29+
public ConstAnnotator(GenerationConfig generationConfig) {
30+
super(generationConfig);
31+
}
32+
33+
@Override
34+
public void propertyField(
35+
JFieldVar field, JDefinedClass clazz, String propertyName, JsonNode propertyNode) {
36+
if (propertyNode.has(CONST)) {
37+
field.annotate(Pattern.class).param("regexp", propertyNode.get(CONST).asText());
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)