[Kotlin Server] Update Ktor to the next major version 3 (#20245)

* [Kotlin Server] Update Ktor to version 3

* [Kotlin Server] Clean up

* [Kotlin Server] Fix problems

* [Kotlin Server] Fix Ktor and modelMutable samples

* [Kotlin Server] Fix the string value for serialization key

* [Kotlin Server] Remove setting Kotlin serialization flag to true

* [Kotlin Server] Remove setting Kotlin serialization flag to true

* [Kotlin Server] Remove the option to enable Kotlin serialization

* [Kotlin Server] Use query parameters
This commit is contained in:
Aleksei Tirman 2024-12-14 09:06:27 +02:00 committed by GitHub
parent 3e6f8753e9
commit f766f445da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 183 additions and 271 deletions

View File

@ -236,6 +236,11 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
LOGGER.info("`library` option is empty. Default to {}", DEFAULT_LIBRARY); LOGGER.info("`library` option is empty. Default to {}", DEFAULT_LIBRARY);
} }
if (isKtor()) {
typeMapping.put("date-time", "kotlin.String");
typeMapping.put("DateTime", "kotlin.String");
}
if (additionalProperties.containsKey(Constants.AUTOMATIC_HEAD_REQUESTS)) { if (additionalProperties.containsKey(Constants.AUTOMATIC_HEAD_REQUESTS)) {
setAutoHeadFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.AUTOMATIC_HEAD_REQUESTS)); setAutoHeadFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.AUTOMATIC_HEAD_REQUESTS));
} else { } else {
@ -298,6 +303,8 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
supportingFiles.add(new SupportingFile("gradle.properties", "", "gradle.properties")); supportingFiles.add(new SupportingFile("gradle.properties", "", "gradle.properties"));
if (isKtor()) { if (isKtor()) {
additionalProperties.put(Constants.IS_KTOR, true);
supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt")); supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt"));
supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt")); supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt"));
@ -365,6 +372,7 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
public static final String USE_MUTINY_DESC = "Whether to use Mutiny (should not be used with useCoroutines). This option is currently supported only when using jaxrs-spec library."; public static final String USE_MUTINY_DESC = "Whether to use Mutiny (should not be used with useCoroutines). This option is currently supported only when using jaxrs-spec library.";
public static final String OMIT_GRADLE_WRAPPER = "omitGradleWrapper"; public static final String OMIT_GRADLE_WRAPPER = "omitGradleWrapper";
public static final String OMIT_GRADLE_WRAPPER_DESC = "Whether to omit Gradle wrapper for creating a sub project."; public static final String OMIT_GRADLE_WRAPPER_DESC = "Whether to omit Gradle wrapper for creating a sub project.";
public static final String IS_KTOR = "isKtor";
} }
@Override @Override
@ -386,6 +394,13 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
if (operations != null && !Objects.equals(library, Constants.JAXRS_SPEC)) { if (operations != null && !Objects.equals(library, Constants.JAXRS_SPEC)) {
List<CodegenOperation> ops = operations.getOperation(); List<CodegenOperation> ops = operations.getOperation();
ops.forEach(operation -> { ops.forEach(operation -> {
if (isKtor()) {
ArrayList<CodegenParameter> params = new ArrayList<>();
params.addAll(operation.pathParams);
params.addAll(operation.queryParams);
operation.vendorExtensions.put("ktor-params", params);
}
List<CodegenResponse> responses = operation.responses; List<CodegenResponse> responses = operation.responses;
if (responses != null) { if (responses != null) {
responses.forEach(resp -> { responses.forEach(resp -> {

View File

@ -1,11 +1,15 @@
{{#parcelizeModels}} {{#isKtor}}
import kotlinx.serialization.Serializable
{{/isKtor}}
{{^isKtor}}
{{#parcelizeModels}}
import android.os.Parcelable import android.os.Parcelable
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
{{/parcelizeModels}}
{{/parcelizeModels}} {{#serializableModel}}
{{#serializableModel}}
import java.io.Serializable import java.io.Serializable
{{/serializableModel}} {{/serializableModel}}
{{/isKtor}}
/** /**
* {{{description}}} * {{{description}}}
{{#vars}} {{#vars}}
@ -15,21 +19,19 @@ import java.io.Serializable
{{#parcelizeModels}} {{#parcelizeModels}}
@Parcelize @Parcelize
{{/parcelizeModels}} {{/parcelizeModels}}
{{#isKtor}}
@Serializable
{{/isKtor}}
{{#hasVars}}data {{/hasVars}}class {{classname}}( {{#hasVars}}data {{/hasVars}}class {{classname}}(
{{#requiredVars}} {{#requiredVars}}
{{>data_class_req_var}}{{^-last}}, {{>data_class_req_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}}, {{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}}, {{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}} {{/-last}}{{/optionalVars}}
) {{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}} ){{^isKtor}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}{{/isKtor}}
{{#vendorExtensions.x-has-data-class-body}} {{#vendorExtensions.x-has-data-class-body}}
{ {
{{/vendorExtensions.x-has-data-class-body}} {{/vendorExtensions.x-has-data-class-body}}
{{#serializableModel}}
companion object {
private const val serialVersionUID: Long = 123
}
{{/serializableModel}}
{{#hasEnums}} {{#hasEnums}}
{{#vars}} {{#vars}}
{{#isEnum}} {{#isEnum}}

View File

@ -1,4 +1,4 @@
package org.openapitools.server.infrastructure package {{packageName}}.infrastructure
import io.ktor.http.auth.* import io.ktor.http.auth.*
import io.ktor.server.application.* import io.ktor.server.application.*

View File

@ -1,7 +1,6 @@
package {{packageName}} package {{packageName}}
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.serialization.gson.*
import io.ktor.http.* import io.ktor.http.*
{{#featureResources}} {{#featureResources}}
import io.ktor.server.resources.* import io.ktor.server.resources.*
@ -30,24 +29,17 @@ import java.util.concurrent.TimeUnit
{{/featureMetrics}} {{/featureMetrics}}
import io.ktor.server.routing.* import io.ktor.server.routing.*
{{#hasAuthMethods}} {{#hasAuthMethods}}
import io.ktor.serialization.kotlinx.json.json
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.engine.apache.Apache import io.ktor.client.engine.apache.Apache
import io.ktor.server.config.HoconApplicationConfig import io.ktor.server.config.HoconApplicationConfig
import io.ktor.server.auth.* import io.ktor.server.auth.*
import org.openapitools.server.infrastructure.* import {{packageName}}.infrastructure.*
{{/hasAuthMethods}} {{/hasAuthMethods}}
{{#generateApis}}{{#apiInfo}}{{#apis}}import {{apiPackage}}.{{classname}} {{#generateApis}}{{#apiInfo}}{{#apis}}import {{apiPackage}}.{{classname}}
{{/apis}}{{/apiInfo}}{{/generateApis}} {{/apis}}{{/apiInfo}}{{/generateApis}}
{{#hasAuthMethods}}
internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader))
object HTTP {
val client = HttpClient(Apache)
}
{{/hasAuthMethods}}
fun Application.main() { fun Application.main() {
install(DefaultHeaders) install(DefaultHeaders)
{{#featureMetrics}} {{#featureMetrics}}
@ -62,7 +54,7 @@ fun Application.main() {
{{/featureMetrics}} {{/featureMetrics}}
{{#generateApis}} {{#generateApis}}
install(ContentNegotiation) { install(ContentNegotiation) {
register(ContentType.Application.Json, GsonConverter()) json()
} }
{{#featureAutoHead}} {{#featureAutoHead}}
install(AutoHeadResponse) // see https://ktor.io/docs/autoheadresponse.html install(AutoHeadResponse) // see https://ktor.io/docs/autoheadresponse.html
@ -125,7 +117,7 @@ fun Application.main() {
{{/authMethods}} {{/authMethods}}
} }
{{/hasAuthMethods}} {{/hasAuthMethods}}
install(Routing) { routing {
{{#apiInfo}} {{#apiInfo}}
{{#apis}} {{#apis}}
{{#operations}} {{#operations}}
@ -134,6 +126,5 @@ fun Application.main() {
{{/apis}} {{/apis}}
{{/apiInfo}} {{/apiInfo}}
} }
{{/generateApis}} {{/generateApis}}
} }

View File

@ -18,10 +18,10 @@ object Paths {
{{#allParams}}* @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} {{#allParams}}* @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}*/ {{/allParams}}*/
{{#hasParams}} {{#hasParams}}
@Serializable @Resource("{{{path}}}") class {{operationId}}({{#allParams}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}}) @Resource("{{{path}}}") class {{operationId}}({{#vendorExtensions.ktor-params}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/vendorExtensions.ktor-params}})
{{/hasParams}} {{/hasParams}}
{{^hasParams}} {{^hasParams}}
@Serializable @Resource("{{{path}}}") class {{operationId}} @Resource("{{{path}}}") class {{operationId}}
{{/hasParams}} {{/hasParams}}
{{/operation}} {{/operation}}

View File

@ -1,10 +1,10 @@
{{#authMethods}} {{#authMethods}}
{{#isBasicBasic}} {{#isBasicBasic}}
val principal = call.authentication.principal<UserIdPrincipal>()!! val principal = call.authentication.principal<UserIdPrincipal>()
{{/isBasicBasic}}{{^isBasicBasic}}{{#isApiKey}} {{/isBasicBasic}}{{^isBasicBasic}}{{#isApiKey}}
val principal = call.authentication.principal<ApiPrincipal>()!! val principal = call.authentication.principal<ApiPrincipal>()
{{/isApiKey}}{{^isApiKey}}{{#isOAuth}} {{/isApiKey}}{{^isApiKey}}{{#isOAuth}}
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
{{/isOAuth}}{{^isOAuth}} {{/isOAuth}}{{^isOAuth}}
val principal = null!! val principal = null!!
{{/isOAuth}}{{/isApiKey}}{{/isBasicBasic}} {{/isOAuth}}{{/isApiKey}}{{/isBasicBasic}}

View File

@ -2,7 +2,7 @@ val exampleContentType = "{{{contentType}}}"
val exampleContentString = """{{&example}}""" val exampleContentString = """{{&example}}"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }

View File

@ -1,7 +1,6 @@
{{>licenseInfo}} {{>licenseInfo}}
package {{apiPackage}} package {{apiPackage}}
import com.google.gson.Gson
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@ -23,7 +22,6 @@ import {{packageName}}.infrastructure.ApiPrincipal
{{#operations}} {{#operations}}
fun Route.{{classname}}() { fun Route.{{classname}}() {
val gson = Gson()
val empty = mutableMapOf<String, Any?>() val empty = mutableMapOf<String, Any?>()
{{#operation}} {{#operation}}

View File

@ -7,7 +7,8 @@ version = "{{artifactVersion}}"
plugins { plugins {
kotlin("jvm") version "2.0.20" kotlin("jvm") version "2.0.20"
id("io.ktor.plugin") version "2.3.12" application
kotlin("plugin.serialization") version "2.0.20"
} }
application { application {
@ -22,6 +23,7 @@ repositories {
} }
dependencies { dependencies {
implementation(platform("io.ktor:ktor-bom:3.0.2"))
implementation("ch.qos.logback:logback-classic:$logback_version") implementation("ch.qos.logback:logback-classic:$logback_version")
{{#hasAuthMethods}} {{#hasAuthMethods}}
implementation("com.typesafe:config:1.4.1") implementation("com.typesafe:config:1.4.1")
@ -35,7 +37,7 @@ dependencies {
{{/featureAutoHead}} {{/featureAutoHead}}
implementation("io.ktor:ktor-server-default-headers") implementation("io.ktor:ktor-server-default-headers")
implementation("io.ktor:ktor-server-content-negotiation") implementation("io.ktor:ktor-server-content-negotiation")
implementation("io.ktor:ktor-serialization-gson") implementation("io.ktor:ktor-serialization-kotlinx-json")
{{#featureResources}} {{#featureResources}}
implementation("io.ktor:ktor-server-resources") implementation("io.ktor:ktor-server-resources")
{{/featureResources}} {{/featureResources}}

View File

@ -1,4 +1,4 @@
kotlin.code.style=official kotlin.code.style=official
ktor_version=2.3.12 ktor_version=3.0.2
kotlin_version=2.0.20 kotlin_version=2.0.20
logback_version=1.4.14 logback_version=1.4.14

View File

@ -1,74 +0,0 @@
group "org.openapitools"
version "1.0.0"
wrapper {
gradleVersion = "7.4.2"
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
}
buildscript {
ext.kotlin_version = "1.7.20"
ext.ktor_version = "2.2.1"
ext.shadow_version = "6.1.0"
repositories {
maven { url "https://repo1.maven.org/maven2" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
classpath("com.github.jengelman.gradle.plugins:shadow:$shadow_version")
}
}
apply plugin: "java"
apply plugin: "kotlin"
apply plugin: "application"
mainClassName = "io.ktor.server.netty.DevelopmentEngine"
// Initialization order with shadow 2.0.1 and Gradle 6.9 is weird.
// See https://github.com/johnrengelman/shadow/issues/336#issuecomment-355402508
apply plugin: "com.github.johnrengelman.shadow"
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
shadowJar {
baseName = "kotlin-server"
classifier = null
version = null
}
repositories {
maven { setUrl("https://repo1.maven.org/maven2") }
maven { setUrl("https://dl.bintray.com/kotlin/ktor") }
maven { setUrl("https://dl.bintray.com/kotlin/kotlinx") }
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version")
implementation("ch.qos.logback:logback-classic:1.2.9")
implementation("com.typesafe:config:1.4.1")
implementation("io.ktor:ktor-server-auth:$ktor_version")
implementation("io.ktor:ktor-client-apache:$ktor_version")
implementation("io.ktor:ktor-server-auto-head-response:$ktor_version")
implementation("io.ktor:ktor-server-default-headers:$ktor_version")
implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-serialization-gson:$ktor_version")
implementation("io.ktor:ktor-server-resources:$ktor_version")
implementation("io.ktor:ktor-server-hsts:$ktor_version")
implementation("io.ktor:ktor-server-compression:$ktor_version")
implementation("io.dropwizard.metrics:metrics-core:4.1.18")
implementation("io.ktor:ktor-server-metrics:$ktor_version")
implementation("io.ktor:ktor-server-netty:$ktor_version")
testImplementation("junit:junit:4.13.2")
}

View File

@ -7,7 +7,8 @@ version = "1.0.0"
plugins { plugins {
kotlin("jvm") version "2.0.20" kotlin("jvm") version "2.0.20"
id("io.ktor.plugin") version "2.3.12" application
kotlin("plugin.serialization") version "2.0.20"
} }
application { application {
@ -22,6 +23,7 @@ repositories {
} }
dependencies { dependencies {
implementation(platform("io.ktor:ktor-bom:3.0.2"))
implementation("ch.qos.logback:logback-classic:$logback_version") implementation("ch.qos.logback:logback-classic:$logback_version")
implementation("com.typesafe:config:1.4.1") implementation("com.typesafe:config:1.4.1")
implementation("io.ktor:ktor-server-auth") implementation("io.ktor:ktor-server-auth")
@ -29,7 +31,7 @@ dependencies {
implementation("io.ktor:ktor-server-auto-head-response") implementation("io.ktor:ktor-server-auto-head-response")
implementation("io.ktor:ktor-server-default-headers") implementation("io.ktor:ktor-server-default-headers")
implementation("io.ktor:ktor-server-content-negotiation") implementation("io.ktor:ktor-server-content-negotiation")
implementation("io.ktor:ktor-serialization-gson") implementation("io.ktor:ktor-serialization-kotlinx-json")
implementation("io.ktor:ktor-server-resources") implementation("io.ktor:ktor-server-resources")
implementation("io.ktor:ktor-server-hsts") implementation("io.ktor:ktor-server-hsts")
implementation("io.ktor:ktor-server-compression") implementation("io.ktor:ktor-server-compression")

View File

@ -1,4 +1,4 @@
kotlin.code.style=official kotlin.code.style=official
ktor_version=2.3.12 ktor_version=3.0.2
kotlin_version=2.0.20 kotlin_version=2.0.20
logback_version=1.4.14 logback_version=1.4.14

View File

@ -1,7 +1,6 @@
package org.openapitools.server package org.openapitools.server
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.serialization.gson.*
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.resources.* import io.ktor.server.resources.*
import io.ktor.server.plugins.autohead.* import io.ktor.server.plugins.autohead.*
@ -13,6 +12,7 @@ import com.codahale.metrics.Slf4jReporter
import io.ktor.server.metrics.dropwizard.* import io.ktor.server.metrics.dropwizard.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import io.ktor.server.routing.* import io.ktor.server.routing.*
import io.ktor.serialization.kotlinx.json.json
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.engine.apache.Apache import io.ktor.client.engine.apache.Apache
@ -24,12 +24,6 @@ import org.openapitools.server.apis.StoreApi
import org.openapitools.server.apis.UserApi 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() { fun Application.main() {
install(DefaultHeaders) install(DefaultHeaders)
install(DropwizardMetrics) { install(DropwizardMetrics) {
@ -41,7 +35,7 @@ fun Application.main() {
reporter.start(10, TimeUnit.SECONDS) reporter.start(10, TimeUnit.SECONDS)
} }
install(ContentNegotiation) { install(ContentNegotiation) {
register(ContentType.Application.Json, GsonConverter()) json()
} }
install(AutoHeadResponse) // see https://ktor.io/docs/autoheadresponse.html install(AutoHeadResponse) // see https://ktor.io/docs/autoheadresponse.html
install(Compression, ApplicationCompressionConfiguration()) // see https://ktor.io/docs/compression.html install(Compression, ApplicationCompressionConfiguration()) // see https://ktor.io/docs/compression.html
@ -66,10 +60,9 @@ fun Application.main() {
} }
} }
} }
install(Routing) { routing {
PetApi() PetApi()
StoreApi() StoreApi()
UserApi() UserApi()
} }
} }

View File

@ -21,7 +21,7 @@ object Paths {
* *
* @param body Pet object that needs to be added to the store * @param body Pet object that needs to be added to the store
*/ */
@Serializable @Resource("/pet") class addPet(val body: Pet) @Resource("/pet") class addPet()
/** /**
* Deletes a pet * Deletes a pet
@ -29,35 +29,35 @@ object Paths {
* @param petId Pet id to delete * @param petId Pet id to delete
* @param apiKey (optional) * @param apiKey (optional)
*/ */
@Serializable @Resource("/pet/{petId}") class deletePet(val petId: kotlin.Long, val apiKey: kotlin.String? = null) @Resource("/pet/{petId}") class deletePet(val petId: kotlin.Long)
/** /**
* Finds Pets by status * Finds Pets by status
* Multiple status values can be provided with comma separated strings * Multiple status values can be provided with comma separated strings
* @param status Status values that need to be considered for filter * @param status Status values that need to be considered for filter
*/ */
@Serializable @Resource("/pet/findByStatus") class findPetsByStatus(val status: kotlin.collections.MutableList<kotlin.String>) @Resource("/pet/findByStatus") class findPetsByStatus(val status: kotlin.collections.MutableList<kotlin.String>)
/** /**
* Finds Pets by tags * Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* @param tags Tags to filter by * @param tags Tags to filter by
*/ */
@Serializable @Resource("/pet/findByTags") class findPetsByTags(val tags: kotlin.collections.MutableList<kotlin.String>) @Resource("/pet/findByTags") class findPetsByTags(val tags: kotlin.collections.MutableList<kotlin.String>)
/** /**
* Find pet by ID * Find pet by ID
* Returns a single pet * Returns a single pet
* @param petId ID of pet to return * @param petId ID of pet to return
*/ */
@Serializable @Resource("/pet/{petId}") class getPetById(val petId: kotlin.Long) @Resource("/pet/{petId}") class getPetById(val petId: kotlin.Long)
/** /**
* Update an existing pet * Update an existing pet
* *
* @param body Pet object that needs to be added to the store * @param body Pet object that needs to be added to the store
*/ */
@Serializable @Resource("/pet") class updatePet(val body: Pet) @Resource("/pet") class updatePet()
/** /**
* Updates a pet in the store with form data * Updates a pet in the store with form data
@ -66,7 +66,7 @@ object Paths {
* @param name Updated name of the pet (optional) * @param name Updated name of the pet (optional)
* @param status Updated status of the pet (optional) * @param status Updated status of the pet (optional)
*/ */
@Serializable @Resource("/pet/{petId}") class updatePetWithForm(val petId: kotlin.Long, val name: kotlin.String? = null, val status: kotlin.String? = null) @Resource("/pet/{petId}") class updatePetWithForm(val petId: kotlin.Long)
/** /**
* uploads an image * uploads an image
@ -75,69 +75,69 @@ object Paths {
* @param additionalMetadata Additional data to pass to server (optional) * @param additionalMetadata Additional data to pass to server (optional)
* @param file file to upload (optional) * @param file file to upload (optional)
*/ */
@Serializable @Resource("/pet/{petId}/uploadImage") class uploadFile(val petId: kotlin.Long, val additionalMetadata: kotlin.String? = null, val file: java.io.File? = null) @Resource("/pet/{petId}/uploadImage") class uploadFile(val petId: kotlin.Long)
/** /**
* Delete purchase order by ID * Delete purchase order by ID
* For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors * For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
* @param orderId ID of the order that needs to be deleted * @param orderId ID of the order that needs to be deleted
*/ */
@Serializable @Resource("/store/order/{orderId}") class deleteOrder(val orderId: kotlin.String) @Resource("/store/order/{orderId}") class deleteOrder(val orderId: kotlin.String)
/** /**
* Returns pet inventories by status * Returns pet inventories by status
* Returns a map of status codes to quantities * Returns a map of status codes to quantities
*/ */
@Serializable @Resource("/store/inventory") class getInventory @Resource("/store/inventory") class getInventory
/** /**
* Find purchase order by ID * Find purchase order by ID
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generate exceptions * For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generate exceptions
* @param orderId ID of pet that needs to be fetched * @param orderId ID of pet that needs to be fetched
*/ */
@Serializable @Resource("/store/order/{orderId}") class getOrderById(val orderId: kotlin.Long) @Resource("/store/order/{orderId}") class getOrderById(val orderId: kotlin.Long)
/** /**
* Place an order for a pet * Place an order for a pet
* *
* @param body order placed for purchasing the pet * @param body order placed for purchasing the pet
*/ */
@Serializable @Resource("/store/order") class placeOrder(val body: Order) @Resource("/store/order") class placeOrder()
/** /**
* Create user * Create user
* This can only be done by the logged in user. * This can only be done by the logged in user.
* @param body Created user object * @param body Created user object
*/ */
@Serializable @Resource("/user") class createUser(val body: User) @Resource("/user") class createUser()
/** /**
* Creates list of users with given input array * Creates list of users with given input array
* *
* @param body List of user object * @param body List of user object
*/ */
@Serializable @Resource("/user/createWithArray") class createUsersWithArrayInput(val body: kotlin.collections.MutableList<User>) @Resource("/user/createWithArray") class createUsersWithArrayInput()
/** /**
* Creates list of users with given input array * Creates list of users with given input array
* *
* @param body List of user object * @param body List of user object
*/ */
@Serializable @Resource("/user/createWithList") class createUsersWithListInput(val body: kotlin.collections.MutableList<User>) @Resource("/user/createWithList") class createUsersWithListInput()
/** /**
* Delete user * Delete user
* This can only be done by the logged in user. * This can only be done by the logged in user.
* @param username The name that needs to be deleted * @param username The name that needs to be deleted
*/ */
@Serializable @Resource("/user/{username}") class deleteUser(val username: kotlin.String) @Resource("/user/{username}") class deleteUser(val username: kotlin.String)
/** /**
* Get user by user name * Get user by user name
* *
* @param username The name that needs to be fetched. Use user1 for testing. * @param username The name that needs to be fetched. Use user1 for testing.
*/ */
@Serializable @Resource("/user/{username}") class getUserByName(val username: kotlin.String) @Resource("/user/{username}") class getUserByName(val username: kotlin.String)
/** /**
* Logs user into the system * Logs user into the system
@ -145,13 +145,13 @@ object Paths {
* @param username The user name for login * @param username The user name for login
* @param password The password for login in clear text * @param password The password for login in clear text
*/ */
@Serializable @Resource("/user/login") class loginUser(val username: kotlin.String, val password: kotlin.String) @Resource("/user/login") class loginUser(val username: kotlin.String, val password: kotlin.String)
/** /**
* Logs out current logged in user session * Logs out current logged in user session
* *
*/ */
@Serializable @Resource("/user/logout") class logoutUser @Resource("/user/logout") class logoutUser
/** /**
* Updated user * Updated user
@ -159,6 +159,6 @@ object Paths {
* @param username name that need to be deleted * @param username name that need to be deleted
* @param body Updated user object * @param body Updated user object
*/ */
@Serializable @Resource("/user/{username}") class updateUser(val username: kotlin.String, val body: User) @Resource("/user/{username}") class updateUser(val username: kotlin.String)
} }

View File

@ -11,7 +11,6 @@
*/ */
package org.openapitools.server.apis package org.openapitools.server.apis
import com.google.gson.Gson
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@ -30,13 +29,12 @@ import org.openapitools.server.models.ModelApiResponse
import org.openapitools.server.models.Pet import org.openapitools.server.models.Pet
fun Route.PetApi() { fun Route.PetApi() {
val gson = Gson()
val empty = mutableMapOf<String, Any?>() val empty = mutableMapOf<String, Any?>()
authenticate("petstore_auth") { authenticate("petstore_auth") {
post<Paths.addPet> { post<Paths.addPet> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -47,7 +45,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
delete<Paths.deletePet> { delete<Paths.deletePet> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -58,7 +56,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
get<Paths.findPetsByStatus> { get<Paths.findPetsByStatus> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
val exampleContentType = "application/json" val exampleContentType = "application/json"
@ -97,7 +95,7 @@ fun Route.PetApi() {
} ]""" } ]"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }
@ -108,7 +106,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
get<Paths.findPetsByTags> { get<Paths.findPetsByTags> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
val exampleContentType = "application/json" val exampleContentType = "application/json"
@ -147,7 +145,7 @@ fun Route.PetApi() {
} ]""" } ]"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }
@ -158,7 +156,7 @@ fun Route.PetApi() {
authenticate("api_key") { authenticate("api_key") {
get<Paths.getPetById> { get<Paths.getPetById> {
val principal = call.authentication.principal<ApiPrincipal>()!! val principal = call.authentication.principal<ApiPrincipal>()
val exampleContentType = "application/json" val exampleContentType = "application/json"
@ -181,7 +179,7 @@ fun Route.PetApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }
@ -192,7 +190,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
put<Paths.updatePet> { put<Paths.updatePet> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -203,7 +201,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
post<Paths.updatePetWithForm> { post<Paths.updatePetWithForm> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -214,7 +212,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
post<Paths.uploadFile> { post<Paths.uploadFile> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
val exampleContentType = "application/json" val exampleContentType = "application/json"
@ -225,7 +223,7 @@ fun Route.PetApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }

View File

@ -11,7 +11,6 @@
*/ */
package org.openapitools.server.apis package org.openapitools.server.apis
import com.google.gson.Gson
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@ -29,7 +28,6 @@ import org.openapitools.server.infrastructure.ApiPrincipal
import org.openapitools.server.models.Order import org.openapitools.server.models.Order
fun Route.StoreApi() { fun Route.StoreApi() {
val gson = Gson()
val empty = mutableMapOf<String, Any?>() val empty = mutableMapOf<String, Any?>()
delete<Paths.deleteOrder> { delete<Paths.deleteOrder> {
@ -40,7 +38,7 @@ fun Route.StoreApi() {
authenticate("api_key") { authenticate("api_key") {
get<Paths.getInventory> { get<Paths.getInventory> {
val principal = call.authentication.principal<ApiPrincipal>()!! val principal = call.authentication.principal<ApiPrincipal>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -60,7 +58,7 @@ fun Route.StoreApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }
@ -79,7 +77,7 @@ fun Route.StoreApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }

View File

@ -11,7 +11,6 @@
*/ */
package org.openapitools.server.apis package org.openapitools.server.apis
import com.google.gson.Gson
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@ -29,7 +28,6 @@ import org.openapitools.server.infrastructure.ApiPrincipal
import org.openapitools.server.models.User import org.openapitools.server.models.User
fun Route.UserApi() { fun Route.UserApi() {
val gson = Gson()
val empty = mutableMapOf<String, Any?>() val empty = mutableMapOf<String, Any?>()
post<Paths.createUser> { post<Paths.createUser> {
@ -66,7 +64,7 @@ fun Route.UserApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }

View File

@ -12,13 +12,15 @@
package org.openapitools.server.models package org.openapitools.server.models
import kotlinx.serialization.Serializable
/** /**
* A category for a pet * A category for a pet
* @param id * @param id
* @param name * @param name
*/ */
@Serializable
data class Category( data class Category(
var id: kotlin.Long? = null, var id: kotlin.Long? = null,
var name: kotlin.String? = null var name: kotlin.String? = null
) )

View File

@ -12,15 +12,17 @@
package org.openapitools.server.models package org.openapitools.server.models
import kotlinx.serialization.Serializable
/** /**
* Describes the result of uploading an image resource * Describes the result of uploading an image resource
* @param code * @param code
* @param type * @param type
* @param message * @param message
*/ */
@Serializable
data class ModelApiResponse( data class ModelApiResponse(
var code: kotlin.Int? = null, var code: kotlin.Int? = null,
var type: kotlin.String? = null, var type: kotlin.String? = null,
var message: kotlin.String? = null var message: kotlin.String? = null
) )

View File

@ -12,6 +12,7 @@
package org.openapitools.server.models package org.openapitools.server.models
import kotlinx.serialization.Serializable
/** /**
* An order for a pets from the pet store * An order for a pets from the pet store
* @param id * @param id
@ -21,15 +22,16 @@ package org.openapitools.server.models
* @param status Order Status * @param status Order Status
* @param complete * @param complete
*/ */
@Serializable
data class Order( data class Order(
var id: kotlin.Long? = null, var id: kotlin.Long? = null,
var petId: kotlin.Long? = null, var petId: kotlin.Long? = null,
var quantity: kotlin.Int? = null, var quantity: kotlin.Int? = null,
var shipDate: java.time.OffsetDateTime? = null, var shipDate: kotlin.String? = null,
/* Order Status */ /* Order Status */
var status: Order.Status? = null, var status: Order.Status? = null,
var complete: kotlin.Boolean? = false var complete: kotlin.Boolean? = false
) )
{ {
/** /**
* Order Status * Order Status

View File

@ -14,6 +14,7 @@ package org.openapitools.server.models
import org.openapitools.server.models.Category import org.openapitools.server.models.Category
import org.openapitools.server.models.Tag import org.openapitools.server.models.Tag
import kotlinx.serialization.Serializable
/** /**
* A pet for sale in the pet store * A pet for sale in the pet store
* @param name * @param name
@ -23,6 +24,7 @@ import org.openapitools.server.models.Tag
* @param tags * @param tags
* @param status pet status in the store * @param status pet status in the store
*/ */
@Serializable
data class Pet( data class Pet(
var name: kotlin.String, var name: kotlin.String,
var photoUrls: kotlin.collections.MutableList<kotlin.String>, var photoUrls: kotlin.collections.MutableList<kotlin.String>,
@ -31,7 +33,7 @@ data class Pet(
var tags: kotlin.collections.MutableList<Tag>? = null, var tags: kotlin.collections.MutableList<Tag>? = null,
/* pet status in the store */ /* pet status in the store */
var status: Pet.Status? = null var status: Pet.Status? = null
) )
{ {
/** /**
* pet status in the store * pet status in the store

View File

@ -12,13 +12,15 @@
package org.openapitools.server.models package org.openapitools.server.models
import kotlinx.serialization.Serializable
/** /**
* A tag for a pet * A tag for a pet
* @param id * @param id
* @param name * @param name
*/ */
@Serializable
data class Tag( data class Tag(
var id: kotlin.Long? = null, var id: kotlin.Long? = null,
var name: kotlin.String? = null var name: kotlin.String? = null
) )

View File

@ -12,6 +12,7 @@
package org.openapitools.server.models package org.openapitools.server.models
import kotlinx.serialization.Serializable
/** /**
* A User who is purchasing from the pet store * A User who is purchasing from the pet store
* @param id * @param id
@ -23,6 +24,7 @@ package org.openapitools.server.models
* @param phone * @param phone
* @param userStatus User Status * @param userStatus User Status
*/ */
@Serializable
data class User( data class User(
var id: kotlin.Long? = null, var id: kotlin.Long? = null,
var username: kotlin.String? = null, var username: kotlin.String? = null,
@ -33,5 +35,5 @@ data class User(
var phone: kotlin.String? = null, var phone: kotlin.String? = null,
/* User Status */ /* User Status */
var userStatus: kotlin.Int? = null var userStatus: kotlin.Int? = null
) )

View File

@ -24,5 +24,5 @@ data class Pet(
val nullableRequired: kotlin.String?, val nullableRequired: kotlin.String?,
val nullableNotRequired: kotlin.String? = null, val nullableNotRequired: kotlin.String? = null,
val notNullableNotRequired: kotlin.String? = null val notNullableNotRequired: kotlin.String? = null
) )

View File

@ -20,5 +20,5 @@ package org.openapitools.server.models
data class Category( data class Category(
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
val name: kotlin.String? = null val name: kotlin.String? = null
) )

View File

@ -22,5 +22,5 @@ data class ModelApiResponse(
val code: kotlin.Int? = null, val code: kotlin.Int? = null,
val type: kotlin.String? = null, val type: kotlin.String? = null,
val message: kotlin.String? = null val message: kotlin.String? = null
) )

View File

@ -29,7 +29,7 @@ data class Order(
/* Order Status */ /* Order Status */
val status: Order.Status? = null, val status: Order.Status? = null,
val complete: kotlin.Boolean? = false val complete: kotlin.Boolean? = false
) )
{ {
/** /**
* Order Status * Order Status

View File

@ -31,7 +31,7 @@ data class Pet(
val tags: kotlin.collections.List<Tag>? = null, val tags: kotlin.collections.List<Tag>? = null,
/* pet status in the store */ /* pet status in the store */
val status: Pet.Status? = null val status: Pet.Status? = null
) )
{ {
/** /**
* pet status in the store * pet status in the store

View File

@ -20,5 +20,5 @@ package org.openapitools.server.models
data class Tag( data class Tag(
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
val name: kotlin.String? = null val name: kotlin.String? = null
) )

View File

@ -33,5 +33,5 @@ data class User(
val phone: kotlin.String? = null, val phone: kotlin.String? = null,
/* User Status */ /* User Status */
val userStatus: kotlin.Int? = null val userStatus: kotlin.Int? = null
) )

View File

@ -20,5 +20,5 @@ package org.openapitools.server.models
data class Category( data class Category(
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
val name: kotlin.String? = null val name: kotlin.String? = null
) )

View File

@ -22,5 +22,5 @@ data class ModelApiResponse(
val code: kotlin.Int? = null, val code: kotlin.Int? = null,
val type: kotlin.String? = null, val type: kotlin.String? = null,
val message: kotlin.String? = null val message: kotlin.String? = null
) )

View File

@ -29,7 +29,7 @@ data class Order(
/* Order Status */ /* Order Status */
val status: Order.Status? = null, val status: Order.Status? = null,
val complete: kotlin.Boolean? = false val complete: kotlin.Boolean? = false
) )
{ {
/** /**
* Order Status * Order Status

View File

@ -31,7 +31,7 @@ data class Pet(
val tags: kotlin.collections.List<Tag>? = null, val tags: kotlin.collections.List<Tag>? = null,
/* pet status in the store */ /* pet status in the store */
val status: Pet.Status? = null val status: Pet.Status? = null
) )
{ {
/** /**
* pet status in the store * pet status in the store

View File

@ -20,5 +20,5 @@ package org.openapitools.server.models
data class Tag( data class Tag(
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
val name: kotlin.String? = null val name: kotlin.String? = null
) )

View File

@ -33,5 +33,5 @@ data class User(
val phone: kotlin.String? = null, val phone: kotlin.String? = null,
/* User Status */ /* User Status */
val userStatus: kotlin.Int? = null val userStatus: kotlin.Int? = null
) )

View File

@ -7,7 +7,8 @@ version = "1.0.0"
plugins { plugins {
kotlin("jvm") version "2.0.20" kotlin("jvm") version "2.0.20"
id("io.ktor.plugin") version "2.3.12" application
kotlin("plugin.serialization") version "2.0.20"
} }
application { application {
@ -22,6 +23,7 @@ repositories {
} }
dependencies { dependencies {
implementation(platform("io.ktor:ktor-bom:3.0.2"))
implementation("ch.qos.logback:logback-classic:$logback_version") implementation("ch.qos.logback:logback-classic:$logback_version")
implementation("com.typesafe:config:1.4.1") implementation("com.typesafe:config:1.4.1")
implementation("io.ktor:ktor-server-auth") implementation("io.ktor:ktor-server-auth")
@ -29,7 +31,7 @@ dependencies {
implementation("io.ktor:ktor-server-auto-head-response") implementation("io.ktor:ktor-server-auto-head-response")
implementation("io.ktor:ktor-server-default-headers") implementation("io.ktor:ktor-server-default-headers")
implementation("io.ktor:ktor-server-content-negotiation") implementation("io.ktor:ktor-server-content-negotiation")
implementation("io.ktor:ktor-serialization-gson") implementation("io.ktor:ktor-serialization-kotlinx-json")
implementation("io.ktor:ktor-server-resources") implementation("io.ktor:ktor-server-resources")
implementation("io.ktor:ktor-server-hsts") implementation("io.ktor:ktor-server-hsts")
implementation("io.ktor:ktor-server-compression") implementation("io.ktor:ktor-server-compression")

View File

@ -1,4 +1,4 @@
kotlin.code.style=official kotlin.code.style=official
ktor_version=2.3.12 ktor_version=3.0.2
kotlin_version=2.0.20 kotlin_version=2.0.20
logback_version=1.4.14 logback_version=1.4.14

View File

@ -1,7 +1,6 @@
package org.openapitools.server package org.openapitools.server
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.serialization.gson.*
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.resources.* import io.ktor.server.resources.*
import io.ktor.server.plugins.autohead.* import io.ktor.server.plugins.autohead.*
@ -13,6 +12,7 @@ import com.codahale.metrics.Slf4jReporter
import io.ktor.server.metrics.dropwizard.* import io.ktor.server.metrics.dropwizard.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import io.ktor.server.routing.* import io.ktor.server.routing.*
import io.ktor.serialization.kotlinx.json.json
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.engine.apache.Apache import io.ktor.client.engine.apache.Apache
@ -24,12 +24,6 @@ import org.openapitools.server.apis.StoreApi
import org.openapitools.server.apis.UserApi 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() { fun Application.main() {
install(DefaultHeaders) install(DefaultHeaders)
install(DropwizardMetrics) { install(DropwizardMetrics) {
@ -41,7 +35,7 @@ fun Application.main() {
reporter.start(10, TimeUnit.SECONDS) reporter.start(10, TimeUnit.SECONDS)
} }
install(ContentNegotiation) { install(ContentNegotiation) {
register(ContentType.Application.Json, GsonConverter()) json()
} }
install(AutoHeadResponse) // see https://ktor.io/docs/autoheadresponse.html install(AutoHeadResponse) // see https://ktor.io/docs/autoheadresponse.html
install(Compression, ApplicationCompressionConfiguration()) // see https://ktor.io/docs/compression.html install(Compression, ApplicationCompressionConfiguration()) // see https://ktor.io/docs/compression.html
@ -66,10 +60,9 @@ fun Application.main() {
} }
} }
} }
install(Routing) { routing {
PetApi() PetApi()
StoreApi() StoreApi()
UserApi() UserApi()
} }
} }

View File

@ -21,7 +21,7 @@ object Paths {
* *
* @param body Pet object that needs to be added to the store * @param body Pet object that needs to be added to the store
*/ */
@Serializable @Resource("/pet") class addPet(val body: Pet) @Resource("/pet") class addPet()
/** /**
* Deletes a pet * Deletes a pet
@ -29,35 +29,35 @@ object Paths {
* @param petId Pet id to delete * @param petId Pet id to delete
* @param apiKey (optional) * @param apiKey (optional)
*/ */
@Serializable @Resource("/pet/{petId}") class deletePet(val petId: kotlin.Long, val apiKey: kotlin.String? = null) @Resource("/pet/{petId}") class deletePet(val petId: kotlin.Long)
/** /**
* Finds Pets by status * Finds Pets by status
* Multiple status values can be provided with comma separated strings * Multiple status values can be provided with comma separated strings
* @param status Status values that need to be considered for filter * @param status Status values that need to be considered for filter
*/ */
@Serializable @Resource("/pet/findByStatus") class findPetsByStatus(val status: kotlin.collections.List<kotlin.String>) @Resource("/pet/findByStatus") class findPetsByStatus(val status: kotlin.collections.List<kotlin.String>)
/** /**
* Finds Pets by tags * Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* @param tags Tags to filter by * @param tags Tags to filter by
*/ */
@Serializable @Resource("/pet/findByTags") class findPetsByTags(val tags: kotlin.collections.List<kotlin.String>) @Resource("/pet/findByTags") class findPetsByTags(val tags: kotlin.collections.List<kotlin.String>)
/** /**
* Find pet by ID * Find pet by ID
* Returns a single pet * Returns a single pet
* @param petId ID of pet to return * @param petId ID of pet to return
*/ */
@Serializable @Resource("/pet/{petId}") class getPetById(val petId: kotlin.Long) @Resource("/pet/{petId}") class getPetById(val petId: kotlin.Long)
/** /**
* Update an existing pet * Update an existing pet
* *
* @param body Pet object that needs to be added to the store * @param body Pet object that needs to be added to the store
*/ */
@Serializable @Resource("/pet") class updatePet(val body: Pet) @Resource("/pet") class updatePet()
/** /**
* Updates a pet in the store with form data * Updates a pet in the store with form data
@ -66,7 +66,7 @@ object Paths {
* @param name Updated name of the pet (optional) * @param name Updated name of the pet (optional)
* @param status Updated status of the pet (optional) * @param status Updated status of the pet (optional)
*/ */
@Serializable @Resource("/pet/{petId}") class updatePetWithForm(val petId: kotlin.Long, val name: kotlin.String? = null, val status: kotlin.String? = null) @Resource("/pet/{petId}") class updatePetWithForm(val petId: kotlin.Long)
/** /**
* uploads an image * uploads an image
@ -75,69 +75,69 @@ object Paths {
* @param additionalMetadata Additional data to pass to server (optional) * @param additionalMetadata Additional data to pass to server (optional)
* @param file file to upload (optional) * @param file file to upload (optional)
*/ */
@Serializable @Resource("/pet/{petId}/uploadImage") class uploadFile(val petId: kotlin.Long, val additionalMetadata: kotlin.String? = null, val file: java.io.File? = null) @Resource("/pet/{petId}/uploadImage") class uploadFile(val petId: kotlin.Long)
/** /**
* Delete purchase order by ID * Delete purchase order by ID
* For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors * For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
* @param orderId ID of the order that needs to be deleted * @param orderId ID of the order that needs to be deleted
*/ */
@Serializable @Resource("/store/order/{orderId}") class deleteOrder(val orderId: kotlin.String) @Resource("/store/order/{orderId}") class deleteOrder(val orderId: kotlin.String)
/** /**
* Returns pet inventories by status * Returns pet inventories by status
* Returns a map of status codes to quantities * Returns a map of status codes to quantities
*/ */
@Serializable @Resource("/store/inventory") class getInventory @Resource("/store/inventory") class getInventory
/** /**
* Find purchase order by ID * Find purchase order by ID
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generate exceptions * For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generate exceptions
* @param orderId ID of pet that needs to be fetched * @param orderId ID of pet that needs to be fetched
*/ */
@Serializable @Resource("/store/order/{orderId}") class getOrderById(val orderId: kotlin.Long) @Resource("/store/order/{orderId}") class getOrderById(val orderId: kotlin.Long)
/** /**
* Place an order for a pet * Place an order for a pet
* *
* @param body order placed for purchasing the pet * @param body order placed for purchasing the pet
*/ */
@Serializable @Resource("/store/order") class placeOrder(val body: Order) @Resource("/store/order") class placeOrder()
/** /**
* Create user * Create user
* This can only be done by the logged in user. * This can only be done by the logged in user.
* @param body Created user object * @param body Created user object
*/ */
@Serializable @Resource("/user") class createUser(val body: User) @Resource("/user") class createUser()
/** /**
* Creates list of users with given input array * Creates list of users with given input array
* *
* @param body List of user object * @param body List of user object
*/ */
@Serializable @Resource("/user/createWithArray") class createUsersWithArrayInput(val body: kotlin.collections.List<User>) @Resource("/user/createWithArray") class createUsersWithArrayInput()
/** /**
* Creates list of users with given input array * Creates list of users with given input array
* *
* @param body List of user object * @param body List of user object
*/ */
@Serializable @Resource("/user/createWithList") class createUsersWithListInput(val body: kotlin.collections.List<User>) @Resource("/user/createWithList") class createUsersWithListInput()
/** /**
* Delete user * Delete user
* This can only be done by the logged in user. * This can only be done by the logged in user.
* @param username The name that needs to be deleted * @param username The name that needs to be deleted
*/ */
@Serializable @Resource("/user/{username}") class deleteUser(val username: kotlin.String) @Resource("/user/{username}") class deleteUser(val username: kotlin.String)
/** /**
* Get user by user name * Get user by user name
* *
* @param username The name that needs to be fetched. Use user1 for testing. * @param username The name that needs to be fetched. Use user1 for testing.
*/ */
@Serializable @Resource("/user/{username}") class getUserByName(val username: kotlin.String) @Resource("/user/{username}") class getUserByName(val username: kotlin.String)
/** /**
* Logs user into the system * Logs user into the system
@ -145,13 +145,13 @@ object Paths {
* @param username The user name for login * @param username The user name for login
* @param password The password for login in clear text * @param password The password for login in clear text
*/ */
@Serializable @Resource("/user/login") class loginUser(val username: kotlin.String, val password: kotlin.String) @Resource("/user/login") class loginUser(val username: kotlin.String, val password: kotlin.String)
/** /**
* Logs out current logged in user session * Logs out current logged in user session
* *
*/ */
@Serializable @Resource("/user/logout") class logoutUser @Resource("/user/logout") class logoutUser
/** /**
* Updated user * Updated user
@ -159,6 +159,6 @@ object Paths {
* @param username name that need to be deleted * @param username name that need to be deleted
* @param body Updated user object * @param body Updated user object
*/ */
@Serializable @Resource("/user/{username}") class updateUser(val username: kotlin.String, val body: User) @Resource("/user/{username}") class updateUser(val username: kotlin.String)
} }

View File

@ -11,7 +11,6 @@
*/ */
package org.openapitools.server.apis package org.openapitools.server.apis
import com.google.gson.Gson
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@ -30,13 +29,12 @@ import org.openapitools.server.models.ModelApiResponse
import org.openapitools.server.models.Pet import org.openapitools.server.models.Pet
fun Route.PetApi() { fun Route.PetApi() {
val gson = Gson()
val empty = mutableMapOf<String, Any?>() val empty = mutableMapOf<String, Any?>()
authenticate("petstore_auth") { authenticate("petstore_auth") {
post<Paths.addPet> { post<Paths.addPet> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -47,7 +45,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
delete<Paths.deletePet> { delete<Paths.deletePet> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -58,7 +56,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
get<Paths.findPetsByStatus> { get<Paths.findPetsByStatus> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
val exampleContentType = "application/json" val exampleContentType = "application/json"
@ -97,7 +95,7 @@ fun Route.PetApi() {
} ]""" } ]"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }
@ -108,7 +106,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
get<Paths.findPetsByTags> { get<Paths.findPetsByTags> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
val exampleContentType = "application/json" val exampleContentType = "application/json"
@ -147,7 +145,7 @@ fun Route.PetApi() {
} ]""" } ]"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }
@ -158,7 +156,7 @@ fun Route.PetApi() {
authenticate("api_key") { authenticate("api_key") {
get<Paths.getPetById> { get<Paths.getPetById> {
val principal = call.authentication.principal<ApiPrincipal>()!! val principal = call.authentication.principal<ApiPrincipal>()
val exampleContentType = "application/json" val exampleContentType = "application/json"
@ -181,7 +179,7 @@ fun Route.PetApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }
@ -192,7 +190,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
put<Paths.updatePet> { put<Paths.updatePet> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -203,7 +201,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
post<Paths.updatePetWithForm> { post<Paths.updatePetWithForm> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -214,7 +212,7 @@ fun Route.PetApi() {
authenticate("petstore_auth") { authenticate("petstore_auth") {
post<Paths.uploadFile> { post<Paths.uploadFile> {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!! val principal = call.authentication.principal<OAuthAccessTokenResponse>()
val exampleContentType = "application/json" val exampleContentType = "application/json"
@ -225,7 +223,7 @@ fun Route.PetApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }

View File

@ -11,7 +11,6 @@
*/ */
package org.openapitools.server.apis package org.openapitools.server.apis
import com.google.gson.Gson
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@ -29,7 +28,6 @@ import org.openapitools.server.infrastructure.ApiPrincipal
import org.openapitools.server.models.Order import org.openapitools.server.models.Order
fun Route.StoreApi() { fun Route.StoreApi() {
val gson = Gson()
val empty = mutableMapOf<String, Any?>() val empty = mutableMapOf<String, Any?>()
delete<Paths.deleteOrder> { delete<Paths.deleteOrder> {
@ -40,7 +38,7 @@ fun Route.StoreApi() {
authenticate("api_key") { authenticate("api_key") {
get<Paths.getInventory> { get<Paths.getInventory> {
val principal = call.authentication.principal<ApiPrincipal>()!! val principal = call.authentication.principal<ApiPrincipal>()
call.respond(HttpStatusCode.NotImplemented) call.respond(HttpStatusCode.NotImplemented)
@ -60,7 +58,7 @@ fun Route.StoreApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }
@ -79,7 +77,7 @@ fun Route.StoreApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }

View File

@ -11,7 +11,6 @@
*/ */
package org.openapitools.server.apis package org.openapitools.server.apis
import com.google.gson.Gson
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.auth.* import io.ktor.server.auth.*
@ -29,7 +28,6 @@ import org.openapitools.server.infrastructure.ApiPrincipal
import org.openapitools.server.models.User import org.openapitools.server.models.User
fun Route.UserApi() { fun Route.UserApi() {
val gson = Gson()
val empty = mutableMapOf<String, Any?>() val empty = mutableMapOf<String, Any?>()
post<Paths.createUser> { post<Paths.createUser> {
@ -66,7 +64,7 @@ fun Route.UserApi() {
}""" }"""
when (exampleContentType) { when (exampleContentType) {
"application/json" -> call.respond(gson.fromJson(exampleContentString, empty::class.java)) "application/json" -> call.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml) "application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString) else -> call.respondText(exampleContentString)
} }

View File

@ -12,19 +12,17 @@
package org.openapitools.server.models package org.openapitools.server.models
import java.io.Serializable import kotlinx.serialization.Serializable
/** /**
* A category for a pet * A category for a pet
* @param id * @param id
* @param name * @param name
*/ */
@Serializable
data class Category( data class Category(
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
val name: kotlin.String? = null val name: kotlin.String? = null
) : Serializable )
{ {
companion object {
private const val serialVersionUID: Long = 123
}
} }

View File

@ -12,21 +12,19 @@
package org.openapitools.server.models package org.openapitools.server.models
import java.io.Serializable import kotlinx.serialization.Serializable
/** /**
* Describes the result of uploading an image resource * Describes the result of uploading an image resource
* @param code * @param code
* @param type * @param type
* @param message * @param message
*/ */
@Serializable
data class ModelApiResponse( data class ModelApiResponse(
val code: kotlin.Int? = null, val code: kotlin.Int? = null,
val type: kotlin.String? = null, val type: kotlin.String? = null,
val message: kotlin.String? = null val message: kotlin.String? = null
) : Serializable )
{ {
companion object {
private const val serialVersionUID: Long = 123
}
} }

View File

@ -12,7 +12,7 @@
package org.openapitools.server.models package org.openapitools.server.models
import java.io.Serializable import kotlinx.serialization.Serializable
/** /**
* An order for a pets from the pet store * An order for a pets from the pet store
* @param id * @param id
@ -22,19 +22,17 @@ import java.io.Serializable
* @param status Order Status * @param status Order Status
* @param complete * @param complete
*/ */
@Serializable
data class Order( data class Order(
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
val petId: kotlin.Long? = null, val petId: kotlin.Long? = null,
val quantity: kotlin.Int? = null, val quantity: kotlin.Int? = null,
val shipDate: java.time.OffsetDateTime? = null, val shipDate: kotlin.String? = null,
/* Order Status */ /* Order Status */
val status: Order.Status? = null, val status: Order.Status? = null,
val complete: kotlin.Boolean? = false val complete: kotlin.Boolean? = false
) : Serializable )
{ {
companion object {
private const val serialVersionUID: Long = 123
}
/** /**
* Order Status * Order Status
* Values: placed,approved,delivered * Values: placed,approved,delivered

View File

@ -14,7 +14,7 @@ package org.openapitools.server.models
import org.openapitools.server.models.Category import org.openapitools.server.models.Category
import org.openapitools.server.models.Tag import org.openapitools.server.models.Tag
import java.io.Serializable import kotlinx.serialization.Serializable
/** /**
* A pet for sale in the pet store * A pet for sale in the pet store
* @param name * @param name
@ -24,6 +24,7 @@ import java.io.Serializable
* @param tags * @param tags
* @param status pet status in the store * @param status pet status in the store
*/ */
@Serializable
data class Pet( data class Pet(
val name: kotlin.String, val name: kotlin.String,
val photoUrls: kotlin.collections.List<kotlin.String>, val photoUrls: kotlin.collections.List<kotlin.String>,
@ -32,11 +33,8 @@ data class Pet(
val tags: kotlin.collections.List<Tag>? = null, val tags: kotlin.collections.List<Tag>? = null,
/* pet status in the store */ /* pet status in the store */
val status: Pet.Status? = null val status: Pet.Status? = null
) : Serializable )
{ {
companion object {
private const val serialVersionUID: Long = 123
}
/** /**
* pet status in the store * pet status in the store
* Values: available,pending,sold * Values: available,pending,sold

View File

@ -12,19 +12,17 @@
package org.openapitools.server.models package org.openapitools.server.models
import java.io.Serializable import kotlinx.serialization.Serializable
/** /**
* A tag for a pet * A tag for a pet
* @param id * @param id
* @param name * @param name
*/ */
@Serializable
data class Tag( data class Tag(
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
val name: kotlin.String? = null val name: kotlin.String? = null
) : Serializable )
{ {
companion object {
private const val serialVersionUID: Long = 123
}
} }

View File

@ -12,7 +12,7 @@
package org.openapitools.server.models package org.openapitools.server.models
import java.io.Serializable import kotlinx.serialization.Serializable
/** /**
* A User who is purchasing from the pet store * A User who is purchasing from the pet store
* @param id * @param id
@ -24,6 +24,7 @@ import java.io.Serializable
* @param phone * @param phone
* @param userStatus User Status * @param userStatus User Status
*/ */
@Serializable
data class User( data class User(
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
val username: kotlin.String? = null, val username: kotlin.String? = null,
@ -34,10 +35,7 @@ data class User(
val phone: kotlin.String? = null, val phone: kotlin.String? = null,
/* User Status */ /* User Status */
val userStatus: kotlin.Int? = null val userStatus: kotlin.Int? = null
) : Serializable )
{ {
companion object {
private const val serialVersionUID: Long = 123
}
} }