Skip to content

Commit 4eae5ab

Browse files
committed
[Fix #461] alternative approach
Signed-off-by: Francisco Javier Tirado Sarti <ftirados@redhat.com>
1 parent c72cfe5 commit 4eae5ab

File tree

15 files changed

+368
-89
lines changed

15 files changed

+368
-89
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
package io.serverlessworkflow.api;
1717

1818
import io.serverlessworkflow.api.types.Workflow;
19+
import java.io.ByteArrayInputStream;
1920
import java.io.FileNotFoundException;
2021
import java.io.IOException;
2122
import java.io.InputStream;
2223
import java.io.Reader;
24+
import java.io.StringReader;
2325
import java.nio.file.Files;
2426
import java.nio.file.Path;
2527

@@ -37,6 +39,19 @@ public static Workflow readWorkflow(Path path, WorkflowFormat format) throws IOE
3739
return format.mapper().readValue(Files.readAllBytes(path), Workflow.class);
3840
}
3941

42+
public static Workflow readWorkflow(byte[] content, WorkflowFormat format) throws IOException {
43+
try (InputStream input = new ByteArrayInputStream(content)) {
44+
return readWorkflow(input, format);
45+
}
46+
}
47+
48+
public static Workflow readWorkflowFromString(String content, WorkflowFormat format)
49+
throws IOException {
50+
try (Reader reader = new StringReader(content)) {
51+
return readWorkflow(reader, format);
52+
}
53+
}
54+
4055
public static Workflow readWorkflowFromClasspath(String classpath) throws IOException {
4156
return readWorkflowFromClasspath(
4257
classpath,

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
package io.serverlessworkflow.api;
1717

1818
import io.serverlessworkflow.api.types.Workflow;
19+
import java.io.ByteArrayOutputStream;
1920
import java.io.IOException;
2021
import java.io.OutputStream;
22+
import java.io.StringWriter;
2123
import java.io.Writer;
2224
import java.nio.file.Files;
2325
import java.nio.file.Path;
@@ -45,5 +47,21 @@ public static void writeWorkflow(Path output, Workflow workflow, WorkflowFormat
4547
}
4648
}
4749

50+
public static String workflowAsString(Workflow workflow, WorkflowFormat format)
51+
throws IOException {
52+
try (Writer writer = new StringWriter()) {
53+
writeWorkflow(writer, workflow, format);
54+
return writer.toString();
55+
}
56+
}
57+
58+
public static byte[] workflowAsBytes(Workflow workflow, WorkflowFormat format)
59+
throws IOException {
60+
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
61+
writeWorkflow(out, workflow, format);
62+
return out.toByteArray();
63+
}
64+
}
65+
4866
private WorkflowWriter() {}
4967
}

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

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,57 @@
2121
import com.fasterxml.jackson.databind.JsonMappingException;
2222
import jakarta.validation.ConstraintViolationException;
2323
import java.io.IOException;
24+
import java.lang.reflect.InvocationTargetException;
25+
import java.lang.reflect.Method;
26+
import java.util.ArrayList;
2427
import java.util.Collection;
2528

2629
public class DeserializeHelper {
2730

2831
public static <T> T deserializeOneOf(
29-
JsonParser p, Class<T> targetClass, Collection<Class<?>> unionTypes) throws IOException {
32+
JsonParser p, Class<T> targetClass, Collection<Class<?>> oneOfTypes) throws IOException {
3033
TreeNode node = p.readValueAsTree();
31-
JsonProcessingException ex =
32-
new JsonMappingException(p, "Problem deserializing " + targetClass);
33-
for (Class<?> unionType : unionTypes) {
34-
try {
35-
Object object = p.getCodec().treeToValue(node, unionType);
36-
return targetClass.getConstructor(unionType).newInstance(object);
37-
} catch (IOException | ReflectiveOperationException | ConstraintViolationException io) {
38-
ex.addSuppressed(io);
34+
try {
35+
T result = targetClass.getDeclaredConstructor().newInstance();
36+
Collection<Exception> exceptions = new ArrayList<>();
37+
for (Class<?> oneOfType : oneOfTypes) {
38+
try {
39+
assingIt(p, result, node, targetClass, oneOfType);
40+
break;
41+
} catch (IOException | ConstraintViolationException | InvocationTargetException ex) {
42+
exceptions.add(ex);
43+
}
44+
}
45+
if (exceptions.size() == oneOfTypes.size()) {
46+
JsonMappingException ex =
47+
new JsonMappingException(
48+
p,
49+
String.format(
50+
"Error deserializing class %s, all oneOf alternatives %s has failed ",
51+
targetClass, oneOfTypes));
52+
exceptions.forEach(ex::addSuppressed);
53+
throw ex;
54+
}
55+
return result;
56+
} catch (ReflectiveOperationException ex) {
57+
throw new IllegalStateException(ex);
58+
}
59+
}
60+
61+
private static <T> void assingIt(
62+
JsonParser p, T result, TreeNode node, Class<T> targetClass, Class<?> type)
63+
throws JsonProcessingException, ReflectiveOperationException {
64+
findSetMethod(targetClass, type).invoke(result, p.getCodec().treeToValue(node, type));
65+
}
66+
67+
private static Method findSetMethod(Class<?> targetClass, Class<?> type) {
68+
for (Method method : targetClass.getMethods()) {
69+
OneOfSetter oneOfSetter = method.getAnnotation(OneOfSetter.class);
70+
if (oneOfSetter != null && type.equals(oneOfSetter.value())) {
71+
return method;
3972
}
4073
}
41-
throw ex;
74+
throw new IllegalStateException("Cannot find a setter for type " + type);
4275
}
4376

4477
public static <T> T deserializeItem(JsonParser p, Class<T> targetClass, Class<?> valueClass)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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 static java.lang.annotation.ElementType.METHOD;
19+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
20+
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.Target;
23+
24+
@Retention(RUNTIME)
25+
@Target(METHOD)
26+
public @interface OneOfSetter {
27+
Class<?> value();
28+
}

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
import static io.serverlessworkflow.api.WorkflowReader.readWorkflow;
1919
import static io.serverlessworkflow.api.WorkflowReader.readWorkflowFromClasspath;
20+
import static io.serverlessworkflow.api.WorkflowWriter.workflowAsBytes;
21+
import static io.serverlessworkflow.api.WorkflowWriter.workflowAsString;
2022
import static io.serverlessworkflow.api.WorkflowWriter.writeWorkflow;
23+
import static org.assertj.core.api.Assertions.assertThat;
2124
import static org.junit.jupiter.api.Assertions.assertNotNull;
2225

2326
import io.serverlessworkflow.api.types.Workflow;
@@ -32,6 +35,13 @@ public class FeaturesTest {
3235
@ParameterizedTest
3336
@ValueSource(
3437
strings = {
38+
"features/authentication-bearer.yaml",
39+
"features/authentication-bearer-uri-format.yaml",
40+
"features/authentication-oauth2.yaml",
41+
"features/authentication-oauth2-secret.yaml",
42+
"features/authentication-oidc.yaml",
43+
"features/authentication-oidc-secret.yaml",
44+
"features/authentication-reusable.yaml",
3545
"features/callHttp.yaml",
3646
"features/callOpenAPI.yaml",
3747
"features/composite.yaml",
@@ -51,7 +61,7 @@ public class FeaturesTest {
5161
public void testSpecFeaturesParsing(String workflowLocation) throws IOException {
5262
Workflow workflow = readWorkflowFromClasspath(workflowLocation);
5363
assertWorkflow(workflow);
54-
assertWorkflow(writeAndReadInMemory(workflow));
64+
assertWorkflowEquals(workflow, writeAndReadInMemory(workflow));
5565
}
5666

5767
private static Workflow writeAndReadInMemory(Workflow workflow) throws IOException {
@@ -70,4 +80,11 @@ private static void assertWorkflow(Workflow workflow) {
7080
assertNotNull(workflow.getDocument());
7181
assertNotNull(workflow.getDo());
7282
}
83+
84+
private static void assertWorkflowEquals(Workflow workflow, Workflow other) throws IOException {
85+
assertThat(workflowAsString(workflow, WorkflowFormat.YAML))
86+
.isEqualTo(workflowAsString(other, WorkflowFormat.YAML));
87+
assertThat(workflowAsBytes(workflow, WorkflowFormat.JSON))
88+
.isEqualTo(workflowAsBytes(other, WorkflowFormat.JSON));
89+
}
7390
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
document:
2+
dsl: '1.0.0-alpha5'
3+
namespace: examples
4+
name: bearer-auth
5+
version: '0.1.0'
6+
do:
7+
- getPet:
8+
call: http
9+
with:
10+
method: get
11+
endpoint:
12+
uri: https://petstore.swagger.io/v2/pet/{petId}
13+
authentication:
14+
bearer:
15+
token: ${ .token }
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
document:
2+
dsl: '1.0.0-alpha5'
3+
namespace: examples
4+
name: bearer-auth-uri-format
5+
version: '0.1.0'
6+
do:
7+
- getPet:
8+
call: http
9+
with:
10+
method: get
11+
endpoint:
12+
uri: https://petstore.swagger.io/v2/pet/1
13+
authentication:
14+
bearer:
15+
token: ${ .token }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
document:
2+
dsl: 1.0.0-alpha1
3+
namespace: examples
4+
name: oauth2-authentication
5+
version: 1.0.0-alpha1
6+
use:
7+
secrets:
8+
- mySecret
9+
do:
10+
- getPet:
11+
call: http
12+
with:
13+
method: get
14+
endpoint:
15+
uri: https://petstore.swagger.io/v2/pet/{petId}
16+
authentication:
17+
oauth2:
18+
use: mySecret
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
document:
2+
dsl: '1.0.0-alpha5'
3+
namespace: examples
4+
name: oauth2-authentication
5+
version: '0.1.0'
6+
do:
7+
- getPet:
8+
call: http
9+
with:
10+
method: get
11+
endpoint:
12+
uri: https://petstore.swagger.io/v2/pet/{petId}
13+
authentication:
14+
oauth2:
15+
authority: http://keycloak/realms/fake-authority
16+
endpoints: #optional
17+
token: /auth/token #defaults to /oauth2/token
18+
introspection: /auth/introspect #defaults to /oauth2/introspect
19+
grant: client_credentials
20+
client:
21+
id: workflow-runtime-id
22+
secret: workflow-runtime-secret
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
document:
2+
dsl: 1.0.0-alpha1
3+
namespace: examples
4+
name: oidc-authentication
5+
version: 1.0.0-alpha1
6+
use:
7+
secrets:
8+
- mySecret
9+
do:
10+
- getPet:
11+
call: http
12+
with:
13+
method: get
14+
endpoint:
15+
uri: https://petstore.swagger.io/v2/pet/{petId}
16+
authentication:
17+
oidc:
18+
use: mySecret

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy