Skip to content

Commit 88fbb63

Browse files
author
Michael Sonnleitner
committed
Support GAV coordinates for client generation #1340
1 parent de02ea8 commit 88fbb63

File tree

11 files changed

+317
-1
lines changed

11 files changed

+317
-1
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@ enum ConfigName {
3636
//global configs
3737
VERBOSE("verbose"),
3838
INPUT_BASE_DIR("input-base-dir"),
39+
GAV_SCANNING("gav-scanning"),
3940
TEMPLATE_BASE_DIR("template-base-dir"),
4041
INCLUDE("include"),
4142
EXCLUDE("exclude"),
43+
EXCLUDE_GAV("exclude-gav"),
4244
VALIDATE_SPEC("validateSpec"),
4345
DEFAULT_SECURITY_SCHEME("default-security-scheme"),
4446

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.quarkiverse.openapi.generator.deployment.codegen;
2+
3+
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.*;
4+
import static io.quarkiverse.openapi.generator.deployment.CodegenConfig.ConfigName.*;
5+
6+
import java.io.IOException;
7+
import java.nio.file.Files;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import java.util.Set;
11+
12+
import org.jboss.logging.Logger;
13+
14+
import io.quarkus.bootstrap.prebuild.CodeGenException;
15+
import io.quarkus.deployment.CodeGenContext;
16+
import io.quarkus.maven.dependency.ResolvedDependency;
17+
18+
public class GAVCoordinateOpenApiSpecInputProvider implements OpenApiSpecInputProvider {
19+
private static final Logger LOG = Logger.getLogger(GAVCoordinateOpenApiSpecInputProvider.class);
20+
21+
private static final Set<String> SUPPORTED_EXTENSIONS = Set.of("yaml", "yml", "json");
22+
23+
@Override
24+
public List<SpecInputModel> read(CodeGenContext context) throws CodeGenException {
25+
if (!context.config().getOptionalValue(getGlobalConfigName(GAV_SCANNING), Boolean.class)
26+
.orElse(true)) {
27+
LOG.debug("GAV scanning is disabled.");
28+
return List.of();
29+
}
30+
31+
// Q: maybe a configuration property to enable GAV scanning (default: true)
32+
List<String> gavsToExclude = context.config().getOptionalValues(getGlobalConfigName(EXCLUDE_GAV), String.class)
33+
.orElse(List.of());
34+
35+
List<ResolvedDependency> yamlDependencies = context.applicationModel().getDependencies().stream()
36+
.filter(rd -> SUPPORTED_EXTENSIONS.contains(rd.getType()))
37+
.filter(rd -> !gavsToExclude.contains(rd.getKey().toGacString()))
38+
.toList();
39+
40+
if (yamlDependencies.isEmpty()) {
41+
LOG.debug("No suitable GAV dependencies found.");
42+
return List.of();
43+
}
44+
var inputModels = new ArrayList<SpecInputModel>();
45+
for (ResolvedDependency yamlDependency : yamlDependencies) {
46+
var gacString = yamlDependency.getKey().toGacString();
47+
var path = yamlDependency.getResolvedPaths().stream().findFirst()
48+
.orElseThrow(() -> new CodeGenException("Could not find maven path of %s.".formatted(gacString)));
49+
try {
50+
inputModels.add(new SpecInputModel(gacString, Files.newInputStream(path)));
51+
} catch (IOException e) {
52+
throw new CodeGenException("Could not open input stream of %s from %s.".formatted(gacString, path.toString()),
53+
e);
54+
}
55+
}
56+
return inputModels;
57+
}
58+
}

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/codegen/OpenApiSpecInputProvider.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.InputStream;
44
import java.util.List;
55

6+
import io.quarkus.bootstrap.prebuild.CodeGenException;
67
import io.quarkus.deployment.CodeGenContext;
78

89
/**
@@ -13,8 +14,10 @@ public interface OpenApiSpecInputProvider {
1314
/**
1415
* Fetch OpenAPI specification files from a given source.
1516
*
17+
* @param context the current codegen context.
18+
* @throws CodeGenException if an error occurs while reading the spec files.
1619
* @return a list of spec files in {@link InputStream} format.
1720
*/
18-
List<SpecInputModel> read(CodeGenContext context);
21+
List<SpecInputModel> read(CodeGenContext context) throws CodeGenException;
1922

2023
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.quarkiverse.openapi.generator.deployment.codegen.GAVCoordinateOpenApiSpecInputProvider
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<parent>
4+
<artifactId>quarkus-openapi-generator-integration-tests</artifactId>
5+
<groupId>io.quarkiverse.openapi.generator</groupId>
6+
<version>3.0.0-SNAPSHOT</version>
7+
</parent>
8+
<modelVersion>4.0.0</modelVersion>
9+
10+
<artifactId>quarkus-openapi-generator-gav-source</artifactId>
11+
<name>Quarkus - OpenAPI Generator - Integration Tests - Client - GAV source</name>
12+
<description>Example project for OpenAPI with GAV source</description>
13+
14+
<build>
15+
<plugins>
16+
<plugin>
17+
<groupId>org.apache.maven.plugins</groupId>
18+
<artifactId>maven-install-plugin</artifactId>
19+
<executions>
20+
<execution>
21+
<id>install-echo1</id>
22+
<goals>
23+
<goal>install-file</goal>
24+
</goals>
25+
<phase>install</phase>
26+
<configuration>
27+
<artifactId>quarkus-openapi-generator-gav-source-echo1</artifactId>
28+
<groupId>io.quarkiverse.openapi.generator</groupId>
29+
<version>3.0.0-SNAPSHOT</version>
30+
<file>src/main/openapi/echo1.yaml</file>
31+
<packaging>yaml</packaging>
32+
</configuration>
33+
</execution>
34+
<execution>
35+
<id>install-echo2</id>
36+
<goals>
37+
<goal>install-file</goal>
38+
</goals>
39+
<phase>install</phase>
40+
<configuration>
41+
<artifactId>quarkus-openapi-generator-gav-source-echo2</artifactId>
42+
<groupId>io.quarkiverse.openapi.generator</groupId>
43+
<version>3.0.0-SNAPSHOT</version>
44+
<file>src/main/openapi/echo2.yaml</file>
45+
<packaging>yaml</packaging>
46+
</configuration>
47+
</execution>
48+
</executions>
49+
</plugin>
50+
</plugins>
51+
</build>
52+
53+
</project>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
openapi: 3.0.3
2+
info:
3+
title: echo
4+
version: '1.0.0'
5+
description: ""
6+
paths:
7+
/echo:
8+
post:
9+
summary: Echo
10+
operationId: echo
11+
requestBody:
12+
content:
13+
application/json:
14+
schema:
15+
$ref: "#/components/schemas/Message"
16+
responses:
17+
"200":
18+
description: OK
19+
content:
20+
application/json:
21+
schema:
22+
$ref: '#/components/schemas/Echo'
23+
components:
24+
schemas:
25+
Echo:
26+
type: object
27+
properties:
28+
echo:
29+
type: string
30+
Message:
31+
type: object
32+
properties:
33+
message:
34+
type: string
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
openapi: 3.0.3
2+
info:
3+
title: echo
4+
version: '1.0.0'
5+
description: ""
6+
paths:
7+
/echo:
8+
post:
9+
summary: Echo
10+
operationId: echo
11+
requestBody:
12+
content:
13+
application/json:
14+
schema:
15+
$ref: "#/components/schemas/Message"
16+
responses:
17+
"200":
18+
description: OK
19+
content:
20+
application/json:
21+
schema:
22+
$ref: '#/components/schemas/Echo'
23+
components:
24+
schemas:
25+
Echo:
26+
type: object
27+
properties:
28+
echo:
29+
type: string
30+
Message:
31+
type: object
32+
properties:
33+
message:
34+
type: string
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<parent>
4+
<artifactId>quarkus-openapi-generator-integration-tests</artifactId>
5+
<groupId>io.quarkiverse.openapi.generator</groupId>
6+
<version>3.0.0-SNAPSHOT</version>
7+
</parent>
8+
<modelVersion>4.0.0</modelVersion>
9+
10+
<artifactId>quarkus-openapi-generator-it-gav</artifactId>
11+
<name>Quarkus - OpenAPI Generator - Integration Tests - Client - GAV</name>
12+
<description>Example project for OpenAPI via GAV coordinates</description>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>io.quarkiverse.openapi.generator</groupId>
17+
<artifactId>quarkus-openapi-generator</artifactId>
18+
</dependency>
19+
<!-- include yaml GAV coordinates -->
20+
<!-- echo1 should be generated -->
21+
<dependency>
22+
<groupId>io.quarkiverse.openapi.generator</groupId>
23+
<artifactId>quarkus-openapi-generator-gav-source-echo1</artifactId>
24+
<version>3.0.0-SNAPSHOT</version>
25+
<type>yaml</type>
26+
</dependency>
27+
<!-- echo2 will be excluded during test -->
28+
<dependency>
29+
<groupId>io.quarkiverse.openapi.generator</groupId>
30+
<artifactId>quarkus-openapi-generator-gav-source-echo2</artifactId>
31+
<version>3.0.0-SNAPSHOT</version>
32+
<type>yaml</type>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.assertj</groupId>
36+
<artifactId>assertj-core</artifactId>
37+
<scope>test</scope>
38+
</dependency>
39+
<dependency>
40+
<groupId>io.quarkus</groupId>
41+
<artifactId>quarkus-junit5</artifactId>
42+
<scope>test</scope>
43+
</dependency>
44+
</dependencies>
45+
<build>
46+
<plugins>
47+
<plugin>
48+
<groupId>io.quarkus</groupId>
49+
<artifactId>quarkus-maven-plugin</artifactId>
50+
<extensions>true</extensions>
51+
<executions>
52+
<execution>
53+
<goals>
54+
<goal>build</goal>
55+
<goal>generate-code</goal>
56+
<goal>generate-code-tests</goal>
57+
</goals>
58+
</execution>
59+
</executions>
60+
</plugin>
61+
</plugins>
62+
</build>
63+
<profiles>
64+
<profile>
65+
<id>native-image</id>
66+
<activation>
67+
<property>
68+
<name>native</name>
69+
</property>
70+
</activation>
71+
<build>
72+
<plugins>
73+
<plugin>
74+
<artifactId>maven-surefire-plugin</artifactId>
75+
<configuration>
76+
<skipTests>${native.surefire.skip}</skipTests>
77+
</configuration>
78+
</plugin>
79+
<plugin>
80+
<artifactId>maven-failsafe-plugin</artifactId>
81+
<executions>
82+
<execution>
83+
<goals>
84+
<goal>integration-test</goal>
85+
<goal>verify</goal>
86+
</goals>
87+
<configuration>
88+
<systemPropertyVariables>
89+
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
90+
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
91+
<maven.home>${maven.home}</maven.home>
92+
</systemPropertyVariables>
93+
</configuration>
94+
</execution>
95+
</executions>
96+
</plugin>
97+
</plugins>
98+
</build>
99+
<properties>
100+
<quarkus.package.type>native</quarkus.package.type>
101+
</properties>
102+
</profile>
103+
</profiles>
104+
105+
</project>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
quarkus.keycloak.devservices.enabled=false
2+
3+
quarkus.openapi-generator.codegen.exclude-gav=io.quarkiverse.openapi.generator:quarkus-openapi-generator-gav-source-echo2
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.quarkiverse.openapi.generator.it;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.assertj.core.api.Assertions.*;
6+
7+
class QuarkusGAVOpenApiTest {
8+
@Test
9+
void apiIsBeingGenerated() {
10+
assertThatCode(
11+
() -> Class.forName("org.openapi.quarkus.io_quarkiverse_openapi_generator_quarkus_openapi_generator_gav_source_echo1.api.DefaultApi"))
12+
.doesNotThrowAnyException();
13+
}
14+
15+
@Test
16+
void apiIsBeingNotGenerated() {
17+
assertThatCode(
18+
() -> Class.forName("org.openapi.quarkus.io_quarkiverse_openapi_generator_quarkus_openapi_generator_gav_source_echo2.api.DefaultApi"))
19+
.isInstanceOf(ClassNotFoundException.class);
20+
}
21+
}

0 commit comments

Comments
 (0)