diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 3bef183..a5ef916 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -6,6 +6,7 @@ val postgresql_version: String by project val hikariCP_version: String by project val exposed_version: String by project val testcontainers_postgresql_version: String by project +val junit_jupiter_version: String by project plugins { @@ -42,7 +43,18 @@ dependencies { implementation("org.jetbrains.exposed:exposed-core:$exposed_version") implementation("org.jetbrains.exposed:exposed-jdbc:$exposed_version") implementation("org.jetbrains.exposed:exposed-java-time:$exposed_version") + implementation("io.ktor:ktor-server-cio:$ktor_version") testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version") testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") testImplementation("org.testcontainers:postgresql:$testcontainers_postgresql_version") + testImplementation("org.junit.jupiter:junit-jupiter-api:$junit_jupiter_version") + testImplementation("org.junit.jupiter:junit-jupiter-params:$junit_jupiter_version") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junit_jupiter_version") +} + +tasks.named("test"){ + useJUnitPlatform() + testLogging{ + events("skipped", "failed") + } } diff --git a/backend/gradle.properties b/backend/gradle.properties index e4b8220..d3278a6 100644 --- a/backend/gradle.properties +++ b/backend/gradle.properties @@ -7,3 +7,4 @@ postgresql_version=42.6.0 hikariCP_version=5.0.1 exposed_version=0.41.1 testcontainers_postgresql_version=1.18.3 +junit_jupiter_version=5.9.3 diff --git a/backend/src/main/kotlin/no/nav/helse/sprik/Application.kt b/backend/src/main/kotlin/no/nav/helse/sprik/Application.kt index 7d149f5..c6f1928 100644 --- a/backend/src/main/kotlin/no/nav/helse/sprik/Application.kt +++ b/backend/src/main/kotlin/no/nav/helse/sprik/Application.kt @@ -1,15 +1,26 @@ package no.nav.helse.sprik -import io.ktor.server.application.* -import io.ktor.server.engine.* -import io.ktor.server.netty.* +import kotlinx.coroutines.runBlocking +import no.nav.helse.sprik.db.Database import no.nav.helse.sprik.plugins.* fun main() { - embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module) - .start(wait = true) + val db = Database() + db.migrate() + val app = Application(db) + app.startBlocking() } -fun Application.module() { - configureRouting() +class Application(private val db: Database) { + fun startBlocking() { + + runBlocking { + configureRouting().start(wait = false) + Runtime.getRuntime().addShutdownHook( + Thread { + db.dataSource.close() + } + ) + } + } } diff --git a/backend/src/main/kotlin/no/nav/helse/sprik/db/Database.kt b/backend/src/main/kotlin/no/nav/helse/sprik/db/Database.kt index ec36ea7..2dff291 100644 --- a/backend/src/main/kotlin/no/nav/helse/sprik/db/Database.kt +++ b/backend/src/main/kotlin/no/nav/helse/sprik/db/Database.kt @@ -5,13 +5,43 @@ import com.zaxxer.hikari.HikariDataSource import no.nav.helse.sprik.db.Environment.Database.host import no.nav.helse.sprik.db.Environment.Database.name import no.nav.helse.sprik.db.Environment.Database.port +import org.flywaydb.core.Flyway +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds +import kotlin.time.toJavaDuration -class Database(dbconfig: HikariConfig) { +class Database(dbconfig: HikariConfig = dbconfig()) { val dataSource by lazy { HikariDataSource(dbconfig) } + fun migrate() { + migrateconfig() + .let { HikariDataSource(it) } + .also { + Flyway.configure() + .dataSource(it) + .lockRetryCount(-1) + .load() + .migrate() + } + .close() + } } private fun dbconfig() = HikariConfig().apply { jdbcUrl = DB_URL + username = username + password = password + maximumPoolSize = 1 + connectionTimeout = 30.seconds.toJavaDuration().toMillis() + initializationFailTimeout = 1.minutes.toJavaDuration().toMillis() +} + +private fun migrateconfig() = HikariConfig().apply { + jdbcUrl = DB_URL + username = username + password = password + maximumPoolSize = 2 + connectionTimeout = 30.seconds.toJavaDuration().toMillis() + initializationFailTimeout = 1.minutes.toJavaDuration().toMillis() } val DB_URL = "jdbc:postgresql://%s:%s/%s".format(host, port, name) @@ -19,8 +49,10 @@ val DB_URL = "jdbc:postgresql://%s:%s/%s".format(host, port, name) object Environment { object Database { private val env = System.getenv() - val host = requireNotNull(env["DATABASE_HOST"]) { "Host må settes" } - val port = requireNotNull(env["DATABASE_PORT"]) { "Port må settes" } - val name = requireNotNull(env["DATABASE_DATABASE"]) { "Databasenavn må settes" } + internal val host = requireNotNull(env["DATABASE_HOST"]) { "Host må settes" } + internal val port = requireNotNull(env["DATABASE_PORT"]) { "Port må settes" } + internal val name = requireNotNull(env["DATABASE_DATABASE"]) { "Databasenavn må settes" } + internal val username = requireNotNull(env["DATABASE_USERNAME"]) { "Brukernavn må settes" } + internal val password = requireNotNull(env["DATABASE_PASSWORD"]) { "Passord må settes" } } } \ No newline at end of file diff --git a/backend/src/main/kotlin/no/nav/helse/sprik/plugins/Routing.kt b/backend/src/main/kotlin/no/nav/helse/sprik/plugins/Routing.kt index ff68d82..e60a50f 100644 --- a/backend/src/main/kotlin/no/nav/helse/sprik/plugins/Routing.kt +++ b/backend/src/main/kotlin/no/nav/helse/sprik/plugins/Routing.kt @@ -6,33 +6,40 @@ import io.ktor.server.response.* import io.ktor.server.application.* import io.ktor.server.plugins.contentnegotiation.* import io.ktor.serialization.kotlinx.json.* +import io.ktor.server.cio.* +import io.ktor.server.engine.* import io.ktor.server.plugins.cors.routing.* import io.ktor.server.request.* import no.nav.helse.sprik.Feil import no.nav.helse.sprik.Test -fun Application.configureRouting() { - install(CORS) { - anyHost() - allowMethod(HttpMethod.Get) - allowMethod(HttpMethod.Post) - allowNonSimpleContentTypes = true - } - install(ContentNegotiation) { - json() - } - routing { - get("/") { - call.respondText("Hello World!") +fun configureRouting(): ApplicationEngine = embeddedServer(CIO, applicationEngineEnvironment { + module { + install(CORS) { + anyHost() + allowMethod(HttpMethod.Get) + allowMethod(HttpMethod.Post) + allowNonSimpleContentTypes = true } - post("/test") { - val test = call.receive() - call.respond(status = HttpStatusCode.Created, message = test) + install(ContentNegotiation) { + json() } - post("/nyFeil"){ - val test = call.receive() - println(test) - call.respond(status = HttpStatusCode.Created, message = test) + routing { + get("/") { + call.respondText("Hello World!") + } + post("/test") { + val test = call.receive() + call.respond(status = HttpStatusCode.Created, message = test) + } + post("/nyFeil") { + val test = call.receive() + println(test) + call.respond(status = HttpStatusCode.Created, message = test) + } + } } -} +}) + + diff --git a/backend/src/test/kotlin/no/nav/helse/sprik/DbTest.kt b/backend/src/test/kotlin/no/nav/helse/sprik/DbTest.kt new file mode 100644 index 0000000..29684f0 --- /dev/null +++ b/backend/src/test/kotlin/no/nav/helse/sprik/DbTest.kt @@ -0,0 +1,14 @@ +package no.nav.helse.sprik + +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + + +class DbTest { + @Test + fun `Tester noe rart for å sjekke om junit funker`() { + val a = 2 + assertEquals(2, a) + } + +} \ No newline at end of file diff --git a/backend/src/test/kotlin/no/nav/helse/sprik/TestUtils.kt b/backend/src/test/kotlin/no/nav/helse/sprik/TestUtils.kt new file mode 100644 index 0000000..7039f07 --- /dev/null +++ b/backend/src/test/kotlin/no/nav/helse/sprik/TestUtils.kt @@ -0,0 +1,43 @@ +package no.nav.helse.sprik + +import com.zaxxer.hikari.HikariConfig +import no.nav.helse.sprik.db.Database +import org.flywaydb.core.Flyway +import org.junit.jupiter.api.Test +import org.testcontainers.containers.PostgreSQLContainer +import kotlin.test.assertEquals + +// Lager Docker-container som databasen kan kjør på, og setter opp env-variabler for oss +fun postgres() = PostgreSQLContainer("postgres:15").apply { + withReuse(true) + withLabel("App", "db") + start() + println("Databasen har startet opp på port $firstMappedPort") +} + +// Lager en testconfig for oss for å connecte til databasen +fun dbconfig(): HikariConfig { + val postgres = postgres() + return HikariConfig().apply { + jdbcUrl = postgres.jdbcUrl + username = postgres.username + password = postgres.password + maximumPoolSize = 2 + minimumIdle = 1 + idleTimeout = 500000 + connectionTimeout = 10000 + maxLifetime = 600000 + initializationFailTimeout = 5000 + } +} + +// Migrerer databasen +fun Database.configureFlyway(): Database = this.also { database -> + Flyway.configure() + .dataSource(database.dataSource) + .failOnMissingLocations(true) + .cleanDisabled(false) + .load() + .also(Flyway::clean) + .migrate() +} \ No newline at end of file