mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-05-12 12:40:53 +00:00
requestMappingMode: Explicit configuration to control the location of the generated class level RequestMapping annotation (#18896)
Based on #13838 but for kotlin-spring. Fixes #18884
This commit is contained in:
parent
129e4dc9c9
commit
c806ea51b3
@ -11,3 +11,4 @@ additionalProperties:
|
||||
serializableModel: "true"
|
||||
beanValidations: "true"
|
||||
useSpringBoot3: "true"
|
||||
requestMappingMode: api_interface
|
||||
|
@ -9,3 +9,4 @@ additionalProperties:
|
||||
useSwaggerUI: "true"
|
||||
delegatePattern: "true"
|
||||
beanValidations: "true"
|
||||
requestMappingMode: none
|
||||
|
@ -10,3 +10,4 @@ additionalProperties:
|
||||
serviceImplementation: "true"
|
||||
serializableModel: "true"
|
||||
beanValidations: "true"
|
||||
requestMappingMode: controller
|
||||
|
@ -41,6 +41,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
|packageName|Generated artifact package name.| |org.openapitools|
|
||||
|parcelizeModels|toggle "@Parcelize" for generated models| |null|
|
||||
|reactive|use coroutines for reactive behavior| |false|
|
||||
|requestMappingMode|Where to generate the class level @RequestMapping annotation.|<dl><dt>**api_interface**</dt><dd>Generate the @RequestMapping annotation on the generated Api Interface.</dd><dt>**controller**</dt><dd>Generate the @RequestMapping annotation on the generated Api Controller Implementation.</dd><dt>**none**</dt><dd>Do not add a class level @RequestMapping annotation.</dd></dl>|controller|
|
||||
|serializableModel|boolean - toggle "implements Serializable" for generated models| |null|
|
||||
|serverPort|configuration the port in which the sever is to run on| |8080|
|
||||
|serviceImplementation|generate stub service implementations that extends service interfaces. If this is set to true service interfaces will also be generated| |false|
|
||||
|
@ -103,6 +103,25 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||
|
||||
public static final String USE_SPRING_BOOT3 = "useSpringBoot3";
|
||||
public static final String APPEND_REQUEST_TO_HANDLER = "appendRequestToHandler";
|
||||
public static final String REQUEST_MAPPING_OPTION = "requestMappingMode";
|
||||
public static final String USE_REQUEST_MAPPING_ON_CONTROLLER = "useRequestMappingOnController";
|
||||
public static final String USE_REQUEST_MAPPING_ON_INTERFACE = "useRequestMappingOnInterface";
|
||||
|
||||
public enum RequestMappingMode {
|
||||
api_interface("Generate the @RequestMapping annotation on the generated Api Interface."),
|
||||
controller("Generate the @RequestMapping annotation on the generated Api Controller Implementation."),
|
||||
none("Do not add a class level @RequestMapping annotation.");
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
private String description;
|
||||
|
||||
RequestMappingMode(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter @Setter
|
||||
private String basePackage;
|
||||
@ -131,6 +150,7 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||
|
||||
@Getter @Setter
|
||||
protected boolean useSpringBoot3 = false;
|
||||
protected RequestMappingMode requestMappingMode = RequestMappingMode.controller;
|
||||
private DocumentationProvider documentationProvider;
|
||||
private AnnotationLibrary annotationLibrary;
|
||||
|
||||
@ -222,6 +242,14 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||
cliOpt.setEnum(supportedLibraries);
|
||||
cliOptions.add(cliOpt);
|
||||
|
||||
CliOption requestMappingOpt = new CliOption(REQUEST_MAPPING_OPTION,
|
||||
"Where to generate the class level @RequestMapping annotation.")
|
||||
.defaultValue(requestMappingMode.name());
|
||||
for (RequestMappingMode mode: RequestMappingMode.values()) {
|
||||
requestMappingOpt.addEnum(mode.name(), mode.getDescription());
|
||||
}
|
||||
cliOptions.add(requestMappingOpt);
|
||||
|
||||
if (null != defaultDocumentationProvider()) {
|
||||
CliOption documentationProviderCliOption = new CliOption(DOCUMENTATION_PROVIDER,
|
||||
"Select the OpenAPI documentation provider.")
|
||||
@ -433,6 +461,13 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||
LOGGER.info("Set base package to invoker package ({})", basePackage);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(REQUEST_MAPPING_OPTION)) {
|
||||
RequestMappingMode optValue = RequestMappingMode.valueOf(
|
||||
String.valueOf(additionalProperties.get(REQUEST_MAPPING_OPTION)));
|
||||
setRequestMappingMode(optValue);
|
||||
additionalProperties.remove(REQUEST_MAPPING_OPTION);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CONFIG_PACKAGE)) {
|
||||
this.setConfigPackage((String) additionalProperties.get(CONFIG_PACKAGE));
|
||||
} else {
|
||||
@ -639,6 +674,9 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||
supportingFiles.add(new SupportingFile("settingsGradle.mustache", "settings.gradle"));
|
||||
}
|
||||
|
||||
// @RequestMapping not supported with spring cloud openfeign.
|
||||
setRequestMappingMode(RequestMappingMode.none);
|
||||
|
||||
supportingFiles.add(new SupportingFile("apiKeyRequestInterceptor.mustache",
|
||||
(sourceFolder + File.separator + configPackage).replace(".", java.io.File.separator),
|
||||
"ApiKeyRequestInterceptor.kt"));
|
||||
@ -662,6 +700,19 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||
}
|
||||
}
|
||||
|
||||
switch (getRequestMappingMode()) {
|
||||
case api_interface:
|
||||
additionalProperties.put(USE_REQUEST_MAPPING_ON_INTERFACE, true);
|
||||
break;
|
||||
case controller:
|
||||
additionalProperties.put(USE_REQUEST_MAPPING_ON_CONTROLLER, true);
|
||||
break;
|
||||
case none:
|
||||
additionalProperties.put(USE_REQUEST_MAPPING_ON_INTERFACE, false);
|
||||
additionalProperties.put(USE_REQUEST_MAPPING_ON_CONTROLLER, false);
|
||||
break;
|
||||
}
|
||||
|
||||
// spring uses the jackson lib, and we disallow configuration.
|
||||
additionalProperties.put("jackson", "true");
|
||||
|
||||
@ -922,4 +973,13 @@ public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
|
||||
static class RequestCodegenParameter extends CodegenParameter {
|
||||
boolean isRequestObject;
|
||||
}
|
||||
|
||||
public RequestMappingMode getRequestMappingMode() {
|
||||
return requestMappingMode;
|
||||
}
|
||||
|
||||
public void setRequestMappingMode(RequestMappingMode requestMappingMode) {
|
||||
this.requestMappingMode = requestMappingMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -57,9 +57,11 @@ import kotlin.collections.Map
|
||||
{{#swagger1AnnotationLibrary}}
|
||||
@Api(value = "{{{baseName}}}", description = "The {{{baseName}}} API")
|
||||
{{/swagger1AnnotationLibrary}}
|
||||
{{#useRequestMappingOnController}}
|
||||
{{=<% %>=}}
|
||||
@RequestMapping("\${api.base-path:<%contextPath%>}")
|
||||
<%={{ }}=%>
|
||||
{{/useRequestMappingOnController}}
|
||||
{{#operations}}
|
||||
class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) val service: {{classname}}Service{{/serviceInterface}}) {
|
||||
{{#operation}}
|
||||
|
@ -6,9 +6,11 @@ import java.util.Optional
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
@Controller{{#beanQualifiers}}("{{package}}.{{classname}}Controller"){{/beanQualifiers}}
|
||||
{{#useRequestMappingOnController}}
|
||||
{{=<% %>=}}
|
||||
@RequestMapping("\${openapi.<%title%>.base-path:<%>defaultBasePath%>}")
|
||||
<%={{ }}=%>
|
||||
{{/useRequestMappingOnController}}
|
||||
{{#operations}}
|
||||
class {{classname}}Controller(
|
||||
@org.springframework.beans.factory.annotation.Autowired(required = false) delegate: {{classname}}Delegate?
|
||||
|
@ -61,11 +61,11 @@ import kotlin.collections.Map
|
||||
{{#swagger1AnnotationLibrary}}
|
||||
@Api(value = "{{{baseName}}}", description = "The {{{baseName}}} API")
|
||||
{{/swagger1AnnotationLibrary}}
|
||||
{{^useFeignClient}}
|
||||
{{#useRequestMappingOnInterface}}
|
||||
{{=<% %>=}}
|
||||
@RequestMapping("\${api.base-path:<%contextPath%>}")
|
||||
<%={{ }}=%>
|
||||
{{/useFeignClient}}
|
||||
{{/useRequestMappingOnInterface}}
|
||||
{{#operations}}
|
||||
interface {{classname}} {
|
||||
{{#isDelegate}}
|
||||
|
@ -7,6 +7,7 @@ import io.swagger.v3.oas.models.servers.Server;
|
||||
import io.swagger.v3.parser.core.models.ParseOptions;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.openapitools.codegen.ClientOptInput;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.DefaultGenerator;
|
||||
@ -82,7 +83,7 @@ public class KotlinSpringServerCodegenTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRequestMappingAnnotation() throws IOException {
|
||||
public void testNoRequestMappingAnnotation_spring_cloud_default() throws IOException {
|
||||
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
|
||||
output.deleteOnExit();
|
||||
|
||||
@ -102,6 +103,74 @@ public class KotlinSpringServerCodegenTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRequestMappingAnnotationNone() throws IOException {
|
||||
File output = generatePetstoreWithRequestMappingMode(KotlinSpringServerCodegen.RequestMappingMode.none);
|
||||
|
||||
// Check that the @RequestMapping annotation is not generated in the Api file
|
||||
assertFileNotContains(
|
||||
Paths.get(output + "/src/main/kotlin/org/openapitools/api/PetApi.kt"),
|
||||
"@RequestMapping(\"\\${"
|
||||
);
|
||||
// Check that the @RequestMapping annotation is not generated in the ApiController file
|
||||
assertFileNotContains(
|
||||
Paths.get(output + "/src/main/kotlin/org/openapitools/api/PetApiController.kt"),
|
||||
"@RequestMapping(\"\\${"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRequestMappingAnnotationController() throws IOException {
|
||||
File output = generatePetstoreWithRequestMappingMode(KotlinSpringServerCodegen.RequestMappingMode.controller);
|
||||
|
||||
// Check that the @RequestMapping annotation is not generated in the Api file
|
||||
assertFileNotContains(
|
||||
Paths.get(output + "/src/main/kotlin/org/openapitools/api/PetApi.kt"),
|
||||
"@RequestMapping(\"\\${"
|
||||
);
|
||||
// Check that the @RequestMapping annotation is generated in the ApiController file
|
||||
assertFileContains(
|
||||
Paths.get(output + "/src/main/kotlin/org/openapitools/api/PetApiController.kt"),
|
||||
"@RequestMapping(\"\\${"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRequestMappingAnnotationApiInterface() throws IOException {
|
||||
File output = generatePetstoreWithRequestMappingMode(KotlinSpringServerCodegen.RequestMappingMode.api_interface);
|
||||
|
||||
// Check that the @RequestMapping annotation is generated in the Api file
|
||||
assertFileContains(
|
||||
Paths.get(output + "/src/main/kotlin/org/openapitools/api/PetApi.kt"),
|
||||
"@RequestMapping(\"\\${"
|
||||
);
|
||||
// Check that the @RequestMapping annotation is not generated in the ApiController file
|
||||
assertFileNotContains(
|
||||
Paths.get(output + "/src/main/kotlin/org/openapitools/api/PetApiController.kt"),
|
||||
"@RequestMapping(\"\\${"
|
||||
);
|
||||
}
|
||||
|
||||
private static @NotNull File generatePetstoreWithRequestMappingMode(KotlinSpringServerCodegen.RequestMappingMode requestMappingMode) throws IOException {
|
||||
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
|
||||
output.deleteOnExit();
|
||||
|
||||
KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen();
|
||||
codegen.setOutputDir(output.getAbsolutePath());
|
||||
codegen.additionalProperties().put(KotlinSpringServerCodegen.DELEGATE_PATTERN, true);
|
||||
codegen.additionalProperties().put(KotlinSpringServerCodegen.USE_TAGS, true);
|
||||
codegen.additionalProperties().put(KotlinSpringServerCodegen.REQUEST_MAPPING_OPTION, requestMappingMode);
|
||||
|
||||
new DefaultGenerator()
|
||||
.opts(
|
||||
new ClientOptInput()
|
||||
.openAPI(TestUtils.parseSpec("src/test/resources/3_0/kotlin/petstore.yaml"))
|
||||
.config(codegen)
|
||||
)
|
||||
.generate();
|
||||
return output;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettersForConfigValues() throws Exception {
|
||||
final KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen();
|
||||
|
@ -26,7 +26,6 @@ import kotlin.collections.Map
|
||||
|
||||
@RestController
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
class PetApiController(@Autowired(required = true) val service: PetApiService) {
|
||||
|
||||
|
||||
|
@ -25,7 +25,6 @@ import kotlin.collections.Map
|
||||
|
||||
@RestController
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
class StoreApiController(@Autowired(required = true) val service: StoreApiService) {
|
||||
|
||||
|
||||
|
@ -25,7 +25,6 @@ import kotlin.collections.Map
|
||||
|
||||
@RestController
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
class UserApiController(@Autowired(required = true) val service: UserApiService) {
|
||||
|
||||
|
||||
|
@ -35,7 +35,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface PetApi {
|
||||
|
||||
fun getDelegate(): PetApiDelegate = object: PetApiDelegate {}
|
||||
|
@ -6,7 +6,6 @@ import java.util.Optional
|
||||
|
||||
@javax.annotation.Generated(value = ["org.openapitools.codegen.languages.KotlinSpringServerCodegen"], comments = "Generator version: 7.7.0-SNAPSHOT")
|
||||
@Controller
|
||||
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||
class PetApiController(
|
||||
@org.springframework.beans.factory.annotation.Autowired(required = false) delegate: PetApiDelegate?
|
||||
) : PetApi {
|
||||
|
@ -34,7 +34,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface StoreApi {
|
||||
|
||||
fun getDelegate(): StoreApiDelegate = object: StoreApiDelegate {}
|
||||
|
@ -6,7 +6,6 @@ import java.util.Optional
|
||||
|
||||
@javax.annotation.Generated(value = ["org.openapitools.codegen.languages.KotlinSpringServerCodegen"], comments = "Generator version: 7.7.0-SNAPSHOT")
|
||||
@Controller
|
||||
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||
class StoreApiController(
|
||||
@org.springframework.beans.factory.annotation.Autowired(required = false) delegate: StoreApiDelegate?
|
||||
) : StoreApi {
|
||||
|
@ -34,7 +34,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface UserApi {
|
||||
|
||||
fun getDelegate(): UserApiDelegate = object: UserApiDelegate {}
|
||||
|
@ -6,7 +6,6 @@ import java.util.Optional
|
||||
|
||||
@javax.annotation.Generated(value = ["org.openapitools.codegen.languages.KotlinSpringServerCodegen"], comments = "Generator version: 7.7.0-SNAPSHOT")
|
||||
@Controller
|
||||
@RequestMapping("\${openapi.openAPIPetstore.base-path:/v2}")
|
||||
class UserApiController(
|
||||
@org.springframework.beans.factory.annotation.Autowired(required = false) delegate: UserApiDelegate?
|
||||
) : UserApi {
|
||||
|
@ -35,7 +35,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface FakeApi {
|
||||
|
||||
@Operation(
|
||||
|
@ -35,7 +35,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface FakeClassnameTestApi {
|
||||
|
||||
@Operation(
|
||||
|
@ -35,7 +35,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface FooApi {
|
||||
|
||||
@Operation(
|
||||
|
@ -36,7 +36,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface PetApi {
|
||||
|
||||
@Operation(
|
||||
|
@ -35,7 +35,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface StoreApi {
|
||||
|
||||
@Operation(
|
||||
|
@ -35,7 +35,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface UserApi {
|
||||
|
||||
@Operation(
|
||||
|
@ -36,7 +36,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface PetApi {
|
||||
|
||||
@Operation(
|
||||
|
@ -35,7 +35,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface StoreApi {
|
||||
|
||||
@Operation(
|
||||
|
@ -35,7 +35,6 @@ import kotlin.collections.List
|
||||
import kotlin.collections.Map
|
||||
|
||||
@Validated
|
||||
@RequestMapping("\${api.base-path:/v2}")
|
||||
interface UserApi {
|
||||
|
||||
@Operation(
|
||||
|
Loading…
x
Reference in New Issue
Block a user