change Server to engineMain with config file (closes #3)

This commit is contained in:
Hartmut Bauer committed 2026-02-07 17:57:13 +01:00
1 parent 600e8a773f
commit c62ee0c2e6
6 files changed
+103 -38

No files matched your search

@@ -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<String>): 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()
}
@@ -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"
@@ -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<AppPrincipal>()
call.respondText("user: ${principal?.userId}")
}
get("/test") {
val principal = call.principal<AppPrincipal>()
call.respondText("Ktor ${VERSION.displayName} ${VERSION.fullVersion} - principal=${principal?.name}")
}
}
}
}
@@ -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<AppPrincipal>()
call.respondText("Ktor ${VERSION.displayName} ${VERSION.fullVersion} - principal=${principal?.name}")
}
get("/test") {
val principal = call.principal<AppPrincipal>()
call.respondText("user: ${principal?.userId}")
}
}
}
}
@@ -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.<name>
#
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}
}
}