Skip to content

Commit a960f90

Browse files
authored
Remove dependency on Jackson via SmallRye - 1.x (#1457)
1 parent dc6b595 commit a960f90

File tree

18 files changed

+2757
-61
lines changed

18 files changed

+2757
-61
lines changed

examples/openapi/src/main/resources/META-INF/openapi.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2019,2020 Oracle and/or its affiliates.
33
#
44
# Licensed under the Apache License, Version 2.0 (the "License");
55
# you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ paths:
5151
summary: Example greeting message to update
5252
value: New greeting message
5353
responses:
54-
200:
54+
"200":
5555
description: OK
5656
content:
5757
application/json: {}

microprofile/tests/tck/tck-rest-client/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
<exclusions>
3838
<exclusion>
3939
<!-- TCK requires Jackson, not JSON-B -->
40-
<groupId>org.glassfish.jersey.media</groupId>
41-
<artifactId>jersey-media-json-binding</artifactId>
40+
<groupId>jakarta.json.bind</groupId>
41+
<artifactId>jakarta.json.bind-api</artifactId>
4242
</exclusion>
4343
</exclusions>
4444
</dependency>

openapi/pom.xml

Lines changed: 99 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
3-
Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
3+
Copyright (c) 2019, 2020 Oracle and/or its affiliates.
44
55
Licensed under the Apache License, Version 2.0 (the "License");
66
you may not use this file except in compliance with the License.
@@ -33,7 +33,76 @@
3333
</description>
3434

3535
<packaging>jar</packaging>
36-
36+
37+
<properties>
38+
<openapi-interfaces-dir>${project.build.directory}/extracted-sources/openapi-interfaces</openapi-interfaces-dir>
39+
<openapi-impls-dir>${project.build.directory}/extracted-sources/openapi-impls</openapi-impls-dir>
40+
</properties>
41+
42+
<build>
43+
<plugins>
44+
<plugin>
45+
<groupId>org.apache.maven.plugins</groupId>
46+
<artifactId>maven-dependency-plugin</artifactId>
47+
<executions>
48+
<execution>
49+
<id>unpack-openapi-interfaces</id>
50+
<goals>
51+
<goal>unpack-dependencies</goal>
52+
</goals>
53+
<phase>generate-sources</phase>
54+
<configuration>
55+
<classifier>sources</classifier>
56+
<failOnMissingClassifierArtifact>true</failOnMissingClassifierArtifact>
57+
<outputDirectory>${openapi-interfaces-dir}</outputDirectory>
58+
<includeGroupIds>org.eclipse.microprofile.openapi</includeGroupIds>
59+
<includeArtifactIds>microprofile-openapi-api</includeArtifactIds>
60+
<includes>org/eclipse/microprofile/openapi/models/**/*.java</includes>
61+
</configuration>
62+
</execution>
63+
<execution>
64+
<id>unpack-openapi-impls</id>
65+
<goals>
66+
<goal>unpack-dependencies</goal>
67+
</goals>
68+
<phase>generate-sources</phase>
69+
<configuration>
70+
<classifier>sources</classifier>
71+
<failOnMissingClassifierArtifact>true</failOnMissingClassifierArtifact>
72+
<outputDirectory>${openapi-impls-dir}</outputDirectory>
73+
<includeGroupIds>io.smallrye</includeGroupIds>
74+
<includeArtifactIds>smallrye-open-api</includeArtifactIds>
75+
<includes>io/smallrye/openapi/api/models/**/*.java</includes>
76+
</configuration>
77+
</execution>
78+
</executions>
79+
</plugin>
80+
<plugin>
81+
<groupId>io.helidon.build-tools</groupId>
82+
<artifactId>snakeyaml-codegen-maven-plugin</artifactId>
83+
<executions>
84+
<execution>
85+
<id>generate-snakeyaml-parsing-helper</id>
86+
<goals>
87+
<goal>generate</goal>
88+
</goals>
89+
<phase>generate-sources</phase>
90+
<configuration>
91+
<outputClass>io.helidon.openapi.SnakeYAMLParserHelper</outputClass>
92+
<interfacesConfig>
93+
<inputDirectory>${openapi-interfaces-dir}</inputDirectory>
94+
</interfacesConfig>
95+
<implementationsConfig>
96+
<inputDirectory>${openapi-impls-dir}</inputDirectory>
97+
</implementationsConfig>
98+
<implementationPrefix>io.smallrye</implementationPrefix>
99+
<interfacePrefix>org.eclipse.microprofile.openapi</interfacePrefix>
100+
</configuration>
101+
</execution>
102+
</executions>
103+
</plugin>
104+
</plugins>
105+
</build>
37106
<dependencies>
38107
<dependency>
39108
<groupId>io.helidon.webserver</groupId>
@@ -42,11 +111,38 @@
42111
<dependency>
43112
<groupId>io.smallrye</groupId>
44113
<artifactId>smallrye-open-api</artifactId>
114+
<exclusions>
115+
<exclusion>
116+
<groupId>com.fasterxml.jackson.core</groupId>
117+
<artifactId>jackson-core</artifactId>
118+
</exclusion>
119+
<exclusion>
120+
<groupId>com.fasterxml.jackson.core</groupId>
121+
<artifactId>jackson-databind</artifactId>
122+
</exclusion>
123+
<exclusion>
124+
<groupId>com.fasterxml.jackson.dataformat</groupId>
125+
<artifactId>jackson-dataformat-yaml</artifactId>
126+
</exclusion>
127+
</exclusions>
45128
</dependency>
46129
<dependency>
47130
<groupId>io.helidon.media.jsonp</groupId>
48131
<artifactId>helidon-media-jsonp-server</artifactId>
49132
</dependency>
133+
<dependency>
134+
<groupId>org.eclipse</groupId>
135+
<artifactId>yasson</artifactId>
136+
</dependency>
137+
<dependency>
138+
<groupId>org.glassfish</groupId>
139+
<artifactId>javax.json</artifactId>
140+
<scope>runtime</scope>
141+
</dependency>
142+
<dependency>
143+
<groupId>org.yaml</groupId>
144+
<artifactId>snakeyaml</artifactId>
145+
</dependency>
50146
<dependency>
51147
<groupId>io.helidon.config</groupId>
52148
<artifactId>helidon-config</artifactId>
@@ -74,16 +170,11 @@
74170
<artifactId>jersey-client</artifactId>
75171
<scope>test</scope>
76172
</dependency>
77-
<dependency>
78-
<groupId>org.yaml</groupId>
79-
<artifactId>snakeyaml</artifactId>
80-
<scope>test</scope>
81-
</dependency>
82173
<dependency>
83174
<groupId>io.helidon.config</groupId>
84175
<artifactId>helidon-config-yaml</artifactId>
85176
<scope>test</scope>
86177
</dependency>
87178
</dependencies>
88-
179+
89180
</project>
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (c) 2019-2020 Oracle and/or its affiliates.
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+
*/
17+
package io.helidon.openapi;
18+
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
22+
import org.eclipse.microprofile.openapi.models.PathItem;
23+
import org.eclipse.microprofile.openapi.models.Paths;
24+
import org.eclipse.microprofile.openapi.models.callbacks.Callback;
25+
import org.eclipse.microprofile.openapi.models.media.Content;
26+
import org.eclipse.microprofile.openapi.models.media.MediaType;
27+
import org.eclipse.microprofile.openapi.models.responses.APIResponse;
28+
import org.eclipse.microprofile.openapi.models.responses.APIResponses;
29+
import org.eclipse.microprofile.openapi.models.security.Scopes;
30+
import org.eclipse.microprofile.openapi.models.security.SecurityRequirement;
31+
import org.eclipse.microprofile.openapi.models.servers.ServerVariable;
32+
import org.eclipse.microprofile.openapi.models.servers.ServerVariables;
33+
import org.yaml.snakeyaml.TypeDescription;
34+
import org.yaml.snakeyaml.constructor.Constructor;
35+
import org.yaml.snakeyaml.nodes.MappingNode;
36+
import org.yaml.snakeyaml.nodes.Node;
37+
import org.yaml.snakeyaml.nodes.NodeId;
38+
import org.yaml.snakeyaml.nodes.SequenceNode;
39+
40+
/**
41+
* Specialized SnakeYAML constructor for modifying {@code Node} objects for OpenAPI types that extend {@code Map} to adjust the
42+
* type of the child nodes of such nodes.
43+
* <p>
44+
* Several MicroProfile OpenAPI interfaces extend {@code Map}. For example, {@code Paths} extends {@code Map
45+
* <String, PathItem>} and {@code SecurityRequirement} extends {@code Map<String, List<String>>}. When SnakeYAML builds the node
46+
* corresponding to one of these types, it correctly creates each child node as a {@code MappingNode} but it assigns those
47+
* child nodes a type of {@code Object} instead of the mapped type -- {@code PathItem} in the example above.
48+
* </p>
49+
* <p>
50+
* This class customizes the preparation of the node tree in these situations by setting the types for the child nodes explicitly
51+
* to the corresponding child type. In OpenAPI 1.1.2 there are two situations, depending on whether the mapped-to type is a
52+
* {@code List} or not.
53+
* </p>
54+
* <p>
55+
* The MicroProfile OpenAPI 2.0 versions of the interfaces no longer use this construct of an interface extending {@code Map}, so
56+
* ideally we can remove this workaround when we adopt 2.0.
57+
* </p>
58+
*/
59+
final class CustomConstructor extends Constructor {
60+
61+
// maps OpenAPI interfaces which extend Map<?, type> to the mapped-to type where that mapped-to type is NOT List
62+
private static final Map<Class<?>, Class<?>> CHILD_MAP_TYPES = new HashMap<>();
63+
64+
// maps OpenAPI interfaces which extend Map<?, List<type>> to the type that appears in the list
65+
private static final Map<Class<?>, Class<?>> CHILD_MAP_OF_LIST_TYPES = new HashMap<>();
66+
67+
static {
68+
CHILD_MAP_TYPES.put(Paths.class, PathItem.class);
69+
CHILD_MAP_TYPES.put(Callback.class, PathItem.class);
70+
CHILD_MAP_TYPES.put(Content.class, MediaType.class);
71+
CHILD_MAP_TYPES.put(APIResponses.class, APIResponse.class);
72+
CHILD_MAP_TYPES.put(ServerVariables.class, ServerVariable.class);
73+
CHILD_MAP_TYPES.put(Scopes.class, String.class);
74+
CHILD_MAP_OF_LIST_TYPES.put(SecurityRequirement.class, String.class);
75+
}
76+
77+
CustomConstructor(TypeDescription td) {
78+
super(td);
79+
}
80+
81+
@Override
82+
protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) {
83+
Class<?> parentType = node.getType();
84+
if (CHILD_MAP_TYPES.containsKey(parentType)) {
85+
Class<?> childType = CHILD_MAP_TYPES.get(parentType);
86+
node.getValue().forEach(tuple -> {
87+
Node valueNode = tuple.getValueNode();
88+
if (valueNode.getType() == Object.class) {
89+
valueNode.setType(childType);
90+
}
91+
});
92+
} else if (CHILD_MAP_OF_LIST_TYPES.containsKey(parentType)) {
93+
Class<?> childType = CHILD_MAP_OF_LIST_TYPES.get(parentType);
94+
node.getValue().forEach(tuple -> {
95+
Node valueNode = tuple.getValueNode();
96+
if (valueNode.getNodeId() == NodeId.sequence) {
97+
SequenceNode seqNode = (SequenceNode) valueNode;
98+
seqNode.setListType(childType);
99+
}
100+
});
101+
}
102+
super.constructMapping2ndStep(node, mapping);
103+
}
104+
}

0 commit comments

Comments
 (0)