Skip to content

Commit 667b9d8

Browse files
committed
[Fix #461] alternative approach
Signed-off-by: Francisco Javier Tirado Sarti <[email protected]>
1 parent c72cfe5 commit 667b9d8

File tree

13 files changed

+325
-88
lines changed

13 files changed

+325
-88
lines changed

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

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,58 @@
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+
56+
return result;
57+
} catch (ReflectiveOperationException ex) {
58+
throw new IllegalStateException(ex);
59+
}
60+
}
61+
62+
private static <T> void assingIt(
63+
JsonParser p, T result, TreeNode node, Class<T> targetClass, Class<?> type)
64+
throws JsonProcessingException, ReflectiveOperationException {
65+
findSetMethod(targetClass, type).invoke(result, p.getCodec().treeToValue(node, type));
66+
}
67+
68+
private static Method findSetMethod(Class<?> targetClass, Class<?> type) {
69+
for (Method method : targetClass.getMethods()) {
70+
OneOfSetter oneOfSetter = method.getAnnotation(OneOfSetter.class);
71+
if (oneOfSetter != null && type.equals(oneOfSetter.value())) {
72+
return method;
3973
}
4074
}
41-
throw ex;
75+
throw new IllegalStateException("Cannot find a setter for type " + type);
4276
}
4377

4478
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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ public class FeaturesTest {
3232
@ParameterizedTest
3333
@ValueSource(
3434
strings = {
35+
"features/authentication-bearer.yaml",
36+
"features/authentication-bearer-uri-format.yaml",
37+
"features/authentication-oauth2.yaml",
38+
"features/authentication-oauth2-secret.yaml",
39+
"features/authentication-oidc.yaml",
40+
"features/authentication-oidc-secret.yaml",
41+
"features/authentication-reusable.yaml",
3542
"features/callHttp.yaml",
3643
"features/callOpenAPI.yaml",
3744
"features/composite.yaml",
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
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
document:
2+
dsl: '1.0.0-alpha5'
3+
namespace: examples
4+
name: oidc-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+
oidc:
15+
authority: http://keycloak/realms/fake-authority #endpoints are resolved using the OIDC configuration located at '/.well-known/openid-configuration'
16+
grant: client_credentials
17+
client:
18+
id: workflow-runtime-id
19+
secret: workflow-runtime-secret
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
document:
2+
dsl: '1.0.0-alpha5'
3+
namespace: examples
4+
name: bearer-auth
5+
version: '0.1.0'
6+
use:
7+
authentications:
8+
petStoreAuth:
9+
bearer:
10+
token: ${ .token }
11+
do:
12+
- getPet:
13+
call: http
14+
with:
15+
method: get
16+
endpoint:
17+
uri: https://petstore.swagger.io/v2/pet/{petId}
18+
authentication:
19+
use: petStoreAuth

0 commit comments

Comments
 (0)