Skip to content

Commit a973d91

Browse files
authored
[BUG] [KOTLIN-SPRING] @HttpExchange in declarative interface does not support property placeholders (#22882)
* fix kotlin-spring declarative http interface * fix kotlin-spring declarative http interface * fix kotlin-spring declarative http interface
1 parent b07f286 commit a973d91

15 files changed

Lines changed: 29 additions & 7 deletions

File tree

bin/configs/kotlin-spring-declarative-interface-wrapped.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ additionalProperties:
1313
reactive: false
1414
useResponseEntity: true
1515
useFlowForArrayReturnType: false
16+
requestMappingMode: "api_interface"

modules/openapi-generator/src/main/resources/kotlin-spring/libraries/spring-declarative-http-interface/apiInterface.mustache

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ package {{package}}
66

77
{{#imports}}import {{import}}
88
{{/imports}}
9+
{{#useRequestMappingOnInterface}}
10+
import {{#apiPackage}}{{.}}.{{/apiPackage}}{{classname}}.Companion.BASE_PATH
11+
{{/useRequestMappingOnInterface}}
912

1013
{{#swagger2AnnotationLibrary}}
1114
import io.swagger.v3.oas.annotations.*
@@ -48,7 +51,7 @@ import kotlin.collections.List
4851
import kotlin.collections.Map
4952

5053
{{#useRequestMappingOnInterface}}
51-
@HttpExchange("\${api.base-path:{{contextPath}}}")
54+
@HttpExchange(BASE_PATH) // Generate with 'requestMappingMode' set to 'none' to skip the base path on the interface
5255
{{/useRequestMappingOnInterface}}
5356
{{#useBeanValidation}}
5457
@Validated
@@ -74,9 +77,7 @@ interface {{classname}} {
7477
{{/operation}}
7578
companion object {
7679
//for your own safety never directly reuse these path definitions in tests
77-
{{#useRequestMappingOnInterface}}
7880
const val BASE_PATH: String = "{{=<% %>=}}<%contextPath%><%={{ }}=%>"
79-
{{/useRequestMappingOnInterface}}
8081
{{#operation}}
8182
const val PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}}: String = "{{{path}}}"
8283
{{/operation}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,7 @@ public void generateHttpInterfaceReactiveWithReactorResponseEntity() throws Exce
10971097
+ " ): Mono<ResponseEntity<Order>>",
10981098
" companion object {\n"
10991099
+ " //for your own safety never directly reuse these path definitions in tests\n"
1100+
+ " const val BASE_PATH: String = \"/v2\"\n"
11001101
+ " const val PATH_DELETE_ORDER: String = \"/store/order/{orderId}\"\n"
11011102
+ " const val PATH_GET_INVENTORY: String = \"/store/inventory\"\n"
11021103
+ " const val PATH_GET_ORDER_BY_ID: String = \"/store/order/{orderId}\"\n"
@@ -1105,7 +1106,8 @@ public void generateHttpInterfaceReactiveWithReactorResponseEntity() throws Exce
11051106
);
11061107
assertFileNotContains(
11071108
path,
1108-
"suspend"
1109+
"suspend",
1110+
"@HttpExchange(BASE_PATH)" // this should not be present since "requestMappingMode" is set to "none"
11091111
);
11101112
}
11111113

@@ -1314,11 +1316,11 @@ public void generateHttpInterface() throws Exception {
13141316
generator.opts(input).generate();
13151317

13161318
Path path = Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/StoreApiClient.kt");
1317-
// Note: We use simple ${api.base-path:<default>} syntax because Spring's @HttpExchange
1318-
// doesn't properly resolve nested ${outer:${inner:default}} property placeholder syntax
1319+
// Note: We cannot use property placeholders as HttpServiceProxyFactory does not resolve them by default.
13191320
assertFileContains(
13201321
path,
1321-
"@HttpExchange(\"\\${api.base-path:/v2}\")",
1322+
"import org.openapitools.api.StoreApi.Companion.BASE_PATH",
1323+
"@HttpExchange(BASE_PATH) // Generate with 'requestMappingMode' set to 'none' to skip the base path on the interface", // this should be present since "requestMappingMode" is set to "api_interface"
13221324
" fun getInventory(\n"
13231325
+ " ): Map<String, kotlin.Int>",
13241326
" fun deleteOrder(\n"

samples/server/petstore/kotlin-spring-declarative-interface-reactive-coroutines/src/main/kotlin/org/openapitools/api/PetApiClient.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ interface PetApi {
109109

110110
companion object {
111111
//for your own safety never directly reuse these path definitions in tests
112+
const val BASE_PATH: String = "/v2"
112113
const val PATH_ADD_PET: String = "/pet"
113114
const val PATH_DELETE_PET: String = "/pet/{petId}"
114115
const val PATH_FIND_PETS_BY_STATUS: String = "/pet/findByStatus"

samples/server/petstore/kotlin-spring-declarative-interface-reactive-coroutines/src/main/kotlin/org/openapitools/api/StoreApiClient.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ interface StoreApi {
6565

6666
companion object {
6767
//for your own safety never directly reuse these path definitions in tests
68+
const val BASE_PATH: String = "/v2"
6869
const val PATH_DELETE_ORDER: String = "/store/order/{orderId}"
6970
const val PATH_GET_INVENTORY: String = "/store/inventory"
7071
const val PATH_GET_ORDER_BY_ID: String = "/store/order/{orderId}"

samples/server/petstore/kotlin-spring-declarative-interface-reactive-coroutines/src/main/kotlin/org/openapitools/api/UserApiClient.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ interface UserApi {
102102

103103
companion object {
104104
//for your own safety never directly reuse these path definitions in tests
105+
const val BASE_PATH: String = "/v2"
105106
const val PATH_CREATE_USER: String = "/user"
106107
const val PATH_CREATE_USERS_WITH_ARRAY_INPUT: String = "/user/createWithArray"
107108
const val PATH_CREATE_USERS_WITH_LIST_INPUT: String = "/user/createWithList"

samples/server/petstore/kotlin-spring-declarative-interface-reactive-reactor-wrapped/src/main/kotlin/org/openapitools/api/PetApiClient.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ interface PetApi {
109109

110110
companion object {
111111
//for your own safety never directly reuse these path definitions in tests
112+
const val BASE_PATH: String = "/v2"
112113
const val PATH_ADD_PET: String = "/pet"
113114
const val PATH_DELETE_PET: String = "/pet/{petId}"
114115
const val PATH_FIND_PETS_BY_STATUS: String = "/pet/findByStatus"

samples/server/petstore/kotlin-spring-declarative-interface-reactive-reactor-wrapped/src/main/kotlin/org/openapitools/api/StoreApiClient.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ interface StoreApi {
6666

6767
companion object {
6868
//for your own safety never directly reuse these path definitions in tests
69+
const val BASE_PATH: String = "/v2"
6970
const val PATH_DELETE_ORDER: String = "/store/order/{orderId}"
7071
const val PATH_GET_INVENTORY: String = "/store/inventory"
7172
const val PATH_GET_ORDER_BY_ID: String = "/store/order/{orderId}"

samples/server/petstore/kotlin-spring-declarative-interface-reactive-reactor-wrapped/src/main/kotlin/org/openapitools/api/UserApiClient.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ interface UserApi {
104104

105105
companion object {
106106
//for your own safety never directly reuse these path definitions in tests
107+
const val BASE_PATH: String = "/v2"
107108
const val PATH_CREATE_USER: String = "/user"
108109
const val PATH_CREATE_USERS_WITH_ARRAY_INPUT: String = "/user/createWithArray"
109110
const val PATH_CREATE_USERS_WITH_LIST_INPUT: String = "/user/createWithList"

samples/server/petstore/kotlin-spring-declarative-interface-wrapped/src/main/kotlin/org/openapitools/api/PetApiClient.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package org.openapitools.api
66

77
import org.openapitools.model.ModelApiResponse
88
import org.openapitools.model.Pet
9+
import org.openapitools.api.PetApi.Companion.BASE_PATH
910

1011
import io.swagger.v3.oas.annotations.*
1112
import io.swagger.v3.oas.annotations.enums.*
@@ -25,6 +26,7 @@ import jakarta.validation.constraints.*
2526
import kotlin.collections.List
2627
import kotlin.collections.Map
2728

29+
@HttpExchange(BASE_PATH) // Generate with 'requestMappingMode' set to 'none' to skip the base path on the interface
2830
@Validated
2931
interface PetApi {
3032

@@ -107,6 +109,7 @@ interface PetApi {
107109

108110
companion object {
109111
//for your own safety never directly reuse these path definitions in tests
112+
const val BASE_PATH: String = "/v2"
110113
const val PATH_ADD_PET: String = "/pet"
111114
const val PATH_DELETE_PET: String = "/pet/{petId}"
112115
const val PATH_FIND_PETS_BY_STATUS: String = "/pet/findByStatus"

0 commit comments

Comments
 (0)