From 55fc27f200acc90e28aee7d883cc822619aed748 Mon Sep 17 00:00:00 2001 From: Fabian Wolter Date: Sun, 14 Jun 2026 06:50:30 +0000 Subject: [PATCH] Extract database health check --- .../kotlin/de/ruvnox/tactical/Database.kt | 68 +++++++++++++++++++ src/main/kotlin/de/ruvnox/tactical/Main.kt | 35 +++------- 2 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 src/main/kotlin/de/ruvnox/tactical/Database.kt diff --git a/src/main/kotlin/de/ruvnox/tactical/Database.kt b/src/main/kotlin/de/ruvnox/tactical/Database.kt new file mode 100644 index 0000000..d0621bb --- /dev/null +++ b/src/main/kotlin/de/ruvnox/tactical/Database.kt @@ -0,0 +1,68 @@ +package de.ruvnox.tactical + +import java.sql.Connection +import java.sql.DriverManager +import kotlin.system.measureTimeMillis + +data class DatabaseConfig( + val host: String, + val port: Int, + val name: String, + val user: String, + val password: String +) + +data class DatabaseCheckResult( + val status: String, + val host: String, + val port: Int, + val name: String, + val latencyMs: Long? +) + +object Database { + fun configFromEnvironment(): DatabaseConfig { + return DatabaseConfig( + host = System.getenv("DB_HOST") ?: "unset", + port = System.getenv("DB_PORT")?.toIntOrNull() ?: 5432, + name = System.getenv("DB_NAME") ?: "unset", + user = System.getenv("DB_USER") ?: "", + password = System.getenv("DB_PASSWORD") ?: "" + ) + } + + fun connection(config: DatabaseConfig = configFromEnvironment()): Connection { + return DriverManager.getConnection( + "jdbc:postgresql://${config.host}:${config.port}/${config.name}", + config.user, + config.password + ) + } + + fun check(): DatabaseCheckResult { + val config = configFromEnvironment() + var ok = false + + val latency = try { + measureTimeMillis { + connection(config).use { connection -> + connection.createStatement().use { statement -> + statement.executeQuery("select 1").use { result -> + ok = result.next() + } + } + } + } + } catch (_: Exception) { + null + } + + return DatabaseCheckResult( + status = if (ok) "online" else "offline", + host = config.host, + port = config.port, + name = config.name, + latencyMs = latency + ) + } +} diff --git a/src/main/kotlin/de/ruvnox/tactical/Main.kt b/src/main/kotlin/de/ruvnox/tactical/Main.kt index 5fbc3a5..9e1f88c 100644 --- a/src/main/kotlin/de/ruvnox/tactical/Main.kt +++ b/src/main/kotlin/de/ruvnox/tactical/Main.kt @@ -13,7 +13,6 @@ import io.ktor.server.routing.routing import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json -import java.sql.DriverManager @Serializable data class ServiceStatusResponse( @@ -28,7 +27,8 @@ data class DatabaseStatusResponse( val status: String, val host: String, val port: Int, - val name: String + val name: String, + val latencyMs: Long? ) fun main() { @@ -83,32 +83,13 @@ fun Application.module() { } fun checkDatabaseStatus(): DatabaseStatusResponse { - val dbHost = System.getenv("DB_HOST") ?: "unset" - val dbPort = System.getenv("DB_PORT")?.toIntOrNull() ?: 5432 - val dbName = System.getenv("DB_NAME") ?: "unset" - val dbUser = System.getenv("DB_USER") ?: "" - val dbPassword = System.getenv("DB_PASSWORD") ?: "" - - val status = try { - DriverManager.getConnection( - "jdbc:postgresql://$dbHost:$dbPort/$dbName", - dbUser, - dbPassword - ).use { connection -> - connection.createStatement().use { statement -> - statement.executeQuery("select 1").use { result -> - if (result.next()) "online" else "error" - } - } - } - } catch (_: Exception) { - "offline" - } + val result = Database.check() return DatabaseStatusResponse( - status = status, - host = dbHost, - port = dbPort, - name = dbName + status = result.status, + host = result.host, + port = result.port, + name = result.name, + latencyMs = result.latencyMs ) }