From 4e4ea0e13334098f3fb0bd56490387153f77a208 Mon Sep 17 00:00:00 2001 From: Andriy Dmytruk Date: Sun, 2 Jul 2023 04:40:33 -0400 Subject: [PATCH 1/2] Improve return type wrapping: - Add an option to generate HttpResponse only where it is required - Use Flux for list return types when reactive = true --- .../AbstractMicronautJavaCodegen.java | 100 +++++++++++++----- .../MicronautCodeGeneratorEntryPoint.java | 20 ++-- .../MicronautCodeGeneratorOptionsBuilder.java | 16 ++- .../java-micronaut/client/api.mustache | 2 +- .../common/operationReturnType.mustache | 12 --- .../server/controller-implementation.mustache | 2 +- .../server/controller-interface.mustache | 2 +- .../generator/MicronautServerCodegenTest.java | 8 +- test-suite-server-generator/build.gradle | 7 +- test-suite-server-generator/spec.yaml | 2 +- .../test/api/RequestBodyController.java | 9 +- .../test/api/ResponseBodyController.java | 18 ++-- .../test/dated/DatedResponseBodyWriter.java | 4 +- .../api/ResponseBodyControllerSpec.groovy | 19 ++-- 14 files changed, 145 insertions(+), 76 deletions(-) delete mode 100644 openapi-generator/src/main/resources/templates/java-micronaut/common/operationReturnType.mustache diff --git a/openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java b/openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java index 2604372927..e4e735fd67 100644 --- a/openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java +++ b/openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java @@ -79,7 +79,8 @@ public abstract class AbstractMicronautJavaCodegen imports) { return parameter; } - @Override - public boolean getUseInlineModelResolver() { - // This will allow TODO - return false; - } - @Override public CodegenOperation fromOperation( String path, String httpMethod, Operation operation, List servers @@ -626,6 +630,7 @@ public CodegenOperation fromOperation( op.vendorExtensions.put("originReturnProperty", op.returnProperty); processParametersWithAdditionalMappings(op.allParams, op.imports); processWithResponseBodyMapping(op); + processOperationWithResponseWrappers(op); return op; } @@ -699,23 +704,64 @@ private void processWithResponseBodyMapping(CodegenOperation op) { } if (bodyMapping != null) { - CodegenProperty newProperty = new CodegenProperty(); - newProperty.required = true; - newProperty.isModel = bodyMapping.isValidated; + wrapOperationReturnType(op, bodyMapping.mappedBodyType, + bodyMapping.isValidated, bodyMapping.isListWrapper); + } + } + + /** + * Wrap the return type of operation in the provided type. + * + * @param op The operation to modify. + * @param wrapperType The wrapper type. + * @param isValidated Whether the wrapper requires validation. + * @param isListWrapper Whether the wrapper should be around list items. + */ + private void wrapOperationReturnType( + CodegenOperation op, String wrapperType, boolean isValidated, boolean isListWrapper + ) { + CodegenProperty newReturnType = new CodegenProperty(); + newReturnType.required = true; + newReturnType.isModel = isValidated; - String typeName = makeSureImported(bodyMapping.mappedBodyType(), op.imports); + String typeName = makeSureImported(wrapperType, op.imports); - if (bodyMapping.isListWrapper) { - newProperty.dataType = typeName + '<' + op.returnBaseType + '>'; - newProperty.items = op.returnProperty.items; + if (isListWrapper && op.isArray && op.returnProperty.items != null) { + newReturnType.dataType = typeName + '<' + op.returnBaseType + '>'; + newReturnType.items = op.returnProperty.items; + } else { + String originalReturnType = op.returnType; + if (originalReturnType == null) { + originalReturnType = "Void"; + op.returnProperty = new CodegenProperty(); + op.returnProperty.dataType = "Void"; + } + newReturnType.dataType = typeName + '<' + originalReturnType + '>'; + newReturnType.items = op.returnProperty; + } + + op.returnType = newReturnType.dataType; + op.returnContainer = null; + op.returnProperty = newReturnType; + op.isArray = op.returnProperty.isArray; + } + + private void processOperationWithResponseWrappers(CodegenOperation op) { + if (reactive) { + if (op.isArray) { + wrapOperationReturnType(op, "reactor.core.publisher.Flux", false, true); } else { - newProperty.dataType = typeName + '<' + op.returnType + '>'; - newProperty.items = op.returnProperty; + wrapOperationReturnType(op, "reactor.core.publisher.Mono", false, false); } + } - op.returnType = newProperty.dataType; - op.returnContainer = null; - op.returnProperty = newProperty; + boolean hasNon200StatusCodes = op.responses.stream().anyMatch( + response -> !"200".equals(response.code) && response.code.startsWith("2") + ); + boolean hasNonMappedHeaders = !op.responseHeaders.isEmpty(); + boolean requiresHttpResponse = hasNon200StatusCodes || hasNonMappedHeaders; + if (generateHttpResponseAlways || (generateHttpResponseWhereRequired && requiresHttpResponse)) { + wrapOperationReturnType(op, "io.micronaut.http.HttpResponse", false, false); } } diff --git a/openapi-generator/src/main/java/io/micronaut/openapi/generator/MicronautCodeGeneratorEntryPoint.java b/openapi-generator/src/main/java/io/micronaut/openapi/generator/MicronautCodeGeneratorEntryPoint.java index 658fa8a823..1f0b433495 100644 --- a/openapi-generator/src/main/java/io/micronaut/openapi/generator/MicronautCodeGeneratorEntryPoint.java +++ b/openapi-generator/src/main/java/io/micronaut/openapi/generator/MicronautCodeGeneratorEntryPoint.java @@ -126,7 +126,7 @@ private void configureOptions() { codeGenerator.addResponseBodyMappings(options.responseBodyMappings); } codeGenerator.setReactive(options.reactive); - codeGenerator.setWrapInHttpResponse(options.wrapInHttpResponse); + codeGenerator.setGenerateHttpResponseAlways(options.generateHttpResponseAlways); codeGenerator.setUseOptional(options.optional); codeGenerator.setUseBeanValidation(options.beanValidation); codeGenerator.setTestTool(options.testFramework.value); @@ -301,7 +301,8 @@ private static class DefaultOptionsBuilder implements MicronautCodeGeneratorOpti private List responseBodyMappings; private boolean optional = false; private boolean reactive = true; - private boolean wrapInHttpResponse; + private boolean generateHttpResponseAlways; + private boolean generateHttpResponseWhereRequired; private TestFramework testFramework = TestFramework.JUNIT5; private SerializationLibraryKind serializationLibraryKind = SerializationLibraryKind.MICRONAUT_SERDE_JACKSON; private DateTimeFormat dateTimeFormat = DateTimeFormat.ZONED_DATETIME; @@ -349,8 +350,14 @@ public MicronautCodeGeneratorOptionsBuilder withReactive(boolean reactive) { } @Override - public MicronautCodeGeneratorOptionsBuilder withWrapInHttpResponse(boolean wrapInHttpResponse) { - this.wrapInHttpResponse = wrapInHttpResponse; + public MicronautCodeGeneratorOptionsBuilder withGenerateHttpResponseAlways(boolean generateHttpResponseAlways) { + this.generateHttpResponseAlways = generateHttpResponseAlways; + return this; + } + + @Override + public MicronautCodeGeneratorOptionsBuilder withGenerateHttpResponseWhereRequired(boolean generateHttpResponseWhereRequired) { + this.generateHttpResponseWhereRequired = generateHttpResponseWhereRequired; return this; } @@ -385,7 +392,7 @@ public MicronautCodeGeneratorOptionsBuilder withDateTimeFormat(DateTimeFormat fo } private Options build() { - return new Options(apiPackage, modelPackage, invokerPackage, artifactId, parameterMappings, responseBodyMappings, beanValidation, optional, reactive, wrapInHttpResponse, testFramework, serializationLibraryKind, dateTimeFormat); + return new Options(apiPackage, modelPackage, invokerPackage, artifactId, parameterMappings, responseBodyMappings, beanValidation, optional, reactive, generateHttpResponseAlways, generateHttpResponseWhereRequired, testFramework, serializationLibraryKind, dateTimeFormat); } } } @@ -415,7 +422,8 @@ private record Options( boolean beanValidation, boolean optional, boolean reactive, - boolean wrapInHttpResponse, + boolean generateHttpResponseAlways, + boolean generateHttpResponseWhereRequired, TestFramework testFramework, SerializationLibraryKind serializationLibraryKind, MicronautCodeGeneratorOptionsBuilder.DateTimeFormat dateTimeFormat diff --git a/openapi-generator/src/main/java/io/micronaut/openapi/generator/MicronautCodeGeneratorOptionsBuilder.java b/openapi-generator/src/main/java/io/micronaut/openapi/generator/MicronautCodeGeneratorOptionsBuilder.java index ecf286873f..3bb44a0075 100644 --- a/openapi-generator/src/main/java/io/micronaut/openapi/generator/MicronautCodeGeneratorOptionsBuilder.java +++ b/openapi-generator/src/main/java/io/micronaut/openapi/generator/MicronautCodeGeneratorOptionsBuilder.java @@ -81,12 +81,20 @@ public interface MicronautCodeGeneratorOptionsBuilder { MicronautCodeGeneratorOptionsBuilder withReactive(boolean reactive); /** - * If true, the generated client will use responses wrapped in HttpResponse. + * If true, the generated operation return types will be wrapped in HttpResponse. * - * @param wrapInHttpResponse the wrapping flag + * @param generateHttpResponseAlways the wrapping flag * @return this builder */ - MicronautCodeGeneratorOptionsBuilder withWrapInHttpResponse(boolean wrapInHttpResponse); + MicronautCodeGeneratorOptionsBuilder withGenerateHttpResponseAlways(boolean generateHttpResponseAlways); + + /** + * Wrap the operations response in HttpResponse object where non-200 HTTP status codes or additional headers are defined. + * + * @param generateHttpResponseWhereRequired the wrapping flag + * @return this builder + */ + MicronautCodeGeneratorOptionsBuilder withGenerateHttpResponseWhereRequired(boolean generateHttpResponseWhereRequired); /** * If set to true, the generated code will use bean validation. @@ -134,7 +142,7 @@ public interface MicronautCodeGeneratorOptionsBuilder { enum DateTimeFormat { OFFSET_DATETIME, ZONED_DATETIME, - LOCAL_DATETIME; + LOCAL_DATETIME } } diff --git a/openapi-generator/src/main/resources/templates/java-micronaut/client/api.mustache b/openapi-generator/src/main/resources/templates/java-micronaut/client/api.mustache index a9f605af09..d044d4ca06 100644 --- a/openapi-generator/src/main/resources/templates/java-micronaut/client/api.mustache +++ b/openapi-generator/src/main/resources/templates/java-micronaut/client/api.mustache @@ -67,7 +67,7 @@ public interface {{classname}} { {{/authMethods}} {{/configureAuth}} {{!the method definition}} - {{>common/operationReturnType}} {{nickname}}({{#allParams}} + {{^returnType}}void{{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}} {{nickname}}({{#allParams}} {{#formatSingleLine}}{{>client/params/queryParams}}{{>client/params/pathParams}}{{>client/params/headerParams}}{{>client/params/bodyParams}}{{>client/params/formParams}}{{>client/params/cookieParams}}{{^-last}},{{/-last}}{{/formatSingleLine}} {{/allParams}}); {{/formatNoEmptyLines}} diff --git a/openapi-generator/src/main/resources/templates/java-micronaut/common/operationReturnType.mustache b/openapi-generator/src/main/resources/templates/java-micronaut/common/operationReturnType.mustache deleted file mode 100644 index 6a4b4a175d..0000000000 --- a/openapi-generator/src/main/resources/templates/java-micronaut/common/operationReturnType.mustache +++ /dev/null @@ -1,12 +0,0 @@ -{{!begin reactive -}}{{#reactive}}Mono<{{/reactive}}{{! -begin wrapInHttpResponse -}}{{#wrapInHttpResponse}}HttpResponse<{{/wrapInHttpResponse}}{{! -return type -}}{{#returnType}}{{{returnType}}}{{/returnType}}{{! -no return type -}}{{^returnType}}{{#reactive}}Void{{/reactive}}{{^reactive}}{{#wrapInHttpResponse}}Void{{/wrapInHttpResponse}}{{/reactive}}{{^reactive}}{{^wrapInHttpResponse}}void{{/wrapInHttpResponse}}{{/reactive}}{{/returnType}}{{! -end wrapInHttpResponse -}}{{#wrapInHttpResponse}}>{{/wrapInHttpResponse}}{{! -end reactive -}}{{#reactive}}>{{/reactive}} \ No newline at end of file diff --git a/openapi-generator/src/main/resources/templates/java-micronaut/server/controller-implementation.mustache b/openapi-generator/src/main/resources/templates/java-micronaut/server/controller-implementation.mustache index c0118fa990..c20a837a4c 100644 --- a/openapi-generator/src/main/resources/templates/java-micronaut/server/controller-implementation.mustache +++ b/openapi-generator/src/main/resources/templates/java-micronaut/server/controller-implementation.mustache @@ -31,7 +31,7 @@ public class {{controllerClassname}} implements {{classname}} { {{#operation}} {{!the method definition}} @Override - public {{>common/operationReturnType}} {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) { + public {{^returnType}}void{{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}} {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) { {{>server/controllerOperationBody}} } {{^-last}} diff --git a/openapi-generator/src/main/resources/templates/java-micronaut/server/controller-interface.mustache b/openapi-generator/src/main/resources/templates/java-micronaut/server/controller-interface.mustache index efc7a800be..acb1dcc5bc 100644 --- a/openapi-generator/src/main/resources/templates/java-micronaut/server/controller-interface.mustache +++ b/openapi-generator/src/main/resources/templates/java-micronaut/server/controller-interface.mustache @@ -73,7 +73,7 @@ public interface {{classname}} { @Secured({{openbrace}}{{#vendorExtensions.x-roles}}{{{.}}}{{^-last}}, {{/-last}}{{/vendorExtensions.x-roles}}{{closebrace}}) {{/useAuth}} {{!the method definition}} - {{>common/operationReturnType}} {{nickname}}({{#allParams}} + {{^returnType}}void{{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}} {{nickname}}({{#allParams}} {{#indent}} {{>common/params/validation}} {{/indent}} diff --git a/openapi-generator/src/test/java/io/micronaut/openapi/generator/MicronautServerCodegenTest.java b/openapi-generator/src/test/java/io/micronaut/openapi/generator/MicronautServerCodegenTest.java index cf010e362a..9146c861f4 100644 --- a/openapi-generator/src/test/java/io/micronaut/openapi/generator/MicronautServerCodegenTest.java +++ b/openapi-generator/src/test/java/io/micronaut/openapi/generator/MicronautServerCodegenTest.java @@ -211,7 +211,7 @@ void generateAuthRolesWithExtension() { void doGenerateMonoWrapHttpResponse() { JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen(); codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_REACTIVE, "true"); - codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_WRAP_IN_HTTP_RESPONSE, "true"); + codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_GENERATE_HTTP_RESPONSE_ALWAYS, "true"); String outputPath = generateFiles(codegen, PETSTORE_PATH, CodegenConstants.MODELS, CodegenConstants.APIS); String apiPath = outputPath + "src/main/java/org/openapitools/api/"; @@ -222,7 +222,7 @@ void doGenerateMonoWrapHttpResponse() { void doGenerateMono() { JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen(); codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_REACTIVE, "true"); - codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_WRAP_IN_HTTP_RESPONSE, "false"); + codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_GENERATE_HTTP_RESPONSE_ALWAYS, "false"); String outputPath = generateFiles(codegen, PETSTORE_PATH, CodegenConstants.MODELS, CodegenConstants.APIS); String apiPath = outputPath + "src/main/java/org/openapitools/api/"; @@ -234,7 +234,7 @@ void doGenerateMono() { void doGenerateWrapHttpResponse() { JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen(); codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_REACTIVE, "false"); - codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_WRAP_IN_HTTP_RESPONSE, "true"); + codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_GENERATE_HTTP_RESPONSE_ALWAYS, "true"); String outputPath = generateFiles(codegen, PETSTORE_PATH, CodegenConstants.MODELS, CodegenConstants.APIS); String apiPath = outputPath + "src/main/java/org/openapitools/api/"; @@ -246,7 +246,7 @@ void doGenerateWrapHttpResponse() { void doGenerateNoMonoNoWrapHttpResponse() { JavaMicronautServerCodegen codegen = new JavaMicronautServerCodegen(); codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_REACTIVE, "false"); - codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_WRAP_IN_HTTP_RESPONSE, "false"); + codegen.additionalProperties().put(JavaMicronautServerCodegen.OPT_GENERATE_HTTP_RESPONSE_ALWAYS, "false"); String outputPath = generateFiles(codegen, PETSTORE_PATH, CodegenConstants.MODELS, CodegenConstants.APIS); String apiPath = outputPath + "src/main/java/org/openapitools/api/"; diff --git a/test-suite-server-generator/build.gradle b/test-suite-server-generator/build.gradle index 452f1d64a7..ef17665bc2 100644 --- a/test-suite-server-generator/build.gradle +++ b/test-suite-server-generator/build.gradle @@ -54,6 +54,11 @@ tasks.named("generateOpenApi") { // Response with Last-Modified header mapping [headerName: "Last-Modified", mappedBodyType: "io.micronaut.openapi.test.dated.DatedResponse"], // Response with Page body - [headerName: "X-Page-Number", mappedBodyType: "io.micronaut.data.model.Page", isListWrapper: true] + [headerName: "X-Page-Number", mappedBodyType: "io.micronaut.data.model.Page", isListWrapper: true], + [headerName: "X-Page-Count", mappedBodyType: "io.micronaut.data.model.Page", isListWrapper: true], + [headerName: "X-Total-Count", mappedBodyType: "io.micronaut.data.model.Page", isListWrapper: true], + [headerName: "X-Page-Size", mappedBodyType: "io.micronaut.data.model.Page", isListWrapper: true], + // Ignored header - Does not wrap the response in HttpResponse + [headerName: "ignored-header"] ] } diff --git a/test-suite-server-generator/spec.yaml b/test-suite-server-generator/spec.yaml index 5a3ca46e8d..316fb452f5 100644 --- a/test-suite-server-generator/spec.yaml +++ b/test-suite-server-generator/spec.yaml @@ -529,7 +529,7 @@ paths: tags: [ responseBody ] description: A method to get a simple model as a response responses: - 202: + 201: description: Success content: application/json: diff --git a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/RequestBodyController.java b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/RequestBodyController.java index 212b632dbc..b373805476 100644 --- a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/RequestBodyController.java +++ b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/RequestBodyController.java @@ -13,6 +13,7 @@ import io.micronaut.http.annotation.Post; import io.micronaut.http.multipart.CompletedFileUpload; import jakarta.validation.Valid; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.io.ByteArrayOutputStream; @@ -38,8 +39,8 @@ public Mono sendSimpleModel(SimpleModel simpleModel) { } @Override - public Mono> sendListOfSimpleModels(List simpleModels) { - return Mono.just(simpleModels); + public Flux sendListOfSimpleModels(List simpleModels) { + return Flux.fromIterable(simpleModels); } @Override @@ -58,9 +59,9 @@ public Mono sendEnum(String color) { } @Override - public Mono> sendEnumList( + public Flux sendEnumList( List<@Valid ColorEnum> availableColors) { - return Mono.just(availableColors); + return Flux.fromIterable(availableColors); } @Override diff --git a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/ResponseBodyController.java b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/ResponseBodyController.java index 76230790ef..15000998fe 100644 --- a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/ResponseBodyController.java +++ b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/ResponseBodyController.java @@ -1,9 +1,9 @@ package io.micronaut.openapi.test.api; +import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; import io.micronaut.data.model.Page; import io.micronaut.data.model.Pageable; -import io.micronaut.http.multipart.CompletedFileUpload; import io.micronaut.http.server.types.files.FileCustomizableResponseType; import io.micronaut.http.server.types.files.StreamedFile; import io.micronaut.openapi.test.model.DateModel; @@ -81,18 +81,22 @@ public Mono> getDatedSimpleModel() { } @Override - public Mono getSimpleModelWithNonStandardStatus() { - return Mono.just(SIMPLE_MODEL); + public HttpResponse> getSimpleModelWithNonStandardStatus() { + return HttpResponse.created(Mono.just(SIMPLE_MODEL)); } @Override - public Mono> getDatedSimpleModelWithNonMappedHeader() { - return Mono.just(DatedResponse.of(SIMPLE_MODEL)); + public HttpResponse>> getDatedSimpleModelWithNonMappedHeader() { + DatedResponse datedResponse = DatedResponse.of(SIMPLE_MODEL) + .withLastModified(LAST_MODIFIED_DATE); + return HttpResponse.ok(Mono.just(datedResponse)) + .header("custom-header", "custom-value"); } @Override - public Mono getSimpleModelWithNonMappedHeader() { - return Mono.just(SIMPLE_MODEL); + public HttpResponse> getSimpleModelWithNonMappedHeader() { + return HttpResponse.ok(Mono.just(SIMPLE_MODEL)) + .header("custom-header", "custom-value-2"); } @Override diff --git a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/dated/DatedResponseBodyWriter.java b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/dated/DatedResponseBodyWriter.java index e00d2b25b1..0a9f75e637 100644 --- a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/dated/DatedResponseBodyWriter.java +++ b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/dated/DatedResponseBodyWriter.java @@ -67,7 +67,9 @@ public void writeTo( OutputStream outputStream ) throws CodecException { if (bodyType != null && bodyWriter != null) { - headers.add(LAST_MODIFIED_HEADER, dated.getLastModified().toString()); + if (dated.getLastModified() != null) { + headers.add(LAST_MODIFIED_HEADER, dated.getLastModified().toString()); + } bodyWriter.writeTo(bodyType, mediaType, dated.getBody(), headers, outputStream); } else { throw new ConfigurationException("No JSON message writer present"); diff --git a/test-suite-server-generator/src/test/groovy/io/micronaut/openapi/test/api/ResponseBodyControllerSpec.groovy b/test-suite-server-generator/src/test/groovy/io/micronaut/openapi/test/api/ResponseBodyControllerSpec.groovy index 19a3aa8808..510d5477c7 100644 --- a/test-suite-server-generator/src/test/groovy/io/micronaut/openapi/test/api/ResponseBodyControllerSpec.groovy +++ b/test-suite-server-generator/src/test/groovy/io/micronaut/openapi/test/api/ResponseBodyControllerSpec.groovy @@ -107,26 +107,33 @@ class ResponseBodyControllerSpec extends Specification { } void "test get simple model with non standard status"() { + when: HttpResponse response = client.exchange("/getSimpleModelWithNonStandardStatus", SimpleModel) - HttpStatus.ACCEPTED == response.status() + then: + HttpStatus.CREATED == response.status() ResponseBodyController.SIMPLE_MODEL == response.body() } - // TODO implement the behavior and test - void "test get dated simple model with non standard headers"() { + void "test get dated simple model with non mapped header"() { + when: HttpResponse response = client.exchange( - HttpRequest.GET("/getTaggedSimpleModelWithNonStandardHeaders"), Argument.of(SimpleModel)) + HttpRequest.GET("/getDatedSimpleModelWithNonMappedHeader"), Argument.of(SimpleModel)) + then: HttpStatus.OK == response.status ResponseBodyController.SIMPLE_MODEL == response.body() + "custom-value" == response.header("custom-header") + ResponseBodyController.LAST_MODIFIED_STRING == response.header("Last-Modified") } void "test get simple model with non mapped header"() { - HttpResponse response = client.exchange("/getSimpleModelWithNonStandardHeader", SimpleModel) + when: + HttpResponse response = client.exchange("/getSimpleModelWithNonMappedHeader", SimpleModel) + then: HttpStatus.OK == response.status - "simple model" == response.headers.get("custom-header") + "custom-value-2" == response.headers.get("custom-header") ResponseBodyController.SIMPLE_MODEL == response.body() } From 258b97805c4a60f69f60f94e0a93b5cf627ac7cd Mon Sep 17 00:00:00 2001 From: Andriy Dmytruk Date: Tue, 4 Jul 2023 17:35:29 -0400 Subject: [PATCH 2/2] Implement review comments --- .../generator/AbstractMicronautJavaCodegen.java | 12 ++++-------- .../openapi/test/api/RequestBodyController.java | 8 ++++---- .../openapi/test/api/ResponseBodyController.java | 16 ++++++++-------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java b/openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java index e4e735fd67..a9cc2d41d7 100644 --- a/openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java +++ b/openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java @@ -747,14 +747,6 @@ private void wrapOperationReturnType( } private void processOperationWithResponseWrappers(CodegenOperation op) { - if (reactive) { - if (op.isArray) { - wrapOperationReturnType(op, "reactor.core.publisher.Flux", false, true); - } else { - wrapOperationReturnType(op, "reactor.core.publisher.Mono", false, false); - } - } - boolean hasNon200StatusCodes = op.responses.stream().anyMatch( response -> !"200".equals(response.code) && response.code.startsWith("2") ); @@ -763,6 +755,10 @@ private void processOperationWithResponseWrappers(CodegenOperation op) { if (generateHttpResponseAlways || (generateHttpResponseWhereRequired && requiresHttpResponse)) { wrapOperationReturnType(op, "io.micronaut.http.HttpResponse", false, false); } + + if (reactive) { + wrapOperationReturnType(op, "reactor.core.publisher.Mono", false, false); + } } private String makeSureImported(String typeName, Set imports) { diff --git a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/RequestBodyController.java b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/RequestBodyController.java index b373805476..9d25633785 100644 --- a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/RequestBodyController.java +++ b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/RequestBodyController.java @@ -39,8 +39,8 @@ public Mono sendSimpleModel(SimpleModel simpleModel) { } @Override - public Flux sendListOfSimpleModels(List simpleModels) { - return Flux.fromIterable(simpleModels); + public Mono> sendListOfSimpleModels(List simpleModels) { + return Mono.just(simpleModels); } @Override @@ -59,9 +59,9 @@ public Mono sendEnum(String color) { } @Override - public Flux sendEnumList( + public Mono> sendEnumList( List<@Valid ColorEnum> availableColors) { - return Flux.fromIterable(availableColors); + return Mono.just(availableColors); } @Override diff --git a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/ResponseBodyController.java b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/ResponseBodyController.java index 15000998fe..614b5842d3 100644 --- a/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/ResponseBodyController.java +++ b/test-suite-server-generator/src/main/java/io/micronaut/openapi/test/api/ResponseBodyController.java @@ -81,22 +81,22 @@ public Mono> getDatedSimpleModel() { } @Override - public HttpResponse> getSimpleModelWithNonStandardStatus() { - return HttpResponse.created(Mono.just(SIMPLE_MODEL)); + public Mono> getSimpleModelWithNonStandardStatus() { + return Mono.just(HttpResponse.created(SIMPLE_MODEL)); } @Override - public HttpResponse>> getDatedSimpleModelWithNonMappedHeader() { + public Mono>> getDatedSimpleModelWithNonMappedHeader() { DatedResponse datedResponse = DatedResponse.of(SIMPLE_MODEL) .withLastModified(LAST_MODIFIED_DATE); - return HttpResponse.ok(Mono.just(datedResponse)) - .header("custom-header", "custom-value"); + return Mono.just(HttpResponse.ok(datedResponse) + .header("custom-header", "custom-value")); } @Override - public HttpResponse> getSimpleModelWithNonMappedHeader() { - return HttpResponse.ok(Mono.just(SIMPLE_MODEL)) - .header("custom-header", "custom-value-2"); + public Mono> getSimpleModelWithNonMappedHeader() { + return Mono.just(HttpResponse.ok(SIMPLE_MODEL) + .header("custom-header", "custom-value-2")); } @Override