Skip to content

Commit 4f7b018

Browse files
committed
squash
1 parent 878d821 commit 4f7b018

16 files changed

Lines changed: 254 additions & 13 deletions

File tree

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,18 @@ public ModelsMap postProcessModels(ModelsMap objs) {
343343
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
344344
objs = super.postProcessOperationsWithModels(objs, allModels);
345345
removeImport(objs, "java.util.List");
346+
if (QUARKUS_LIBRARY.equals(library) && !returnResponse && !returnJbossResponse) {
347+
for (CodegenOperation op : objs.getOperations().getOperation()) {
348+
op.responses.stream()
349+
.filter(r -> r.is2xx || r.is3xx)
350+
.findFirst()
351+
.ifPresent(r -> op.vendorExtensions.put("x-java-success-response-code", r.code));
352+
}
353+
if (objs.getOperations().getOperation().stream()
354+
.anyMatch(op -> op.vendorExtensions.containsKey("x-java-success-response-code"))) {
355+
objs.put("hasResponseStatusAnnotations", true);
356+
}
357+
}
346358
return objs;
347359
}
348360

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package {{package}};
66
import {{javaxPackage}}.ws.rs.*;
77
import {{javaxPackage}}.ws.rs.core.Response;
88
{{#returnJBossResponse}}import org.jboss.resteasy.reactive.RestResponse;{{/returnJBossResponse}}
9+
{{#hasResponseStatusAnnotations}}import org.jboss.resteasy.reactive.ResponseStatus;{{/hasResponseStatusAnnotations}}
910

1011
{{#useGzipFeature}}
1112
import org.jboss.resteasy.annotations.GZIP;
@@ -116,4 +117,4 @@ public {{#interfaceOnly}}interface{{/interfaceOnly}}{{^interfaceOnly}}class{{/in
116117
{{#interfaceOnly}}{{>apiInterface}}{{/interfaceOnly}}{{^interfaceOnly}}{{>apiMethod}}{{/interfaceOnly}}
117118
{{/operation}}
118119
}
119-
{{/operations}}
120+
{{/operations}}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@
4444
{{^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}}
4545
}){{^-last}},{{/-last}}{{/responses}}
4646
}){{/hasProduces}}{{/useMicroProfileOpenAPIAnnotations}}
47-
{{#supportAsync}}{{>returnAsyncTypeInterface}}{{/supportAsync}}{{^supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}{{#returnResponse}}Response{{/returnResponse}}{{^returnResponse}}{{>returnTypeInterface}}{{/returnResponse}}{{/returnJBossResponse}}{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}});
47+
{{#vendorExtensions.x-java-success-response-code}}@ResponseStatus({{{vendorExtensions.x-java-success-response-code}}})
48+
{{/vendorExtensions.x-java-success-response-code}}{{#supportAsync}}{{>returnAsyncTypeInterface}}{{/supportAsync}}{{^supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}{{#returnResponse}}Response{{/returnResponse}}{{^returnResponse}}{{>returnTypeInterface}}{{/returnResponse}}{{/returnJBossResponse}}{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}});

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
{{^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}}
4545
}){{^-last}},{{/-last}}{{/responses}}
4646
}){{/hasProduces}}{{/useMicroProfileOpenAPIAnnotations}}
47-
public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}Response{{/returnJBossResponse}}{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
47+
{{#vendorExtensions.x-java-success-response-code}}@ResponseStatus({{{vendorExtensions.x-java-success-response-code}}})
48+
{{/vendorExtensions.x-java-success-response-code}}public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}Response{{/returnJBossResponse}}{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
4849
return {{#supportAsync}}{{#useMutiny}}Uni.createFrom().item({{/useMutiny}}{{^useMutiny}}CompletableFuture.supplyAsync(() -> {{/useMutiny}}{{/supportAsync}}Response.ok().entity("magic!").build(){{#supportAsync}}){{/supportAsync}};
49-
}
50+
}

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

Lines changed: 141 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ public void disableGenerateJsonCreator() throws Exception {
12361236

12371237
assertFileNotContains(files.get("RequiredProperties.java").toPath(), "@JsonCreator");
12381238
}
1239-
1239+
12401240
@Test
12411241
public void testDiscriminatorMappingUsedInJsonTypeName() throws Exception {
12421242
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
@@ -1273,38 +1273,170 @@ public void testDiscriminatorMappingUsedInJsonTypeName() throws Exception {
12731273
public void testGenerateJsonNullableListFieldsHelperMethodReferences_issue23251() throws Exception {
12741274
Map<String, Object> properties = new HashMap<>();
12751275
properties.put(OPENAPI_NULLABLE, "true");
1276-
1276+
12771277
File output = Files.createTempDirectory("test").toFile();
1278-
1278+
12791279
final CodegenConfigurator configurator = new CodegenConfigurator()
12801280
.setGeneratorName("jaxrs-spec")
12811281
.setAdditionalProperties(properties)
12821282
.setInputSpec("src/test/resources/bugs/issue_23251.yaml")
12831283
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
1284-
1284+
12851285
final ClientOptInput clientOptInput = configurator.toClientOptInput();
12861286
DefaultGenerator generator = new DefaultGenerator();
12871287
List<File> files = generator.opts(clientOptInput).generate();
1288-
1288+
12891289
validateJavaSourceFiles(files);
1290-
1290+
12911291
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/model/BugResponse.java");
1292-
1292+
12931293
// Assert that the generated model contains JsonNullable fields
12941294
assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/model/BugResponse.java"),
12951295
"private JsonNullable<String> nullableField = JsonNullable.<String>undefined();",
12961296
"private JsonNullable<List<String>> nullableList = JsonNullable.<List<String>>undefined();",
12971297
"private JsonNullable<List<@Valid NestedResponse>> nullableObjectList = JsonNullable.<List<@Valid NestedResponse>>undefined();"
12981298
);
1299-
1299+
13001300
// Assert that the generated model contains correct add and remove helper methods reference for JsonNullable fields
13011301
assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/model/BugResponse.java"),
13021302
"this.nullableList.get().add(nullableListItem);",
13031303
"this.nullableList.get().remove(nullableListItem);",
13041304
"this.nullableObjectList.get().add(nullableObjectListItem);",
13051305
"this.nullableObjectList.get().remove(nullableObjectListItem);");
1306-
1306+
1307+
output.deleteOnExit();
1308+
}
1309+
1310+
/**
1311+
* Verify that when using the quarkus library with interfaceOnly=true, the generated interface
1312+
* method is always annotated with {@code @ResponseStatus(<code>)} for any 2xx or 3xx response,
1313+
* including 200, for explicit documentation purposes.
1314+
* ping.yaml has a 201 response.
1315+
*/
1316+
@Test
1317+
public void generateQuarkusInterfaceAddsResponseStatusAnnotationForSuccessCode() throws Exception {
1318+
final File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
1319+
output.deleteOnExit();
1320+
1321+
final OpenAPI openAPI = new OpenAPIParser()
1322+
.readLocation("src/test/resources/3_0/ping.yaml", null, new ParseOptions()).getOpenAPI();
1323+
1324+
codegen.setOutputDir(output.getAbsolutePath());
1325+
codegen.setLibrary(QUARKUS_LIBRARY); //Given the quarkus library is used
1326+
codegen.additionalProperties().put(INTERFACE_ONLY, true); //And only interfaces are generated
1327+
// returnResponse and returnJBossResponse are both false (defaults)
1328+
1329+
final ClientOptInput input = new ClientOptInput()
1330+
.openAPI(openAPI)
1331+
.config(codegen);
1332+
1333+
final DefaultGenerator generator = new DefaultGenerator();
1334+
final List<File> files = generator.opts(input).generate();
1335+
1336+
validateJavaSourceFiles(files);
1337+
1338+
//Then the generated interface contains the ResponseStatus import and annotation with code 201
1339+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/PingApi.java");
1340+
assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/api/PingApi.java"),
1341+
"import org.jboss.resteasy.reactive.ResponseStatus;",
1342+
"@ResponseStatus(201)");
1343+
}
1344+
1345+
/**
1346+
* Verify that {@code @ResponseStatus(200)} IS emitted even for the default 200 status code,
1347+
* for explicit documentation purposes.
1348+
*/
1349+
@Test
1350+
public void generateQuarkusInterfaceAddsResponseStatusAnnotationFor200Response() throws Exception {
1351+
final File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
1352+
output.deleteOnExit();
1353+
1354+
final OpenAPI openAPI = new OpenAPIParser()
1355+
.readLocation("src/test/resources/3_0/petstore.yaml", null, new ParseOptions()).getOpenAPI();
1356+
1357+
codegen.setOutputDir(output.getAbsolutePath());
1358+
codegen.setLibrary(QUARKUS_LIBRARY);
1359+
codegen.additionalProperties().put(INTERFACE_ONLY, true);
1360+
1361+
final ClientOptInput input = new ClientOptInput()
1362+
.openAPI(openAPI)
1363+
.config(codegen);
1364+
1365+
final DefaultGenerator generator = new DefaultGenerator();
1366+
final List<File> files = generator.opts(input).generate();
1367+
1368+
validateJavaSourceFiles(files);
1369+
1370+
//Then @ResponseStatus(200) IS present for explicit documentation
1371+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/PetApi.java");
1372+
assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/api/PetApi.java"),
1373+
"import org.jboss.resteasy.reactive.ResponseStatus;",
1374+
"@ResponseStatus(200)");
1375+
}
1376+
1377+
/**
1378+
* Verify that the {@code @ResponseStatus} annotation is NOT emitted when returnResponse=true,
1379+
* because the user controls the status code via the {@code Response} builder in that mode.
1380+
*/
1381+
@Test
1382+
public void generateQuarkusInterfaceDoesNotAddResponseStatusAnnotationWhenReturnResponse() throws Exception {
1383+
final File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
1384+
output.deleteOnExit();
1385+
1386+
final OpenAPI openAPI = new OpenAPIParser()
1387+
.readLocation("src/test/resources/3_0/ping.yaml", null, new ParseOptions()).getOpenAPI();
1388+
1389+
codegen.setOutputDir(output.getAbsolutePath());
1390+
codegen.setLibrary(QUARKUS_LIBRARY);
1391+
codegen.additionalProperties().put(INTERFACE_ONLY, true);
1392+
codegen.additionalProperties().put(RETURN_RESPONSE, true); //Given returnResponse is true
1393+
1394+
final ClientOptInput input = new ClientOptInput()
1395+
.openAPI(openAPI)
1396+
.config(codegen);
1397+
1398+
final DefaultGenerator generator = new DefaultGenerator();
1399+
final List<File> files = generator.opts(input).generate();
1400+
1401+
validateJavaSourceFiles(files);
1402+
1403+
//Then the annotation must NOT appear
1404+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/PingApi.java");
1405+
assertFileNotContains(output.toPath().resolve("src/gen/java/org/openapitools/api/PingApi.java"),
1406+
"@ResponseStatus",
1407+
"import org.jboss.resteasy.reactive.ResponseStatus");
1408+
}
1409+
1410+
/**
1411+
* Verify that when using the quarkus library with interfaceOnly=true and a 3xx response,
1412+
* the generated interface method is annotated with {@code @ResponseStatus(<code>)}.
1413+
*/
1414+
@Test
1415+
public void generateQuarkusInterfaceAddsResponseStatusAnnotationFor3xxResponseCode() throws Exception {
1416+
final File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
13071417
output.deleteOnExit();
1418+
1419+
final OpenAPI openAPI = new OpenAPIParser()
1420+
.readLocation("src/test/resources/3_0/jaxrs-spec-quarkus-redirect.yaml", null, new ParseOptions()).getOpenAPI();
1421+
1422+
codegen.setOutputDir(output.getAbsolutePath());
1423+
codegen.setLibrary(QUARKUS_LIBRARY);
1424+
codegen.additionalProperties().put(INTERFACE_ONLY, true);
1425+
1426+
final ClientOptInput input = new ClientOptInput()
1427+
.openAPI(openAPI)
1428+
.config(codegen);
1429+
1430+
final DefaultGenerator generator = new DefaultGenerator();
1431+
final List<File> files = generator.opts(input).generate();
1432+
1433+
validateJavaSourceFiles(files);
1434+
1435+
//Then the generated interface contains the ResponseStatus import and annotation with code 302
1436+
TestUtils.ensureContainsFile(files, output, "src/gen/java/org/openapitools/api/RedirectApi.java");
1437+
assertFileContains(output.toPath().resolve("src/gen/java/org/openapitools/api/RedirectApi.java"),
1438+
"import org.jboss.resteasy.reactive.ResponseStatus;",
1439+
"@ResponseStatus(302)");
13081440
}
13091441

13101442
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
openapi: 3.0.1
2+
info:
3+
title: redirect test
4+
version: '1.0'
5+
servers:
6+
- url: 'http://localhost:8000/'
7+
paths:
8+
/redirect:
9+
get:
10+
operationId: redirectGet
11+
responses:
12+
'302':
13+
description: Temporary Redirect
14+
headers:
15+
Location:
16+
schema:
17+
type: string
18+

samples/server/petstore/jaxrs-spec-microprofile-openapi-annotations/src/gen/java/org/openapitools/api/PetApi.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212

1313

14+
1415
import java.io.InputStream;
1516
import java.util.Map;
1617
import java.util.List;
@@ -72,6 +73,7 @@ public Response addPet(@Valid @NotNull Pet pet) {
7273
return Response.ok().entity("magic!").build();
7374
}
7475

76+
7577
@DELETE
7678
@Path("/{petId}")
7779
@org.eclipse.microprofile.openapi.annotations.security.SecurityRequirements(value={
@@ -88,6 +90,7 @@ public Response deletePet(@PathParam("petId") @org.eclipse.microprofile.openapi.
8890
return Response.ok().entity("magic!").build();
8991
}
9092

93+
9194
@GET
9295
@Path("/findByStatus")
9396
@Produces({ "application/xml", "application/json" })
@@ -110,6 +113,7 @@ public Response findPetsByStatus(@QueryParam("status") @NotNull @org.eclipse.mi
110113
return Response.ok().entity("magic!").build();
111114
}
112115

116+
113117
@GET
114118
@Path("/findByTags")
115119
@Produces({ "application/xml", "application/json" })
@@ -132,6 +136,7 @@ public Response findPetsByTags(@QueryParam("tags") @NotNull @org.eclipse.microp
132136
return Response.ok().entity("magic!").build();
133137
}
134138

139+
135140
@GET
136141
@Path("/{petId}")
137142
@Produces({ "application/xml", "application/json" })
@@ -158,6 +163,7 @@ public Response getPetById(@PathParam("petId") @org.eclipse.microprofile.openapi
158163
return Response.ok().entity("magic!").build();
159164
}
160165

166+
161167
@PUT
162168
@Consumes({ "application/json", "application/xml" })
163169
@Produces({ "application/xml", "application/json" })
@@ -188,6 +194,7 @@ public Response updatePet(@Valid @NotNull Pet pet) {
188194
return Response.ok().entity("magic!").build();
189195
}
190196

197+
191198
@POST
192199
@Path("/{petId}")
193200
@Consumes({ "application/x-www-form-urlencoded" })
@@ -205,6 +212,7 @@ public Response updatePetWithForm(@PathParam("petId") @org.eclipse.microprofile.
205212
return Response.ok().entity("magic!").build();
206213
}
207214

215+
208216
@POST
209217
@Path("/{petId}/uploadImage")
210218
@Consumes({ "multipart/form-data" })
@@ -222,4 +230,5 @@ public Response updatePetWithForm(@PathParam("petId") @org.eclipse.microprofile.
222230
public Response uploadFile(@PathParam("petId") @org.eclipse.microprofile.openapi.annotations.parameters.Parameter(description="ID of pet to update") Long petId,@FormParam(value = "additionalMetadata") String additionalMetadata, @FormParam(value = "file") InputStream _fileInputStream) {
223231
return Response.ok().entity("magic!").build();
224232
}
233+
225234
}

samples/server/petstore/jaxrs-spec-microprofile-openapi-annotations/src/gen/java/org/openapitools/api/StoreApi.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111

1212

13+
1314
import java.io.InputStream;
1415
import java.util.Map;
1516
import java.util.List;
@@ -66,6 +67,7 @@ public Response deleteOrder(@PathParam("orderId") @org.eclipse.microprofile.open
6667
return Response.ok().entity("magic!").build();
6768
}
6869

70+
6971
@GET
7072
@Path("/inventory")
7173
@Produces({ "application/json" })
@@ -83,6 +85,7 @@ public Response getInventory() {
8385
return Response.ok().entity("magic!").build();
8486
}
8587

88+
8689
@GET
8790
@Path("/order/{orderId}")
8891
@Produces({ "application/xml", "application/json" })
@@ -107,6 +110,7 @@ public Response getOrderById(@PathParam("orderId") @Min(1L) @Max(5L) @org.eclips
107110
return Response.ok().entity("magic!").build();
108111
}
109112

113+
110114
@POST
111115
@Path("/order")
112116
@Consumes({ "application/json" })
@@ -127,4 +131,5 @@ public Response getOrderById(@PathParam("orderId") @Min(1L) @Max(5L) @org.eclips
127131
public Response placeOrder(@Valid @NotNull Order order) {
128132
return Response.ok().entity("magic!").build();
129133
}
134+
130135
}

0 commit comments

Comments
 (0)