Skip to content

Commit f8edd15

Browse files
bpassonBas Passonhbelmiro
authored
Added support for Open API Normalizer options (#323)
* Added support for Open API Normalizer options * Unfolded imports * Update integration-tests/open-api-normalizer/pom.xml Co-authored-by: Helber Belmiro <[email protected]> * Unfolded more imports * No longer depending on transitive commons-io dependency * Fixed CodeQL warning --------- Co-authored-by: Bas Passon <[email protected]> Co-authored-by: Helber Belmiro <[email protected]>
1 parent 67846bd commit f8edd15

File tree

13 files changed

+489
-1
lines changed

13 files changed

+489
-1
lines changed

deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/CodegenConfig.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class CodegenConfig {
3030
private static final String ADDITIONAL_MODEL_TYPE_ANNOTATIONS_PROP_FORMAT = "%s.additional-model-type-annotations";
3131
private static final String TYPE_MAPPINGS_PROP_FORMAT = "%s.type-mappings";
3232
private static final String IMPORT_MAPPINGS_PROP_FORMAT = "%s.import-mappings";
33-
33+
private static final String NORMALIZER_PROP_FORMAT = "%s.open-api-normalizer";
3434
private static final String CUSTOM_REGISTER_PROVIDERS_FORMAT = "%s.custom-register-providers";
3535

3636
private static final String RETURN_RESPONSE_PROP_FORMAT = "%s.return-response";
@@ -87,6 +87,10 @@ public static String getImportMappingsPropertyName(final Path openApiFilePath) {
8787
return String.format(IMPORT_MAPPINGS_PROP_FORMAT, getBuildTimeSpecPropertyPrefix(openApiFilePath));
8888
}
8989

90+
public static String getNormalizerPropertyName(final Path openApiFilePath) {
91+
return String.format(NORMALIZER_PROP_FORMAT, getBuildTimeSpecPropertyPrefix(openApiFilePath));
92+
}
93+
9094
/**
9195
* Gets the config prefix for a given OpenAPI file in the path.
9296
* For example, given a path like /home/luke/projects/petstore.json, the returned value is

deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/SpecItemConfig.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,10 @@ public class SpecItemConfig {
5858
*/
5959
@ConfigItem(name = "return-response")
6060
public Optional<Boolean> returnResponse;
61+
62+
/**
63+
* Defines the normalizer options.
64+
*/
65+
@ConfigItem(name = "open-api-normalizer")
66+
public Map<String, String> normalizer;
6167
}

deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiGeneratorCodeGenBase.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getBasePackagePropertyName;
1010
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getCustomRegisterProvidersFormat;
1111
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getImportMappingsPropertyName;
12+
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getNormalizerPropertyName;
1213
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getReturnResponsePropertyName;
1314
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getSanitizedFileName;
1415
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.getSkipFormModelPropertyName;
@@ -176,6 +177,9 @@ protected void generate(final Config config, final Path openApiFilePath, final P
176177
smallRyeConfig.getOptionalValues(getImportMappingsPropertyName(openApiFilePath), String.class, String.class)
177178
.ifPresent(generator::withImportMappings);
178179

180+
smallRyeConfig.getOptionalValues(getNormalizerPropertyName(openApiFilePath), String.class, String.class)
181+
.ifPresent(generator::withOpenApiNormalizer);
182+
179183
generator.generate(basePackage);
180184
}
181185

deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ public OpenApiClientGeneratorWrapper withImportMappings(final Map<String, String
139139
return this;
140140
}
141141

142+
public OpenApiClientGeneratorWrapper withOpenApiNormalizer(final Map<String, String> openApiNormalizer) {
143+
configurator.setOpenAPINormalizer(openApiNormalizer);
144+
return this;
145+
}
146+
142147
/**
143148
* Sets the global 'additionalModelTypeAnnotations' setting. If not set this setting will default to empty.
144149
*

deployment/src/test/java/io/quarkiverse/openapi/generator/deployment/wrapper/OpenApiClientGeneratorWrapperTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.github.javaparser.ast.body.Parameter;
3333
import com.github.javaparser.ast.body.VariableDeclarator;
3434
import com.github.javaparser.ast.expr.AnnotationExpr;
35+
import com.github.javaparser.ast.expr.SimpleName;
3536
import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
3637
import com.github.javaparser.ast.nodeTypes.NodeWithName;
3738
import com.github.javaparser.ast.type.Type;
@@ -520,6 +521,27 @@ void verifyCustomRegisterProviderAnnotationsWithoutSecurity() throws URISyntaxEx
520521
});
521522
}
522523

524+
@Test
525+
void verifyAPINormalization() throws Exception {
526+
final List<File> generatedFiles = this.createGeneratorWrapper("open-api-normalizer.json")
527+
.withOpenApiNormalizer(Map.of("REF_AS_PARENT_IN_ALLOF", "true"))
528+
.generate("org.acme.openapi.animals");
529+
530+
assertNotNull(generatedFiles);
531+
assertFalse(generatedFiles.isEmpty());
532+
533+
Optional<File> file = generatedFiles.stream()
534+
.filter(f -> f.getName().endsWith("Primate.java"))
535+
.findAny();
536+
assertThat(file).isNotEmpty();
537+
CompilationUnit compilationUnit = StaticJavaParser.parse(file.orElseThrow());
538+
List<ClassOrInterfaceDeclaration> types = compilationUnit.findAll(ClassOrInterfaceDeclaration.class);
539+
540+
assertThat(types).hasSize(1);
541+
assertThat(types.get(0).getExtendedTypes()).hasSize(1);
542+
assertThat(types.get(0).getExtendedTypes(0).getName()).isEqualTo(new SimpleName("Mammal"));
543+
}
544+
523545
private Optional<AnnotationExpr> getRegisterProviderAnnotation(ClassOrInterfaceDeclaration declaration,
524546
String annotationValue) {
525547
return declaration.getAnnotations()
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
{
2+
"openapi": "3.0.2",
3+
"info": {
4+
"title": "Animals - OpenAPI 3.0",
5+
"version": "1.0.5"
6+
},
7+
"servers": [
8+
{
9+
"url": "/api/v3"
10+
}
11+
],
12+
"tags": [
13+
{
14+
"name": "primate",
15+
"description": "Everything about Primates"
16+
}
17+
],
18+
"paths": {
19+
"/primate/{id}": {
20+
"get": {
21+
"tags": [
22+
"primate"
23+
],
24+
"summary": "Find primate by ID",
25+
"description": "Returns a single primate",
26+
"operationId": "getPrimateById",
27+
"parameters": [
28+
{
29+
"name": "id",
30+
"in": "path",
31+
"description": "ID of primate to return",
32+
"required": true,
33+
"schema": {
34+
"type": "integer",
35+
"format": "int64"
36+
}
37+
}
38+
],
39+
"responses": {
40+
"200": {
41+
"description": "successful operation",
42+
"content": {
43+
"application/json": {
44+
"schema": {
45+
"$ref": "#/components/schemas/Primate"
46+
}
47+
}
48+
}
49+
},
50+
"400": {
51+
"description": "Invalid ID supplied"
52+
},
53+
"404": {
54+
"description": "Primate not found"
55+
}
56+
}
57+
}
58+
}
59+
},
60+
"components": {
61+
"schemas": {
62+
"Animal":{
63+
"type": "object",
64+
"properties": {
65+
"born": {
66+
"type": "string",
67+
"description": "Dated Base extension.",
68+
"format": "date-time"
69+
},
70+
"deceased": {
71+
"type": "string",
72+
"description": "Dated Base extension.",
73+
"format": "date-time"
74+
}
75+
},
76+
"xml": {
77+
"name": "animal"
78+
}
79+
},
80+
"Mammal": {
81+
"type": "object",
82+
"allOf": [{
83+
"$ref": "#/components/schemas/Animal"
84+
}],
85+
"properties": {
86+
"gender": {
87+
"type": "string",
88+
"enum": [
89+
"female",
90+
"male"
91+
]
92+
}
93+
},
94+
"xml": {
95+
"name": "mammal"
96+
}
97+
},
98+
"Primate": {
99+
"required": [
100+
"name"
101+
],
102+
"type": "object",
103+
"allOf": [
104+
{
105+
"$ref": "#/components/schemas/Mammal"
106+
}
107+
],
108+
"properties": {
109+
"id": {
110+
"type": "integer",
111+
"format": "int64",
112+
"example": 10
113+
},
114+
"name": {
115+
"type": "string",
116+
"example": "jane doe"
117+
}
118+
},
119+
"xml": {
120+
"name": "primate"
121+
}
122+
}
123+
}
124+
}
125+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<artifactId>quarkus-openapi-generator-integration-tests</artifactId>
8+
<groupId>io.quarkiverse.openapi.generator</groupId>
9+
<version>3.0.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<artifactId>quarkus-openapi-generator-it-open-api-normalizer</artifactId>
13+
<name>Quarkus - Openapi Generator - Integration Tests - OpenAPI Normalizer</name>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>io.quarkiverse.openapi.generator</groupId>
18+
<artifactId>quarkus-openapi-generator</artifactId>
19+
</dependency>
20+
<dependency>
21+
<groupId>org.assertj</groupId>
22+
<artifactId>assertj-core</artifactId>
23+
<scope>test</scope>
24+
</dependency>
25+
<dependency>
26+
<groupId>io.quarkus</groupId>
27+
<artifactId>quarkus-junit5</artifactId>
28+
<scope>test</scope>
29+
</dependency>
30+
<dependency>
31+
<groupId>com.github.tomakehurst</groupId>
32+
<artifactId>wiremock-jre8</artifactId>
33+
<scope>test</scope>
34+
</dependency>
35+
</dependencies>
36+
37+
<build>
38+
<plugins>
39+
<plugin>
40+
<groupId>io.quarkus</groupId>
41+
<artifactId>quarkus-maven-plugin</artifactId>
42+
<extensions>true</extensions>
43+
<executions>
44+
<execution>
45+
<goals>
46+
<goal>build</goal>
47+
<goal>generate-code</goal>
48+
<goal>generate-code-tests</goal>
49+
</goals>
50+
</execution>
51+
</executions>
52+
</plugin>
53+
</plugins>
54+
</build>
55+
<profiles>
56+
<profile>
57+
<id>native-image</id>
58+
<activation>
59+
<property>
60+
<name>native</name>
61+
</property>
62+
</activation>
63+
<build>
64+
<plugins>
65+
<plugin>
66+
<artifactId>maven-surefire-plugin</artifactId>
67+
<configuration>
68+
<skipTests>${native.surefire.skip}</skipTests>
69+
</configuration>
70+
</plugin>
71+
<plugin>
72+
<artifactId>maven-failsafe-plugin</artifactId>
73+
<executions>
74+
<execution>
75+
<goals>
76+
<goal>integration-test</goal>
77+
<goal>verify</goal>
78+
</goals>
79+
<configuration>
80+
<systemPropertyVariables>
81+
<native.image.path>
82+
${project.build.directory}/${project.build.finalName}-runner
83+
</native.image.path>
84+
<java.util.logging.manager>org.jboss.logmanager.LogManager
85+
</java.util.logging.manager>
86+
<maven.home>${maven.home}</maven.home>
87+
</systemPropertyVariables>
88+
</configuration>
89+
</execution>
90+
</executions>
91+
</plugin>
92+
</plugins>
93+
</build>
94+
<properties>
95+
<quarkus.package.type>native</quarkus.package.type>
96+
</properties>
97+
</profile>
98+
</profiles>
99+
100+
</project>

0 commit comments

Comments
 (0)