Skip to content

Commit

Permalink
Merge pull request micronaut-projects#1913 from altro3/request-body-enum
Browse files Browse the repository at this point in the history
Fixed request body enum
  • Loading branch information
altro3 authored Dec 18, 2024
2 parents 0dcac7a + e86e456 commit aec11bd
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.parser.util.SchemaTypeUtil;
Expand Down Expand Up @@ -732,6 +733,62 @@ public String toModelTestFilename(String name) {
return toModelName(name) + "Test";
}

@Override
public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, String bodyParameterName) {
var rqBody = super.fromRequestBody(body, imports, bodyParameterName);

var rqBodySchema = body.getContent() != null && !body.getContent().isEmpty() ? body.getContent().entrySet().iterator().next().getValue().getSchema() : null;
CodegenProperty codegenProperty = fromProperty(bodyParameterName, rqBodySchema, false);

if (rqBodySchema != null) {
rqBodySchema = unaliasSchema(rqBodySchema);

if (getUseInlineModelResolver()) {
codegenProperty = fromProperty(bodyParameterName, getReferencedSchemaWhenNotEnum(rqBodySchema), false);
} else {
codegenProperty = fromProperty(bodyParameterName, rqBodySchema, false);
}
rqBody.setSchema(codegenProperty);
}

if (Boolean.TRUE.equals(codegenProperty.isModel)) {
rqBody.isModel = true;
}

rqBody.dataFormat = codegenProperty.dataFormat;
if (body.getRequired() != null) {
rqBody.required = body.getRequired();
}

// set containerType
rqBody.containerType = codegenProperty.containerType;
rqBody.containerTypeMapped = codegenProperty.containerTypeMapped;

// enum
updateCodegenPropertyEnum(codegenProperty);
rqBody.isEnum = codegenProperty.isEnum;
rqBody.isEnumRef = codegenProperty.isEnumRef;
rqBody._enum = codegenProperty._enum;
rqBody.allowableValues = codegenProperty.allowableValues;

if (codegenProperty.isEnum || codegenProperty.isEnumRef) {
rqBody.datatypeWithEnum = codegenProperty.datatypeWithEnum;
rqBody.enumName = codegenProperty.enumName;
if (codegenProperty.defaultValue != null) {
rqBody.enumDefaultValue = codegenProperty.defaultValue.replace(codegenProperty.enumName + ".", "");
}
}
return rqBody;
}

private Schema getReferencedSchemaWhenNotEnum(Schema parameterSchema) {
Schema referencedSchema = ModelUtils.getReferencedSchema(openAPI, parameterSchema);
if (referencedSchema.getEnum() != null && !referencedSchema.getEnum().isEmpty()) {
referencedSchema = parameterSchema;
}
return referencedSchema;
}

@Override
public CodegenParameter fromParameter(Parameter p, Set<String> imports) {
var parameter = super.fromParameter(p, imports);
Expand Down Expand Up @@ -816,7 +873,11 @@ public CodegenProperty fromProperty(String name, Schema schema, boolean required
property.vendorExtensions.put("realName", realName);

if (schema != null && schema.get$ref() != null) {
schema = ModelUtils.getSchemaFromRefToSchemaWithProperties(openAPI, schema.get$ref());
var refSchema = ModelUtils.getSchemaFromRefToSchemaWithProperties(openAPI, schema.get$ref());
if (refSchema == null) {
refSchema = ModelUtils.getReferencedSchema(openAPI, schema);
}
schema = refSchema;
}

String defaultValueInit;
Expand Down Expand Up @@ -1369,6 +1430,9 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
}

for (var param : op.allParams) {
if (param.isEnumRef) {
param.isEnum = true;
}
processGenericAnnotations(param, useBeanValidation, isGenerateHardNullable(), false, false, false, false);
if (useBeanValidation && !param.isContainer && param.isModel) {
param.vendorExtensions.put("withValid", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,9 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
}

for (var param : op.allParams) {
if (param.isEnumRef) {
param.isEnum = true;
}
processGenericAnnotations(param, useBeanValidation, false, param.isNullable || !param.required,
param.required, false, true);
param.vendorExtensions.put("isString", "string".equalsIgnoreCase(param.dataType));
Expand Down Expand Up @@ -1425,13 +1428,63 @@ public String toModelName(final String name) {
@Override
public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, String bodyParameterName) {
var rqBody = super.fromRequestBody(body, imports, bodyParameterName);

var rqBodySchema = body.getContent() != null && !body.getContent().isEmpty() ? body.getContent().entrySet().iterator().next().getValue().getSchema() : null;
CodegenProperty codegenProperty = fromProperty(bodyParameterName, rqBodySchema, false);

if (rqBodySchema != null) {
rqBodySchema = unaliasSchema(rqBodySchema);

if (getUseInlineModelResolver()) {
codegenProperty = fromProperty(bodyParameterName, getReferencedSchemaWhenNotEnum(rqBodySchema), false);
} else {
codegenProperty = fromProperty(bodyParameterName, rqBodySchema, false);
}
rqBody.setSchema(codegenProperty);
}

if (Boolean.TRUE.equals(codegenProperty.isModel)) {
rqBody.isModel = true;
}

rqBody.dataFormat = codegenProperty.dataFormat;
if (body.getRequired() != null) {
rqBody.required = body.getRequired();
}
if (!rqBody.required) {
rqBody.vendorExtensions.put("defaultValueInit", "null");
}

// set containerType
rqBody.containerType = codegenProperty.containerType;
rqBody.containerTypeMapped = codegenProperty.containerTypeMapped;

// enum
updateCodegenPropertyEnum(codegenProperty);
rqBody.isEnum = codegenProperty.isEnum;
rqBody.isEnumRef = codegenProperty.isEnumRef;
rqBody._enum = codegenProperty._enum;
rqBody.allowableValues = codegenProperty.allowableValues;

if (codegenProperty.isEnum || codegenProperty.isEnumRef) {
rqBody.datatypeWithEnum = codegenProperty.datatypeWithEnum;
rqBody.enumName = codegenProperty.enumName;
if (codegenProperty.defaultValue != null) {
rqBody.enumDefaultValue = codegenProperty.defaultValue.replace(codegenProperty.enumName + ".", "");
}
}

return rqBody;
}

private Schema getReferencedSchemaWhenNotEnum(Schema parameterSchema) {
Schema referencedSchema = ModelUtils.getReferencedSchema(openAPI, parameterSchema);
if (referencedSchema.getEnum() != null && !referencedSchema.getEnum().isEmpty()) {
referencedSchema = parameterSchema;
}
return referencedSchema;
}

@Override
public CodegenParameter fromParameter(Parameter p, Set<String> imports) {
var parameter = super.fromParameter(p, imports);
Expand Down Expand Up @@ -1512,7 +1565,11 @@ public CodegenProperty fromProperty(String name, Schema schema, boolean required
property.vendorExtensions.put("realName", realName);

if (schema != null && schema.get$ref() != null) {
schema = ModelUtils.getSchemaFromRefToSchemaWithProperties(openAPI, schema.get$ref());
var refSchema = ModelUtils.getSchemaFromRefToSchemaWithProperties(openAPI, schema.get$ref());
if (refSchema == null) {
refSchema = ModelUtils.getReferencedSchema(openAPI, schema);
}
schema = refSchema;
}

String defaultValueInit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class JavaMicronautClientCodegenTest extends AbstractMicronautCodegenTest {

@Test
void clientOptsUnicity() {
void clientOptsUniqueness() {
var codegen = new JavaMicronautClientCodegen();
codegen.cliOptions()
.stream()
Expand Down Expand Up @@ -1460,4 +1460,20 @@ public int hashCode() {
}
""");
}

@Test
void testBodyEnum() {

var codegen = new JavaMicronautClientCodegen();
String outputPath = generateFiles(codegen, "src/test/resources/3_0/body-enum.yml", CodegenConstants.APIS, CodegenConstants.MODELS);
String path = outputPath + "src/main/java/org/openapitools/";

assertFileContains(path + "api/MyCustomApi.java", """
@Post("/api/v1/colors/{name}")
Mono<@NotNull String> selectColor(
@Body @NotNull Color body
);
""");
assertFileContains(path + "model/Color.java", "public enum Color {");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class JavaMicronautServerCodegenTest extends AbstractMicronautCodegenTest {
static String MULTI_TAGS_TEST_PATH = "src/test/resources/3_0/micronaut/multi-tags-test.yaml";

@Test
void clientOptsUnicity() {
void clientOptsUniqueness() {
var codegen = new JavaMicronautServerCodegen();
codegen.cliOptions()
.stream()
Expand Down Expand Up @@ -717,4 +717,22 @@ void testSwaggerAnnotations() {
);
""");
}

@Test
void testBodyEnum() {

var codegen = new JavaMicronautServerCodegen();
codegen.setGenerateSwaggerAnnotations(false);
codegen.setUseAuth(false);
String outputPath = generateFiles(codegen, "src/test/resources/3_0/body-enum.yml", CodegenConstants.APIS, CodegenConstants.MODELS);
String path = outputPath + "src/main/java/org/openapitools/";

assertFileContains(path + "api/MyCustomApi.java", """
@Post("/api/v1/colors/{name}")
Mono<@NotNull String> selectColor(
@Body @NotNull Color body
);
""");
assertFileContains(path + "model/Color.java", "public enum Color {");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class KotlinMicronautClientCodegenTest extends AbstractMicronautCodegenTest {

@Test
void clientOptsUnicity() {
void clientOptsUniqueness() {
var codegen = new KotlinMicronautClientCodegen();
codegen.cliOptions()
.stream()
Expand Down Expand Up @@ -1468,4 +1468,20 @@ fun sendPrimitives(
): Mono<String>
""");
}

@Test
void testBodyEnum() {

var codegen = new KotlinMicronautClientCodegen();
String outputPath = generateFiles(codegen, "src/test/resources/3_0/body-enum.yml", CodegenConstants.APIS, CodegenConstants.MODELS);
String path = outputPath + "src/main/kotlin/org/openapitools/";

assertFileContains(path + "api/MyCustomApi.kt", """
@Post("/api/v1/colors/{name}")
fun selectColor(
@Body @NotNull body: Color,
): Mono<String>
""");
assertFileContains(path + "model/Color.kt", "enum class Color(");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class KotlinMicronautServerCodegenTest extends AbstractMicronautCodegenTest {
static String MULTI_TAGS_TEST_PATH = "src/test/resources/3_0/micronaut/multi-tags-test.yaml";

@Test
void clientOptsUnicity() {
void clientOptsUniqueness() {
var codegen = new KotlinMicronautServerCodegen();
codegen.cliOptions()
.stream()
Expand Down Expand Up @@ -866,4 +866,22 @@ fun sendPrimitives(
): Mono<String>
""");
}

@Test
void testBodyEnum() {

var codegen = new KotlinMicronautServerCodegen();
codegen.setGenerateSwaggerAnnotations(false);
codegen.setUseAuth(false);
String outputPath = generateFiles(codegen, "src/test/resources/3_0/body-enum.yml", CodegenConstants.APIS, CodegenConstants.MODELS);
String path = outputPath + "src/main/kotlin/org/openapitools/";

assertFileContains(path + "api/MyCustomApi.kt", """
@Post("/api/v1/colors/{name}")
fun selectColor(
@Body @NotNull body: Color,
): Mono<String>
""");
assertFileContains(path + "model/Color.kt", "enum class Color(");
}
}
42 changes: 42 additions & 0 deletions openapi-generator/src/test/resources/3_0/body-enum.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
openapi: 3.1.0
info:
version: '1.0.0'
title: 'OpenAPI BUG REST API'
servers:
- url: 'localhost:3000'

paths:
/api/v1/colors/{name}:
post:
tags: [ my-custom ]
operationId: "selectColor"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/Color"
responses:
"200":
description: "OK"
content:
application/json:
schema:
type: string

components:
schemas:

Color:
type: string
enum:
- GREEN
- RED
- WHITE
- BLACK
- YELLOW
- BLUE

tags:
- name: my-custom
description: 'All API operations'
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package io.micronaut.openapi.test.api;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;

import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.multipart.CompletedFileUpload;
Expand All @@ -17,10 +13,13 @@
import io.micronaut.openapi.test.model.ModelWithValidatedListProperty;
import io.micronaut.openapi.test.model.NestedModel;
import io.micronaut.openapi.test.model.SimpleModel;

import jakarta.validation.Valid;
import reactor.core.publisher.Mono;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;

@Controller
public class RequestBodyController implements RequestBodyApi {

Expand Down Expand Up @@ -55,8 +54,8 @@ public Mono<DateModel> sendDateModel(DateModel model) {
}

@Override
public Mono<ColorEnum> sendEnum(String color) {
return Mono.just(ColorEnum.fromValue(color.replace("\"", "")));
public Mono<ColorEnum> sendEnum(ColorEnum color) {
return Mono.just(color);
}

@Override
Expand Down Expand Up @@ -91,8 +90,8 @@ public Mono<Animal> sendModelWithDiscriminator(Animal model) {
}

@Override
public Mono<byte[]> sendBytes(byte[] bytes) {
return Mono.just(bytes);
public Mono<byte[]> sendBytes(byte[] body) {
return Mono.just(body);
}

@Override
Expand Down
Loading

0 comments on commit aec11bd

Please sign in to comment.