diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/apiDelegate.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/apiDelegate.mustache index cb76cbcc7dda..219e156168c3 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/apiDelegate.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/apiDelegate.mustache @@ -33,7 +33,7 @@ interface {{classname}}Delegate { /** * @see {{classname}}#{{operationId}} */ - {{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}{{#isBodyParam}}Flow<{{{baseType}}}>{{/isBodyParam}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{/isArray}}{{/reactive}}{{^-last}}, + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{#isFile}}{{>fileParamType}}{{/isFile}}{{^isFile}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}{{#isBodyParam}}Flow<{{{baseType}}}>{{/isBodyParam}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{/isArray}}{{/reactive}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{/isFile}}{{^-last}}, {{/-last}}{{/allParams}}): {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}}{{^skipDefaultDelegateInterface}} { {{>methodBody}}{{! prevent indent}} }{{/skipDefaultDelegateInterface}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/fileParamType.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/fileParamType.mustache new file mode 100644 index 000000000000..a6daa389e383 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/fileParamType.mustache @@ -0,0 +1 @@ +{{#isFile}}{{#reactive}}{{#isArray}}Flux<{{/isArray}}org.springframework.http.codec.multipart.Part{{#isArray}}>{{/isArray}}{{^required}}?{{/required}}{{/reactive}}{{^reactive}}{{#isArray}}Array<{{/isArray}}org.springframework.web.multipart.MultipartFile{{#isArray}}>{{/isArray}}{{^required}}?{{/required}}{{/reactive}}{{/isFile}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/formParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/formParams.mustache index c6eb0799686a..b5d333863f45 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/formParams.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/formParams.mustache @@ -1 +1 @@ -{{#isFormParam}}{{^isFile}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} {{#isModel}}@RequestPart{{/isModel}}{{^isModel}}@RequestParam{{/isModel}}(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{paramName}}}: {{>optionalDataType}} {{/isFile}}{{#isFile}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "file detail"){{/swagger1AnnotationLibrary}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart("{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{paramName}}}: {{>optionalDataType}}{{/isFile}}{{/isFormParam}} \ No newline at end of file +{{#isFormParam}}{{^isFile}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} {{#isModel}}@RequestPart{{/isModel}}{{^isModel}}@RequestParam{{/isModel}}(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{paramName}}}: {{>optionalDataType}} {{/isFile}}{{#isFile}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "file detail"){{/swagger1AnnotationLibrary}} {{#useBeanValidation}}@Valid{{/useBeanValidation}} @RequestPart("{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{{paramName}}}: {{>fileParamType}}{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/optionalDataType.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/optionalDataType.mustache index a6b059b8632a..ed2a4468e9d3 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/optionalDataType.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/optionalDataType.mustache @@ -1 +1 @@ -{{^isFile}}{{{dataType}}}{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}}{{/isFile}}{{#isFile}}{{#isArray}}Array<{{/isArray}}org.springframework.web.multipart.MultipartFile{{#isArray}}>{{/isArray}}{{^isArray}}{{^required}}?{{/required}}{{/isArray}}{{/isFile}} \ No newline at end of file +{{{dataType}}}{{^required}}{{^defaultValue}}?{{/defaultValue}}{{/required}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/service.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/service.mustache index 309be55743b4..1b4cde03f8c7 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/service.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/service.mustache @@ -30,7 +30,7 @@ interface {{classname}}Service { {{/externalDocs}} * @see {{classname}}#{{operationId}} */ - {{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} + {{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{#isFile}}{{>fileParamType}}{{/isFile}}{{^isFile}}{{>optionalDataType}}{{/isFile}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} {{/operation}} } {{/operations}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/serviceImpl.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/serviceImpl.mustache index 181bfa52991c..e4730f488bb5 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/serviceImpl.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/serviceImpl.mustache @@ -11,7 +11,7 @@ import org.springframework.stereotype.Service class {{classname}}ServiceImpl : {{classname}}Service { {{#operation}} - override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} { + override {{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{^isBodyParam}}{{#isFile}}{{>fileParamType}}{{/isFile}}{{^isFile}}{{>optionalDataType}}{{/isFile}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{>optionalDataType}}{{/reactive}}{{#reactive}}{{^isArray}}{{>optionalDataType}}{{/isArray}}{{#isArray}}Flow<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{^-last}}, {{/-last}}{{/allParams}}): {{>returnTypes}} { TODO("Implement me") } {{/operation}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index 5a0d24cdcf1a..425768f02891 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -5,8 +5,11 @@ import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.servers.Server; import io.swagger.v3.parser.core.models.ParseOptions; +import java.util.Arrays; import java.util.HashMap; +import java.util.Objects; import java.util.function.Consumer; +import java.util.stream.Stream; import org.apache.commons.io.FileUtils; import org.assertj.core.api.Assertions; import org.jetbrains.annotations.NotNull; @@ -38,7 +41,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.assertFileNotContains; -import static org.openapitools.codegen.languages.SpringCodegen.SPRING_BOOT; import static org.openapitools.codegen.languages.features.DocumentationProviderFeatures.ANNOTATION_LIBRARY; import static org.openapitools.codegen.languages.features.DocumentationProviderFeatures.DOCUMENTATION_PROVIDER; @@ -789,42 +791,138 @@ public void contractWithResolvedInnerEnumContainsEnumConverter() throws IOExcept } @Test - public void givenMultipartFormArray_whenGenerateDelegateAndService_thenParameterIsCreatedAsListOfMultipartFile() throws IOException { - File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); - output.deleteOnExit(); - String outputPath = output.getAbsolutePath().replace('\\', '/'); + public void givenNonRequiredMultipartFileArray_whenGenerateDelegateAndService_thenParameterIsCreatedAsNullableListOfMultipartFile() throws IOException { + Map additionalProperties = new HashMap<>(); + additionalProperties.put(KotlinSpringServerCodegen.DELEGATE_PATTERN, true); + additionalProperties.put(KotlinSpringServerCodegen.SERVICE_IMPLEMENTATION, true); + + Map generatorPropertyDefaults = new HashMap<>(); + generatorPropertyDefaults.put(CodegenConstants.MODELS, "false"); + generatorPropertyDefaults.put(CodegenConstants.MODEL_TESTS, "false"); + generatorPropertyDefaults.put(CodegenConstants.MODEL_DOCS, "false"); + generatorPropertyDefaults.put(CodegenConstants.APIS, "true"); + generatorPropertyDefaults.put(CodegenConstants.SUPPORTING_FILES, "false"); - final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/kotlin/petstore-with-tags.yaml"); - final KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen(); - codegen.setOpenAPI(openAPI); - codegen.setOutputDir(output.getAbsolutePath()); - codegen.setDelegatePattern(true); - codegen.setServiceInterface(true); + Map files = generateFromContract( + "src/test/resources/3_0/kotlin/petstore-with-tags.yaml", + additionalProperties, + generatorPropertyDefaults + ); - ClientOptInput input = new ClientOptInput(); - input.openAPI(openAPI); - input.config(codegen); + validateMultipartFiles( + files, + "Pet", + "additionalMetadata: kotlin.String?", + "images: Array?)" + ); + } - DefaultGenerator generator = new DefaultGenerator(); + @Test + public void givenMultipartBinaryArray_whenGenerateDelegateAndService_correctMultipartFileIsCreated() throws IOException { + Map additionalProperties = new HashMap<>(); + additionalProperties.put(KotlinSpringServerCodegen.DELEGATE_PATTERN, true); + additionalProperties.put(KotlinSpringServerCodegen.SERVICE_IMPLEMENTATION, true); + + Map generatorPropertyDefaults = new HashMap<>(); + generatorPropertyDefaults.put(CodegenConstants.MODELS, "false"); + generatorPropertyDefaults.put(CodegenConstants.MODEL_TESTS, "false"); + generatorPropertyDefaults.put(CodegenConstants.MODEL_DOCS, "false"); + generatorPropertyDefaults.put(CodegenConstants.APIS, "true"); + generatorPropertyDefaults.put(CodegenConstants.SUPPORTING_FILES, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); - generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + Map files = generateFromContract( + "src/test/resources/3_0/form-multipart-binary-array.yaml", + additionalProperties, + generatorPropertyDefaults + ); - generator.opts(input).generate(); + validateMultipartFiles( + files, + "MultipartArray", + "files: Array?)" + ); - Path delegateFile = Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/PetApiDelegate.kt"); - assertFileContains(delegateFile, "additionalMetadata: kotlin.String?"); - assertFileContains(delegateFile, "images: Array"); + validateMultipartFiles( + files, + "MultipartMixed", + "file: org.springframework.web.multipart.MultipartFile,", + "marker: MultipartMixedRequestMarker?", + "statusArray: kotlin.collections.List?" + ); - Path controllerFile = Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/PetApi.kt"); - assertFileContains(controllerFile, "images: Array"); + validateMultipartFiles( + files, + "MultipartSingle", + "file: org.springframework.web.multipart.MultipartFile?" + ); + } + @Test + public void givenMultipartBinaryArray_whenGenerateReactiveDelegateAndService_correctPartIsCreated() throws IOException { + Map additionalProperties = new HashMap<>(); + additionalProperties.put(KotlinSpringServerCodegen.DELEGATE_PATTERN, true); + additionalProperties.put(KotlinSpringServerCodegen.SERVICE_IMPLEMENTATION, true); + additionalProperties.put(KotlinSpringServerCodegen.REACTIVE, true); + + Map generatorPropertyDefaults = new HashMap<>(); + generatorPropertyDefaults.put(CodegenConstants.MODELS, "false"); + generatorPropertyDefaults.put(CodegenConstants.MODEL_TESTS, "false"); + generatorPropertyDefaults.put(CodegenConstants.MODEL_DOCS, "false"); + generatorPropertyDefaults.put(CodegenConstants.APIS, "true"); + generatorPropertyDefaults.put(CodegenConstants.SUPPORTING_FILES, "false"); - Path serviceFile = Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/PetApiService.kt"); - assertFileContains(serviceFile, "images: Array"); + Map files = generateFromContract( + "src/test/resources/3_0/form-multipart-binary-array.yaml", + additionalProperties, + generatorPropertyDefaults + ); + + validateMultipartFiles( + files, + "MultipartArray", + "files: Flux?)" + ); + + validateMultipartFiles( + files, + "MultipartMixed", + "file: org.springframework.http.codec.multipart.Part,", + "marker: MultipartMixedRequestMarker?", + "statusArray: kotlin.collections.List?" + ); + + validateMultipartFiles( + files, + "MultipartSingle", + "file: org.springframework.http.codec.multipart.Part?" + ); + } + + /** + * Utility function to help validate that all delegate, service & api code generated for + * schemas with multipart-form-data have the same lines. + */ + private void validateMultipartFiles( + Map files, + String filePrefix, + String... lines + ) { + Stream.of( + filePrefix + "ApiDelegate.kt", + filePrefix + "ApiService.kt", + filePrefix + "ApiServiceImpl.kt", + filePrefix + "Api.kt" + ) + .map(files::get) + .map(Objects::requireNonNull) + .map(File::toPath) + .forEach(path -> { + try { + TestUtils.assertFileContains(path, lines); + } catch (AssertionError e) { + throw new AssertionError(path.toString() + " does not contain a line", e); + } + }); } @Test @@ -887,7 +985,7 @@ public void givenMultipartForm_whenGenerateReactiveServer_thenParameterAreCreate assertFileContains(outputFilepath, "@Parameter(description = \"Additional data to pass to server\") @Valid @RequestParam(value = \"additionalMetadata\", required = false) additionalMetadata: kotlin.String?"); assertFileContains(outputFilepath, - "@Parameter(description = \"image to upload\") @Valid @RequestPart(\"image\", required = false) image: org.springframework.web.multipart.MultipartFile"); + "@Parameter(description = \"image to upload\") @Valid @RequestPart(\"image\", required = false) image: org.springframework.web.multipart.MultipartFile?)"); } @@ -1269,7 +1367,7 @@ private Map generateFromContract( .setAdditionalProperties(additionalProperties) .setValidateSpec(false) .setInputSpec(url) - .setLibrary(SPRING_BOOT) + .setLibrary(KotlinSpringServerCodegen.SPRING_BOOT) .setOutputDir(output.getAbsolutePath()); consumer.accept(configurator); diff --git a/modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml b/modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml index 062ab023e2d0..f8eef9225bd6 100644 --- a/modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml @@ -267,16 +267,15 @@ paths: content: multipart/form-data: schema: + type: object properties: additionalMetadata: - type: string - description: Additional data to pass to server - required: false + type: string + description: Additional data to pass to server image: - type: string - description: image to upload - format: binary - required: true + type: string + description: image to upload + format: binary responses: 200: description: successful operation @@ -306,18 +305,17 @@ paths: content: multipart/form-data: schema: + type: object properties: additionalMetadata: type: string description: Additional data to pass to server - required: false images: type: array items: type: string description: image to upload format: binary - required: true responses: 200: description: successful operation diff --git a/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiController.kt b/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiController.kt index 05575e31959f..3d04601aec1c 100644 --- a/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiController.kt +++ b/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiController.kt @@ -177,7 +177,7 @@ class PetApiController(@Autowired(required = true) val service: PetApiService) { produces = ["application/json"], consumes = ["multipart/form-data"] ) - suspend fun uploadFile(@Parameter(description = "ID of pet to update", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) additionalMetadata: kotlin.String? ,@Parameter(description = "file to upload") @Valid @RequestPart("file", required = false) file: org.springframework.web.multipart.MultipartFile?): ResponseEntity { + suspend fun uploadFile(@Parameter(description = "ID of pet to update", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) additionalMetadata: kotlin.String? ,@Parameter(description = "file to upload") @Valid @RequestPart("file", required = false) file: org.springframework.http.codec.multipart.Part?): ResponseEntity { return ResponseEntity(service.uploadFile(petId, additionalMetadata, file), HttpStatus.valueOf(200)) } } diff --git a/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiService.kt b/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiService.kt index 9a6c4b569f00..64e01a90bafa 100644 --- a/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiService.kt +++ b/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiService.kt @@ -100,5 +100,5 @@ interface PetApiService { * @return successful operation (status code 200) * @see PetApi#uploadFile */ - suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: org.springframework.web.multipart.MultipartFile?): ModelApiResponse + suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: org.springframework.http.codec.multipart.Part?): ModelApiResponse } diff --git a/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiServiceImpl.kt b/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiServiceImpl.kt index 2590f434f52c..5b580f565b0d 100644 --- a/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiServiceImpl.kt +++ b/samples/server/petstore/kotlin-springboot-reactive-without-flow/src/main/kotlin/org/openapitools/api/PetApiServiceImpl.kt @@ -35,7 +35,7 @@ class PetApiServiceImpl : PetApiService { TODO("Implement me") } - override suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: org.springframework.web.multipart.MultipartFile?): ModelApiResponse { + override suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: org.springframework.http.codec.multipart.Part?): ModelApiResponse { TODO("Implement me") } } diff --git a/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiController.kt b/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiController.kt index 3a9a2760dd62..46e216272b1a 100644 --- a/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiController.kt +++ b/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiController.kt @@ -177,7 +177,7 @@ class PetApiController(@Autowired(required = true) val service: PetApiService) { produces = ["application/json"], consumes = ["multipart/form-data"] ) - suspend fun uploadFile(@Parameter(description = "ID of pet to update", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) additionalMetadata: kotlin.String? ,@Parameter(description = "file to upload") @Valid @RequestPart("file", required = false) file: org.springframework.web.multipart.MultipartFile?): ResponseEntity { + suspend fun uploadFile(@Parameter(description = "ID of pet to update", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) additionalMetadata: kotlin.String? ,@Parameter(description = "file to upload") @Valid @RequestPart("file", required = false) file: org.springframework.http.codec.multipart.Part?): ResponseEntity { return ResponseEntity(service.uploadFile(petId, additionalMetadata, file), HttpStatus.valueOf(200)) } } diff --git a/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiService.kt b/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiService.kt index 29ff5bc85617..4e8184ec8327 100644 --- a/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiService.kt +++ b/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiService.kt @@ -100,5 +100,5 @@ interface PetApiService { * @return successful operation (status code 200) * @see PetApi#uploadFile */ - suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: org.springframework.web.multipart.MultipartFile?): ModelApiResponse + suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: org.springframework.http.codec.multipart.Part?): ModelApiResponse } diff --git a/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiServiceImpl.kt b/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiServiceImpl.kt index 58b6df4cc091..4565b2cbadf0 100644 --- a/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiServiceImpl.kt +++ b/samples/server/petstore/kotlin-springboot-reactive/src/main/kotlin/org/openapitools/api/PetApiServiceImpl.kt @@ -35,7 +35,7 @@ class PetApiServiceImpl : PetApiService { TODO("Implement me") } - override suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: org.springframework.web.multipart.MultipartFile?): ModelApiResponse { + override suspend fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: org.springframework.http.codec.multipart.Part?): ModelApiResponse { TODO("Implement me") } }