From 92af81d3b4f0db0acadcaea5af8217d138f6e343 Mon Sep 17 00:00:00 2001 From: feczkob Date: Wed, 1 Apr 2026 23:15:37 +0200 Subject: [PATCH 1/6] Fix class names for useTags = false --- .../languages/KotlinServerCodegen.java | 88 +++++++++++++------ .../jaxrs-spec/apiInterface.mustache | 4 +- .../kotlin/KotlinServerCodegenTest.java | 41 +++++---- 3 files changed, 86 insertions(+), 47 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java index f8b0cb2c224b..0e540f263b6f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java @@ -18,12 +18,36 @@ package org.openapitools.codegen.languages; import com.google.common.collect.ImmutableMap; +import io.swagger.v3.oas.models.Operation; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import lombok.Getter; import lombok.Setter; import org.apache.commons.lang3.StringUtils; -import org.openapitools.codegen.*; +import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.CodegenDiscriminator; +import org.openapitools.codegen.CodegenModel; +import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.CodegenParameter; +import org.openapitools.codegen.CodegenProperty; +import org.openapitools.codegen.CodegenResponse; +import org.openapitools.codegen.CodegenType; +import org.openapitools.codegen.SupportingFile; import org.openapitools.codegen.languages.features.BeanValidationFeatures; -import org.openapitools.codegen.meta.features.*; +import org.openapitools.codegen.meta.features.DocumentationFeature; +import org.openapitools.codegen.meta.features.GlobalFeature; +import org.openapitools.codegen.meta.features.ParameterFeature; +import org.openapitools.codegen.meta.features.SchemaSupportFeature; +import org.openapitools.codegen.meta.features.SecurityFeature; +import org.openapitools.codegen.meta.features.WireFormatFeature; import org.openapitools.codegen.model.ModelMap; import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationMap; @@ -33,9 +57,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.util.*; - public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanValidationFeatures { public static final String DEFAULT_LIBRARY = Constants.KTOR; @@ -702,32 +723,45 @@ public void postProcess() { System.out.println("################################################################################"); } + @Override + public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) { + if (!Objects.equals(library, Constants.JAXRS_SPEC) || useTags) { + super.addOperationToGroup(tag, resourcePath, operation, co, operations); + return; + } + + final String basePath = StringUtils.substringBefore(resourcePath.startsWith("/") ? resourcePath.substring(1) : resourcePath, "/"); + if (!StringUtils.isEmpty(basePath)) { + co.subresourceOperation = !co.path.isEmpty(); + } + co.baseName = basePath; + if (StringUtils.isEmpty(co.baseName) || co.baseName.chars().anyMatch(ch -> ch == '{' || ch == '}')) { + co.baseName = "default"; + } + final List opList = operations.computeIfAbsent(co.baseName, k -> new ArrayList<>()); + opList.add(co); + } + @Override public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) { OperationMap operations = objs.getOperations(); - // For JAXRS_SPEC library, compute commonPath when useTags=true, otherwise default to "/" + // For JAXRS_SPEC library, compute commonPath for all library modes if (operations != null && Objects.equals(library, Constants.JAXRS_SPEC)) { - if (useTags) { - String commonPath = null; - List ops = operations.getOperation(); - for (CodegenOperation operation : ops) { - if (commonPath == null) { - commonPath = operation.path; - } else { - commonPath = getCommonPath(commonPath, operation.path); - } - } - for (CodegenOperation co : ops) { - co.path = StringUtils.removeStart(co.path, commonPath); - co.subresourceOperation = co.path.length() > 1; - } - objs.put("commonPath", "/".equals(commonPath) ? StringUtils.EMPTY : commonPath); - } else { - for (CodegenOperation co : operations.getOperation()) { - co.subresourceOperation = !co.path.isEmpty(); + List ops = operations.getOperation(); + // Compute commonPath from operations in this group (called once per API class) + String commonPath = null; + for (CodegenOperation operation : ops) { + if (commonPath == null) { + commonPath = operation.path; + } else { + commonPath = getCommonPath(commonPath, operation.path); } - objs.put("commonPath", "/"); } + for (CodegenOperation co : ops) { + co.path = StringUtils.removeStart(co.path, commonPath); + co.subresourceOperation = co.path.length() > 1; + } + objs.put("commonPath", "/".equals(commonPath) ? StringUtils.EMPTY : commonPath); } // The following processing breaks the JAX-RS spec, so we only do this for the other libs. if (operations != null && !Objects.equals(library, Constants.JAXRS_SPEC)) { @@ -801,8 +835,8 @@ private boolean isJavalin() { */ private boolean usesJacksonSerialization() { return Constants.JAVALIN5.equals(library) || - Constants.JAVALIN6.equals(library) || - Constants.JAXRS_SPEC.equals(library); + Constants.JAVALIN6.equals(library) || + Constants.JAXRS_SPEC.equals(library); } private boolean isKtor2Or3() { diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache index e5f33141a3ba..c1eccb534dba 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache @@ -1,5 +1,5 @@ - @{{httpMethod}} - @Path("{{{path}}}"){{#hasConsumes}} + @{{httpMethod}}{{#subresourceOperation}} + @Path("{{{path}}}"){{/subresourceOperation}}{{#hasConsumes}} @Consumes({{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}){{/hasConsumes}}{{#hasProduces}} @Produces({{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}){{/hasProduces}} {{#useCoroutines}}suspend {{/useCoroutines}}fun {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}){{#returnResponse}}: {{#useMutiny}}io.smallrye.mutiny.Uni<{{/useMutiny}}Response{{#useMutiny}}>{{/useMutiny}}{{/returnResponse}}{{^returnResponse}}{{#returnType}}: {{#useMutiny}}io.smallrye.mutiny.Uni<{{/useMutiny}}{{{returnType}}}{{#useMutiny}}>{{/useMutiny}}{{/returnType}}{{/returnResponse}}{{^returnResponse}}{{^returnType}}{{#useMutiny}}: io.smallrye.mutiny.Uni{{/useMutiny}}{{/returnType}}{{/returnResponse}} \ No newline at end of file diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java index 508b84d03ab3..cefe70432c3c 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java @@ -1,37 +1,41 @@ package org.openapitools.codegen.kotlin; -import lombok.Getter; -import org.antlr.v4.runtime.*; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.checkerframework.checker.units.qual.C; import org.openapitools.codegen.ClientOptInput; import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.DefaultGenerator; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.antlr4.KotlinLexer; import org.openapitools.codegen.antlr4.KotlinParser; -import org.openapitools.codegen.antlr4.KotlinParserBaseListener; import org.openapitools.codegen.languages.KotlinServerCodegen; import org.openapitools.codegen.languages.KotlinSpringServerCodegen; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; - -import static org.openapitools.codegen.CodegenConstants.*; +import static org.openapitools.codegen.CodegenConstants.API_PACKAGE; +import static org.openapitools.codegen.CodegenConstants.LIBRARY; +import static org.openapitools.codegen.CodegenConstants.MODEL_PACKAGE; +import static org.openapitools.codegen.CodegenConstants.PACKAGE_NAME; import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.assertFileNotContains; import static org.openapitools.codegen.languages.AbstractKotlinCodegen.USE_JAKARTA_EE; import static org.openapitools.codegen.languages.AbstractKotlinCodegen.USE_TAGS; -import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.*; +import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.INTERFACE_ONLY; +import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.JAVALIN5; +import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.JAVALIN6; +import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.JAXRS_SPEC; +import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.RETURN_RESPONSE; import static org.openapitools.codegen.languages.features.BeanValidationFeatures.USE_BEANVALIDATION; public class KotlinServerCodegenTest { @@ -222,6 +226,7 @@ public void issue18177Arrays() throws IOException { codegen.additionalProperties().put(INTERFACE_ONLY, true); codegen.additionalProperties().put(USE_JAKARTA_EE, true); codegen.additionalProperties().put(LIBRARY, JAXRS_SPEC); + codegen.additionalProperties().put(USE_TAGS, true); new DefaultGenerator().opts(new ClientOptInput() .openAPI(TestUtils.parseSpec("src/test/resources/3_0/kotlin/issue18177-array.yaml")) .config(codegen)) @@ -559,9 +564,9 @@ public void useTags_false_classNameFromTagsAndRootPathForJaxrsSpecLibrary() thro assertFileContains(petApi, "class PetApi", - "@Path(\"/\")", "@Path(\"/pet\")", - "@Path(\"/pet/{petId}\")" + "@Path(\"/findByStatus\")", + "@Path(\"/{petId}\")" ); assertFileNotContains(petApi, "@Path(\"/pet\")".replace("/pet", "/store")); } @@ -586,9 +591,9 @@ public void useTags_notSpecified_behavesLikeUseTagsFalseForJaxrsSpecLibrary() th assertFileContains(petApi, "class PetApi", - "@Path(\"/\")", "@Path(\"/pet\")", - "@Path(\"/pet/{petId}\")" + "@Path(\"/findByStatus\")", + "@Path(\"/{petId}\")" ); assertFileNotContains(petApi, "@Path(\"/store\")"); } From 7a365ce3c9dfb4d527a62737220e2c257a1e548f Mon Sep 17 00:00:00 2001 From: feczkob Date: Wed, 1 Apr 2026 23:33:14 +0200 Subject: [PATCH 2/6] Regenerate samples --- ...tlin-server-jaxrs-spec-array-response.yaml | 1 + ...lin-server-jaxrs-spec-parameter-tests.yaml | 1 + bin/configs/kotlin-server-jaxrs-spec.yaml | 1 - .../resources/kotlin-server/README.mustache | 2 +- .../org/openapitools/server/apis/StuffApi.kt | 2 +- .../openapitools/server/apis/DefaultApi.kt | 3 +- .../kotlin-server/jaxrs-spec-mutiny/README.md | 40 +++++++++---------- .../org/openapitools/server/apis/PetApi.kt | 16 ++++---- .../org/openapitools/server/apis/StoreApi.kt | 10 ++--- .../org/openapitools/server/apis/UserApi.kt | 17 ++++---- .../kotlin-server/jaxrs-spec/README.md | 40 +++++++++---------- 11 files changed, 65 insertions(+), 68 deletions(-) diff --git a/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml b/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml index ce6fe3f06c8a..de81f9dceb66 100644 --- a/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml +++ b/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml @@ -6,3 +6,4 @@ templateDir: modules/openapi-generator/src/main/resources/kotlin-server additionalProperties: interfaceOnly: "true" useJakartaEe: true + useTags: "true" diff --git a/bin/configs/kotlin-server-jaxrs-spec-parameter-tests.yaml b/bin/configs/kotlin-server-jaxrs-spec-parameter-tests.yaml index 948d739d995d..a18a371f62e6 100644 --- a/bin/configs/kotlin-server-jaxrs-spec-parameter-tests.yaml +++ b/bin/configs/kotlin-server-jaxrs-spec-parameter-tests.yaml @@ -5,3 +5,4 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/parameter-test-spec. templateDir: modules/openapi-generator/src/main/resources/kotlin-server additionalProperties: useCoroutines: "true" + useTags: "true" diff --git a/bin/configs/kotlin-server-jaxrs-spec.yaml b/bin/configs/kotlin-server-jaxrs-spec.yaml index 3ffc6a51f1d5..c80e330cd785 100644 --- a/bin/configs/kotlin-server-jaxrs-spec.yaml +++ b/bin/configs/kotlin-server-jaxrs-spec.yaml @@ -5,5 +5,4 @@ inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml templateDir: modules/openapi-generator/src/main/resources/kotlin-server additionalProperties: useCoroutines: "true" - useTags: "true" implicitHeaders: "true" diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/README.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/README.mustache index df987591f1bd..c20d79a43dca 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/README.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/README.mustache @@ -35,7 +35,7 @@ All URIs are relative to *{{{basePath}}}* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- -{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{#useTags}}{{commonPath}}{{/useTags}}{{path}} | {{{summary}}} +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{commonPath}}{{path}} | {{{summary}}} {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/generateApiDocs}} diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt b/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt index 3f5bce2366e4..d0c12b7a4ddc 100644 --- a/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt @@ -10,7 +10,7 @@ import java.io.InputStream -@Path("/") +@Path("") @jakarta.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT") interface StuffApi { diff --git a/samples/server/others/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt b/samples/server/others/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt index 516e7ef25dfb..73997d550dd9 100644 --- a/samples/server/others/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt +++ b/samples/server/others/kotlin-server/jaxrs-spec/src/main/kotlin/org/openapitools/server/apis/DefaultApi.kt @@ -9,12 +9,11 @@ import java.io.InputStream -@Path("/") +@Path("/test/parameters/{path_default}/{path_nullable}") @javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT") class DefaultApi { @GET - @Path("/test/parameters/{path_default}/{path_nullable}") 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 { return Response.ok().entity("magic!").build(); } diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/README.md b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/README.md index 231a738d36cc..c332fd4d8d2b 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/README.md +++ b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/README.md @@ -34,26 +34,26 @@ All URIs are relative to *http://petstore.swagger.io/v2* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- -*PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store -*PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet -*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status -*PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags -*PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID -*PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet -*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data -*PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image -*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID -*StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status -*StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID -*StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet -*UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user -*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array -*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array -*UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user -*UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name -*UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system -*UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session -*UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user +*PetApi* | [**addPet**](docs/PetApi.md#) | **POST** /pet | Add a new pet to the store +*PetApi* | [**deletePet**](docs/PetApi.md#) | **DELETE** /pet/{petId} | Deletes a pet +*PetApi* | [**findPetsByStatus**](docs/PetApi.md#) | **GET** /pet/findByStatus | Finds Pets by status +*PetApi* | [**findPetsByTags**](docs/PetApi.md#) | **GET** /pet/findByTags | Finds Pets by tags +*PetApi* | [**getPetById**](docs/PetApi.md#) | **GET** /pet/{petId} | Find pet by ID +*PetApi* | [**updatePet**](docs/PetApi.md#) | **PUT** /pet | Update an existing pet +*PetApi* | [**updatePetWithForm**](docs/PetApi.md#) | **POST** /pet/{petId} | Updates a pet in the store with form data +*PetApi* | [**uploadFile**](docs/PetApi.md#) | **POST** /pet/{petId}/uploadImage | uploads an image +*StoreApi* | [**deleteOrder**](docs/StoreApi.md#) | **DELETE** /store/order/{orderId} | Delete purchase order by ID +*StoreApi* | [**getInventory**](docs/StoreApi.md#) | **GET** /store/inventory | Returns pet inventories by status +*StoreApi* | [**getOrderById**](docs/StoreApi.md#) | **GET** /store/order/{orderId} | Find purchase order by ID +*StoreApi* | [**placeOrder**](docs/StoreApi.md#) | **POST** /store/order | Place an order for a pet +*UserApi* | [**createUser**](docs/UserApi.md#) | **POST** /user | Create user +*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#) | **POST** /user/createWithArray | Creates list of users with given input array +*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#) | **POST** /user/createWithList | Creates list of users with given input array +*UserApi* | [**deleteUser**](docs/UserApi.md#) | **DELETE** /user/{username} | Delete user +*UserApi* | [**getUserByName**](docs/UserApi.md#) | **GET** /user/{username} | Get user by user name +*UserApi* | [**loginUser**](docs/UserApi.md#) | **GET** /user/login | Logs user into the system +*UserApi* | [**logoutUser**](docs/UserApi.md#) | **GET** /user/logout | Logs out current logged in user session +*UserApi* | [**updateUser**](docs/UserApi.md#) | **PUT** /user/{username} | Updated user diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt index c5991e639955..45fc8405122d 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt +++ b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -11,46 +11,44 @@ import java.io.InputStream -@Path("/") +@Path("/pet") @javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT") interface PetApi { @POST - @Path("/pet") @Consumes("application/json", "application/xml") fun addPet( body: Pet): io.smallrye.mutiny.Uni @DELETE - @Path("/pet/{petId}") + @Path("/{petId}") fun deletePet(@PathParam("petId") petId: kotlin.Long,@HeaderParam("api_key") apiKey: kotlin.String?): io.smallrye.mutiny.Uni @GET - @Path("/pet/findByStatus") + @Path("/findByStatus") @Produces("application/xml", "application/json") fun findPetsByStatus(@QueryParam("status") status: kotlin.collections.List): io.smallrye.mutiny.Uni @GET - @Path("/pet/findByTags") + @Path("/findByTags") @Produces("application/xml", "application/json") fun findPetsByTags(@QueryParam("tags") tags: kotlin.collections.List): io.smallrye.mutiny.Uni @GET - @Path("/pet/{petId}") + @Path("/{petId}") @Produces("application/xml", "application/json") fun getPetById(@PathParam("petId") petId: kotlin.Long): io.smallrye.mutiny.Uni @PUT - @Path("/pet") @Consumes("application/json", "application/xml") fun updatePet( body: Pet): io.smallrye.mutiny.Uni @POST - @Path("/pet/{petId}") + @Path("/{petId}") @Consumes("application/x-www-form-urlencoded") fun updatePetWithForm(@PathParam("petId") petId: kotlin.Long,@FormParam(value = "name") name: kotlin.String?,@FormParam(value = "status") status: kotlin.String?): io.smallrye.mutiny.Uni @POST - @Path("/pet/{petId}/uploadImage") + @Path("/{petId}/uploadImage") @Consumes("multipart/form-data") @Produces("application/json") fun uploadFile(@PathParam("petId") petId: kotlin.Long,@FormParam(value = "additionalMetadata") additionalMetadata: kotlin.String?, @FormParam(value = "file") fileInputStream: InputStream?): io.smallrye.mutiny.Uni diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt index 18698be8de2a..afcdeb1c40a6 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +++ b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -10,26 +10,26 @@ import java.io.InputStream -@Path("/") +@Path("/store") @javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT") interface StoreApi { @DELETE - @Path("/store/order/{orderId}") + @Path("/order/{orderId}") fun deleteOrder(@PathParam("orderId") orderId: kotlin.String): io.smallrye.mutiny.Uni @GET - @Path("/store/inventory") + @Path("/inventory") @Produces("application/json") fun getInventory(): io.smallrye.mutiny.Uni @GET - @Path("/store/order/{orderId}") + @Path("/order/{orderId}") @Produces("application/xml", "application/json") fun getOrderById(@PathParam("orderId") orderId: kotlin.Long): io.smallrye.mutiny.Uni @POST - @Path("/store/order") + @Path("/order") @Produces("application/xml", "application/json") fun placeOrder( body: Order): io.smallrye.mutiny.Uni } diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt index d8c542088541..fe783ee8dce5 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt +++ b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -10,41 +10,40 @@ import java.io.InputStream -@Path("/") +@Path("/user") @javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.22.0-SNAPSHOT") interface UserApi { @POST - @Path("/user") fun createUser( body: User): io.smallrye.mutiny.Uni @POST - @Path("/user/createWithArray") + @Path("/createWithArray") fun createUsersWithArrayInput( body: kotlin.collections.List): io.smallrye.mutiny.Uni @POST - @Path("/user/createWithList") + @Path("/createWithList") fun createUsersWithListInput( body: kotlin.collections.List): io.smallrye.mutiny.Uni @DELETE - @Path("/user/{username}") + @Path("/{username}") fun deleteUser(@PathParam("username") username: kotlin.String): io.smallrye.mutiny.Uni @GET - @Path("/user/{username}") + @Path("/{username}") @Produces("application/xml", "application/json") fun getUserByName(@PathParam("username") username: kotlin.String): io.smallrye.mutiny.Uni @GET - @Path("/user/login") + @Path("/login") @Produces("application/xml", "application/json") fun loginUser(@QueryParam("username") username: kotlin.String,@QueryParam("password") password: kotlin.String): io.smallrye.mutiny.Uni @GET - @Path("/user/logout") + @Path("/logout") fun logoutUser(): io.smallrye.mutiny.Uni @PUT - @Path("/user/{username}") + @Path("/{username}") fun updateUser(@PathParam("username") username: kotlin.String, body: User): io.smallrye.mutiny.Uni } diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/README.md b/samples/server/petstore/kotlin-server/jaxrs-spec/README.md index 231a738d36cc..c332fd4d8d2b 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec/README.md +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/README.md @@ -34,26 +34,26 @@ All URIs are relative to *http://petstore.swagger.io/v2* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- -*PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store -*PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet -*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status -*PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags -*PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID -*PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet -*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data -*PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image -*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID -*StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status -*StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID -*StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet -*UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user -*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array -*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array -*UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user -*UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name -*UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system -*UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session -*UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user +*PetApi* | [**addPet**](docs/PetApi.md#) | **POST** /pet | Add a new pet to the store +*PetApi* | [**deletePet**](docs/PetApi.md#) | **DELETE** /pet/{petId} | Deletes a pet +*PetApi* | [**findPetsByStatus**](docs/PetApi.md#) | **GET** /pet/findByStatus | Finds Pets by status +*PetApi* | [**findPetsByTags**](docs/PetApi.md#) | **GET** /pet/findByTags | Finds Pets by tags +*PetApi* | [**getPetById**](docs/PetApi.md#) | **GET** /pet/{petId} | Find pet by ID +*PetApi* | [**updatePet**](docs/PetApi.md#) | **PUT** /pet | Update an existing pet +*PetApi* | [**updatePetWithForm**](docs/PetApi.md#) | **POST** /pet/{petId} | Updates a pet in the store with form data +*PetApi* | [**uploadFile**](docs/PetApi.md#) | **POST** /pet/{petId}/uploadImage | uploads an image +*StoreApi* | [**deleteOrder**](docs/StoreApi.md#) | **DELETE** /store/order/{orderId} | Delete purchase order by ID +*StoreApi* | [**getInventory**](docs/StoreApi.md#) | **GET** /store/inventory | Returns pet inventories by status +*StoreApi* | [**getOrderById**](docs/StoreApi.md#) | **GET** /store/order/{orderId} | Find purchase order by ID +*StoreApi* | [**placeOrder**](docs/StoreApi.md#) | **POST** /store/order | Place an order for a pet +*UserApi* | [**createUser**](docs/UserApi.md#) | **POST** /user | Create user +*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#) | **POST** /user/createWithArray | Creates list of users with given input array +*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#) | **POST** /user/createWithList | Creates list of users with given input array +*UserApi* | [**deleteUser**](docs/UserApi.md#) | **DELETE** /user/{username} | Delete user +*UserApi* | [**getUserByName**](docs/UserApi.md#) | **GET** /user/{username} | Get user by user name +*UserApi* | [**loginUser**](docs/UserApi.md#) | **GET** /user/login | Logs user into the system +*UserApi* | [**logoutUser**](docs/UserApi.md#) | **GET** /user/logout | Logs out current logged in user session +*UserApi* | [**updateUser**](docs/UserApi.md#) | **PUT** /user/{username} | Updated user From c3e559b0d5e2fc8f4886517c8908004a4a9544fe Mon Sep 17 00:00:00 2001 From: feczkob Date: Thu, 9 Apr 2026 17:23:18 +0200 Subject: [PATCH 3/6] Default useTags to true and simplify addOperationToGroup for kotlin-server --- ...tlin-server-jaxrs-spec-array-response.yaml | 1 - ...lin-server-jaxrs-spec-parameter-tests.yaml | 1 - docs/generators/kotlin-server.md | 2 +- .../languages/AbstractKotlinCodegen.java | 2 - .../languages/KotlinServerCodegen.java | 21 +++++----- .../kotlin/KotlinServerCodegenTest.java | 8 ++-- .../kotlin-server/jaxrs-spec-mutiny/README.md | 40 +++++++++---------- .../kotlin-server/jaxrs-spec/README.md | 40 +++++++++---------- 8 files changed, 55 insertions(+), 60 deletions(-) diff --git a/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml b/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml index de81f9dceb66..ce6fe3f06c8a 100644 --- a/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml +++ b/bin/configs/kotlin-server-jaxrs-spec-array-response.yaml @@ -6,4 +6,3 @@ templateDir: modules/openapi-generator/src/main/resources/kotlin-server additionalProperties: interfaceOnly: "true" useJakartaEe: true - useTags: "true" diff --git a/bin/configs/kotlin-server-jaxrs-spec-parameter-tests.yaml b/bin/configs/kotlin-server-jaxrs-spec-parameter-tests.yaml index a18a371f62e6..948d739d995d 100644 --- a/bin/configs/kotlin-server-jaxrs-spec-parameter-tests.yaml +++ b/bin/configs/kotlin-server-jaxrs-spec-parameter-tests.yaml @@ -5,4 +5,3 @@ inputSpec: modules/openapi-generator/src/test/resources/3_0/parameter-test-spec. templateDir: modules/openapi-generator/src/main/resources/kotlin-server additionalProperties: useCoroutines: "true" - useTags: "true" diff --git a/docs/generators/kotlin-server.md b/docs/generators/kotlin-server.md index e53b6934d2a6..83182f56ba2c 100644 --- a/docs/generators/kotlin-server.md +++ b/docs/generators/kotlin-server.md @@ -48,7 +48,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |useCoroutines|Whether to use the Coroutines. This option is currently supported only when using jaxrs-spec library.| |false| |useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false| |useMutiny|Whether to use Mutiny (should not be used with useCoroutines). This option is currently supported only when using jaxrs-spec library.| |false| -|useTags|use tags for creating interface and controller classnames| |false| +|useTags|use tags for creating interface and controller classnames. This option is currently supported only when using jaxrs-spec library.| |true| ## IMPORT MAPPING diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java index 734dae1971f3..cd130c766530 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractKotlinCodegen.java @@ -61,8 +61,6 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co public static final String JACKSON2_PACKAGE = "com.fasterxml.jackson"; public static final String JACKSON3_PACKAGE = "tools.jackson"; public static final String JACKSON_PACKAGE = "jacksonPackage"; - public static final String USE_TAGS = "useTags"; - public static final String USE_TAGS_DESC = "use tags for creating interface and controller classnames"; public static final String SCHEMA_IMPLEMENTS = "schemaImplements"; public static final String SCHEMA_IMPLEMENTS_FIELDS = "schemaImplementsFields"; public static final String X_KOTLIN_IMPLEMENTS_SKIP = "xKotlinImplementsSkip"; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java index 0e540f263b6f..b25c13f43a76 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java @@ -57,6 +57,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.USE_TAGS; + public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanValidationFeatures { public static final String DEFAULT_LIBRARY = Constants.KTOR; @@ -85,7 +87,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa private Boolean metricsFeatureEnabled = true; private boolean interfaceOnly = false; private boolean useBeanValidation = false; - private boolean useTags = false; + private boolean useTags = true; private boolean useCoroutines = false; private boolean useMutiny = false; private boolean returnResponse = false; @@ -193,7 +195,7 @@ public KotlinServerCodegen() { addSwitch(Constants.METRICS, Constants.METRICS_DESC, getMetricsFeatureEnabled()); addSwitch(Constants.INTERFACE_ONLY, Constants.INTERFACE_ONLY_DESC, interfaceOnly); addSwitch(USE_BEANVALIDATION, Constants.USE_BEANVALIDATION_DESC, useBeanValidation); - addSwitch(USE_TAGS, USE_TAGS_DESC, useTags); + addSwitch(USE_TAGS, Constants.USE_TAGS_DESC, useTags); addSwitch(Constants.USE_COROUTINES, Constants.USE_COROUTINES_DESC, useCoroutines); addSwitch(Constants.USE_MUTINY, Constants.USE_MUTINY_DESC, useMutiny); addSwitch(Constants.RETURN_RESPONSE, Constants.RETURN_RESPONSE_DESC, returnResponse); @@ -426,6 +428,8 @@ public static class Constants { public static final String IS_KTOR = "isKtor"; public static final String FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE = "fixJacksonJsonTypeInfoInheritance"; public static final String FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE_DESC = "When true (default), ensures Jackson polymorphism works correctly by: (1) always setting visible=true on @JsonTypeInfo, and (2) adding the discriminator property to child models with appropriate default values. When false, visible is only set to true if all children already define the discriminator property."; + public static final String USE_TAGS = "useTags"; + public static final String USE_TAGS_DESC = "use tags for creating interface and controller classnames. This option is currently supported only when using jaxrs-spec library."; } @Override @@ -730,16 +734,11 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera return; } - final String basePath = StringUtils.substringBefore(resourcePath.startsWith("/") ? resourcePath.substring(1) : resourcePath, "/"); - if (!StringUtils.isEmpty(basePath)) { - co.subresourceOperation = !co.path.isEmpty(); - } - co.baseName = basePath; - if (StringUtils.isEmpty(co.baseName) || co.baseName.chars().anyMatch(ch -> ch == '{' || ch == '}')) { - co.baseName = "default"; + String basePath = StringUtils.substringBefore(resourcePath.startsWith("/") ? resourcePath.substring(1) : resourcePath, "/"); + if (StringUtils.isEmpty(basePath) || basePath.chars().anyMatch(ch -> ch == '{' || ch == '}')) { + basePath = "default"; } - final List opList = operations.computeIfAbsent(co.baseName, k -> new ArrayList<>()); - opList.add(co); + super.addOperationToGroup(basePath, resourcePath, operation, co, operations); } @Override diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java index cefe70432c3c..796e711993cc 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java @@ -30,12 +30,12 @@ import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.assertFileNotContains; import static org.openapitools.codegen.languages.AbstractKotlinCodegen.USE_JAKARTA_EE; -import static org.openapitools.codegen.languages.AbstractKotlinCodegen.USE_TAGS; import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.INTERFACE_ONLY; import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.JAVALIN5; import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.JAVALIN6; import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.JAXRS_SPEC; import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.RETURN_RESPONSE; +import static org.openapitools.codegen.languages.KotlinServerCodegen.Constants.USE_TAGS; import static org.openapitools.codegen.languages.features.BeanValidationFeatures.USE_BEANVALIDATION; public class KotlinServerCodegenTest { @@ -226,7 +226,6 @@ public void issue18177Arrays() throws IOException { codegen.additionalProperties().put(INTERFACE_ONLY, true); codegen.additionalProperties().put(USE_JAKARTA_EE, true); codegen.additionalProperties().put(LIBRARY, JAXRS_SPEC); - codegen.additionalProperties().put(USE_TAGS, true); new DefaultGenerator().opts(new ClientOptInput() .openAPI(TestUtils.parseSpec("src/test/resources/3_0/kotlin/issue18177-array.yaml")) .config(codegen)) @@ -572,14 +571,14 @@ public void useTags_false_classNameFromTagsAndRootPathForJaxrsSpecLibrary() thro } @Test - public void useTags_notSpecified_behavesLikeUseTagsFalseForJaxrsSpecLibrary() throws IOException { + public void useTags_notSpecified_behavesLikeUseTagsTrueForJaxrsSpecLibrary() throws IOException { File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); output.deleteOnExit(); KotlinServerCodegen codegen = new KotlinServerCodegen(); codegen.setOutputDir(output.getAbsolutePath()); codegen.additionalProperties().put(LIBRARY, JAXRS_SPEC); - // useTags intentionally NOT set — must default to false + // useTags intentionally NOT set — must default to true new DefaultGenerator().opts(new ClientOptInput() .openAPI(TestUtils.parseSpec("src/test/resources/2_0/petstore.yaml")) @@ -595,6 +594,7 @@ public void useTags_notSpecified_behavesLikeUseTagsFalseForJaxrsSpecLibrary() th "@Path(\"/findByStatus\")", "@Path(\"/{petId}\")" ); + assertFileNotContains(petApi, "@Path(\"/\")"); assertFileNotContains(petApi, "@Path(\"/store\")"); } } diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/README.md b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/README.md index c332fd4d8d2b..231a738d36cc 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/README.md +++ b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/README.md @@ -34,26 +34,26 @@ All URIs are relative to *http://petstore.swagger.io/v2* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- -*PetApi* | [**addPet**](docs/PetApi.md#) | **POST** /pet | Add a new pet to the store -*PetApi* | [**deletePet**](docs/PetApi.md#) | **DELETE** /pet/{petId} | Deletes a pet -*PetApi* | [**findPetsByStatus**](docs/PetApi.md#) | **GET** /pet/findByStatus | Finds Pets by status -*PetApi* | [**findPetsByTags**](docs/PetApi.md#) | **GET** /pet/findByTags | Finds Pets by tags -*PetApi* | [**getPetById**](docs/PetApi.md#) | **GET** /pet/{petId} | Find pet by ID -*PetApi* | [**updatePet**](docs/PetApi.md#) | **PUT** /pet | Update an existing pet -*PetApi* | [**updatePetWithForm**](docs/PetApi.md#) | **POST** /pet/{petId} | Updates a pet in the store with form data -*PetApi* | [**uploadFile**](docs/PetApi.md#) | **POST** /pet/{petId}/uploadImage | uploads an image -*StoreApi* | [**deleteOrder**](docs/StoreApi.md#) | **DELETE** /store/order/{orderId} | Delete purchase order by ID -*StoreApi* | [**getInventory**](docs/StoreApi.md#) | **GET** /store/inventory | Returns pet inventories by status -*StoreApi* | [**getOrderById**](docs/StoreApi.md#) | **GET** /store/order/{orderId} | Find purchase order by ID -*StoreApi* | [**placeOrder**](docs/StoreApi.md#) | **POST** /store/order | Place an order for a pet -*UserApi* | [**createUser**](docs/UserApi.md#) | **POST** /user | Create user -*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#) | **POST** /user/createWithArray | Creates list of users with given input array -*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#) | **POST** /user/createWithList | Creates list of users with given input array -*UserApi* | [**deleteUser**](docs/UserApi.md#) | **DELETE** /user/{username} | Delete user -*UserApi* | [**getUserByName**](docs/UserApi.md#) | **GET** /user/{username} | Get user by user name -*UserApi* | [**loginUser**](docs/UserApi.md#) | **GET** /user/login | Logs user into the system -*UserApi* | [**logoutUser**](docs/UserApi.md#) | **GET** /user/logout | Logs out current logged in user session -*UserApi* | [**updateUser**](docs/UserApi.md#) | **PUT** /user/{username} | Updated user +*PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store +*PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet +*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status +*PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags +*PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID +*PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet +*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data +*PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image +*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID +*StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status +*StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID +*StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet +*UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user +*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array +*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array +*UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user +*UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name +*UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system +*UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session +*UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec/README.md b/samples/server/petstore/kotlin-server/jaxrs-spec/README.md index c332fd4d8d2b..231a738d36cc 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec/README.md +++ b/samples/server/petstore/kotlin-server/jaxrs-spec/README.md @@ -34,26 +34,26 @@ All URIs are relative to *http://petstore.swagger.io/v2* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- -*PetApi* | [**addPet**](docs/PetApi.md#) | **POST** /pet | Add a new pet to the store -*PetApi* | [**deletePet**](docs/PetApi.md#) | **DELETE** /pet/{petId} | Deletes a pet -*PetApi* | [**findPetsByStatus**](docs/PetApi.md#) | **GET** /pet/findByStatus | Finds Pets by status -*PetApi* | [**findPetsByTags**](docs/PetApi.md#) | **GET** /pet/findByTags | Finds Pets by tags -*PetApi* | [**getPetById**](docs/PetApi.md#) | **GET** /pet/{petId} | Find pet by ID -*PetApi* | [**updatePet**](docs/PetApi.md#) | **PUT** /pet | Update an existing pet -*PetApi* | [**updatePetWithForm**](docs/PetApi.md#) | **POST** /pet/{petId} | Updates a pet in the store with form data -*PetApi* | [**uploadFile**](docs/PetApi.md#) | **POST** /pet/{petId}/uploadImage | uploads an image -*StoreApi* | [**deleteOrder**](docs/StoreApi.md#) | **DELETE** /store/order/{orderId} | Delete purchase order by ID -*StoreApi* | [**getInventory**](docs/StoreApi.md#) | **GET** /store/inventory | Returns pet inventories by status -*StoreApi* | [**getOrderById**](docs/StoreApi.md#) | **GET** /store/order/{orderId} | Find purchase order by ID -*StoreApi* | [**placeOrder**](docs/StoreApi.md#) | **POST** /store/order | Place an order for a pet -*UserApi* | [**createUser**](docs/UserApi.md#) | **POST** /user | Create user -*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#) | **POST** /user/createWithArray | Creates list of users with given input array -*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#) | **POST** /user/createWithList | Creates list of users with given input array -*UserApi* | [**deleteUser**](docs/UserApi.md#) | **DELETE** /user/{username} | Delete user -*UserApi* | [**getUserByName**](docs/UserApi.md#) | **GET** /user/{username} | Get user by user name -*UserApi* | [**loginUser**](docs/UserApi.md#) | **GET** /user/login | Logs user into the system -*UserApi* | [**logoutUser**](docs/UserApi.md#) | **GET** /user/logout | Logs out current logged in user session -*UserApi* | [**updateUser**](docs/UserApi.md#) | **PUT** /user/{username} | Updated user +*PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store +*PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet +*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status +*PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags +*PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID +*PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet +*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data +*PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image +*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID +*StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status +*StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID +*StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet +*UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user +*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array +*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array +*UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user +*UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name +*UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system +*UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session +*UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user From 52f23964c158a3e9a87da9ea57d4b8188d160b0e Mon Sep 17 00:00:00 2001 From: feczkob Date: Thu, 9 Apr 2026 21:08:27 +0200 Subject: [PATCH 4/6] Enable useTags for all kotlin-server generators --- docs/generators/kotlin-server.md | 2 +- .../languages/KotlinServerCodegen.java | 38 +-------- .../kotlin/KotlinServerCodegenTest.java | 84 +++++++++++++------ 3 files changed, 60 insertions(+), 64 deletions(-) diff --git a/docs/generators/kotlin-server.md b/docs/generators/kotlin-server.md index 83182f56ba2c..31f042e5128f 100644 --- a/docs/generators/kotlin-server.md +++ b/docs/generators/kotlin-server.md @@ -48,7 +48,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |useCoroutines|Whether to use the Coroutines. This option is currently supported only when using jaxrs-spec library.| |false| |useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false| |useMutiny|Whether to use Mutiny (should not be used with useCoroutines). This option is currently supported only when using jaxrs-spec library.| |false| -|useTags|use tags for creating interface and controller classnames. This option is currently supported only when using jaxrs-spec library.| |true| +|useTags|use tags for creating interface and controller classnames.| |true| ## IMPORT MAPPING diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java index b25c13f43a76..8437a0e3d50c 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java @@ -17,11 +17,9 @@ package org.openapitools.codegen.languages; -import com.google.common.collect.ImmutableMap; import io.swagger.v3.oas.models.Operation; import java.io.File; import java.util.ArrayList; -import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; @@ -97,38 +95,6 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa @Setter private boolean fixJacksonJsonTypeInfoInheritance = true; - // This is here to potentially warn the user when an option is not supported by the target framework. - private Map> optionsSupportedPerFramework = new ImmutableMap.Builder>() - .put(Constants.KTOR, Arrays.asList( - Constants.AUTOMATIC_HEAD_REQUESTS, - Constants.CONDITIONAL_HEADERS, - Constants.HSTS, - Constants.CORS, - Constants.COMPRESSION, - Constants.RESOURCES, - Constants.METRICS, - Constants.OMIT_GRADLE_WRAPPER - )) - .put(Constants.KTOR2, Arrays.asList( - Constants.AUTOMATIC_HEAD_REQUESTS, - Constants.CONDITIONAL_HEADERS, - Constants.HSTS, - Constants.CORS, - Constants.COMPRESSION, - Constants.RESOURCES, - Constants.METRICS, - Constants.OMIT_GRADLE_WRAPPER - )) - .put(Constants.JAXRS_SPEC, Arrays.asList( - USE_BEANVALIDATION, - USE_TAGS, - Constants.USE_COROUTINES, - Constants.USE_MUTINY, - Constants.RETURN_RESPONSE, - Constants.INTERFACE_ONLY - )) - .build(); - /** * Constructs an instance of `KotlinServerCodegen`. */ @@ -429,7 +395,7 @@ public static class Constants { public static final String FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE = "fixJacksonJsonTypeInfoInheritance"; public static final String FIX_JACKSON_JSON_TYPE_INFO_INHERITANCE_DESC = "When true (default), ensures Jackson polymorphism works correctly by: (1) always setting visible=true on @JsonTypeInfo, and (2) adding the discriminator property to child models with appropriate default values. When false, visible is only set to true if all children already define the discriminator property."; public static final String USE_TAGS = "useTags"; - public static final String USE_TAGS_DESC = "use tags for creating interface and controller classnames. This option is currently supported only when using jaxrs-spec library."; + public static final String USE_TAGS_DESC = "use tags for creating interface and controller classnames."; } @Override @@ -729,7 +695,7 @@ public void postProcess() { @Override public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) { - if (!Objects.equals(library, Constants.JAXRS_SPEC) || useTags) { + if (useTags) { super.addOperationToGroup(tag, resourcePath, operation, co, operations); return; } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java index 796e711993cc..3cdee67e7e61 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java @@ -1,12 +1,15 @@ package org.openapitools.codegen.kotlin; +import io.swagger.v3.oas.models.Operation; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.openapitools.codegen.CodegenOperation; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -515,33 +518,7 @@ public void fixJacksonJsonTypeInfoInheritance_canBeDisabled() throws IOException ); } - @Test - public void useTags_commonPathIsComputedForJaxrsSpecLibrary() throws IOException { - File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); - output.deleteOnExit(); - - KotlinServerCodegen codegen = new KotlinServerCodegen(); - codegen.setOutputDir(output.getAbsolutePath()); - codegen.additionalProperties().put(LIBRARY, JAXRS_SPEC); - codegen.additionalProperties().put(USE_TAGS, true); - - new DefaultGenerator().opts(new ClientOptInput() - .openAPI(TestUtils.parseSpec("src/test/resources/2_0/petstore.yaml")) - .config(codegen)) - .generate(); - - String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server"; - Path petApi = Paths.get(outputPath + "/apis/PetApi.kt"); - - assertFileContains( - petApi, - "@Path(\"/pet\")" - ); - assertFileNotContains( - petApi, - "@Path(\"/\")" - ); - } + // ==================== useTags for JAXRS-SPEC ==================== @Test public void useTags_false_classNameFromTagsAndRootPathForJaxrsSpecLibrary() throws IOException { @@ -597,4 +574,57 @@ public void useTags_notSpecified_behavesLikeUseTagsTrueForJaxrsSpecLibrary() thr assertFileNotContains(petApi, "@Path(\"/\")"); assertFileNotContains(petApi, "@Path(\"/store\")"); } + + // ==================== useTags for all libraries ==================== + + @Test + public void useTags_false_groupsByFirstPathSegment() { + KotlinServerCodegen codegen = new KotlinServerCodegen(); + codegen.additionalProperties().put(LIBRARY, JAVALIN6); + codegen.additionalProperties().put(USE_TAGS, false); + codegen.processOpts(); + + CodegenOperation co = new CodegenOperation(); + co.operationId = "findByStatus"; + Map> groups = new HashMap<>(); + + codegen.addOperationToGroup("Pet", "/pet/findByStatus", new Operation(), co, groups); + + Assert.assertTrue(groups.containsKey("pet")); + Assert.assertEquals(co.baseName, "pet"); + } + + @Test + public void useTags_false_rootPath_groupsAsDefault() { + KotlinServerCodegen codegen = new KotlinServerCodegen(); + codegen.additionalProperties().put(LIBRARY, JAVALIN6); + codegen.additionalProperties().put(USE_TAGS, false); + codegen.processOpts(); + + CodegenOperation co = new CodegenOperation(); + co.operationId = "getRoot"; + Map> groups = new HashMap<>(); + + codegen.addOperationToGroup("Root", "/", new Operation(), co, groups); + + Assert.assertTrue(groups.containsKey("default")); + Assert.assertEquals(co.baseName, "default"); + } + + @Test + public void useTags_false_pathParamOnly_groupsAsDefault() { + KotlinServerCodegen codegen = new KotlinServerCodegen(); + codegen.additionalProperties().put(LIBRARY, JAVALIN6); + codegen.additionalProperties().put(USE_TAGS, false); + codegen.processOpts(); + + CodegenOperation co = new CodegenOperation(); + co.operationId = "getById"; + Map> groups = new HashMap<>(); + + codegen.addOperationToGroup("Resource", "/{uuid}", new Operation(), co, groups); + + Assert.assertTrue(groups.containsKey("default")); + Assert.assertEquals(co.baseName, "default"); + } } From d7d0b97d7592a06bbfa9525378b94f76d8402202 Mon Sep 17 00:00:00 2001 From: feczkob Date: Fri, 10 Apr 2026 08:48:54 +0200 Subject: [PATCH 5/6] Add a new sample for ktor2 --- .../kotlin-server-ktor2-usetags-false.yaml | 9 + .../3_0/kotlin/petstore-with-tags.yaml | 4 - .../.openapi-generator-ignore | 23 ++ .../.openapi-generator/FILES | 21 ++ .../.openapi-generator/VERSION | 1 + .../ktor2-usetags-false/Dockerfile | 7 + .../ktor2-usetags-false/README.md | 109 +++++++ .../ktor2-usetags-false/build.gradle.kts | 41 +++ .../ktor2-usetags-false/gradle.properties | 4 + .../gradle/wrapper/gradle-wrapper.properties | 5 + .../ktor2-usetags-false/settings.gradle | 1 + .../kotlin/org/openapitools/server/AppMain.kt | 75 +++++ .../org/openapitools/server/Configuration.kt | 63 ++++ .../kotlin/org/openapitools/server/Paths.kt | 186 ++++++++++++ .../org/openapitools/server/apis/PetApi.kt | 269 ++++++++++++++++++ .../org/openapitools/server/apis/StoreApi.kt | 89 ++++++ .../org/openapitools/server/apis/UserApi.kt | 96 +++++++ .../server/infrastructure/ApiKeyAuth.kt | 102 +++++++ .../openapitools/server/models/Category.kt | 30 ++ .../server/models/ModelApiResponse.kt | 32 +++ .../org/openapitools/server/models/Order.kt | 48 ++++ .../org/openapitools/server/models/Pet.kt | 50 ++++ .../org/openapitools/server/models/Tag.kt | 30 ++ .../org/openapitools/server/models/User.kt | 43 +++ .../src/main/resources/application.conf | 23 ++ .../src/main/resources/logback.xml | 15 + 26 files changed, 1372 insertions(+), 4 deletions(-) create mode 100644 bin/configs/kotlin-server-ktor2-usetags-false.yaml create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator-ignore create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator/FILES create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator/VERSION create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/Dockerfile create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/README.md create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/build.gradle.kts create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/gradle.properties create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/gradle/wrapper/gradle-wrapper.properties create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/settings.gradle create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/AppMain.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/Configuration.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/Paths.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/PetApi.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/UserApi.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Category.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Order.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Pet.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Tag.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/User.kt create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/application.conf create mode 100644 samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/logback.xml diff --git a/bin/configs/kotlin-server-ktor2-usetags-false.yaml b/bin/configs/kotlin-server-ktor2-usetags-false.yaml new file mode 100644 index 000000000000..31d04c38d7cb --- /dev/null +++ b/bin/configs/kotlin-server-ktor2-usetags-false.yaml @@ -0,0 +1,9 @@ +generatorName: kotlin-server +outputDir: samples/server/petstore/kotlin-server/ktor2-usetags-false +library: ktor2 +inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml +templateDir: modules/openapi-generator/src/main/resources/kotlin-server +additionalProperties: + hideGenerationTimestamp: "true" + serializableModel: "true" + useTags: "false" diff --git a/modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml b/modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml index 062ab023e2d0..fac95745cc30 100644 --- a/modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/kotlin/petstore-with-tags.yaml @@ -271,12 +271,10 @@ paths: additionalMetadata: type: string description: Additional data to pass to server - required: false image: type: string description: image to upload format: binary - required: true responses: 200: description: successful operation @@ -310,14 +308,12 @@ paths: additionalMetadata: type: string description: Additional data to pass to server - required: false images: type: array items: type: string description: image to upload format: binary - required: true responses: 200: description: successful operation diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator-ignore b/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator/FILES b/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator/FILES new file mode 100644 index 000000000000..52c6d592e8f2 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator/FILES @@ -0,0 +1,21 @@ +Dockerfile +README.md +build.gradle.kts +gradle.properties +gradle/wrapper/gradle-wrapper.properties +settings.gradle +src/main/kotlin/org/openapitools/server/AppMain.kt +src/main/kotlin/org/openapitools/server/Configuration.kt +src/main/kotlin/org/openapitools/server/Paths.kt +src/main/kotlin/org/openapitools/server/apis/PetApi.kt +src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +src/main/kotlin/org/openapitools/server/apis/UserApi.kt +src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt +src/main/kotlin/org/openapitools/server/models/Category.kt +src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt +src/main/kotlin/org/openapitools/server/models/Order.kt +src/main/kotlin/org/openapitools/server/models/Pet.kt +src/main/kotlin/org/openapitools/server/models/Tag.kt +src/main/kotlin/org/openapitools/server/models/User.kt +src/main/resources/application.conf +src/main/resources/logback.xml diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator/VERSION b/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator/VERSION new file mode 100644 index 000000000000..f7962df3e243 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.22.0-SNAPSHOT diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/Dockerfile b/samples/server/petstore/kotlin-server/ktor2-usetags-false/Dockerfile new file mode 100644 index 000000000000..0c1f942d32ae --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/Dockerfile @@ -0,0 +1,7 @@ +FROM openjdk:8-jre-alpine + +COPY ./build/libs/kotlin-server.jar /root/kotlin-server.jar + +WORKDIR /root + +CMD ["java", "-server", "-Xms4g", "-Xmx4g", "-XX:+UseG1GC", "-XX:MaxGCPauseMillis=100", "-XX:+UseStringDeduplication", "-jar", "kotlin-server.jar"] \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/README.md b/samples/server/petstore/kotlin-server/ktor2-usetags-false/README.md new file mode 100644 index 000000000000..e45bcf105ab0 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/README.md @@ -0,0 +1,109 @@ +# org.openapitools.server - Kotlin Server library for OpenAPI Petstore + +This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + +Generated by OpenAPI Generator 7.22.0-SNAPSHOT. + +## Requires + +* Kotlin 2.0.20 +* Gradle 8.10.2 + +## Build + +First, create the gradle wrapper script: + +``` +gradle wrapper +``` + +Then, run: + +``` +./gradlew check assemble +``` + +This runs all tests and packages the library. + +## Running + +The server builds as a fat jar with a main entrypoint. To start the service, run `java -jar ./build/libs/kotlin-server.jar`. + +You may also run in docker: + +``` +docker build -t kotlin-server . +docker run -p 8080:8080 kotlin-server +``` + +## Features/Implementation Notes + +* Supports JSON inputs/outputs, File inputs, and Form inputs (see ktor documentation for more info). +* ~Supports collection formats for query parameters: csv, tsv, ssv, pipes.~ +* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions. + + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io/v2* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*PetApi* | [**addPet**](docs/PetApi.md#addpet) | **POST** /pet | Add a new pet to the store +*PetApi* | [**deletePet**](docs/PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet +*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status +*PetApi* | [**findPetsByTags**](docs/PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags +*PetApi* | [**getImage**](docs/PetApi.md#getimage) | **GET** /pet/{petId}/getImage | Get an image +*PetApi* | [**getPetById**](docs/PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID +*PetApi* | [**updatePet**](docs/PetApi.md#updatepet) | **PUT** /pet | Update an existing pet +*PetApi* | [**updatePetWithForm**](docs/PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data +*PetApi* | [**uploadFile**](docs/PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image +*PetApi* | [**uploadMultipleFile**](docs/PetApi.md#uploadmultiplefile) | **POST** /pet/{petId}/uploadMultipleImage | uploads multiple images +*StoreApi* | [**deleteOrder**](docs/StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID +*StoreApi* | [**getInventory**](docs/StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status +*StoreApi* | [**getOrderById**](docs/StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID +*StoreApi* | [**placeOrder**](docs/StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet +*UserApi* | [**createUser**](docs/UserApi.md#createuser) | **POST** /user | Create user +*UserApi* | [**createUsersWithArrayInput**](docs/UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array +*UserApi* | [**createUsersWithListInput**](docs/UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array +*UserApi* | [**deleteUser**](docs/UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user +*UserApi* | [**getUserByName**](docs/UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name +*UserApi* | [**loginUser**](docs/UserApi.md#loginuser) | **GET** /user/login | Logs user into the system +*UserApi* | [**logoutUser**](docs/UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session +*UserApi* | [**logoutUserOptions**](docs/UserApi.md#logoutuseroptions) | **OPTIONS** /user/logout | logoutUserOptions +*UserApi* | [**updateUser**](docs/UserApi.md#updateuser) | **PUT** /user/{username} | Updated user + + + +## Documentation for Models + + - [org.openapitools.server.models.Category](docs/Category.md) + - [org.openapitools.server.models.ModelApiResponse](docs/ModelApiResponse.md) + - [org.openapitools.server.models.Order](docs/Order.md) + - [org.openapitools.server.models.Pet](docs/Pet.md) + - [org.openapitools.server.models.Tag](docs/Tag.md) + - [org.openapitools.server.models.User](docs/User.md) + + + +## Documentation for Authorization + + +Authentication schemes defined for the API: + +### petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - write:pets: modify pets in your account + - read:pets: read your pets + + +### api_key + +- **Type**: API key +- **API key parameter name**: api_key +- **Location**: HTTP header + diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/build.gradle.kts b/samples/server/petstore/kotlin-server/ktor2-usetags-false/build.gradle.kts new file mode 100644 index 000000000000..fb35b77164a8 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/build.gradle.kts @@ -0,0 +1,41 @@ + +val kotlin_version: String by project +val logback_version: String by project + +group = "org.openapitools" +version = "1.0.0" + +plugins { + kotlin("jvm") version "2.0.20" + id("io.ktor.plugin") version "2.3.12" +} + +application { + mainClass.set("io.ktor.server.netty.EngineMain") + + val isDevelopment: Boolean = project.ext.has("development") + applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment") +} + +repositories { + mavenCentral() +} + +dependencies { + implementation("ch.qos.logback:logback-classic:$logback_version") + implementation("com.typesafe:config:1.4.1") + implementation("io.ktor:ktor-server-auth") + implementation("io.ktor:ktor-client-apache") + implementation("io.ktor:ktor-server-auto-head-response") + implementation("io.ktor:ktor-server-default-headers") + implementation("io.ktor:ktor-server-content-negotiation") + implementation("io.ktor:ktor-serialization-gson") + implementation("io.ktor:ktor-server-resources") + implementation("io.ktor:ktor-server-hsts") + implementation("io.ktor:ktor-server-compression") + implementation("io.dropwizard.metrics:metrics-core:4.1.18") + implementation("io.ktor:ktor-server-metrics") + implementation("io.ktor:ktor-server-netty") + + testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") +} diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/gradle.properties b/samples/server/petstore/kotlin-server/ktor2-usetags-false/gradle.properties new file mode 100644 index 000000000000..d0d1af21b844 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/gradle.properties @@ -0,0 +1,4 @@ +kotlin.code.style=official +ktor_version=2.3.12 +kotlin_version=2.0.20 +logback_version=1.5.19 diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/gradle/wrapper/gradle-wrapper.properties b/samples/server/petstore/kotlin-server/ktor2-usetags-false/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..18330fcba804 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/settings.gradle b/samples/server/petstore/kotlin-server/ktor2-usetags-false/settings.gradle new file mode 100644 index 000000000000..a09a58efab11 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'kotlin-server' \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/AppMain.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/AppMain.kt new file mode 100644 index 000000000000..2de9d58ce937 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/AppMain.kt @@ -0,0 +1,75 @@ +package org.openapitools.server + +import io.ktor.server.application.* +import io.ktor.serialization.gson.* +import io.ktor.http.* +import io.ktor.server.resources.* +import io.ktor.server.plugins.autohead.* +import io.ktor.server.plugins.compression.* +import io.ktor.server.plugins.contentnegotiation.* +import io.ktor.server.plugins.defaultheaders.* +import io.ktor.server.plugins.hsts.* +import com.codahale.metrics.Slf4jReporter +import io.ktor.server.metrics.dropwizard.* +import java.util.concurrent.TimeUnit +import io.ktor.server.routing.* +import com.typesafe.config.ConfigFactory +import io.ktor.client.HttpClient +import io.ktor.client.engine.apache.Apache +import io.ktor.server.config.HoconApplicationConfig +import io.ktor.server.auth.* +import org.openapitools.server.infrastructure.* +import org.openapitools.server.apis.PetApi +import org.openapitools.server.apis.StoreApi +import org.openapitools.server.apis.UserApi + + +internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader)) + +object HTTP { + val client = HttpClient(Apache) +} + +fun Application.main() { + install(DefaultHeaders) + install(DropwizardMetrics) { + val reporter = Slf4jReporter.forRegistry(registry) + .outputTo(this@main.log) + .convertRatesTo(TimeUnit.SECONDS) + .convertDurationsTo(TimeUnit.MILLISECONDS) + .build() + reporter.start(10, TimeUnit.SECONDS) + } + install(ContentNegotiation) { + register(ContentType.Application.Json, GsonConverter()) + } + install(AutoHeadResponse) // see https://ktor.io/docs/autoheadresponse.html + install(Compression, ApplicationCompressionConfiguration()) // see https://ktor.io/docs/compression.html + install(HSTS, ApplicationHstsConfiguration()) // see https://ktor.io/docs/hsts.html + install(Resources) + install(Authentication) { + oauth("petstore_auth") { + client = HttpClient(Apache) + providerLookup = { applicationAuthProvider(this@main.environment.config) } + urlProvider = { _ -> + // TODO: define a callback url here. + "/" + } + } + // "Implement API key auth (api_key) for parameter name 'api_key'." + apiKeyAuth("api_key") { + validate { apikeyCredential: ApiKeyCredential -> + when { + apikeyCredential.value == "keyboardcat" -> ApiPrincipal(apikeyCredential) + else -> null + } + } + } + } + install(Routing) { + PetApi() + StoreApi() + UserApi() + } + +} diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/Configuration.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/Configuration.kt new file mode 100644 index 000000000000..f78654c60f0f --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/Configuration.kt @@ -0,0 +1,63 @@ +package org.openapitools.server + +// Use this file to hold package-level internal functions that return receiver object passed to the `install` method. +import io.ktor.http.* +import io.ktor.server.auth.* +import io.ktor.server.config.* +import io.ktor.util.* +import java.time.Duration +import java.util.concurrent.TimeUnit +import io.ktor.server.plugins.compression.* +import io.ktor.server.plugins.hsts.* + + +/** + * Application block for [HSTS] configuration. + * + * This file may be excluded in .openapi-generator-ignore, + * and application-specific configuration can be applied in this function. + * + * See http://ktor.io/features/hsts.html + */ +internal fun ApplicationHstsConfiguration(): HSTSConfig.() -> Unit { + return { + maxAgeInSeconds = TimeUnit.DAYS.toSeconds(365) + includeSubDomains = true + preload = false + + // You may also apply any custom directives supported by specific user-agent. For example: + // customDirectives.put("redirectHttpToHttps", "false") + } +} + +/** + * Application block for [Compression] configuration. + * + * This file may be excluded in .openapi-generator-ignore, + * and application-specific configuration can be applied in this function. + * + * See http://ktor.io/features/compression.html + */ +internal fun ApplicationCompressionConfiguration(): CompressionConfig.() -> Unit { + return { + gzip { + priority = 1.0 + } + deflate { + priority = 10.0 + minimumSize(1024) // condition + } + } +} + +// Defines authentication mechanisms used throughout the application. +fun applicationAuthProvider(config: ApplicationConfig): OAuthServerSettings = + OAuthServerSettings.OAuth2ServerSettings( + name = "petstore_auth", + authorizeUrl = "http://petstore.swagger.io/api/oauth/dialog", + accessTokenUrl = "", + requestMethod = HttpMethod.Get, + clientId = config.property("auth.oauth.petstore_auth.clientId").getString(), + clientSecret = config.property("auth.oauth.petstore_auth.clientSecret").getString(), + defaultScopes = listOf("write:pets", "read:pets") + ) diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/Paths.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/Paths.kt new file mode 100644 index 000000000000..e088053519df --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/Paths.kt @@ -0,0 +1,186 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server + +import io.ktor.resources.* +import kotlinx.serialization.* +import org.openapitools.server.models.* + +object Paths { + /** + * Add a new pet to the store + * + * @param body Pet object that needs to be added to the store + */ + @Serializable @Resource("/pet") class addPet(@SerialName("body") val body: Pet) + + /** + * Deletes a pet + * + * @param petId Pet id to delete + * @param apiKey (optional) + */ + @Serializable @Resource("/pet/{petId}") class deletePet(@SerialName("petId") val petId: kotlin.Long, @SerialName("api_key") val apiKey: kotlin.String? = null) + + /** + * Finds Pets by status + * Multiple status values can be provided with comma separated strings + * @param status Status values that need to be considered for filter + */ + @Serializable @Resource("/pet/findByStatus") class findPetsByStatus(@SerialName("status") val status: kotlin.collections.List) + + /** + * Finds Pets by tags + * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + * @param tags Tags to filter by + */ + @Serializable @Resource("/pet/findByTags") class findPetsByTags(@SerialName("tags") val tags: kotlin.collections.List) + + /** + * Get an image + * + * @param petId ID of pet to get image + */ + @Serializable @Resource("/pet/{petId}/getImage") class getImage(@SerialName("petId") val petId: kotlin.Long) + + /** + * Find pet by ID + * Returns a single pet + * @param petId ID of pet to return + */ + @Serializable @Resource("/pet/{petId}") class getPetById(@SerialName("petId") val petId: kotlin.Long) + + /** + * Update an existing pet + * + * @param body Pet object that needs to be added to the store + */ + @Serializable @Resource("/pet") class updatePet(@SerialName("body") val body: Pet) + + /** + * Updates a pet in the store with form data + * + * @param petId ID of pet that needs to be updated + * @param name Updated name of the pet (optional) + * @param status Updated status of the pet (optional) + */ + @Serializable @Resource("/pet/{petId}") class updatePetWithForm(@SerialName("petId") val petId: kotlin.Long, @SerialName("name") val name: kotlin.String? = null, @SerialName("status") val status: kotlin.String? = null) + + /** + * uploads an image + * + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server (optional) + * @param image image to upload (optional) + */ + @Serializable @Resource("/pet/{petId}/uploadImage") class uploadFile(@SerialName("petId") val petId: kotlin.Long, @SerialName("additionalMetadata") val additionalMetadata: kotlin.String? = null, @SerialName("image") val image: java.io.File? = null) + + /** + * uploads multiple images + * + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server (optional) + * @param images (optional) + */ + @Serializable @Resource("/pet/{petId}/uploadMultipleImage") class uploadMultipleFile(@SerialName("petId") val petId: kotlin.Long, @SerialName("additionalMetadata") val additionalMetadata: kotlin.String? = null, @SerialName("images") val images: kotlin.collections.List? = null) + + /** + * Delete purchase order by ID + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * @param orderId ID of the order that needs to be deleted + */ + @Serializable @Resource("/store/order/{orderId}") class deleteOrder(@SerialName("orderId") val orderId: kotlin.String) + + /** + * Returns pet inventories by status + * Returns a map of status codes to quantities + */ + @Serializable @Resource("/store/inventory") class getInventory + + /** + * Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions + * @param orderId ID of pet that needs to be fetched + */ + @Serializable @Resource("/store/order/{orderId}") class getOrderById(@SerialName("orderId") val orderId: kotlin.Long) + + /** + * Place an order for a pet + * + * @param body order placed for purchasing the pet + */ + @Serializable @Resource("/store/order") class placeOrder(@SerialName("body") val body: Order) + + /** + * Create user + * This can only be done by the logged in user. + * @param body Created user object + */ + @Serializable @Resource("/user") class createUser(@SerialName("body") val body: User) + + /** + * Creates list of users with given input array + * + * @param body List of user object + */ + @Serializable @Resource("/user/createWithArray") class createUsersWithArrayInput(@SerialName("body") val body: kotlin.collections.List) + + /** + * Creates list of users with given input array + * + * @param body List of user object + */ + @Serializable @Resource("/user/createWithList") class createUsersWithListInput(@SerialName("body") val body: kotlin.collections.List) + + /** + * Delete user + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + */ + @Serializable @Resource("/user/{username}") class deleteUser(@SerialName("username") val username: kotlin.String) + + /** + * Get user by user name + * + * @param username The name that needs to be fetched. Use user1 for testing. + */ + @Serializable @Resource("/user/{username}") class getUserByName(@SerialName("username") val username: kotlin.String) + + /** + * Logs user into the system + * + * @param username The user name for login + * @param password The password for login in clear text + */ + @Serializable @Resource("/user/login") class loginUser(@SerialName("username") val username: kotlin.String, @SerialName("password") val password: kotlin.String) + + /** + * Logs out current logged in user session + * + */ + @Serializable @Resource("/user/logout") class logoutUser + + /** + * logoutUserOptions + * + */ + @Serializable @Resource("/user/logout") class logoutUserOptions + + /** + * Updated user + * This can only be done by the logged in user. + * @param username name that need to be deleted + * @param body Updated user object + */ + @Serializable @Resource("/user/{username}") class updateUser(@SerialName("username") val username: kotlin.String, @SerialName("body") val body: User) + +} diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/PetApi.kt new file mode 100644 index 000000000000..a1c717be2979 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -0,0 +1,269 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.apis + +import com.google.gson.Gson +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.response.* +import org.openapitools.server.Paths +import io.ktor.server.resources.options +import io.ktor.server.resources.get +import io.ktor.server.resources.post +import io.ktor.server.resources.put +import io.ktor.server.resources.delete +import io.ktor.server.resources.head +import io.ktor.server.resources.patch +import io.ktor.server.routing.* +import org.openapitools.server.infrastructure.ApiPrincipal +import org.openapitools.server.models.ModelApiResponse +import org.openapitools.server.models.Pet + +fun Route.PetApi() { + val gson = Gson() + val empty = mutableMapOf() + + authenticate("petstore_auth") { + post { + + val principal = call.authentication.principal()!! + + + call.respond(HttpStatusCode.NotImplemented) + + } + } + + authenticate("petstore_auth") { + delete { + + val principal = call.authentication.principal()!! + + + call.respond(HttpStatusCode.NotImplemented) + + } + } + + authenticate("petstore_auth") { + get { + + val principal = call.authentication.principal()!! + + + val exampleContentType = "application/json" + val exampleContentString = """[ { + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + }, { + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + } ]""" + + when (exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + + } + } + + authenticate("petstore_auth") { + get { + + val principal = call.authentication.principal()!! + + + val exampleContentType = "application/json" + val exampleContentString = """[ { + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + }, { + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + } ]""" + + when (exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + + } + } + + authenticate("petstore_auth") { + get { + + val principal = call.authentication.principal()!! + + + call.respond(HttpStatusCode.NotImplemented) + + } + } + + authenticate("api_key") { + get { + + val principal = call.authentication.principal()!! + + + val exampleContentType = "application/json" + val exampleContentString = """{ + "photoUrls" : [ "photoUrls", "photoUrls" ], + "name" : "doggie", + "id" : 0, + "category" : { + "name" : "name", + "id" : 6 + }, + "tags" : [ { + "name" : "name", + "id" : 1 + }, { + "name" : "name", + "id" : 1 + } ], + "status" : "available" + }""" + + when (exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + + } + } + + authenticate("petstore_auth") { + put { + + val principal = call.authentication.principal()!! + + + call.respond(HttpStatusCode.NotImplemented) + + } + } + + authenticate("petstore_auth") { + post { + + val principal = call.authentication.principal()!! + + + call.respond(HttpStatusCode.NotImplemented) + + } + } + + authenticate("petstore_auth") { + post { + + val principal = call.authentication.principal()!! + + + val exampleContentType = "application/json" + val exampleContentString = """{ + "code" : 0, + "type" : "type", + "message" : "message" + }""" + + when (exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + + } + } + + authenticate("petstore_auth") { + post { + + val principal = call.authentication.principal()!! + + + val exampleContentType = "application/json" + val exampleContentString = """{ + "code" : 0, + "type" : "type", + "message" : "message" + }""" + + when (exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + + } + } + +} diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt new file mode 100644 index 000000000000..fe780f7feb46 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -0,0 +1,89 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.apis + +import com.google.gson.Gson +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.response.* +import org.openapitools.server.Paths +import io.ktor.server.resources.options +import io.ktor.server.resources.get +import io.ktor.server.resources.post +import io.ktor.server.resources.put +import io.ktor.server.resources.delete +import io.ktor.server.resources.head +import io.ktor.server.resources.patch +import io.ktor.server.routing.* +import org.openapitools.server.infrastructure.ApiPrincipal +import org.openapitools.server.models.Order + +fun Route.StoreApi() { + val gson = Gson() + val empty = mutableMapOf() + + delete { + call.respond(HttpStatusCode.NotImplemented) + + } + + authenticate("api_key") { + get { + + val principal = call.authentication.principal()!! + + + call.respond(HttpStatusCode.NotImplemented) + + } + } + + get { + val exampleContentType = "application/json" + val exampleContentString = """{ + "petId" : 6, + "quantity" : 1, + "id" : 0, + "shipDate" : "2000-01-23T04:56:07.000+00:00", + "complete" : false, + "status" : "placed" + }""" + + when (exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + + } + + post { + val exampleContentType = "application/json" + val exampleContentString = """{ + "petId" : 6, + "quantity" : 1, + "id" : 0, + "shipDate" : "2000-01-23T04:56:07.000+00:00", + "complete" : false, + "status" : "placed" + }""" + + when (exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + + } + +} diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/UserApi.kt new file mode 100644 index 000000000000..388cd6953635 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -0,0 +1,96 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.apis + +import com.google.gson.Gson +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.response.* +import org.openapitools.server.Paths +import io.ktor.server.resources.options +import io.ktor.server.resources.get +import io.ktor.server.resources.post +import io.ktor.server.resources.put +import io.ktor.server.resources.delete +import io.ktor.server.resources.head +import io.ktor.server.resources.patch +import io.ktor.server.routing.* +import org.openapitools.server.infrastructure.ApiPrincipal +import org.openapitools.server.models.User + +fun Route.UserApi() { + val gson = Gson() + val empty = mutableMapOf() + + post { + call.respond(HttpStatusCode.NotImplemented) + + } + + post { + call.respond(HttpStatusCode.NotImplemented) + + } + + post { + call.respond(HttpStatusCode.NotImplemented) + + } + + delete { + call.respond(HttpStatusCode.NotImplemented) + + } + + get { + val exampleContentType = "application/json" + val exampleContentString = """{ + "firstName" : "firstName", + "lastName" : "lastName", + "password" : "password", + "userStatus" : 6, + "phone" : "phone", + "id" : 0, + "email" : "email", + "username" : "username" + }""" + + when (exampleContentType) { + "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) + else -> call.respondText(exampleContentString) + } + + } + + get { + call.respond(HttpStatusCode.NotImplemented) + + } + + get { + call.respond(HttpStatusCode.NotImplemented) + + } + + options { + call.respond(HttpStatusCode.NotImplemented) + + } + + put { + call.respond(HttpStatusCode.NotImplemented) + + } + +} diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt new file mode 100644 index 000000000000..c2cad7fe7a7f --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/infrastructure/ApiKeyAuth.kt @@ -0,0 +1,102 @@ +package org.openapitools.server.infrastructure + +import io.ktor.http.auth.* +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.request.* +import io.ktor.server.response.* + +enum class ApiKeyLocation(val location: String) { + QUERY("query"), + HEADER("header") +} + +data class ApiKeyCredential(val value: String) : Credential +data class ApiPrincipal(val apiKeyCredential: ApiKeyCredential?) : Principal + +/** +* Represents an Api Key authentication provider +*/ +class ApiKeyAuthenticationProvider(configuration: Configuration) : AuthenticationProvider(configuration) { + + private val authenticationFunction = configuration.authenticationFunction + + private val apiKeyName: String = configuration.apiKeyName + + private val apiKeyLocation: ApiKeyLocation = configuration.apiKeyLocation + + override suspend fun onAuthenticate(context: AuthenticationContext) { + val call = context.call + val credentials = call.request.apiKeyAuthenticationCredentials(apiKeyName, apiKeyLocation) + val principal = credentials?.let { authenticationFunction.invoke(call, it) } + + val cause = when { + credentials == null -> AuthenticationFailedCause.NoCredentials + principal == null -> AuthenticationFailedCause.InvalidCredentials + else -> null + } + + if (cause != null) { + context.challenge(apiKeyName, cause) { challenge, call -> + call.respond( + UnauthorizedResponse( + HttpAuthHeader.Parameterized( + "API_KEY", + mapOf("key" to apiKeyName), + HeaderValueEncoding.QUOTED_ALWAYS + ) + ) + ) + challenge.complete() + } + } + + if (principal != null) { + context.principal(principal) + } + } + + class Configuration internal constructor(name: String?) : Config(name) { + + internal var authenticationFunction: suspend ApplicationCall.(ApiKeyCredential) -> Principal? = { + throw NotImplementedError( + "Api Key auth validate function is not specified. Use apiKeyAuth { validate { ... } } to fix." + ) + } + + var apiKeyName: String = "" + + var apiKeyLocation: ApiKeyLocation = ApiKeyLocation.QUERY + + /** + * Sets a validation function that will check given [ApiKeyCredential] instance and return [Principal], + * or null if credential does not correspond to an authenticated principal + */ + fun validate(body: suspend ApplicationCall.(ApiKeyCredential) -> Principal?) { + authenticationFunction = body + } + } +} + +fun AuthenticationConfig.apiKeyAuth( + name: String? = null, + configure: ApiKeyAuthenticationProvider.Configuration.() -> Unit +) { + val configuration = ApiKeyAuthenticationProvider.Configuration(name).apply(configure) + val provider = ApiKeyAuthenticationProvider(configuration) + register(provider) +} + +fun ApplicationRequest.apiKeyAuthenticationCredentials( + apiKeyName: String, + apiKeyLocation: ApiKeyLocation +): ApiKeyCredential? { + val value: String? = when (apiKeyLocation) { + ApiKeyLocation.QUERY -> this.queryParameters[apiKeyName] + ApiKeyLocation.HEADER -> this.headers[apiKeyName] + } + return when (value) { + null -> null + else -> ApiKeyCredential(value) + } +} diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Category.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Category.kt new file mode 100644 index 000000000000..9d8571921384 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Category.kt @@ -0,0 +1,30 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.models + + +import java.io.Serializable +/** + * A category for a pet + * @param id + * @param name + */ +data class Category( + val id: kotlin.Long? = null, + val name: kotlin.String? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } +} + diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt new file mode 100644 index 000000000000..5548175d9048 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/ModelApiResponse.kt @@ -0,0 +1,32 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.models + + +import java.io.Serializable +/** + * Describes the result of uploading an image resource + * @param code + * @param type + * @param message + */ +data class ModelApiResponse( + val code: kotlin.Int? = null, + val type: kotlin.String? = null, + val message: kotlin.String? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } +} + diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Order.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Order.kt new file mode 100644 index 000000000000..79dce95e1e47 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Order.kt @@ -0,0 +1,48 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.models + + +import java.io.Serializable +/** + * An order for a pets from the pet store + * @param id + * @param petId + * @param quantity + * @param shipDate + * @param status Order Status + * @param complete + */ +data class Order( + val id: kotlin.Long? = null, + val petId: kotlin.Long? = null, + val quantity: kotlin.Int? = null, + val shipDate: java.time.OffsetDateTime? = null, + /* Order Status */ + val status: Order.Status? = null, + val complete: kotlin.Boolean? = false +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } + /** + * Order Status + * Values: placed,approved,delivered + */ + enum class Status(val value: kotlin.String){ + placed("placed"), + approved("approved"), + delivered("delivered"); + } +} + diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Pet.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Pet.kt new file mode 100644 index 000000000000..8b98ce0469c5 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Pet.kt @@ -0,0 +1,50 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.models + +import org.openapitools.server.models.Category +import org.openapitools.server.models.Tag + +import java.io.Serializable +/** + * A pet for sale in the pet store + * @param name + * @param photoUrls + * @param id + * @param category + * @param tags + * @param status pet status in the store + */ +data class Pet( + val name: kotlin.String, + val photoUrls: kotlin.collections.List, + val id: kotlin.Long? = null, + val category: Category? = null, + val tags: kotlin.collections.List? = null, + /* pet status in the store */ + val status: Pet.Status? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } + /** + * pet status in the store + * Values: available,pending,sold + */ + enum class Status(val value: kotlin.String){ + available("available"), + pending("pending"), + sold("sold"); + } +} + diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Tag.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Tag.kt new file mode 100644 index 000000000000..e9626b25c6d1 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/Tag.kt @@ -0,0 +1,30 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.models + + +import java.io.Serializable +/** + * A tag for a pet + * @param id + * @param name + */ +data class Tag( + val id: kotlin.Long? = null, + val name: kotlin.String? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } +} + diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/User.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/User.kt new file mode 100644 index 000000000000..fdbdb4e1cff4 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/models/User.kt @@ -0,0 +1,43 @@ +/** +* OpenAPI Petstore +* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +package org.openapitools.server.models + + +import java.io.Serializable +/** + * A User who is purchasing from the pet store + * @param id + * @param username + * @param firstName + * @param lastName + * @param email + * @param password + * @param phone + * @param userStatus User Status + */ +data class User( + val id: kotlin.Long? = null, + val username: kotlin.String? = null, + val firstName: kotlin.String? = null, + val lastName: kotlin.String? = null, + val email: kotlin.String? = null, + val password: kotlin.String? = null, + val phone: kotlin.String? = null, + /* User Status */ + val userStatus: kotlin.Int? = null +) : Serializable +{ + companion object { + private const val serialVersionUID: Long = 123 + } +} + diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/application.conf b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/application.conf new file mode 100644 index 000000000000..d33fe93f9937 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/application.conf @@ -0,0 +1,23 @@ +ktor { + deployment { + environment = development + port = 8080 + autoreload = true + watch = [ org.openapitools.server ] + } + + application { + modules = [ org.openapitools.server.AppMainKt.main ] + } +} + +# Typesafe config allows multiple ways to provide configuration values without hard-coding them here. +# Please see https://github.com/lightbend/config for details. +auth { + oauth { + petstore_auth { + clientId = "" + clientSecret = "" + } + } +} \ No newline at end of file diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/logback.xml b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/logback.xml new file mode 100644 index 000000000000..d0eaba8debd6 --- /dev/null +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + From 878b96b67e740615aa29a6f5c612b96fe87b4b4b Mon Sep 17 00:00:00 2001 From: feczkob Date: Fri, 10 Apr 2026 10:02:13 +0200 Subject: [PATCH 6/6] Fix deserialization for ktor and ktor2 into `Any` and use calendar year --- .../kotlin-server/libraries/ktor/api.mustache | 2 -- .../kotlin-server/libraries/ktor/logback.xml | 2 +- .../libraries/ktor2/_response.mustache | 2 +- .../kotlin-server/libraries/ktor2/api.mustache | 2 -- .../kotlin-server/libraries/ktor2/logback.xml | 2 +- .../kotlin/org/openapitools/server/apis/PetApi.kt | 2 -- .../org/openapitools/server/apis/StoreApi.kt | 2 -- .../kotlin/org/openapitools/server/apis/UserApi.kt | 2 -- .../src/main/resources/logback.xml | 2 +- .../kotlin/org/openapitools/server/apis/PetApi.kt | 2 -- .../org/openapitools/server/apis/StoreApi.kt | 2 -- .../kotlin/org/openapitools/server/apis/UserApi.kt | 2 -- .../ktor/src/main/resources/logback.xml | 2 +- .../kotlin/org/openapitools/server/apis/PetApi.kt | 12 +++++------- .../org/openapitools/server/apis/StoreApi.kt | 6 ++---- .../kotlin/org/openapitools/server/apis/UserApi.kt | 4 +--- .../src/main/resources/logback.xml | 2 +- .../kotlin/org/openapitools/server/apis/PetApi.kt | 14 ++++++-------- .../org/openapitools/server/apis/StoreApi.kt | 6 ++---- .../kotlin/org/openapitools/server/apis/UserApi.kt | 4 +--- .../ktor2/src/main/resources/logback.xml | 2 +- 21 files changed, 24 insertions(+), 52 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/api.mustache index 885ba6ae50dc..2e39aa595b75 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/api.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/api.mustache @@ -22,8 +22,6 @@ import {{packageName}}.infrastructure.ApiPrincipal {{#operations}} fun Route.{{classname}}() { - val empty = mutableMapOf() - {{#operation}} {{#hasAuthMethods}} {{#authMethods}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/logback.xml b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/logback.xml index d0eaba8debd6..b4671538e9e7 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/logback.xml +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor/logback.xml @@ -1,7 +1,7 @@ - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/_response.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/_response.mustache index 931dad98f5e1..477ffc2acda7 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/_response.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/_response.mustache @@ -2,7 +2,7 @@ val exampleContentType = "{{{contentType}}}" val exampleContentString = """{{&example}}""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/api.mustache index 5c139b28effb..a7f0757e65ca 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/api.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/api.mustache @@ -24,8 +24,6 @@ import {{packageName}}.infrastructure.ApiPrincipal {{#operations}} fun Route.{{classname}}() { val gson = Gson() - val empty = mutableMapOf() - {{#operation}} {{#hasAuthMethods}} {{#authMethods}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/logback.xml b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/logback.xml index d0eaba8debd6..b4671538e9e7 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/logback.xml +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/ktor2/logback.xml @@ -1,7 +1,7 @@ - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/PetApi.kt index b72ec0d72cec..45747e56482a 100644 --- a/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/PetApi.kt +++ b/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -29,8 +29,6 @@ import org.openapitools.server.models.ModelApiResponse import org.openapitools.server.models.Pet fun Route.PetApi() { - val empty = mutableMapOf() - authenticate("petstore_auth") { post { diff --git a/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt index 4a4395778401..7a2b5a45b2fa 100644 --- a/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +++ b/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -28,8 +28,6 @@ import org.openapitools.server.infrastructure.ApiPrincipal import org.openapitools.server.models.Order fun Route.StoreApi() { - val empty = mutableMapOf() - delete { call.respond(HttpStatusCode.NotImplemented) diff --git a/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/UserApi.kt index 299f743e141d..646343e21a7b 100644 --- a/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/UserApi.kt +++ b/samples/server/petstore/kotlin-server-modelMutable/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -28,8 +28,6 @@ import org.openapitools.server.infrastructure.ApiPrincipal import org.openapitools.server.models.User fun Route.UserApi() { - val empty = mutableMapOf() - post { call.respond(HttpStatusCode.NotImplemented) diff --git a/samples/server/petstore/kotlin-server-modelMutable/src/main/resources/logback.xml b/samples/server/petstore/kotlin-server-modelMutable/src/main/resources/logback.xml index d0eaba8debd6..b4671538e9e7 100644 --- a/samples/server/petstore/kotlin-server-modelMutable/src/main/resources/logback.xml +++ b/samples/server/petstore/kotlin-server-modelMutable/src/main/resources/logback.xml @@ -1,7 +1,7 @@ - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt index b72ec0d72cec..45747e56482a 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -29,8 +29,6 @@ import org.openapitools.server.models.ModelApiResponse import org.openapitools.server.models.Pet fun Route.PetApi() { - val empty = mutableMapOf() - authenticate("petstore_auth") { post { diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt index 4a4395778401..7a2b5a45b2fa 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -28,8 +28,6 @@ import org.openapitools.server.infrastructure.ApiPrincipal import org.openapitools.server.models.Order fun Route.StoreApi() { - val empty = mutableMapOf() - delete { call.respond(HttpStatusCode.NotImplemented) diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt index 299f743e141d..646343e21a7b 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt +++ b/samples/server/petstore/kotlin-server/ktor/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -28,8 +28,6 @@ import org.openapitools.server.infrastructure.ApiPrincipal import org.openapitools.server.models.User fun Route.UserApi() { - val empty = mutableMapOf() - post { call.respond(HttpStatusCode.NotImplemented) diff --git a/samples/server/petstore/kotlin-server/ktor/src/main/resources/logback.xml b/samples/server/petstore/kotlin-server/ktor/src/main/resources/logback.xml index d0eaba8debd6..b4671538e9e7 100644 --- a/samples/server/petstore/kotlin-server/ktor/src/main/resources/logback.xml +++ b/samples/server/petstore/kotlin-server/ktor/src/main/resources/logback.xml @@ -1,7 +1,7 @@ - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/PetApi.kt index a1c717be2979..deac07497e74 100644 --- a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/PetApi.kt +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -31,8 +31,6 @@ import org.openapitools.server.models.Pet fun Route.PetApi() { val gson = Gson() - val empty = mutableMapOf() - authenticate("petstore_auth") { post { @@ -97,7 +95,7 @@ fun Route.PetApi() { } ]""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -147,7 +145,7 @@ fun Route.PetApi() { } ]""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -192,7 +190,7 @@ fun Route.PetApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -236,7 +234,7 @@ fun Route.PetApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -258,7 +256,7 @@ fun Route.PetApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt index fe780f7feb46..b85f5bc3a5fd 100644 --- a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -30,8 +30,6 @@ import org.openapitools.server.models.Order fun Route.StoreApi() { val gson = Gson() - val empty = mutableMapOf() - delete { call.respond(HttpStatusCode.NotImplemented) @@ -60,7 +58,7 @@ fun Route.StoreApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -79,7 +77,7 @@ fun Route.StoreApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/UserApi.kt index 388cd6953635..1f295edcbc31 100644 --- a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/UserApi.kt +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -30,8 +30,6 @@ import org.openapitools.server.models.User fun Route.UserApi() { val gson = Gson() - val empty = mutableMapOf() - post { call.respond(HttpStatusCode.NotImplemented) @@ -66,7 +64,7 @@ fun Route.UserApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } diff --git a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/logback.xml b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/logback.xml index d0eaba8debd6..b4671538e9e7 100644 --- a/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/logback.xml +++ b/samples/server/petstore/kotlin-server/ktor2-usetags-false/src/main/resources/logback.xml @@ -1,7 +1,7 @@ - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/PetApi.kt index 7b0482f3d322..c3ae8e62f836 100644 --- a/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/PetApi.kt +++ b/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -31,8 +31,6 @@ import org.openapitools.server.models.Pet fun Route.PetApi() { val gson = Gson() - val empty = mutableMapOf() - authenticate("petstore_auth") { post { @@ -59,7 +57,7 @@ fun Route.PetApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -120,7 +118,7 @@ fun Route.PetApi() { } ]""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -170,7 +168,7 @@ fun Route.PetApi() { } ]""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -204,7 +202,7 @@ fun Route.PetApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -238,7 +236,7 @@ fun Route.PetApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -271,7 +269,7 @@ fun Route.PetApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } diff --git a/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt index fe780f7feb46..b85f5bc3a5fd 100644 --- a/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +++ b/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -30,8 +30,6 @@ import org.openapitools.server.models.Order fun Route.StoreApi() { val gson = Gson() - val empty = mutableMapOf() - delete { call.respond(HttpStatusCode.NotImplemented) @@ -60,7 +58,7 @@ fun Route.StoreApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } @@ -79,7 +77,7 @@ fun Route.StoreApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } diff --git a/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/UserApi.kt index f3b7a76c39a0..4dd034786ca9 100644 --- a/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/UserApi.kt +++ b/samples/server/petstore/kotlin-server/ktor2/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -30,8 +30,6 @@ import org.openapitools.server.models.User fun Route.UserApi() { val gson = Gson() - val empty = mutableMapOf() - authenticate("api_key") { post { @@ -90,7 +88,7 @@ fun Route.UserApi() { }""" when (exampleContentType) { - "application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) + "application/json" -> call.respond(gson.fromJson(exampleContentString, Any::class.java)) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) else -> call.respondText(exampleContentString) } diff --git a/samples/server/petstore/kotlin-server/ktor2/src/main/resources/logback.xml b/samples/server/petstore/kotlin-server/ktor2/src/main/resources/logback.xml index d0eaba8debd6..b4671538e9e7 100644 --- a/samples/server/petstore/kotlin-server/ktor2/src/main/resources/logback.xml +++ b/samples/server/petstore/kotlin-server/ktor2/src/main/resources/logback.xml @@ -1,7 +1,7 @@ - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n