From 1646c9f71c5c1558c2b6289233461cbd965c6644 Mon Sep 17 00:00:00 2001 From: Niels Leemburg Date: Tue, 24 Jan 2023 13:21:53 +0100 Subject: [PATCH 1/4] Dont use @RequestParam when it's multipart, but instead @RequestPart. --- .../src/main/templates/boat-spring/formParams.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boat-scaffold/src/main/templates/boat-spring/formParams.mustache b/boat-scaffold/src/main/templates/boat-spring/formParams.mustache index b0819f315..505e5909e 100644 --- a/boat-scaffold/src/main/templates/boat-spring/formParams.mustache +++ b/boat-scaffold/src/main/templates/boat-spring/formParams.mustache @@ -1 +1 @@ -{{#isFormParam}}{{^isFile}}{{>paramDoc}}{{#useBeanValidation}} @Valid{{/useBeanValidation}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}){{>dateTimeParam}} {{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}}{{>paramDoc}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{#isArray}}List<{{/isArray}}{{#reactive}}Flux{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{#isArray}}>{{/isArray}} {{paramName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file +{{#isFormParam}}{{^isFile}}{{>paramDoc}}{{#isMultipart}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{>dateTimeParam}} {{{dataType}}} {{paramName}}{{/isMultipart}}{{^isMultipart}}{{#useBeanValidation}} @Valid{{/useBeanValidation}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}){{>dateTimeParam}} {{{dataType}}} {{paramName}}{{/isMultipart}}{{/isFile}}{{#isFile}}{{>paramDoc}} @RequestPart(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}) {{#isArray}}List<{{/isArray}}{{#reactive}}Flux{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{#isArray}}>{{/isArray}} {{paramName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file From e16c785a25de38f8dc82113efc388b39136e947f Mon Sep 17 00:00:00 2001 From: Niels Leemburg Date: Tue, 24 Jan 2023 13:22:31 +0100 Subject: [PATCH 2/4] Added test --- boat-scaffold/pom.xml | 7 +++ .../codegen/java/BoatSpringCodeGenTests.java | 55 ++++++++++++++++++- .../test/resources/boat-spring/multipart.yaml | 39 +++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 boat-scaffold/src/test/resources/boat-spring/multipart.yaml diff --git a/boat-scaffold/pom.xml b/boat-scaffold/pom.xml index 4ece94e9f..c13886751 100644 --- a/boat-scaffold/pom.xml +++ b/boat-scaffold/pom.xml @@ -108,6 +108,13 @@ 2.6 compile + + + com.github.javaparser + javaparser-core + 3.24.9 + test + diff --git a/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java b/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java index 105234f1c..e9b17ce7a 100644 --- a/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java +++ b/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java @@ -7,23 +7,43 @@ import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.backbase.oss.codegen.java.BoatSpringCodeGen.NewLineIndent; +import com.github.javaparser.StaticJavaParser; +import com.github.javaparser.ast.body.MethodDeclaration; import com.samskivert.mustache.Template.Fragment; +import io.swagger.parser.OpenAPIParser; +import io.swagger.v3.parser.core.models.ParseOptions; +import java.io.File; import java.io.IOException; import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Map; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.openapitools.codegen.CliOption; +import org.openapitools.codegen.ClientOptInput; import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenParameter; import org.openapitools.codegen.CodegenProperty; - +import org.openapitools.codegen.DefaultGenerator; class BoatSpringCodeGenTests { + static final String PROP_BASE = BoatSpringCodeGenTests.class.getSimpleName() + "."; + static final String TEST_OUTPUT = System.getProperty(PROP_BASE + "output", "target/boat-spring-codegen-tests"); + + @BeforeAll + static void before() throws IOException { + Files.createDirectories(Paths.get(TEST_OUTPUT)); + FileUtils.deleteDirectory(new File(TEST_OUTPUT, "src")); + } + @Test void clientOptsUnicity() { final BoatSpringCodeGen gen = new BoatSpringCodeGen(); @@ -97,4 +117,37 @@ void newLineIndent() throws IOException { assertThat(output.toString(), equalTo(String.format("__%n__Good%n__ morning,%n__ Dave%n"))); } + + @Test + void multipartWithFileAndObject() throws IOException { + var codegen = new BoatSpringCodeGen(); + var input = new File("src/test/resources/boat-spring/multipart.yaml"); + codegen.setLibrary("spring-boot"); + codegen.setInterfaceOnly(true); + codegen.setOutputDir(TEST_OUTPUT + "/multipart"); + codegen.setInputSpec(input.getAbsolutePath()); + + var openApiInput = new OpenAPIParser().readLocation(input.getAbsolutePath(), null, new ParseOptions()).getOpenAPI(); + var clientOptInput = new ClientOptInput(); + clientOptInput.config(codegen); + clientOptInput.openAPI(openApiInput); + + var files = new DefaultGenerator().opts(clientOptInput).generate(); + + var testApi = files.stream().filter(file -> file.getName().equals("TestApi.java")) + .findFirst() + .get(); + var testPostMethod = StaticJavaParser.parse(testApi) + .findAll(MethodDeclaration.class) + .get(1); + + var filesParam = testPostMethod.getParameterByName("files").get(); + var contentParam = testPostMethod.getParameterByName("content").get(); + + assertTrue(filesParam.getAnnotationByName("RequestPart").isPresent()); + assertTrue(contentParam.getAnnotationByName("RequestPart").isPresent()); + assertThat(contentParam.getTypeAsString(), equalTo("TestObjectPart")); + assertThat(filesParam.getTypeAsString(), equalTo("List")); + } + } diff --git a/boat-scaffold/src/test/resources/boat-spring/multipart.yaml b/boat-scaffold/src/test/resources/boat-spring/multipart.yaml new file mode 100644 index 000000000..f51f70d20 --- /dev/null +++ b/boat-scaffold/src/test/resources/boat-spring/multipart.yaml @@ -0,0 +1,39 @@ +openapi: 3.0.2 +info: + version: 1.0.0 + title: test + +paths: + /test: + post: + requestBody: + content: + multipart/form-data: + schema: + type: object + required: + - files + - content + properties: + files: + type: array + items: + type: string + format: binary + content: + $ref: "#/components/schemas/testObjectPart" + responses: + 200: + description: OK + +components: + schemas: + testObjectPart: + type: object + required: + - foo + properties: + foo: + type: string + bar: + type: number \ No newline at end of file From 27a1741d667e465cdc9144c7055a5d671f632d17 Mon Sep 17 00:00:00 2001 From: Niels Leemburg Date: Wed, 23 Aug 2023 11:10:50 +0200 Subject: [PATCH 3/4] Cleanup + added fix to readme --- README.md | 3 +++ .../backbase/oss/codegen/java/BoatSpringCodeGenTests.java | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5ca6461b6..3eb6665f6 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,9 @@ The project is very much Work In Progress and will be published on maven central # Release Notes BOAT is still under development and subject to change. +## 0.17.10 +* Boat maven plugin + * Fix: When using Multipart, generate with `@RequestPart` instead of `@RequestParam` ## 0.17.7 * Boat maven plugin * Fix: Added 'containerDefaultToNull' default option to the MOJO generator diff --git a/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java b/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java index e2a505435..c682a171e 100644 --- a/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java +++ b/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java @@ -3,10 +3,8 @@ import static com.backbase.oss.codegen.java.BoatSpringCodeGen.USE_PROTECTED_FIELDS; import static java.util.stream.Collectors.groupingBy; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasEntry; -import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; @@ -31,10 +29,7 @@ import org.junit.jupiter.api.Test; import org.openapitools.codegen.CliOption; import org.openapitools.codegen.ClientOptInput; -import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenOperation; -import org.openapitools.codegen.CodegenParameter; -import org.openapitools.codegen.CodegenProperty; import org.openapitools.codegen.DefaultGenerator; class BoatSpringCodeGenTests { From cd5ca3d4cf2d2217d0a81a9e9de7e3c1537cc0f8 Mon Sep 17 00:00:00 2001 From: Niels Leemburg Date: Wed, 23 Aug 2023 11:54:58 +0200 Subject: [PATCH 4/4] Make types a bit more explicit --- .../oss/codegen/java/BoatSpringCodeGenTests.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java b/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java index c682a171e..730c92aa4 100644 --- a/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java +++ b/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatSpringCodeGenTests.java @@ -13,6 +13,7 @@ import com.backbase.oss.codegen.java.BoatSpringCodeGen.NewLineIndent; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.Parameter; import com.samskivert.mustache.Template.Fragment; import io.swagger.v3.oas.models.Operation; import io.swagger.parser.OpenAPIParser; @@ -23,6 +24,7 @@ import java.util.Arrays; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.List; import java.util.Map; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.BeforeAll; @@ -103,17 +105,17 @@ void multipartWithFileAndObject() throws IOException { clientOptInput.config(codegen); clientOptInput.openAPI(openApiInput); - var files = new DefaultGenerator().opts(clientOptInput).generate(); + List files = new DefaultGenerator().opts(clientOptInput).generate(); - var testApi = files.stream().filter(file -> file.getName().equals("TestApi.java")) + File testApi = files.stream().filter(file -> file.getName().equals("TestApi.java")) .findFirst() .get(); - var testPostMethod = StaticJavaParser.parse(testApi) + MethodDeclaration testPostMethod = StaticJavaParser.parse(testApi) .findAll(MethodDeclaration.class) .get(1); - var filesParam = testPostMethod.getParameterByName("files").get(); - var contentParam = testPostMethod.getParameterByName("content").get(); + Parameter filesParam = testPostMethod.getParameterByName("files").get(); + Parameter contentParam = testPostMethod.getParameterByName("content").get(); assertTrue(filesParam.getAnnotationByName("RequestPart").isPresent()); assertTrue(contentParam.getAnnotationByName("RequestPart").isPresent());