From c62ee0c2e6f7f500f425b39484f4e5b9dad80444 Mon Sep 17 00:00:00 2001 From: Hartmut Bauer Date: Sat, 7 Feb 2026 17:57:13 +0100 Subject: [PATCH] change Server to engineMain with config file (closes #3) --- server/buildnumber.properties | 4 +- .../kotlin/net/keinekekse/app/Application.kt | 23 ++++++---- .../net/keinekekse/app/server/Version.kt | 8 ++-- .../keinekekse/app/server/config/routing.kt | 26 +++++++++++ .../keinekekse/app/server/config/security.kt | 45 +++++++++---------- server/src/main/resources/application.conf | 35 +++++++++++++++ 6 files changed, 103 insertions(+), 38 deletions(-) create mode 100644 server/src/main/kotlin/net/keinekekse/app/server/config/routing.kt create mode 100644 server/src/main/resources/application.conf diff --git a/server/buildnumber.properties b/server/buildnumber.properties index 8a84efc..50ccf1d 100644 --- a/server/buildnumber.properties +++ b/server/buildnumber.properties @@ -1,3 +1,3 @@ #auto generated -#Sat Feb 07 00:11:27 CET 2026 -build.number=21 +#Sat Feb 07 17:52:53 CET 2026 +build.number=25 diff --git a/server/src/main/kotlin/net/keinekekse/app/Application.kt b/server/src/main/kotlin/net/keinekekse/app/Application.kt index 8b449bf..164ac48 100644 --- a/server/src/main/kotlin/net/keinekekse/app/Application.kt +++ b/server/src/main/kotlin/net/keinekekse/app/Application.kt @@ -2,21 +2,26 @@ package net.keinekekse.app import io.github.oshai.kotlinlogging.KotlinLogging import io.ktor.server.application.* -import io.ktor.server.engine.* -import io.ktor.server.netty.* import net.keinekekse.app.server.VERSION +import net.keinekekse.app.server.config.configureRouting import net.keinekekse.app.server.config.configureSecurity private val logger = KotlinLogging.logger {} -fun main() { -// embeddedServer(Netty, port = SERVER_PORT, host = "0.0.0.0", module = Application::module) - logger.debug { "\n**\n** Starting ${VERSION.displayName} - ${VERSION.description} ${VERSION.fullVersion}\n**" } - embeddedServer(Netty, port = 7770, host = "0.0.0.0", module = Application::module) - .start(wait = true) -} +fun main(args: Array): Unit = io.ktor.server.netty.EngineMain.main(args) + +//fun main() { +//// embeddedServer(Netty, port = SERVER_PORT, host = "0.0.0.0", module = Application::module) +// // environment.config.propertyOrNull("ktor.environment")?.getString() +// +// logger.debug { "\n**\n** Starting ${VERSION.displayName} - ${VERSION.description} ${VERSION.fullVersion}\n**" } +// embeddedServer(Netty, port = 7770, host = "0.0.0.0", module = Application::module) +// .start(wait = true) +//} fun Application.module() { - configureSecurity() + logger.info { "\n**\n** Starting ${VERSION.displayName} - ${VERSION.description} ${VERSION.fullVersion}\n**" } + configureSecurity() + configureRouting() } diff --git a/server/src/main/kotlin/net/keinekekse/app/server/Version.kt b/server/src/main/kotlin/net/keinekekse/app/server/Version.kt index de789ea..1072529 100644 --- a/server/src/main/kotlin/net/keinekekse/app/server/Version.kt +++ b/server/src/main/kotlin/net/keinekekse/app/server/Version.kt @@ -3,14 +3,14 @@ package net.keinekekse.app.server import net.keinekekse.version.Version object VERSION: Version { - override val version = "0.1.0-beta.1+build.21" - override val fullVersion = "0.1.0-beta.1+build.21" + override val version = "0.1.0-beta.1+build.25" + override val fullVersion = "0.1.0-beta.1+build.25" override val major = 0 override val minor = 1 override val patch = 0 override val preRelease = "beta.1" - override val buildMetadata = "build.21" - override val buildDate = "2026-02-06T23:11:27.778805Z" + override val buildMetadata = "build.25" + override val buildDate = "2026-02-07T16:52:53.281643Z" override val displayName = "kAS" override val copyright = "Copyright (c) 2026 Hartmut Bauer" override val name = "server" diff --git a/server/src/main/kotlin/net/keinekekse/app/server/config/routing.kt b/server/src/main/kotlin/net/keinekekse/app/server/config/routing.kt new file mode 100644 index 0000000..37b1ece --- /dev/null +++ b/server/src/main/kotlin/net/keinekekse/app/server/config/routing.kt @@ -0,0 +1,26 @@ +package net.keinekekse.app.server.config + +import io.github.oshai.kotlinlogging.KotlinLogging +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import net.keinekekse.app.server.VERSION + +private val logger = KotlinLogging.logger {} + +fun Application.configureRouting() { + routing { + authenticate("auth-KC") { + get("/") { + val principal = call.principal() + call.respondText("user: ${principal?.userId}") + } + + get("/test") { + val principal = call.principal() + call.respondText("Ktor ${VERSION.displayName} ${VERSION.fullVersion} - principal=${principal?.name}") + } + } + } +} diff --git a/server/src/main/kotlin/net/keinekekse/app/server/config/security.kt b/server/src/main/kotlin/net/keinekekse/app/server/config/security.kt index b3d0fa5..0a5f3b3 100644 --- a/server/src/main/kotlin/net/keinekekse/app/server/config/security.kt +++ b/server/src/main/kotlin/net/keinekekse/app/server/config/security.kt @@ -6,32 +6,44 @@ import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.auth.jwt.* +import io.ktor.server.config.* import io.ktor.server.response.* -import io.ktor.server.routing.* -import net.keinekekse.app.server.VERSION import java.net.URI private val logger = KotlinLogging.logger {} fun Application.configureSecurity() { - // TODO die Werte müssen aus der Config kommen + fun getFromConfig(key: String): String { + try { + return environment.config.property("ktor.conf.$key").getString() + } catch (e: ApplicationConfigurationException) { + // ohne die Konfig-Params geht nix (und defaults sind hier sinnlos), hier ist nur noch Abbruch möglich + throw IllegalStateException( + "Configuration key '$key' not found, server start aborted.", + e + ) + } + } // Kommunikation funktioniert nur im internen Containernetzwerk, // d.h. Container- bzw. Pod-Name + interner Port - val keycloakInternal = "http://kec:8080/realms" - val keycloak = "https://kec.keinekekse.net/realms" - val realm = "app-server-realm" - val clientId = "pkce-book-app" - val certUrl = "$keycloakInternal/$realm/protocol/openid-connect/certs" - val issuer = "$keycloak/$realm" + val keycloakInternalUrl = getFromConfig("keycloakInternalUrl") + val keycloakUrl = getFromConfig("keycloakUrl") + val keycloakRealm = getFromConfig("keycloakRealm") + val keycloakClientId = getFromConfig("keycloakClientId") + val keycloakCertUrl = getFromConfig("keycloakCertUrl") + + val certUrl = "$keycloakInternalUrl/$keycloakRealm/$keycloakCertUrl" + val issuer = "$keycloakUrl/$keycloakRealm" + authentication { jwt("auth-KC") { verifier( UrlJwkProvider(URI(certUrl).toURL()), issuer ) { withAudience("account") - withClaim("azp", clientId) + withClaim("azp", keycloakClientId) } challenge { _, _ -> call.respond(HttpStatusCode.Unauthorized, "Token is not valid or has expired") @@ -42,17 +54,4 @@ fun Application.configureSecurity() { } } - routing { - authenticate("auth-KC") { - get("/") { - val principal = call.principal() - call.respondText("Ktor ${VERSION.displayName} ${VERSION.fullVersion} - principal=${principal?.name}") - } - - get("/test") { - val principal = call.principal() - call.respondText("user: ${principal?.userId}") - } - } - } } diff --git a/server/src/main/resources/application.conf b/server/src/main/resources/application.conf new file mode 100644 index 0000000..fc58843 --- /dev/null +++ b/server/src/main/resources/application.conf @@ -0,0 +1,35 @@ +ktor { + deployment { + # alle Server + port = 7770 + host = 0.0.0.0 + # defaults * 2 + connectionGroupSize = 4 + workerGroupSize = 10 + callGroupSize = 20 + shutdownGracePeriod = 2000 + shutdownTimeout = 3000 + # Netty defaults + maxInitialLineLength = 4096 + maxHeaderSize = 8192 + maxChunkSize = 8192 + } + application { + # ApplicationKt.module() übernimmt die Konfiguration + modules = [ net.keinekekse.app.ApplicationKt.module ] + } + conf { + # eigene Parameter -> ktor.conf. + # + keycloakInternalUrl = "http://kec:8080/realms" + keycloakUrl = "https://kec.keinekekse.net/realms" + keycloakRealm = "app-server-realm" + keycloakClientId = "pkce-book-app" + keycloakCertUrl = "protocol/openid-connect/certs" + # DB-Params werden vom Container als env vars gesetzt + dbHost = ${DB_HOST} + dbPort = ${DB_PORT} + dbUser = ${DB_USER} + dbPassword = ${DB_PASSWORD} + } +}