diff --git a/mediator/build.gradle.kts b/mediator/build.gradle.kts index cf891736..f763796a 100644 --- a/mediator/build.gradle.kts +++ b/mediator/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { testImplementation(libs.mock.oauth2.server) testImplementation(libs.bundles.postgres.test) testImplementation("io.ktor:ktor-server-test-host-jvm:${libs.versions.ktor.get()}") + testImplementation("com.github.navikt.tbd-libs:naisful-test-app:2024.11.19-09.27-9c591574") testImplementation("com.approvaltests:approvaltests:22.3.3") } diff --git a/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/ApplicationBuilder.kt b/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/ApplicationBuilder.kt index 1fc2387c..20b1a473 100644 --- a/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/ApplicationBuilder.kt +++ b/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/ApplicationBuilder.kt @@ -2,13 +2,7 @@ package no.nav.dagpenger.behandling.mediator import com.github.navikt.tbd_libs.rapids_and_rivers.KafkaRapid import com.github.navikt.tbd_libs.rapids_and_rivers_api.RapidsConnection -import io.ktor.http.HttpStatusCode -import io.ktor.server.application.ApplicationCall -import io.ktor.server.plugins.statuspages.StatusPagesConfig -import io.ktor.server.request.uri -import io.ktor.server.response.respond import mu.KotlinLogging -import no.nav.dagpenger.behandling.api.models.HttpProblemDTO import no.nav.dagpenger.behandling.db.PostgresDataSourceBuilder.clean import no.nav.dagpenger.behandling.db.PostgresDataSourceBuilder.runMigration import no.nav.dagpenger.behandling.konfigurasjon.Configuration.config @@ -29,8 +23,6 @@ import no.nav.dagpenger.behandling.objectMapper import no.nav.dagpenger.opplysning.Opplysningstype import no.nav.dagpenger.regel.RegelverkDagpenger import no.nav.helse.rapids_rivers.RapidApplication -import org.apache.kafka.common.errors.ResourceNotFoundException -import java.net.URI internal class ApplicationBuilder( config: Map, @@ -43,9 +35,7 @@ internal class ApplicationBuilder( private val opplysningstyper: Set> = RegelverkDagpenger.produserer private val rapidsConnection: RapidsConnection = - RapidApplication.create(env = config, objectMapper = objectMapper, builder = { - withStatusPagesConfig(statusPages()) - }) { engine, rapidsConnection: KafkaRapid -> + RapidApplication.create(env = config, objectMapper = objectMapper) { engine, rapidsConnection: KafkaRapid -> val aktivitetsloggMediator = AktivitetsloggMediator() // Logger bare oppgaver enn så lenge. Bør inn i HendelseMediator @@ -78,43 +68,6 @@ internal class ApplicationBuilder( ) } - private fun statusPages(): StatusPagesConfig.() -> Unit = - { - exception { call: ApplicationCall, cause: IllegalArgumentException -> - val problem = - HttpProblemDTO( - type = URI.create(call.request.uri), - title = "Ugyldig forespørsel", - status = HttpStatusCode.BadRequest.value, - detail = cause.message ?: "Ugyldig forespørsel", - ) - logger.error(cause) { "Noe gikk galt på ${call.request.uri}" } - call.respond(HttpStatusCode.BadRequest, problem) - } - exception { call: ApplicationCall, cause: ResourceNotFoundException -> - val problem = - HttpProblemDTO( - type = URI.create(call.request.uri), - title = "Fant ikke ressurs", - status = HttpStatusCode.NotFound.value, - detail = cause.message ?: "Fant ikke ressurs", - ) - logger.error(cause) { "Noe gikk galt på ${call.request.uri}" } - call.respond(HttpStatusCode.NotFound, problem) - } - exception { call: ApplicationCall, cause: Throwable -> - val problem = - HttpProblemDTO( - type = URI.create(call.request.uri), - title = "Noe gikk galt", - status = HttpStatusCode.InternalServerError.value, - detail = cause.message ?: "Noe gikk galt", - ) - logger.error(cause) { "Noe gikk galt på ${call.request.uri}" } - call.respond(HttpStatusCode.InternalServerError, problem) - } - } - init { rapidsConnection.register(this) } diff --git a/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/api/BehandlingApi.kt b/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/api/BehandlingApi.kt index fda77a55..d940681b 100644 --- a/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/api/BehandlingApi.kt +++ b/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/api/BehandlingApi.kt @@ -7,6 +7,8 @@ import io.ktor.server.application.ApplicationCall import io.ktor.server.application.createApplicationPlugin import io.ktor.server.application.install import io.ktor.server.auth.authenticate +import io.ktor.server.plugins.BadRequestException +import io.ktor.server.plugins.NotFoundException import io.ktor.server.plugins.swagger.swaggerUI import io.ktor.server.request.receive import io.ktor.server.response.respond @@ -48,7 +50,6 @@ import no.nav.dagpenger.opplysning.Penger import no.nav.dagpenger.opplysning.Tekst import no.nav.dagpenger.opplysning.ULID import no.nav.dagpenger.uuid.UUIDv7 -import org.apache.kafka.common.errors.ResourceNotFoundException import java.time.LocalDate import java.time.LocalDateTime import java.util.UUID @@ -105,7 +106,7 @@ internal fun Application.behandlingApi( val person = personRepository.hent( ident.tilPersonIdentfikator(), - ) ?: throw ResourceNotFoundException("Person ikke funnet") + ) ?: throw NotFoundException("Person ikke funnet") auditlogg.les("Listet ut behandlinger", ident, call.saksbehandlerId()) @@ -115,9 +116,7 @@ internal fun Application.behandlingApi( route("{behandlingId}") { get { val behandling = - personRepository.hentBehandling( - call.behandlingId, - ) ?: throw ResourceNotFoundException("Behandling ikke funnet") + hentBehandling(personRepository, call.behandlingId) auditlogg.les("Så en behandling", behandling.behandler.ident, call.saksbehandlerId()) @@ -126,9 +125,7 @@ internal fun Application.behandlingApi( get("vedtak") { val behandling = - personRepository.hentBehandling( - call.behandlingId, - ) ?: throw ResourceNotFoundException("Behandling ikke funnet") + hentBehandling(personRepository, call.behandlingId) auditlogg.les("Så en behandling", behandling.behandler.ident, call.saksbehandlerId()) @@ -178,10 +175,10 @@ internal fun Application.behandlingApi( val opplysningId = call.opplysningId val oppdaterOpplysningRequestDTO = call.receive() val behandling = - personRepository.hentBehandling(behandlingId) ?: throw ResourceNotFoundException("Behandling ikke funnet") + hentBehandling(personRepository, behandlingId) - require(!behandling.harTilstand(Redigert)) { - "Kan ikke redigere opplysninger før forrige redigering er ferdig" + if (behandling.harTilstand(Redigert)) { + throw BadRequestException("Kan ikke redigere opplysninger før forrige redigering er ferdig") } val opplysning = behandling.opplysninger().finnOpplysning(opplysningId) @@ -209,7 +206,7 @@ internal fun Application.behandlingApi( get("avklaring") { val behandlingId = call.behandlingId val behandling = - personRepository.hentBehandling(behandlingId) ?: throw ResourceNotFoundException("Behandling ikke funnet") + hentBehandling(personRepository, behandlingId) call.respond(HttpStatusCode.OK, behandling.avklaringer().map { it.tilAvklaringDTO() }) } @@ -218,11 +215,11 @@ internal fun Application.behandlingApi( val avklaringId = call.avklaringId val kvitteringDTO = call.receive() val behandling = - personRepository.hentBehandling(behandlingId) ?: throw ResourceNotFoundException("Behandling ikke funnet") + hentBehandling(personRepository, behandlingId) val avklaring = behandling.avklaringer().singleOrNull { it.id == avklaringId } - ?: throw ResourceNotFoundException("Avklaring ikke funnet") + ?: throw NotFoundException("Avklaring ikke funnet") if (!avklaring.kanKvitteres) { call.respond(HttpStatusCode.BadRequest) @@ -250,6 +247,11 @@ internal fun Application.behandlingApi( } } +private fun hentBehandling( + personRepository: PersonRepository, + behandlingId: UUID, +) = personRepository.hentBehandling(behandlingId) ?: throw NotFoundException("Behandling ikke funnet") + internal class ApiMessageContext( val rapid: MessageContext, val ident: String, diff --git a/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/repository/OpplysningerRepositoryPostgres.kt b/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/repository/OpplysningerRepositoryPostgres.kt index 3eec14d4..fdb5f376 100644 --- a/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/repository/OpplysningerRepositoryPostgres.kt +++ b/mediator/src/main/kotlin/no/nav/dagpenger/behandling/mediator/repository/OpplysningerRepositoryPostgres.kt @@ -1,5 +1,6 @@ package no.nav.dagpenger.behandling.mediator.repository +import com.fasterxml.jackson.core.type.TypeReference import kotliquery.Row import kotliquery.Session import kotliquery.queryOf @@ -26,6 +27,7 @@ import no.nav.dagpenger.opplysning.Tekst import no.nav.dagpenger.opplysning.ULID import no.nav.dagpenger.opplysning.Utledning import no.nav.dagpenger.opplysning.id +import no.nav.dagpenger.opplysning.verdier.Barn import no.nav.dagpenger.opplysning.verdier.BarnListe import no.nav.dagpenger.opplysning.verdier.Beløp import no.nav.dagpenger.opplysning.verdier.Inntekt @@ -230,7 +232,7 @@ class OpplysningerRepositoryPostgres : OpplysningerRepository { Heltall -> row.int("verdi_heltall") ULID -> Ulid(row.string("verdi_string")) Penger -> Beløp(row.string("verdi_string")) - BarnDatatype -> objectMapper.readValue(row.string("verdi_jsonb"), BarnListe::class.java) as T + BarnDatatype -> BarnListe(objectMapper.readValue(row.string("verdi_jsonb"), object : TypeReference>() {})) as T InntektDataType -> Inntekt( row.binaryStream("verdi_jsonb").use { diff --git a/mediator/src/test/kotlin/no/nav/dagpenger/behandling/mediator/api/BehandlingApiTest.kt b/mediator/src/test/kotlin/no/nav/dagpenger/behandling/mediator/api/BehandlingApiTest.kt index d3d7b794..473bf1dc 100644 --- a/mediator/src/test/kotlin/no/nav/dagpenger/behandling/mediator/api/BehandlingApiTest.kt +++ b/mediator/src/test/kotlin/no/nav/dagpenger/behandling/mediator/api/BehandlingApiTest.kt @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.SerializationFeature import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue +import com.github.navikt.tbd_libs.naisful.test.TestContext import com.github.navikt.tbd_libs.rapids_and_rivers.JsonMessage import com.github.navikt.tbd_libs.rapids_and_rivers.test_support.TestRapid import com.github.navikt.tbd_libs.rapids_and_rivers_api.MessageProblems @@ -18,7 +19,6 @@ import io.ktor.client.request.setBody import io.ktor.client.statement.bodyAsText import io.ktor.http.HttpMethod import io.ktor.http.HttpStatusCode -import io.ktor.server.testing.ApplicationTestBuilder import io.mockk.mockk import io.mockk.slot import io.mockk.spyk @@ -332,7 +332,6 @@ internal class BehandlingApiTest { @Test fun `saksbehandler kan kvittere ut avklaring`() { medSikretBehandlingApi { - val messageMediator = mockk(relaxed = true) val kvitteringHendelse = slot() val behandlingId = person.behandlinger().first().behandlingId @@ -363,7 +362,7 @@ internal class BehandlingApiTest { private fun medSikretBehandlingApi( personRepository: PersonRepository = this.personRepository, hendelseMediator: HendelseMediator = this.hendelseMediator, - test: suspend ApplicationTestBuilder.() -> Unit, + test: suspend TestContext.() -> Unit, ) { System.setProperty("Grupper.saksbehandler", "dagpenger-saksbehandler") TestApplication.withMockAuthServerAndTestApplication( diff --git a/mediator/src/test/kotlin/no/nav/dagpenger/behandling/mediator/api/TestApplication.kt b/mediator/src/test/kotlin/no/nav/dagpenger/behandling/mediator/api/TestApplication.kt index ac772adf..bb434c09 100644 --- a/mediator/src/test/kotlin/no/nav/dagpenger/behandling/mediator/api/TestApplication.kt +++ b/mediator/src/test/kotlin/no/nav/dagpenger/behandling/mediator/api/TestApplication.kt @@ -1,5 +1,7 @@ package no.nav.dagpenger.behandling.mediator.api +import com.github.navikt.tbd_libs.naisful.test.TestContext +import com.github.navikt.tbd_libs.naisful.test.naisfulTestApp import io.ktor.client.request.header import io.ktor.client.request.request import io.ktor.client.request.setBody @@ -9,9 +11,10 @@ import io.ktor.http.HttpHeaders import io.ktor.http.HttpMethod import io.ktor.http.content.TextContent import io.ktor.server.application.Application -import io.ktor.server.testing.ApplicationTestBuilder -import io.ktor.server.testing.testApplication +import io.micrometer.prometheusmetrics.PrometheusConfig +import io.micrometer.prometheusmetrics.PrometheusMeterRegistry import no.nav.dagpenger.behandling.konfigurasjon.Configuration +import no.nav.dagpenger.behandling.objectMapper import no.nav.security.mock.oauth2.MockOAuth2Server object TestApplication { @@ -38,18 +41,23 @@ object TestApplication { internal fun withMockAuthServerAndTestApplication( moduleFunction: Application.() -> Unit, - test: suspend ApplicationTestBuilder.() -> Unit, + test: suspend TestContext.() -> Unit, ) { System.setProperty("azure-app.client-id", CLIENT_ID) System.setProperty("azure-app.well-known-url", "${mockOAuth2Server.wellKnownUrl(AZUREAD_ISSUER_ID)}") - return testApplication { - application(moduleFunction) + return naisfulTestApp( + { + apply { moduleFunction() } + }, + objectMapper, + PrometheusMeterRegistry(PrometheusConfig.DEFAULT), + ) { test() } } - internal suspend fun ApplicationTestBuilder.autentisert( + internal suspend fun TestContext.autentisert( endepunkt: String, token: String = testAzureAdToken( @@ -62,5 +70,7 @@ object TestApplication { this.method = httpMethod body?.let { this.setBody(TextContent(it, ContentType.Application.Json)) } this.header(HttpHeaders.Authorization, "Bearer $token") + this.header(HttpHeaders.Accept, ContentType.Application.Json.toString()) + this.header(HttpHeaders.ContentType, ContentType.Application.Json.toString()) } }