Skip to content

Commit 213564a

Browse files
#18388: Add Mutiny support to JaxRS (#18389)
* #18388: Add Mutiny support to JaxRS * Updated samples * Updated doccs * Updated example to 3_0 * Updated sample
1 parent 7b0f963 commit 213564a

89 files changed

Lines changed: 15217 additions & 2 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
generatorName: jaxrs-spec
2+
outputDir: samples/server/petstore/jaxrs-spec-quarkus-mutiny
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/JavaJaxRS/spec
5+
additionalProperties:
6+
artifactId: jaxrs-spec-petstore-server
7+
serializableModel: "true"
8+
hideGenerationTimestamp: "true"
9+
implicitHeadersRegex: (api_key|enum_header_string)
10+
generateBuilders: "true"
11+
useMicroProfileOpenAPIAnnotations: "true"
12+
useAsync: "true"
13+
useMutiny: "true"
14+
library: "quarkus"
15+
dateLibrary: "java8-localdatetime"

docs/generators/jaxrs-cxf-cdi.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
7878
|useBeanValidation|Use BeanValidation API annotations| |true|
7979
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
8080
|useMicroProfileOpenAPIAnnotations|Whether to generate Microprofile OpenAPI annotations. Only valid when library is set to quarkus.| |false|
81+
|useMutiny|Whether to use Smallrye Mutiny instead of CompletionStage for asynchronous computation. Only valid when library is set to quarkus.| |false|
8182
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
8283
|useSwaggerAnnotations|Whether to generate Swagger annotations.| |true|
8384
|useTags|use tags for creating interface and controller classnames| |false|

docs/generators/jaxrs-spec.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
7878
|useBeanValidation|Use BeanValidation API annotations| |true|
7979
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
8080
|useMicroProfileOpenAPIAnnotations|Whether to generate Microprofile OpenAPI annotations. Only valid when library is set to quarkus.| |false|
81+
|useMutiny|Whether to use Smallrye Mutiny instead of CompletionStage for asynchronous computation. Only valid when library is set to quarkus.| |false|
8182
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
8283
|useSwaggerAnnotations|Whether to generate Swagger annotations.| |true|
8384
|useTags|use tags for creating interface and controller classnames| |false|

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaJAXRSSpecServerCodegen.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
3838
public static final String GENERATE_POM = "generatePom";
3939
public static final String USE_SWAGGER_ANNOTATIONS = "useSwaggerAnnotations";
4040
public static final String USE_MICROPROFILE_OPENAPI_ANNOTATIONS = "useMicroProfileOpenAPIAnnotations";
41+
public static final String USE_MUTINY = "useMutiny";
4142
public static final String OPEN_API_SPEC_FILE_LOCATION = "openApiSpecFileLocation";
4243
public static final String GENERATE_BUILDERS = "generateBuilders";
4344

@@ -53,6 +54,7 @@ public class JavaJAXRSSpecServerCodegen extends AbstractJavaJAXRSServerCodegen {
5354
private boolean generateBuilders = false;
5455
private boolean useSwaggerAnnotations = true;
5556
private boolean useMicroProfileOpenAPIAnnotations = false;
57+
private boolean useMutiny = false;
5658

5759
protected boolean useGzipFeature = false;
5860
private boolean useJackson = false;
@@ -120,6 +122,7 @@ public JavaJAXRSSpecServerCodegen() {
120122
cliOptions.add(CliOption.newBoolean(USE_MICROPROFILE_OPENAPI_ANNOTATIONS, "Whether to generate Microprofile OpenAPI annotations. Only valid when library is set to quarkus.", useMicroProfileOpenAPIAnnotations));
121123
cliOptions.add(CliOption.newString(OPEN_API_SPEC_FILE_LOCATION, "Location where the file containing the spec will be generated in the output folder. No file generated when set to null or empty string."));
122124
cliOptions.add(CliOption.newBoolean(SUPPORT_ASYNC, "Wrap responses in CompletionStage type, allowing asynchronous computation (requires JAX-RS 2.1).", supportAsync));
125+
cliOptions.add(CliOption.newBoolean(USE_MUTINY, "Whether to use Smallrye Mutiny instead of CompletionStage for asynchronous computation. Only valid when library is set to quarkus.", useMutiny));
123126
}
124127

125128
@Override
@@ -167,6 +170,12 @@ public void processOpts() {
167170
writePropertyBack(USE_MICROPROFILE_OPENAPI_ANNOTATIONS, useMicroProfileOpenAPIAnnotations);
168171
}
169172

173+
if (QUARKUS_LIBRARY.equals(library)) {
174+
if (additionalProperties.containsKey(USE_MUTINY)) {
175+
useMutiny = Boolean.parseBoolean(additionalProperties.get(USE_MUTINY).toString());
176+
}
177+
writePropertyBack(USE_MUTINY, useMutiny);
178+
}
170179

171180
if (additionalProperties.containsKey(GENERATE_BUILDERS)) {
172181
generateBuilders = Boolean.parseBoolean(additionalProperties.get(GENERATE_BUILDERS).toString());

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/api.mustache

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@ import io.swagger.annotations.*;
1515
{{/useSwaggerAnnotations}}
1616

1717
{{#supportAsync}}
18+
{{#useMutiny}}
19+
import io.smallrye.mutiny.Uni;
20+
{{/useMutiny}}
21+
{{^useMutiny}}
1822
import java.util.concurrent.CompletionStage;
1923
import java.util.concurrent.CompletableFuture;
24+
{{/useMutiny}}
2025
{{/supportAsync}}
2126

2227
import java.io.InputStream;

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/apiMethod.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@
4040
{{^vendorExtensions.x-java-is-response-void}}@org.eclipse.microprofile.openapi.annotations.media.Content(schema = @org.eclipse.microprofile.openapi.annotations.media.Schema(implementation = {{{baseType}}}.class{{#vendorExtensions.x-microprofile-open-api-return-schema-container}}, type = {{{.}}} {{/vendorExtensions.x-microprofile-open-api-return-schema-container}}{{#vendorExtensions.x-microprofile-open-api-return-unique-items}}, uniqueItems = true {{/vendorExtensions.x-microprofile-open-api-return-unique-items}})){{/vendorExtensions.x-java-is-response-void}}
4141
}){{^-last}},{{/-last}}{{/responses}}
4242
}){{/hasProduces}}{{/useMicroProfileOpenAPIAnnotations}}
43-
public {{#supportAsync}}CompletionStage<{{/supportAsync}}Response{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
44-
return {{#supportAsync}}CompletableFuture.supplyAsync(() -> {{/supportAsync}}Response.ok().entity("magic!").build(){{#supportAsync}}){{/supportAsync}};
43+
public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}Response{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
44+
return {{#supportAsync}}{{#useMutiny}}Uni.createFrom().item({{/useMutiny}}{{^useMutiny}}CompletableFuture.supplyAsync(() -> {{/useMutiny}}{{/supportAsync}}Response.ok().entity("magic!").build(){{#supportAsync}}){{/supportAsync}};
4545
}

modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/pom.mustache

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
{{#useSwaggerAnnotations}}
4545
<io.swagger.annotations.version>1.6.10</io.swagger.annotations.version>
4646
{{/useSwaggerAnnotations}}
47+
{{#useMutiny}}
48+
<smallrye.rest.client.version>1.2.1</smallrye.rest.client.version>
49+
{{/useMutiny}}
4750
</properties>
4851
<dependencyManagement>
4952
<dependencies>
@@ -109,6 +112,14 @@
109112
<scope>provided</scope>
110113
</dependency>
111114
{{/useSwaggerAnnotations}}
115+
{{#useMutiny}}
116+
<dependency>
117+
<groupId>io.smallrye</groupId>
118+
<artifactId>smallrye-rest-client</artifactId>
119+
<version>${smallrye.rest.client.version}</version>
120+
<scope>test</scope>
121+
</dependency>
122+
{{/useMutiny}}
112123
</dependencies>
113124
<build>
114125
<plugins>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{#returnResponse}}Response{{/returnResponse}}{{^returnResponse}}{{#returnContainer}}{{#isMap}}Map<String, {{{returnBaseType}}}>{{/isMap}}{{#isArray}}{{{returnContainer}}}<{{{returnBaseType}}}>{{/isArray}}{{/returnContainer}}{{^returnContainer}}{{{returnBaseType}}}{{/returnContainer}}{{/returnResponse}}>

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/jaxrs/JavaJAXRSSpecServerCodegenTest.java

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,103 @@ public void generateApiForQuarkusWithGzipFeature() throws Exception {
808808
);
809809
}
810810

811+
@Test
812+
public void generateApiForQuarkusWithoutMutiny() throws Exception {
813+
final File output = Files.createTempDirectory("test").toFile();
814+
output.deleteOnExit();
815+
816+
final OpenAPI openAPI = new OpenAPIParser()
817+
.readLocation("src/test/resources/3_0/issue_4832.yaml", null, new ParseOptions()).getOpenAPI();
818+
819+
codegen.setOutputDir(output.getAbsolutePath());
820+
codegen.setLibrary(QUARKUS_LIBRARY);
821+
codegen.additionalProperties().put(SUPPORT_ASYNC, true);
822+
codegen.additionalProperties().put(USE_TAGS, true); //And use tags to generate everything in PingApi.java
823+
824+
final ClientOptInput input = new ClientOptInput()
825+
.openAPI(openAPI)
826+
.config(codegen); //Using JavaJAXRSSpecServerCodegen
827+
828+
final DefaultGenerator generator = new DefaultGenerator();
829+
final List<File> files = generator.opts(input).generate(); //When generating files
830+
831+
//Then the java files are compilable
832+
validateJavaSourceFiles(files);
833+
834+
//And the generated class contains CompletionStage<Response>
835+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/PingApi.java");
836+
TestUtils.assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/api/PingApi.java"),
837+
"CompletionStage<Response> pingGetBoolean", //Support primitive types response
838+
"CompletionStage<Response> pingGetInteger" //Support primitive types response
839+
);
840+
}
841+
842+
@Test
843+
public void generateApiForQuarkusWithMutinyApi() throws Exception {
844+
final File output = Files.createTempDirectory("test").toFile();
845+
output.deleteOnExit();
846+
847+
final OpenAPI openAPI = new OpenAPIParser()
848+
.readLocation("src/test/resources/3_0/issue_4832.yaml", null, new ParseOptions()).getOpenAPI();
849+
850+
codegen.setOutputDir(output.getAbsolutePath());
851+
codegen.setLibrary(QUARKUS_LIBRARY);
852+
codegen.additionalProperties().put(USE_TAGS, true); //And use tags to generate everything in PingApi.java
853+
codegen.additionalProperties().put(SUPPORT_ASYNC, true);
854+
codegen.additionalProperties().put(INTERFACE_ONLY, true);
855+
codegen.additionalProperties().put(USE_MUTINY, true);
856+
857+
final ClientOptInput input = new ClientOptInput()
858+
.openAPI(openAPI)
859+
.config(codegen); //Using JavaJAXRSSpecServerCodegen
860+
861+
final DefaultGenerator generator = new DefaultGenerator();
862+
final List<File> files = generator.opts(input).generate(); //When generating files
863+
864+
//Then the java files are compilable
865+
validateJavaSourceFiles(files);
866+
867+
//And the generated class contains CompletionStage<Response>
868+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/PingApi.java");
869+
TestUtils.assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/api/PingApi.java"),
870+
"Uni<Boolean> pingGetBoolean", //Support primitive types response
871+
"Uni<Integer> pingGetInteger" //Support primitive types response
872+
);
873+
}
874+
875+
876+
@Test
877+
public void generateApiForQuarkusWithMutinyImpl() throws Exception {
878+
final File output = Files.createTempDirectory("test").toFile();
879+
output.deleteOnExit();
880+
881+
final OpenAPI openAPI = new OpenAPIParser()
882+
.readLocation("src/test/resources/3_0/issue_4832.yaml", null, new ParseOptions()).getOpenAPI();
883+
884+
codegen.setOutputDir(output.getAbsolutePath());
885+
codegen.setLibrary(QUARKUS_LIBRARY);
886+
codegen.additionalProperties().put(USE_TAGS, true); //And use tags to generate everything in PingApi.java
887+
codegen.additionalProperties().put(SUPPORT_ASYNC, true);
888+
codegen.additionalProperties().put(USE_MUTINY, true);
889+
890+
final ClientOptInput input = new ClientOptInput()
891+
.openAPI(openAPI)
892+
.config(codegen); //Using JavaJAXRSSpecServerCodegen
893+
894+
final DefaultGenerator generator = new DefaultGenerator();
895+
final List<File> files = generator.opts(input).generate(); //When generating files
896+
897+
//Then the java files are compilable
898+
validateJavaSourceFiles(files);
899+
900+
//And the generated class contains CompletionStage<Response>
901+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/PingApi.java");
902+
TestUtils.assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/api/PingApi.java"),
903+
"Uni<Response> pingGetBoolean", //Support primitive types response
904+
"Uni<Response> pingGetInteger" //Support primitive types response
905+
);
906+
}
907+
811908
@Test
812909
public void testHandleRequiredAndReadOnlyPropertiesCorrectly() throws Exception {
813910
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*
2+
!target/*-runner
3+
!target/*-runner.jar
4+
!target/lib/*

0 commit comments

Comments
 (0)