Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix generating endpoints by operations with multiple content types. #1757

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/checkstyle/custom-suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
<suppress checks="FileLength" files=".*" />
<suppress checks="ParameterNumber" files=".*" />
<suppress checks="." files="io[\\/]micronaut[\\/]openapi[\\/]adoc[\\/]md" />
<suppress checks="." files="org[\\/]openapitools[\\/]codegen[\\/]" />
</suppressions>
4 changes: 3 additions & 1 deletion openapi-generator/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ dependencies {
because("OpenAPI generator depends on older release which isn't compatible with SnakeYAML")
}
}
api libs.openapi.generator
api(libs.openapi.generator) {
exclude group: "org.projectlombok"
}
api libs.commons.codec
api libs.managed.evo.inflector

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.languages.AbstractJavaCodegen;
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.languages.features.OptionalFeatures;
Expand Down Expand Up @@ -75,6 +76,7 @@
import java.util.stream.Collectors;

import static io.micronaut.openapi.generator.Utils.DEFAULT_BODY_PARAM_NAME;
import static io.micronaut.openapi.generator.Utils.DIVIDE_OPERATIONS_BY_CONTENT_TYPE;
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_CLASS;
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_FIELD;
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_OPERATION;
Expand Down Expand Up @@ -186,6 +188,8 @@ protected AbstractMicronautJavaCodegen() {
inlineSchemaOption.put("RESOLVE_INLINE_ENUMS", "true");
// CHECKSTYLE:ON

GlobalSettings.setProperty(DIVIDE_OPERATIONS_BY_CONTENT_TYPE, "true");

// Set implemented features for user information
modifyFeatureSet(features -> features
.includeDocumentationFeatures(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.languages.AbstractKotlinCodegen;
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.meta.features.ClientModificationFeature;
Expand Down Expand Up @@ -78,6 +79,7 @@
import java.util.stream.Collectors;

import static io.micronaut.openapi.generator.Utils.DEFAULT_BODY_PARAM_NAME;
import static io.micronaut.openapi.generator.Utils.DIVIDE_OPERATIONS_BY_CONTENT_TYPE;
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_CLASS;
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_FIELD;
import static io.micronaut.openapi.generator.Utils.EXT_ANNOTATIONS_OPERATION;
Expand Down Expand Up @@ -237,6 +239,8 @@ protected AbstractMicronautKotlinCodegen() {
useOneOfInterfaces = true;
// CHECKSTYLE:ON

GlobalSettings.setProperty(DIVIDE_OPERATIONS_BY_CONTENT_TYPE, "true");

// Set implemented features for user information
modifyFeatureSet(features -> features
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public final class Utils {
"LocalDate",
"LocalTime"
);
public static final String DIVIDE_OPERATIONS_BY_CONTENT_TYPE = "divideOperationsByContentType";

public static final String DEFAULT_BODY_PARAM_NAME = "requestBody";
public static final String EXT_ANNOTATIONS_OPERATION = "x-operation-extra-annotation";
public static final String EXT_ANNOTATIONS_CLASS = "x-class-extra-annotation";
Expand Down
8,740 changes: 8,740 additions & 0 deletions openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java

Large diffs are not rendered by default.

2,069 changes: 2,069 additions & 0 deletions openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -748,4 +748,27 @@ public FileCreateDto(String typeCode, String orgName) {
}
""");
}

@Test
void testMultipleContentTypesEndpoints() {

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

assertFileContains(path + "api/DefaultApi.java", """
@Post("/multiplecontentpath")
Mono<HttpResponse<Void>> myOp(
@Body @Nullable @Valid Coordinates coordinates
);
""",
"""
@Post("/multiplecontentpath")
@Produces("multipart/form-data")
Mono<HttpResponse<Void>> myOp_1(
@Nullable @Valid Coordinates coordinates,
@Nullable byte[] file
);
""");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -528,4 +528,37 @@ void testMultipartFormData() {
);
""");
}

@Test
void testMultipleContentTypesEndpoints() {

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

assertFileContains(path + "api/DefaultApi.java", """
@Operation(
operationId = "myOp",
responses = @ApiResponse(responseCode = "201", description = "Successfully created")
)
@Post("/multiplecontentpath")
@Secured(SecurityRule.IS_ANONYMOUS)
Mono<HttpResponse<Void>> myOp(
@Body @Nullable(inherited = true) @Valid Coordinates coordinates
);
""",
"""
@Operation(
operationId = "myOp_0",
responses = @ApiResponse(responseCode = "201", description = "Successfully created")
)
@Post("/multiplecontentpath")
@Consumes("multipart/form-data")
@Secured(SecurityRule.IS_ANONYMOUS)
Mono<HttpResponse<Void>> myOp_1(
@Nullable(inherited = true) @Valid Coordinates coordinates,
@Nullable(inherited = true) CompletedFileUpload file
);
""");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -779,4 +779,27 @@ data class FileCreateDto(
) {
""");
}

@Test
void testMultipleContentTypesEndpoints() {

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

assertFileContains(path + "api/DefaultApi.kt", """
@Post("/multiplecontentpath")
fun myOp(
@Body @Nullable @Valid coordinates: Coordinates?
): Mono<HttpResponse<Void>>
""",
"""
@Post("/multiplecontentpath")
@Produces("multipart/form-data")
fun myOp_1(
@Nullable @Valid coordinates: Coordinates?,
@Nullable file: ByteArray?
): Mono<HttpResponse<Void>>
""");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -613,4 +613,41 @@ fun profilePasswordPost(
): Mono<SuccessResetPassword>
""");
}

@Test
void testMultipleContentTypesEndpoints() {

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

assertFileContains(path + "api/DefaultApi.kt", """
@Operation(
operationId = "myOp",
responses = [
ApiResponse(responseCode = "201", description = "Successfully created")
]
)
@Post("/multiplecontentpath")
@Secured(SecurityRule.IS_ANONYMOUS)
fun myOp(
@Body @Nullable @Valid coordinates: Coordinates?
): Mono<HttpResponse<Void>>
""",
"""
@Operation(
operationId = "myOp_0",
responses = [
ApiResponse(responseCode = "201", description = "Successfully created")
]
)
@Post("/multiplecontentpath")
@Consumes("multipart/form-data")
@Secured(SecurityRule.IS_ANONYMOUS)
fun myOp_1(
@Nullable @Valid coordinates: Coordinates?,
@Nullable file: CompletedFileUpload?
): Mono<HttpResponse<Void>>
""");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
openapi: 3.0.3
info:
version: "1"
title: Multiple Content Types for same request
paths:
/multiplecontentpath:
post:
operationId: myOp
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/coordinates'
multipart/form-data:
schema:
type: object
properties:
coordinates:
$ref: '#/components/schemas/coordinates'
file:
type: string
format: binary
responses:
201:
description: Successfully created
headers:
Location:
schema:
type: string
components:
schemas:
coordinates:
type: object
required:
- lat
- long
properties:
lat:
type: number
long:
type: number
Loading