From 1b6ab63953636addf37e648dd82240253490dade Mon Sep 17 00:00:00 2001 From: Sergey Vladimirov Date: Tue, 1 Mar 2022 19:57:30 +0300 Subject: [PATCH] Add beanQualifiers option to kotlin-server (#11745) --- docs/generators/kotlin-spring.md | 1 + .../languages/KotlinSpringServerCodegen.java | 18 ++++++++++++++++ .../main/resources/kotlin-spring/api.mustache | 2 +- .../kotlin-spring/apiController.mustache | 2 +- .../spring/KotlinSpringServerCodegenTest.java | 21 +++++++++++++++++++ .../resources/3_0/kotlin/bean-qualifiers.yaml | 13 ++++++++++++ 6 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/kotlin/bean-qualifiers.yaml diff --git a/docs/generators/kotlin-spring.md b/docs/generators/kotlin-spring.md index 98d5d0f1bef7..bff2a15e6733 100644 --- a/docs/generators/kotlin-spring.md +++ b/docs/generators/kotlin-spring.md @@ -23,6 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |artifactId|Generated artifact id (name of jar).| |openapi-spring| |artifactVersion|Generated artifact's package version.| |1.0.0| |basePackage|base package (invokerPackage) for generated code| |org.openapitools| +|beanQualifiers|Whether to add fully-qualifier class names as bean qualifiers in @Component and @RestController annotations. May be used to prevent bean names clash if multiple generated libraries (contexts) added to single project.| |false| |delegatePattern|Whether to generate the server files using the delegate pattern| |false| |enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase| |exceptionHandler|generate default global exception handlers (not compatible with reactive. enabling reactive will disable exceptionHandler )| |true| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java index f9ef3026e60c..6adf38be3581 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java @@ -66,6 +66,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen public static final String INTERFACE_ONLY = "interfaceOnly"; public static final String DELEGATE_PATTERN = "delegatePattern"; public static final String USE_TAGS = "useTags"; + public static final String BEAN_QUALIFIERS = "beanQualifiers"; private String basePackage; private String invokerPackage; @@ -82,6 +83,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen private boolean interfaceOnly = false; private boolean delegatePattern = false; protected boolean useTags = false; + private boolean beanQualifiers = false; public KotlinSpringServerCodegen() { super(); @@ -146,6 +148,9 @@ public KotlinSpringServerCodegen() { addSwitch(INTERFACE_ONLY, "Whether to generate only API interface stubs without the server files.", interfaceOnly); addSwitch(DELEGATE_PATTERN, "Whether to generate the server files using the delegate pattern", delegatePattern); addSwitch(USE_TAGS, "Whether to use tags for creating interface and controller class names", useTags); + addSwitch(BEAN_QUALIFIERS, "Whether to add fully-qualifier class names as bean qualifiers in @Component and " + + "@RestController annotations. May be used to prevent bean names clash if multiple generated libraries" + + " (contexts) added to single project.", beanQualifiers); supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application."); setLibrary(SPRING_BOOT); @@ -256,6 +261,14 @@ public void setReactive(boolean reactive) { this.reactive = reactive; } + public boolean isBeanQualifiers() { + return beanQualifiers; + } + + public void setBeanQualifiers(boolean beanQualifiers) { + this.beanQualifiers = beanQualifiers; + } + @Override public CodegenType getTag() { return CodegenType.SERVER; @@ -363,6 +376,11 @@ public void processOpts() { writePropertyBack(REACTIVE, reactive); writePropertyBack(EXCEPTION_HANDLER, exceptionHandler); + if (additionalProperties.containsKey(BEAN_QUALIFIERS) && library.equals(SPRING_BOOT)) { + this.setBeanQualifiers(convertPropertyToBoolean(BEAN_QUALIFIERS)); + } + writePropertyBack(BEAN_QUALIFIERS, beanQualifiers); + if (additionalProperties.containsKey(INTERFACE_ONLY)) { this.setInterfaceOnly(Boolean.parseBoolean(additionalProperties.get(INTERFACE_ONLY).toString())); } diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache index 9ea6611216fe..eb4e64ac3578 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/api.mustache @@ -40,7 +40,7 @@ import kotlinx.coroutines.flow.Flow; import kotlin.collections.List import kotlin.collections.Map -@RestController +@RestController{{#beanQualifiers}}("{{package}}.{{classname}}Controller"){{/beanQualifiers}} {{#useBeanValidation}} @Validated {{/useBeanValidation}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/apiController.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/apiController.mustache index 9d3f568d7c86..6e5fdb78a78c 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/apiController.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/apiController.mustache @@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import java.util.Optional; {{>generatedAnnotation}} -@Controller +@Controller{{#beanQualifiers}}("{{package}}.{{classname}}Controller"){{/beanQualifiers}} {{=<% %>=}} @RequestMapping("\${openapi.<%title%>.base-path:<%>defaultBasePath%>}") <%={{ }}=%> 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 90b5a86dc6e8..20be80f2f55c 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 @@ -374,4 +374,25 @@ public void generateFormatForDateAndDateTimeQueryParam() throws IOException { "@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)" ); } + + @Test(description = "test bean qualifiers") + public void beanQualifiers() throws Exception { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.additionalProperties().put(KotlinSpringServerCodegen.BEAN_QUALIFIERS, true); + + new DefaultGenerator().opts(new ClientOptInput() + .openAPI(TestUtils.parseSpec("src/test/resources/3_0/kotlin/bean-qualifiers.yaml")) + .config(codegen)) + .generate(); + + assertFileContains( + Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/PingApiController.kt"), + "@RestController(\"org.openapitools.api.PingApiController\")" + ); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/kotlin/bean-qualifiers.yaml b/modules/openapi-generator/src/test/resources/3_0/kotlin/bean-qualifiers.yaml new file mode 100644 index 000000000000..7b9d60bac6e1 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/kotlin/bean-qualifiers.yaml @@ -0,0 +1,13 @@ +openapi: "3.0.1" +info: + title: test + version: "1.0" + +paths: + + /ping: + get: + operationId: ping + responses: + 200: + description: OK