Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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

Merged
merged 9 commits into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/generators/kotlin-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl

| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|Whether Kotlin serialization should be used|Whether Kotlin serialization should be used| |true|
|additionalModelTypeAnnotations|Additional annotations for model type(class level annotations). List separated by semicolon(;) or new line (Linux or Windows)| |null|
|apiSuffix|suffix for api classes| |Api|
|artifactId|Generated artifact id (name of jar).| |kotlin-server|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public class KotlinServerCodegen extends AbstractKotlinCodegen implements BeanVa
@Getter @Setter
private Boolean compressionFeatureEnabled = true;
@Getter @Setter
private Boolean kotlinSerializationEnabled = true;
@Getter @Setter
private Boolean resourcesFeatureEnabled = true;
@Getter @Setter
private Boolean metricsFeatureEnabled = true;
Expand Down Expand Up @@ -136,6 +138,7 @@ public KotlinServerCodegen() {
addSwitch(Constants.AUTOMATIC_HEAD_REQUESTS, Constants.AUTOMATIC_HEAD_REQUESTS_DESC, getAutoHeadFeatureEnabled());
addSwitch(Constants.CONDITIONAL_HEADERS, Constants.CONDITIONAL_HEADERS_DESC, getConditionalHeadersFeatureEnabled());
addSwitch(Constants.HSTS, Constants.HSTS_DESC, getHstsFeatureEnabled());
addSwitch(Constants.KOTLIN_SERIALIZATION, Constants.KOTLIN_SERIALIZATION, getKotlinSerializationEnabled());
addSwitch(Constants.CORS, Constants.CORS_DESC, getCorsFeatureEnabled());
addSwitch(Constants.COMPRESSION, Constants.COMPRESSION_DESC, getCompressionFeatureEnabled());
addSwitch(Constants.RESOURCES, Constants.RESOURCES_DESC, getResourcesFeatureEnabled());
Expand Down Expand Up @@ -225,6 +228,11 @@ public void processOpts() {
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)) {
setAutoHeadFeatureEnabled(convertPropertyToBooleanAndWriteBack(Constants.AUTOMATIC_HEAD_REQUESTS));
} else {
Expand Down Expand Up @@ -287,6 +295,14 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("gradle.properties", "", "gradle.properties"));

if (isKtor()) {
setKotlinSerializationEnabled(true);

if (additionalProperties.containsKey(Constants.KOTLIN_SERIALIZATION)) {
setKotlinSerializationEnabled(convertPropertyToBooleanAndWriteBack(Constants.KOTLIN_SERIALIZATION));
} else {
additionalProperties.put(Constants.KOTLIN_SERIALIZATION, getKotlinSerializationEnabled());
}

supportingFiles.add(new SupportingFile("AppMain.kt.mustache", packageFolder, "AppMain.kt"));
supportingFiles.add(new SupportingFile("Configuration.kt.mustache", packageFolder, "Configuration.kt"));

Expand Down Expand Up @@ -353,6 +369,7 @@ public static class Constants {
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_DESC = "Whether to omit Gradle wrapper for creating a sub project.";
public static final String KOTLIN_SERIALIZATION = "Whether Kotlin serialization should be used";
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{{#parcelizeModels}}
import android.os.Parcelable
import kotlinx.parcelize.Parcelize

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
{{/parcelizeModels}}
{{#serializableModel}}
import java.io.Serializable
import java.io.Serializable
{{/serializableModel}}
{{#kotlinSerialization}}
import kotlinx.serialization.Serializable
{{/kotlinSerialization}}
/**
* {{{description}}}
{{#vars}}
Expand All @@ -15,21 +17,19 @@ import java.io.Serializable
{{#parcelizeModels}}
@Parcelize
{{/parcelizeModels}}
{{#kotlinSerialization}}
@Serializable
{{/kotlinSerialization}}
{{#hasVars}}data {{/hasVars}}class {{classname}}(
{{#requiredVars}}
{{>data_class_req_var}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
{{/-last}}{{/optionalVars}}
) {{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}
){{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}
{{#vendorExtensions.x-has-data-class-body}}
{
{{/vendorExtensions.x-has-data-class-body}}
{{#serializableModel}}
companion object {
private const val serialVersionUID: Long = 123
}
{{/serializableModel}}
{{#hasEnums}}
{{#vars}}
{{#isEnum}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.openapitools.server.infrastructure
package {{packageName}}.infrastructure

import io.ktor.http.auth.*
import io.ktor.server.application.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package {{packageName}}

import io.ktor.server.application.*
import io.ktor.serialization.gson.*
import io.ktor.http.*
{{#featureResources}}
import io.ktor.server.resources.*
Expand Down Expand Up @@ -30,24 +29,17 @@ import java.util.concurrent.TimeUnit
{{/featureMetrics}}
import io.ktor.server.routing.*
{{#hasAuthMethods}}
import io.ktor.serialization.kotlinx.json.json
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 {{packageName}}.infrastructure.*
{{/hasAuthMethods}}
{{#generateApis}}{{#apiInfo}}{{#apis}}import {{apiPackage}}.{{classname}}
{{/apis}}{{/apiInfo}}{{/generateApis}}

{{#hasAuthMethods}}
internal val settings = HoconApplicationConfig(ConfigFactory.defaultApplication(HTTP::class.java.classLoader))

object HTTP {
val client = HttpClient(Apache)
}
{{/hasAuthMethods}}

fun Application.main() {
install(DefaultHeaders)
{{#featureMetrics}}
Expand All @@ -62,7 +54,7 @@ fun Application.main() {
{{/featureMetrics}}
{{#generateApis}}
install(ContentNegotiation) {
register(ContentType.Application.Json, GsonConverter())
json()
}
{{#featureAutoHead}}
install(AutoHeadResponse) // see https://ktor.io/docs/autoheadresponse.html
Expand Down Expand Up @@ -125,7 +117,7 @@ fun Application.main() {
{{/authMethods}}
}
{{/hasAuthMethods}}
install(Routing) {
routing {
{{#apiInfo}}
{{#apis}}
{{#operations}}
Expand All @@ -134,6 +126,5 @@ fun Application.main() {
{{/apis}}
{{/apiInfo}}
}

{{/generateApis}}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ object Paths {
{{#allParams}}* @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}*/
{{#hasParams}}
@Serializable @Resource("{{{path}}}") class {{operationId}}({{#allParams}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
@Resource("{{{path}}}") class {{operationId}}({{#pathParams}}val {{paramName}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#required}}{{#isNullable}}?{{/isNullable}}{{/required}}{{^-last}}, {{/-last}}{{/pathParams}})
{{/hasParams}}
{{^hasParams}}
@Serializable @Resource("{{{path}}}") class {{operationId}}
@Resource("{{{path}}}") class {{operationId}}
{{/hasParams}}

{{/operation}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{{#authMethods}}
{{#isBasicBasic}}
val principal = call.authentication.principal<UserIdPrincipal>()!!
val principal = call.authentication.principal<UserIdPrincipal>()
{{/isBasicBasic}}{{^isBasicBasic}}{{#isApiKey}}
val principal = call.authentication.principal<ApiPrincipal>()!!
val principal = call.authentication.principal<ApiPrincipal>()
{{/isApiKey}}{{^isApiKey}}{{#isOAuth}}
val principal = call.authentication.principal<OAuthAccessTokenResponse>()!!
val principal = call.authentication.principal<OAuthAccessTokenResponse>()
{{/isOAuth}}{{^isOAuth}}
val principal = null!!
{{/isOAuth}}{{/isApiKey}}{{/isBasicBasic}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.respondText(exampleContentType, ContentType.Application.Json)
"application/xml" -> call.respondText(exampleContentString, ContentType.Text.Xml)
else -> call.respondText(exampleContentString)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{{>licenseInfo}}
package {{apiPackage}}

import com.google.gson.Gson
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
Expand All @@ -23,7 +22,6 @@ import {{packageName}}.infrastructure.ApiPrincipal

{{#operations}}
fun Route.{{classname}}() {
val gson = Gson()
val empty = mutableMapOf<String, Any?>()

{{#operation}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ version = "{{artifactVersion}}"

plugins {
kotlin("jvm") version "2.0.20"
id("io.ktor.plugin") version "2.3.12"
application
kotlin("plugin.serialization") version "2.0.20"
}

application {
Expand All @@ -22,6 +23,7 @@ repositories {
}

dependencies {
implementation(platform("io.ktor:ktor-bom:3.0.2"))
implementation("ch.qos.logback:logback-classic:$logback_version")
{{#hasAuthMethods}}
implementation("com.typesafe:config:1.4.1")
Expand All @@ -35,7 +37,7 @@ dependencies {
{{/featureAutoHead}}
implementation("io.ktor:ktor-server-default-headers")
implementation("io.ktor:ktor-server-content-negotiation")
implementation("io.ktor:ktor-serialization-gson")
implementation("io.ktor:ktor-serialization-kotlinx-json")
{{#featureResources}}
implementation("io.ktor:ktor-server-resources")
{{/featureResources}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kotlin.code.style=official
ktor_version=2.3.12
ktor_version=3.0.2
kotlin_version=2.0.20
logback_version=1.4.14
74 changes: 0 additions & 74 deletions samples/server/petstore/kotlin-server-modelMutable/build.gradle

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ version = "1.0.0"

plugins {
kotlin("jvm") version "2.0.20"
id("io.ktor.plugin") version "2.3.12"
application
kotlin("plugin.serialization") version "2.0.20"
}

application {
Expand All @@ -22,14 +23,15 @@ repositories {
}

dependencies {
implementation(platform("io.ktor:ktor-bom:3.0.2"))
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-serialization-kotlinx-json")
implementation("io.ktor:ktor-server-resources")
implementation("io.ktor:ktor-server-hsts")
implementation("io.ktor:ktor-server-compression")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kotlin.code.style=official
ktor_version=2.3.12
ktor_version=3.0.2
kotlin_version=2.0.20
logback_version=1.4.14
Loading
Loading