Skip to content

Commit

Permalink
Erstatt river for å markere forespørsel som besvart (#658)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjerga authored Aug 7, 2024
1 parent d85deb0 commit 8ae1251
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -31,11 +30,6 @@ fun JsonMessage.requireKeys(vararg keys: IKey) {
requireKey(*keysAsStr)
}

fun JsonMessage.require(vararg keyAndParserPairs: Pair<IKey, (JsonElement) -> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Original file line number Diff line number Diff line change
@@ -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<Melding>() {
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<Key, JsonElement>): 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<Key, JsonElement>): Map<Key, JsonElement>? {
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<Key, JsonElement>,
error: Throwable,
): Map<Key, JsonElement>? {
"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<String, String> =
mapOf(
Log.klasse(this@MarkerForespoerselBesvartRiver),
Log.event(eventName),
Log.transaksjonId(transaksjonId),
Log.forespoerselId(forespoerselId),
)
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<PriProducer>()

MarkerForespoerselBesvartRiver(testRapid, mockPriProducer)
MarkerForespoerselBesvartRiver(mockPriProducer).connect(testRapid)

beforeEach {
beforeTest {
testRapid.reset()
clearAllMocks()
}
Expand All @@ -36,11 +40,11 @@ class MarkerForespoerselBesvartRiverTest :
// Må bare returnere en Result med gyldig JSON
every { mockPriProducer.send(*anyVararg<Pair<Pri.Key, JsonElement>>()) } 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(),
)

Expand All @@ -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<Pair<Pri.Key, JsonElement>>())
}
}

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<Pair<Pri.Key, JsonElement>>())
verify(exactly = 0) {
mockPriProducer.send(*anyVararg<Pair<Pri.Key, JsonElement>>())
}
}
}
})

private val mockFail =
Fail(
feilmelding = "Life, eh, finds a way.",
event = EventName.INNTEKTSMELDING_MOTTATT,
transaksjonId = UUID.randomUUID(),
forespoerselId = UUID.randomUUID(),
utloesendeMelding = JsonNull,
)

0 comments on commit 8ae1251

Please sign in to comment.