Skip to content

Commit 115e29c

Browse files
committedJul 19, 2024·
fix OpenAPITools#18555 kotlin-spring generator flag appendRequestToHandler generates broken code when used with flag delegatePattern
1 parent e542b06 commit 115e29c

File tree

9 files changed

+99
-62
lines changed

9 files changed

+99
-62
lines changed
 

Diff for: ‎bin/configs/kotlin-spring-boot-delegate.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ additionalProperties:
88
annotationLibrary: swagger2
99
useSwaggerUI: "true"
1010
delegatePattern: "true"
11+
appendRequestToHandler: "true"
1112
beanValidations: "true"
1213
requestMappingMode: none

Diff for: ‎modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinSpringServerCodegen.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,7 @@ public void setReturnContainer(final String returnContainer) {
875875
final List<CodegenParameter> allParams = operation.allParams;
876876
if (allParams != null) {
877877
if (this.isAppendRequestToHandler()) {
878-
allParams.add(new RequestCodegenParameter(true));
878+
allParams.add(new RequestCodegenParameter());
879879
}
880880
allParams.forEach(param ->
881881
// This is necessary in case 'modelMutable' is enabled,
@@ -972,7 +972,16 @@ protected boolean needToImport(String type) {
972972
@Data
973973
@EqualsAndHashCode(callSuper = true)
974974
static class RequestCodegenParameter extends CodegenParameter {
975-
boolean isRequestObject;
975+
976+
boolean isRequestObject = true;
977+
978+
public RequestCodegenParameter() {
979+
this.isOptional = false;
980+
this.required = true;
981+
this.paramName = "serverHttpRequest";
982+
this.dataType = "ServerHttpRequest";
983+
}
984+
976985
}
977986

978987
public RequestMappingMode getRequestMappingMode() {

Diff for: ‎modules/openapi-generator/src/main/resources/kotlin-spring/apiDelegate.mustache

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import org.springframework.http.MediaType
77
import org.springframework.http.ResponseEntity
88
import org.springframework.web.context.request.NativeWebRequest
99
import org.springframework.core.io.Resource
10+
{{#appendRequestToHandler}}
11+
import org.springframework.http.server.reactive.ServerHttpRequest
12+
{{/appendRequestToHandler}}
1013
{{#reactive}}
1114
import kotlinx.coroutines.flow.Flow
1215
{{/reactive}}

Diff for: ‎samples/server/petstore/kotlin-springboot-delegate/src/main/kotlin/org/openapitools/api/PetApi.kt

+17-16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.security.*
1515
import org.springframework.http.HttpStatus
1616
import org.springframework.http.MediaType
1717
import org.springframework.http.ResponseEntity
18+
import org.springframework.http.server.reactive.ServerHttpRequest
1819

1920
import org.springframework.web.bind.annotation.*
2021
import org.springframework.validation.annotation.Validated
@@ -57,8 +58,8 @@ interface PetApi {
5758
produces = ["application/xml", "application/json"],
5859
consumes = ["application/json", "application/xml"]
5960
)
60-
fun addPet(@Parameter(description = "Pet object that needs to be added to the store", required = true) @Valid @RequestBody pet: Pet): ResponseEntity<Pet> {
61-
return getDelegate().addPet(pet)
61+
fun addPet(@Parameter(description = "Pet object that needs to be added to the store", required = true) @Valid @RequestBody pet: Pet,serverHttpRequest: ServerHttpRequest): ResponseEntity<Pet> {
62+
return getDelegate().addPet(pet, serverHttpRequest)
6263
}
6364

6465
@Operation(
@@ -75,8 +76,8 @@ interface PetApi {
7576
method = [RequestMethod.DELETE],
7677
value = ["/pet/{petId}"]
7778
)
78-
fun deletePet(@Parameter(description = "Pet id to delete", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "", `in` = ParameterIn.HEADER) @RequestHeader(value = "api_key", required = false) apiKey: kotlin.String?): ResponseEntity<Unit> {
79-
return getDelegate().deletePet(petId, apiKey)
79+
fun deletePet(@Parameter(description = "Pet id to delete", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "", `in` = ParameterIn.HEADER) @RequestHeader(value = "api_key", required = false) apiKey: kotlin.String?,serverHttpRequest: ServerHttpRequest): ResponseEntity<Unit> {
80+
return getDelegate().deletePet(petId, apiKey, serverHttpRequest)
8081
}
8182

8283
@Operation(
@@ -95,8 +96,8 @@ interface PetApi {
9596
value = ["/pet/findByStatus"],
9697
produces = ["application/xml", "application/json"]
9798
)
98-
fun findPetsByStatus(@NotNull @Parameter(description = "Status values that need to be considered for filter", required = true, schema = Schema(allowableValues = ["available", "pending", "sold"])) @Valid @RequestParam(value = "status", required = true) status: kotlin.collections.List<kotlin.String>): ResponseEntity<List<Pet>> {
99-
return getDelegate().findPetsByStatus(status)
99+
fun findPetsByStatus(@NotNull @Parameter(description = "Status values that need to be considered for filter", required = true, schema = Schema(allowableValues = ["available", "pending", "sold"])) @Valid @RequestParam(value = "status", required = true) status: kotlin.collections.List<kotlin.String>,serverHttpRequest: ServerHttpRequest): ResponseEntity<List<Pet>> {
100+
return getDelegate().findPetsByStatus(status, serverHttpRequest)
100101
}
101102

102103
@Operation(
@@ -115,8 +116,8 @@ interface PetApi {
115116
value = ["/pet/findByTags"],
116117
produces = ["application/xml", "application/json"]
117118
)
118-
fun findPetsByTags(@NotNull @Parameter(description = "Tags to filter by", required = true) @Valid @RequestParam(value = "tags", required = true) tags: kotlin.collections.List<kotlin.String>): ResponseEntity<List<Pet>> {
119-
return getDelegate().findPetsByTags(tags)
119+
fun findPetsByTags(@NotNull @Parameter(description = "Tags to filter by", required = true) @Valid @RequestParam(value = "tags", required = true) tags: kotlin.collections.List<kotlin.String>,serverHttpRequest: ServerHttpRequest): ResponseEntity<List<Pet>> {
120+
return getDelegate().findPetsByTags(tags, serverHttpRequest)
120121
}
121122

122123
@Operation(
@@ -136,8 +137,8 @@ interface PetApi {
136137
value = ["/pet/{petId}"],
137138
produces = ["application/xml", "application/json"]
138139
)
139-
fun getPetById(@Parameter(description = "ID of pet to return", required = true) @PathVariable("petId") petId: kotlin.Long): ResponseEntity<Pet> {
140-
return getDelegate().getPetById(petId)
140+
fun getPetById(@Parameter(description = "ID of pet to return", required = true) @PathVariable("petId") petId: kotlin.Long,serverHttpRequest: ServerHttpRequest): ResponseEntity<Pet> {
141+
return getDelegate().getPetById(petId, serverHttpRequest)
141142
}
142143

143144
@Operation(
@@ -159,8 +160,8 @@ interface PetApi {
159160
produces = ["application/xml", "application/json"],
160161
consumes = ["application/json", "application/xml"]
161162
)
162-
fun updatePet(@Parameter(description = "Pet object that needs to be added to the store", required = true) @Valid @RequestBody pet: Pet): ResponseEntity<Pet> {
163-
return getDelegate().updatePet(pet)
163+
fun updatePet(@Parameter(description = "Pet object that needs to be added to the store", required = true) @Valid @RequestBody pet: Pet,serverHttpRequest: ServerHttpRequest): ResponseEntity<Pet> {
164+
return getDelegate().updatePet(pet, serverHttpRequest)
164165
}
165166

166167
@Operation(
@@ -178,8 +179,8 @@ interface PetApi {
178179
value = ["/pet/{petId}"],
179180
consumes = ["application/x-www-form-urlencoded"]
180181
)
181-
fun updatePetWithForm(@Parameter(description = "ID of pet that needs to be updated", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "Updated name of the pet") @RequestParam(value = "name", required = false) name: kotlin.String? ,@Parameter(description = "Updated status of the pet") @RequestParam(value = "status", required = false) status: kotlin.String? ): ResponseEntity<Unit> {
182-
return getDelegate().updatePetWithForm(petId, name, status)
182+
fun updatePetWithForm(@Parameter(description = "ID of pet that needs to be updated", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "Updated name of the pet") @RequestParam(value = "name", required = false) name: kotlin.String? ,@Parameter(description = "Updated status of the pet") @RequestParam(value = "status", required = false) status: kotlin.String? ,serverHttpRequest: ServerHttpRequest): ResponseEntity<Unit> {
183+
return getDelegate().updatePetWithForm(petId, name, status, serverHttpRequest)
183184
}
184185

185186
@Operation(
@@ -198,7 +199,7 @@ interface PetApi {
198199
produces = ["application/json"],
199200
consumes = ["multipart/form-data"]
200201
)
201-
fun uploadFile(@Parameter(description = "ID of pet to update", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "Additional data to pass to server") @RequestParam(value = "additionalMetadata", required = false) additionalMetadata: kotlin.String? ,@Parameter(description = "file to upload") @Valid @RequestPart("file", required = false) file: org.springframework.core.io.Resource?): ResponseEntity<ModelApiResponse> {
202-
return getDelegate().uploadFile(petId, additionalMetadata, file)
202+
fun uploadFile(@Parameter(description = "ID of pet to update", required = true) @PathVariable("petId") petId: kotlin.Long,@Parameter(description = "Additional data to pass to server") @RequestParam(value = "additionalMetadata", required = false) additionalMetadata: kotlin.String? ,@Parameter(description = "file to upload") @Valid @RequestPart("file", required = false) file: org.springframework.core.io.Resource?,serverHttpRequest: ServerHttpRequest): ResponseEntity<ModelApiResponse> {
203+
return getDelegate().uploadFile(petId, additionalMetadata, file, serverHttpRequest)
203204
}
204205
}

Diff for: ‎samples/server/petstore/kotlin-springboot-delegate/src/main/kotlin/org/openapitools/api/PetApiDelegate.kt

+17-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import org.springframework.http.MediaType
77
import org.springframework.http.ResponseEntity
88
import org.springframework.web.context.request.NativeWebRequest
99
import org.springframework.core.io.Resource
10+
import org.springframework.http.server.reactive.ServerHttpRequest
1011

1112
import java.util.Optional
1213

@@ -22,7 +23,8 @@ interface PetApiDelegate {
2223
/**
2324
* @see PetApi#addPet
2425
*/
25-
fun addPet(pet: Pet): ResponseEntity<Pet> {
26+
fun addPet(pet: Pet,
27+
serverHttpRequest: ServerHttpRequest): ResponseEntity<Pet> {
2628
getRequest().ifPresent { request ->
2729
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
2830
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
@@ -44,7 +46,8 @@ interface PetApiDelegate {
4446
* @see PetApi#deletePet
4547
*/
4648
fun deletePet(petId: kotlin.Long,
47-
apiKey: kotlin.String?): ResponseEntity<Unit> {
49+
apiKey: kotlin.String?,
50+
serverHttpRequest: ServerHttpRequest): ResponseEntity<Unit> {
4851
return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
4952

5053
}
@@ -53,7 +56,8 @@ interface PetApiDelegate {
5356
/**
5457
* @see PetApi#findPetsByStatus
5558
*/
56-
fun findPetsByStatus(status: kotlin.collections.List<kotlin.String>): ResponseEntity<List<Pet>> {
59+
fun findPetsByStatus(status: kotlin.collections.List<kotlin.String>,
60+
serverHttpRequest: ServerHttpRequest): ResponseEntity<List<Pet>> {
5761
getRequest().ifPresent { request ->
5862
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
5963
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
@@ -74,7 +78,8 @@ interface PetApiDelegate {
7478
/**
7579
* @see PetApi#findPetsByTags
7680
*/
77-
fun findPetsByTags(tags: kotlin.collections.List<kotlin.String>): ResponseEntity<List<Pet>> {
81+
fun findPetsByTags(tags: kotlin.collections.List<kotlin.String>,
82+
serverHttpRequest: ServerHttpRequest): ResponseEntity<List<Pet>> {
7883
getRequest().ifPresent { request ->
7984
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
8085
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
@@ -95,7 +100,8 @@ interface PetApiDelegate {
95100
/**
96101
* @see PetApi#getPetById
97102
*/
98-
fun getPetById(petId: kotlin.Long): ResponseEntity<Pet> {
103+
fun getPetById(petId: kotlin.Long,
104+
serverHttpRequest: ServerHttpRequest): ResponseEntity<Pet> {
99105
getRequest().ifPresent { request ->
100106
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
101107
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
@@ -116,7 +122,8 @@ interface PetApiDelegate {
116122
/**
117123
* @see PetApi#updatePet
118124
*/
119-
fun updatePet(pet: Pet): ResponseEntity<Pet> {
125+
fun updatePet(pet: Pet,
126+
serverHttpRequest: ServerHttpRequest): ResponseEntity<Pet> {
120127
getRequest().ifPresent { request ->
121128
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
122129
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
@@ -139,7 +146,8 @@ interface PetApiDelegate {
139146
*/
140147
fun updatePetWithForm(petId: kotlin.Long,
141148
name: kotlin.String?,
142-
status: kotlin.String?): ResponseEntity<Unit> {
149+
status: kotlin.String?,
150+
serverHttpRequest: ServerHttpRequest): ResponseEntity<Unit> {
143151
return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
144152

145153
}
@@ -150,7 +158,8 @@ interface PetApiDelegate {
150158
*/
151159
fun uploadFile(petId: kotlin.Long,
152160
additionalMetadata: kotlin.String?,
153-
file: Resource?): ResponseEntity<ModelApiResponse> {
161+
file: Resource?,
162+
serverHttpRequest: ServerHttpRequest): ResponseEntity<ModelApiResponse> {
154163
getRequest().ifPresent { request ->
155164
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
156165
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {

Diff for: ‎samples/server/petstore/kotlin-springboot-delegate/src/main/kotlin/org/openapitools/api/StoreApi.kt

+9-8
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import io.swagger.v3.oas.annotations.security.*
1414
import org.springframework.http.HttpStatus
1515
import org.springframework.http.MediaType
1616
import org.springframework.http.ResponseEntity
17+
import org.springframework.http.server.reactive.ServerHttpRequest
1718

1819
import org.springframework.web.bind.annotation.*
1920
import org.springframework.validation.annotation.Validated
@@ -53,8 +54,8 @@ interface StoreApi {
5354
method = [RequestMethod.DELETE],
5455
value = ["/store/order/{orderId}"]
5556
)
56-
fun deleteOrder(@Parameter(description = "ID of the order that needs to be deleted", required = true) @PathVariable("orderId") orderId: kotlin.String): ResponseEntity<Unit> {
57-
return getDelegate().deleteOrder(orderId)
57+
fun deleteOrder(@Parameter(description = "ID of the order that needs to be deleted", required = true) @PathVariable("orderId") orderId: kotlin.String,serverHttpRequest: ServerHttpRequest): ResponseEntity<Unit> {
58+
return getDelegate().deleteOrder(orderId, serverHttpRequest)
5859
}
5960

6061
@Operation(
@@ -72,8 +73,8 @@ interface StoreApi {
7273
value = ["/store/inventory"],
7374
produces = ["application/json"]
7475
)
75-
fun getInventory(): ResponseEntity<Map<String, kotlin.Int>> {
76-
return getDelegate().getInventory()
76+
fun getInventory(serverHttpRequest: ServerHttpRequest): ResponseEntity<Map<String, kotlin.Int>> {
77+
return getDelegate().getInventory(serverHttpRequest)
7778
}
7879

7980
@Operation(
@@ -92,8 +93,8 @@ interface StoreApi {
9293
value = ["/store/order/{orderId}"],
9394
produces = ["application/xml", "application/json"]
9495
)
95-
fun getOrderById(@Min(1L) @Max(5L) @Parameter(description = "ID of pet that needs to be fetched", required = true) @PathVariable("orderId") orderId: kotlin.Long): ResponseEntity<Order> {
96-
return getDelegate().getOrderById(orderId)
96+
fun getOrderById(@Min(1L) @Max(5L) @Parameter(description = "ID of pet that needs to be fetched", required = true) @PathVariable("orderId") orderId: kotlin.Long,serverHttpRequest: ServerHttpRequest): ResponseEntity<Order> {
97+
return getDelegate().getOrderById(orderId, serverHttpRequest)
9798
}
9899

99100
@Operation(
@@ -112,7 +113,7 @@ interface StoreApi {
112113
produces = ["application/xml", "application/json"],
113114
consumes = ["application/json"]
114115
)
115-
fun placeOrder(@Parameter(description = "order placed for purchasing the pet", required = true) @Valid @RequestBody order: Order): ResponseEntity<Order> {
116-
return getDelegate().placeOrder(order)
116+
fun placeOrder(@Parameter(description = "order placed for purchasing the pet", required = true) @Valid @RequestBody order: Order,serverHttpRequest: ServerHttpRequest): ResponseEntity<Order> {
117+
return getDelegate().placeOrder(order, serverHttpRequest)
117118
}
118119
}

Diff for: ‎samples/server/petstore/kotlin-springboot-delegate/src/main/kotlin/org/openapitools/api/StoreApiDelegate.kt

+8-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.springframework.http.MediaType
66
import org.springframework.http.ResponseEntity
77
import org.springframework.web.context.request.NativeWebRequest
88
import org.springframework.core.io.Resource
9+
import org.springframework.http.server.reactive.ServerHttpRequest
910

1011
import java.util.Optional
1112

@@ -21,7 +22,8 @@ interface StoreApiDelegate {
2122
/**
2223
* @see StoreApi#deleteOrder
2324
*/
24-
fun deleteOrder(orderId: kotlin.String): ResponseEntity<Unit> {
25+
fun deleteOrder(orderId: kotlin.String,
26+
serverHttpRequest: ServerHttpRequest): ResponseEntity<Unit> {
2527
return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
2628

2729
}
@@ -30,7 +32,7 @@ interface StoreApiDelegate {
3032
/**
3133
* @see StoreApi#getInventory
3234
*/
33-
fun getInventory(): ResponseEntity<Map<String, kotlin.Int>> {
35+
fun getInventory(serverHttpRequest: ServerHttpRequest): ResponseEntity<Map<String, kotlin.Int>> {
3436
return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
3537

3638
}
@@ -39,7 +41,8 @@ interface StoreApiDelegate {
3941
/**
4042
* @see StoreApi#getOrderById
4143
*/
42-
fun getOrderById(orderId: kotlin.Long): ResponseEntity<Order> {
44+
fun getOrderById(orderId: kotlin.Long,
45+
serverHttpRequest: ServerHttpRequest): ResponseEntity<Order> {
4346
getRequest().ifPresent { request ->
4447
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
4548
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
@@ -60,7 +63,8 @@ interface StoreApiDelegate {
6063
/**
6164
* @see StoreApi#placeOrder
6265
*/
63-
fun placeOrder(order: Order): ResponseEntity<Order> {
66+
fun placeOrder(order: Order,
67+
serverHttpRequest: ServerHttpRequest): ResponseEntity<Order> {
6468
getRequest().ifPresent { request ->
6569
for (mediaType in MediaType.parseMediaTypes(request.getHeader("Accept"))) {
6670
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {

0 commit comments

Comments
 (0)
Please sign in to comment.