Skip to content

Commit 7717eb8

Browse files
authored
[kotlin-server][JAX-RS] useTags: default to false, class names from tags, @path('/') when useTags=false (#23379)
* set commonPath only when useTags = true * regenerate samples, add test * ci: retrigger checks
1 parent 866e814 commit 7717eb8

File tree

8 files changed

+80
-65
lines changed

8 files changed

+80
-65
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.openapitools.codegen.languages;
1919

2020
import com.google.common.collect.ImmutableMap;
21-
import io.swagger.v3.oas.models.Operation;
2221
import lombok.Getter;
2322
import lombok.Setter;
2423
import org.apache.commons.lang3.StringUtils;
@@ -706,22 +705,29 @@ public void postProcess() {
706705
@Override
707706
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
708707
OperationMap operations = objs.getOperations();
709-
// For JAXRS_SPEC library, compute commonPath similar to JavaJaxRS generators
708+
// For JAXRS_SPEC library, compute commonPath when useTags=true, otherwise default to "/"
710709
if (operations != null && Objects.equals(library, Constants.JAXRS_SPEC)) {
711-
String commonPath = null;
712-
List<CodegenOperation> ops = operations.getOperation();
713-
for (CodegenOperation operation : ops) {
714-
if (commonPath == null) {
715-
commonPath = operation.path;
716-
} else {
717-
commonPath = getCommonPath(commonPath, operation.path);
710+
if (useTags) {
711+
String commonPath = null;
712+
List<CodegenOperation> ops = operations.getOperation();
713+
for (CodegenOperation operation : ops) {
714+
if (commonPath == null) {
715+
commonPath = operation.path;
716+
} else {
717+
commonPath = getCommonPath(commonPath, operation.path);
718+
}
718719
}
720+
for (CodegenOperation co : ops) {
721+
co.path = StringUtils.removeStart(co.path, commonPath);
722+
co.subresourceOperation = co.path.length() > 1;
723+
}
724+
objs.put("commonPath", "/".equals(commonPath) ? StringUtils.EMPTY : commonPath);
725+
} else {
726+
for (CodegenOperation co : operations.getOperation()) {
727+
co.subresourceOperation = !co.path.isEmpty();
728+
}
729+
objs.put("commonPath", "/");
719730
}
720-
for (CodegenOperation co : ops) {
721-
co.path = StringUtils.removeStart(co.path, commonPath);
722-
co.subresourceOperation = co.path.length() > 1;
723-
}
724-
objs.put("commonPath", "/".equals(commonPath) ? StringUtils.EMPTY : commonPath);
725731
}
726732
// The following processing breaks the JAX-RS spec, so we only do this for the other libs.
727733
if (operations != null && !Objects.equals(library, Constants.JAXRS_SPEC)) {
@@ -783,24 +789,6 @@ public void setReturnContainer(final String returnContainer) {
783789
return objs;
784790
}
785791

786-
@Override
787-
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
788-
if (Objects.equals(library, Constants.JAXRS_SPEC) && additionalProperties.containsKey(USE_TAGS) && !useTags) {
789-
String basePath = StringUtils.substringBefore(StringUtils.removeStart(resourcePath, "/"), "/");
790-
if (!StringUtils.isEmpty(basePath)) {
791-
co.subresourceOperation = !co.path.isEmpty();
792-
}
793-
co.baseName = basePath;
794-
if (StringUtils.isEmpty(co.baseName) || StringUtils.containsAny(co.baseName, "{", "}")) {
795-
co.baseName = "default";
796-
}
797-
final List<CodegenOperation> opList = operations.computeIfAbsent(co.baseName, k -> new ArrayList<>());
798-
opList.add(co);
799-
} else {
800-
super.addOperationToGroup(tag, resourcePath, operation, co, operations);
801-
}
802-
}
803-
804792
private boolean isJavalin() {
805793
return Constants.JAVALIN5.equals(library) || Constants.JAVALIN6.equals(library);
806794
}

modules/openapi-generator/src/main/resources/kotlin-server/README.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ All URIs are relative to *{{{basePath}}}*
3535

3636
Class | Method | HTTP request | Description
3737
------------ | ------------- | ------------- | -------------
38-
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{#commonPath}}{{commonPath}}{{/commonPath}}{{path}} | {{{summary}}}
38+
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{#useTags}}{{commonPath}}{{/useTags}}{{path}} | {{{summary}}}
3939
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
4040
{{/generateApiDocs}}
4141

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

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ public void useTags_commonPathIsComputedForJaxrsSpecLibrary() throws IOException
540540
}
541541

542542
@Test
543-
public void useTags_false_operationsGroupedByPathBaseForJaxrsSpecLibrary() throws IOException {
543+
public void useTags_false_classNameFromTagsAndRootPathForJaxrsSpecLibrary() throws IOException {
544544
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
545545
output.deleteOnExit();
546546

@@ -557,13 +557,39 @@ public void useTags_false_operationsGroupedByPathBaseForJaxrsSpecLibrary() throw
557557
String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
558558
Path petApi = Paths.get(outputPath + "/apis/PetApi.kt");
559559

560-
assertFileContains(
561-
petApi,
562-
"class PetApi"
560+
assertFileContains(petApi,
561+
"class PetApi",
562+
"@Path(\"/\")",
563+
"@Path(\"/pet\")",
564+
"@Path(\"/pet/{petId}\")"
563565
);
564-
assertFileNotContains(
565-
petApi,
566-
"class DefaultApi"
566+
assertFileNotContains(petApi, "@Path(\"/pet\")".replace("/pet", "/store"));
567+
}
568+
569+
@Test
570+
public void useTags_notSpecified_behavesLikeUseTagsFalseForJaxrsSpecLibrary() throws IOException {
571+
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
572+
output.deleteOnExit();
573+
574+
KotlinServerCodegen codegen = new KotlinServerCodegen();
575+
codegen.setOutputDir(output.getAbsolutePath());
576+
codegen.additionalProperties().put(LIBRARY, JAXRS_SPEC);
577+
// useTags intentionally NOT set — must default to false
578+
579+
new DefaultGenerator().opts(new ClientOptInput()
580+
.openAPI(TestUtils.parseSpec("src/test/resources/2_0/petstore.yaml"))
581+
.config(codegen))
582+
.generate();
583+
584+
String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
585+
Path petApi = Paths.get(outputPath + "/apis/PetApi.kt");
586+
587+
assertFileContains(petApi,
588+
"class PetApi",
589+
"@Path(\"/\")",
590+
"@Path(\"/pet\")",
591+
"@Path(\"/pet/{petId}\")"
567592
);
593+
assertFileNotContains(petApi, "@Path(\"/store\")");
568594
}
569595
}

samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import java.io.InputStream
1010

1111

1212

13-
@Path("")
13+
@Path("/")
1414
@jakarta.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT")
1515
interface StuffApi {
1616

samples/server/others/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import java.io.InputStream
99

1010

1111

12-
@Path("/test/parameters/{path_default}/{path_nullable}")
12+
@Path("/")
1313
@javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT")
1414
class DefaultApi {
1515

1616
@GET
17+
@Path("/test/parameters/{path_default}/{path_nullable}")
1718
suspend fun findPetsByStatus(@PathParam("path_default") pathDefault: kotlin.String,@PathParam("path_nullable") pathNullable: kotlin.String,@QueryParam("query_default") @DefaultValue("available") queryDefault: kotlin.String,@QueryParam("query_default_enum") @DefaultValue("B") queryDefaultEnum: kotlin.String,@QueryParam("query_default_int") @DefaultValue("3") queryDefaultInt: java.math.BigDecimal,@HeaderParam("header_default") @DefaultValue("available") headerDefault: kotlin.String,@HeaderParam("header_default_enum") @DefaultValue("B") headerDefaultEnum: kotlin.String,@HeaderParam("header_default_int") @DefaultValue("3") headerDefaultInt: java.math.BigDecimal,@CookieParam("cookie_default") @DefaultValue("available") cookieDefault: kotlin.String,@CookieParam("cookie_default_enum") @DefaultValue("B") cookieDefaultEnum: kotlin.String,@CookieParam("cookie_default_int") @DefaultValue("3") cookieDefaultInt: java.math.BigDecimal,@QueryParam("query_nullable") queryNullable: kotlin.String?,@HeaderParam("header_nullable") headerNullable: kotlin.String?,@CookieParam("cookie_nullable") cookieNullable: kotlin.String?,@QueryParam("\$query-\$dollar-sign") dollarQueryDollarDollarSign: kotlin.String?): Response {
1819
return Response.ok().entity("magic!").build();
1920
}

samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,46 @@ import java.io.InputStream
1111

1212

1313

14-
@Path("/pet")
14+
@Path("/")
1515
@javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT")
1616
interface PetApi {
1717

1818
@POST
19-
@Path("")
19+
@Path("/pet")
2020
@Consumes("application/json", "application/xml")
2121
fun addPet( body: Pet): io.smallrye.mutiny.Uni<Response>
2222

2323
@DELETE
24-
@Path("/{petId}")
24+
@Path("/pet/{petId}")
2525
fun deletePet(@PathParam("petId") petId: kotlin.Long,@HeaderParam("api_key") apiKey: kotlin.String?): io.smallrye.mutiny.Uni<Response>
2626

2727
@GET
28-
@Path("/findByStatus")
28+
@Path("/pet/findByStatus")
2929
@Produces("application/xml", "application/json")
3030
fun findPetsByStatus(@QueryParam("status") status: kotlin.collections.List<kotlin.String>): io.smallrye.mutiny.Uni<Response>
3131

3232
@GET
33-
@Path("/findByTags")
33+
@Path("/pet/findByTags")
3434
@Produces("application/xml", "application/json")
3535
fun findPetsByTags(@QueryParam("tags") tags: kotlin.collections.List<kotlin.String>): io.smallrye.mutiny.Uni<Response>
3636

3737
@GET
38-
@Path("/{petId}")
38+
@Path("/pet/{petId}")
3939
@Produces("application/xml", "application/json")
4040
fun getPetById(@PathParam("petId") petId: kotlin.Long): io.smallrye.mutiny.Uni<Response>
4141

4242
@PUT
43-
@Path("")
43+
@Path("/pet")
4444
@Consumes("application/json", "application/xml")
4545
fun updatePet( body: Pet): io.smallrye.mutiny.Uni<Response>
4646

4747
@POST
48-
@Path("/{petId}")
48+
@Path("/pet/{petId}")
4949
@Consumes("application/x-www-form-urlencoded")
5050
fun updatePetWithForm(@PathParam("petId") petId: kotlin.Long,@FormParam(value = "name") name: kotlin.String?,@FormParam(value = "status") status: kotlin.String?): io.smallrye.mutiny.Uni<Response>
5151

5252
@POST
53-
@Path("/{petId}/uploadImage")
53+
@Path("/pet/{petId}/uploadImage")
5454
@Consumes("multipart/form-data")
5555
@Produces("application/json")
5656
fun uploadFile(@PathParam("petId") petId: kotlin.Long,@FormParam(value = "additionalMetadata") additionalMetadata: kotlin.String?, @FormParam(value = "file") fileInputStream: InputStream?): io.smallrye.mutiny.Uni<Response>

samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,26 @@ import java.io.InputStream
1010

1111

1212

13-
@Path("/store")
13+
@Path("/")
1414
@javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT")
1515
interface StoreApi {
1616

1717
@DELETE
18-
@Path("/order/{orderId}")
18+
@Path("/store/order/{orderId}")
1919
fun deleteOrder(@PathParam("orderId") orderId: kotlin.String): io.smallrye.mutiny.Uni<Response>
2020

2121
@GET
22-
@Path("/inventory")
22+
@Path("/store/inventory")
2323
@Produces("application/json")
2424
fun getInventory(): io.smallrye.mutiny.Uni<Response>
2525

2626
@GET
27-
@Path("/order/{orderId}")
27+
@Path("/store/order/{orderId}")
2828
@Produces("application/xml", "application/json")
2929
fun getOrderById(@PathParam("orderId") orderId: kotlin.Long): io.smallrye.mutiny.Uni<Response>
3030

3131
@POST
32-
@Path("/order")
32+
@Path("/store/order")
3333
@Produces("application/xml", "application/json")
3434
fun placeOrder( body: Order): io.smallrye.mutiny.Uni<Response>
3535
}

samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,41 @@ import java.io.InputStream
1010

1111

1212

13-
@Path("/user")
13+
@Path("/")
1414
@javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT")
1515
interface UserApi {
1616

1717
@POST
18-
@Path("")
18+
@Path("/user")
1919
fun createUser( body: User): io.smallrye.mutiny.Uni<Response>
2020

2121
@POST
22-
@Path("/createWithArray")
22+
@Path("/user/createWithArray")
2323
fun createUsersWithArrayInput( body: kotlin.collections.List<User>): io.smallrye.mutiny.Uni<Response>
2424

2525
@POST
26-
@Path("/createWithList")
26+
@Path("/user/createWithList")
2727
fun createUsersWithListInput( body: kotlin.collections.List<User>): io.smallrye.mutiny.Uni<Response>
2828

2929
@DELETE
30-
@Path("/{username}")
30+
@Path("/user/{username}")
3131
fun deleteUser(@PathParam("username") username: kotlin.String): io.smallrye.mutiny.Uni<Response>
3232

3333
@GET
34-
@Path("/{username}")
34+
@Path("/user/{username}")
3535
@Produces("application/xml", "application/json")
3636
fun getUserByName(@PathParam("username") username: kotlin.String): io.smallrye.mutiny.Uni<Response>
3737

3838
@GET
39-
@Path("/login")
39+
@Path("/user/login")
4040
@Produces("application/xml", "application/json")
4141
fun loginUser(@QueryParam("username") username: kotlin.String,@QueryParam("password") password: kotlin.String): io.smallrye.mutiny.Uni<Response>
4242

4343
@GET
44-
@Path("/logout")
44+
@Path("/user/logout")
4545
fun logoutUser(): io.smallrye.mutiny.Uni<Response>
4646

4747
@PUT
48-
@Path("/{username}")
48+
@Path("/user/{username}")
4949
fun updateUser(@PathParam("username") username: kotlin.String, body: User): io.smallrye.mutiny.Uni<Response>
5050
}

0 commit comments

Comments
 (0)