From 8ae1251bf9ec335784d14d7711c6d0540c0036e6 Mon Sep 17 00:00:00 2001 From: Mikael Bjerga <6940327+bjerga@users.noreply.github.com> Date: Wed, 7 Aug 2024 10:43:22 +0200 Subject: [PATCH] =?UTF-8?q?Erstatt=20river=20for=20=C3=A5=20markere=20fore?= =?UTF-8?q?sp=C3=B8rsel=20som=20besvart=20(#658)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../felles/rapidsrivers/RiverUtils.kt | 6 - .../forespoerselmarkerbesvart/App.kt | 2 +- .../MarkerForespoerselBesvartRiver.kt | 116 ++++++++---------- .../MarkerForespoerselBesvartRiverTest.kt | 66 +++++----- 4 files changed, 87 insertions(+), 103 deletions(-) diff --git a/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/RiverUtils.kt b/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/RiverUtils.kt index de15a66c9..499d3b297 100644 --- a/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/RiverUtils.kt +++ b/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/RiverUtils.kt @@ -11,7 +11,6 @@ import no.nav.helsearbeidsgiver.felles.Key import no.nav.helsearbeidsgiver.utils.json.parseJson import no.nav.helsearbeidsgiver.utils.json.toJson import no.nav.helsearbeidsgiver.utils.json.toPretty -import no.nav.helsearbeidsgiver.utils.pipe.mapFirst fun JsonMessage.toPretty(): String = toJson().parseJson().toPretty() @@ -31,11 +30,6 @@ fun JsonMessage.requireKeys(vararg keys: IKey) { requireKey(*keysAsStr) } -fun JsonMessage.require(vararg keyAndParserPairs: Pair Any>) { - val keyStringAndParserPairs = keyAndParserPairs.map { it.mapFirst(IKey::str) } - validate(JsonMessage::require, keyStringAndParserPairs) -} - fun JsonMessage.interestedIn(vararg keys: IKey) { val keysAsStr = keys.map(IKey::str).toTypedArray() interestedIn(*keysAsStr) diff --git a/forespoersel-marker-besvart/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/App.kt b/forespoersel-marker-besvart/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/App.kt index 158fa89d6..9cf4166dc 100644 --- a/forespoersel-marker-besvart/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/App.kt +++ b/forespoersel-marker-besvart/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/App.kt @@ -23,5 +23,5 @@ fun main() { fun RapidsConnection.createMarkerForespoerselBesvart(priProducer: PriProducer): RapidsConnection = also { logger.info("Starter ${MarkerForespoerselBesvartRiver::class.simpleName}...") - MarkerForespoerselBesvartRiver(this, priProducer) + MarkerForespoerselBesvartRiver(priProducer).connect(this) } diff --git a/forespoersel-marker-besvart/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/MarkerForespoerselBesvartRiver.kt b/forespoersel-marker-besvart/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/MarkerForespoerselBesvartRiver.kt index f9ee5e8f2..e4d5b59e5 100644 --- a/forespoersel-marker-besvart/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/MarkerForespoerselBesvartRiver.kt +++ b/forespoersel-marker-besvart/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/MarkerForespoerselBesvartRiver.kt @@ -1,95 +1,79 @@ package no.nav.helsearbeidsgiver.inntektsmelding.forespoerselmarkerbesvart -import no.nav.helse.rapids_rivers.JsonMessage -import no.nav.helse.rapids_rivers.MessageContext -import no.nav.helse.rapids_rivers.RapidsConnection -import no.nav.helse.rapids_rivers.River +import kotlinx.serialization.json.JsonElement import no.nav.helsearbeidsgiver.felles.EventName import no.nav.helsearbeidsgiver.felles.Key +import no.nav.helsearbeidsgiver.felles.json.krev import no.nav.helsearbeidsgiver.felles.json.les -import no.nav.helsearbeidsgiver.felles.json.toMap -import no.nav.helsearbeidsgiver.felles.rapidsrivers.demandValues +import no.nav.helsearbeidsgiver.felles.json.toPretty import no.nav.helsearbeidsgiver.felles.rapidsrivers.pritopic.Pri import no.nav.helsearbeidsgiver.felles.rapidsrivers.pritopic.PriProducer -import no.nav.helsearbeidsgiver.felles.rapidsrivers.rejectKeys -import no.nav.helsearbeidsgiver.felles.rapidsrivers.require +import no.nav.helsearbeidsgiver.felles.rapidsrivers.river.ObjectRiver import no.nav.helsearbeidsgiver.felles.utils.Log -import no.nav.helsearbeidsgiver.utils.json.fromJson -import no.nav.helsearbeidsgiver.utils.json.parseJson import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer import no.nav.helsearbeidsgiver.utils.json.toJson import no.nav.helsearbeidsgiver.utils.json.toPretty -import no.nav.helsearbeidsgiver.utils.log.MdcUtils import no.nav.helsearbeidsgiver.utils.log.logger import no.nav.helsearbeidsgiver.utils.log.sikkerLogger import java.util.UUID +data class Melding( + val eventName: EventName, + val transaksjonId: UUID, + val forespoerselId: UUID, +) + class MarkerForespoerselBesvartRiver( - rapid: RapidsConnection, private val priProducer: PriProducer, -) : River.PacketListener { +) : ObjectRiver() { private val logger = logger() private val sikkerLogger = sikkerLogger() - init { - River(rapid) - .validate { msg -> - msg.demandValues( - Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.name, - ) - msg.require( - Key.UUID to { it.fromJson(UuidSerializer) }, - Key.FORESPOERSEL_ID to { it.fromJson(UuidSerializer) }, - ) - msg.rejectKeys( - Key.BEHOV, - Key.DATA, - Key.FAIL, - ) - }.register(this) - } - - override fun onPacket( - packet: JsonMessage, - context: MessageContext, - ) { - if (packet[Key.FORESPOERSEL_ID.str].asText().isEmpty()) { - logger.warn("Mangler forespørselId!") - sikkerLogger.warn("Mangler forespørselId!") + override fun les(json: Map): Melding? = + if (setOf(Key.BEHOV, Key.DATA, Key.FAIL).any(json::containsKey)) { + null + } else { + Melding( + eventName = Key.EVENT_NAME.krev(EventName.INNTEKTSMELDING_MOTTATT, EventName.serializer(), json), + transaksjonId = Key.UUID.les(UuidSerializer, json), + forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, json), + ) } - val json = packet.toJson().parseJson() - MdcUtils.withLogFields( - Log.klasse(this), - Log.event(EventName.INNTEKTSMELDING_MOTTATT), - ) { - logger.info("Mottok melding om ${EventName.INNTEKTSMELDING_MOTTATT}.") - sikkerLogger.info("Mottok melding:\n${json.toPretty()}.") + override fun Melding.haandter(json: Map): Map? { + logger.info("Mottok melding om ${EventName.INNTEKTSMELDING_MOTTATT}.") + sikkerLogger.info("Mottok melding:\n${json.toPretty()}.") - val jsonMap = json.toMap() + val publisert = + priProducer + .send( + Pri.Key.NOTIS to Pri.NotisType.FORESPOERSEL_BESVART_SIMBA.toJson(Pri.NotisType.serializer()), + Pri.Key.FORESPOERSEL_ID to forespoerselId.toJson(), + ).getOrThrow() - val transaksjonId = Key.UUID.les(UuidSerializer, jsonMap) - val forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, jsonMap) + logger.info("Publiserte melding på pri-topic om ${Pri.NotisType.FORESPOERSEL_BESVART_SIMBA}.") + sikkerLogger.info("Publiserte melding på pri-topic:\n${publisert.toPretty()}") - MdcUtils.withLogFields( - Log.transaksjonId(transaksjonId), - Log.forespoerselId(forespoerselId), - ) { - sendMeldingOmBesvarelse(forespoerselId) - } - } + return null } - private fun sendMeldingOmBesvarelse(forespoerselId: UUID) { - priProducer - .send( - Pri.Key.NOTIS to Pri.NotisType.FORESPOERSEL_BESVART_SIMBA.toJson(Pri.NotisType.serializer()), - Pri.Key.FORESPOERSEL_ID to forespoerselId.toJson(), - ).onSuccess { - logger.info("Publiserte melding på pri-topic om ${Pri.NotisType.FORESPOERSEL_BESVART_SIMBA}.") - sikkerLogger.info("Publiserte melding på pri-topic:\n${it.toPretty()}") - }.onFailure { - logger.error("Klarte ikke publiserte melding på pri-topic om ${Pri.NotisType.FORESPOERSEL_BESVART_SIMBA}.") - } + override fun Melding.haandterFeil( + json: Map, + error: Throwable, + ): Map? { + "Klarte ikke publiserte melding på pri-topic om ${Pri.NotisType.FORESPOERSEL_BESVART_SIMBA}.".also { + logger.error(it) + sikkerLogger().error(it) + } + + return null } + + override fun Melding.loggfelt(): Map = + mapOf( + Log.klasse(this@MarkerForespoerselBesvartRiver), + Log.event(eventName), + Log.transaksjonId(transaksjonId), + Log.forespoerselId(forespoerselId), + ) } diff --git a/forespoersel-marker-besvart/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/MarkerForespoerselBesvartRiverTest.kt b/forespoersel-marker-besvart/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/MarkerForespoerselBesvartRiverTest.kt index 12af4607c..6205835b9 100644 --- a/forespoersel-marker-besvart/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/MarkerForespoerselBesvartRiverTest.kt +++ b/forespoersel-marker-besvart/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/forespoerselmarkerbesvart/MarkerForespoerselBesvartRiverTest.kt @@ -1,6 +1,7 @@ package no.nav.helsearbeidsgiver.inntektsmelding.forespoerselmarkerbesvart import io.kotest.core.spec.style.FunSpec +import io.kotest.datatest.withData import io.kotest.matchers.ints.shouldBeExactly import io.mockk.clearAllMocks import io.mockk.every @@ -14,20 +15,23 @@ import no.nav.helsearbeidsgiver.felles.BehovType import no.nav.helsearbeidsgiver.felles.EventName import no.nav.helsearbeidsgiver.felles.Key import no.nav.helsearbeidsgiver.felles.json.toJson +import no.nav.helsearbeidsgiver.felles.rapidsrivers.model.Fail import no.nav.helsearbeidsgiver.felles.rapidsrivers.pritopic.Pri import no.nav.helsearbeidsgiver.felles.rapidsrivers.pritopic.PriProducer import no.nav.helsearbeidsgiver.felles.test.rapidsrivers.sendJson -import no.nav.helsearbeidsgiver.felles.utils.randomUuid import no.nav.helsearbeidsgiver.utils.json.toJson +import no.nav.helsearbeidsgiver.utils.test.wrapper.genererGyldig +import no.nav.helsearbeidsgiver.utils.wrapper.Fnr +import java.util.UUID class MarkerForespoerselBesvartRiverTest : FunSpec({ val testRapid = TestRapid() val mockPriProducer = mockk() - MarkerForespoerselBesvartRiver(testRapid, mockPriProducer) + MarkerForespoerselBesvartRiver(mockPriProducer).connect(testRapid) - beforeEach { + beforeTest { testRapid.reset() clearAllMocks() } @@ -36,11 +40,11 @@ class MarkerForespoerselBesvartRiverTest : // Må bare returnere en Result med gyldig JSON every { mockPriProducer.send(*anyVararg>()) } returns Result.success(JsonNull) - val expectedForespoerselId = randomUuid() + val expectedForespoerselId = UUID.randomUUID() testRapid.sendJson( Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.toJson(), - Key.UUID to randomUuid().toJson(), + Key.UUID to UUID.randomUUID().toJson(), Key.FORESPOERSEL_ID to expectedForespoerselId.toJson(), ) @@ -54,33 +58,35 @@ class MarkerForespoerselBesvartRiverTest : } } - test("Ignorerer meldinger med behov") { - testRapid.sendJson( - Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.toJson(), - Key.UUID to randomUuid().toJson(), - Key.FORESPOERSEL_ID to randomUuid().toJson(), - Key.BEHOV to BehovType.HENT_PERSONER.toJson(), - ) - - testRapid.inspektør.size shouldBeExactly 0 - - verify(exactly = 0) { - mockPriProducer.send(*anyVararg>()) - } - } - - test("Ignorerer meldinger med data") { - testRapid.sendJson( - Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.toJson(), - Key.UUID to randomUuid().toJson(), - Key.FORESPOERSEL_ID to randomUuid().toJson(), - Key.DATA to "".toJson(), - ) + context("ignorerer melding") { + withData( + mapOf( + "melding med behov" to Pair(Key.BEHOV, BehovType.HENT_PERSONER.toJson()), + "melding med data" to Pair(Key.DATA, mapOf(Key.FNR to Fnr.genererGyldig().toJson()).toJson()), + "melding med fail" to Pair(Key.FAIL, mockFail.toJson(Fail.serializer())), + ), + ) { uoensketKeyMedVerdi -> + testRapid.sendJson( + Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.toJson(), + Key.UUID to UUID.randomUUID().toJson(), + Key.FORESPOERSEL_ID to UUID.randomUUID().toJson(), + uoensketKeyMedVerdi, + ) - testRapid.inspektør.size shouldBeExactly 0 + testRapid.inspektør.size shouldBeExactly 0 - verify(exactly = 0) { - mockPriProducer.send(*anyVararg>()) + verify(exactly = 0) { + mockPriProducer.send(*anyVararg>()) + } } } }) + +private val mockFail = + Fail( + feilmelding = "Life, eh, finds a way.", + event = EventName.INNTEKTSMELDING_MOTTATT, + transaksjonId = UUID.randomUUID(), + forespoerselId = UUID.randomUUID(), + utloesendeMelding = JsonNull, + )