From a96057c72e30db150dfa7c022fe9d910d58b54ac Mon Sep 17 00:00:00 2001 From: Mikael Bjerga <6940327+bjerga@users.noreply.github.com> Date: Thu, 18 Jul 2024 10:54:40 +0200 Subject: [PATCH 1/3] Bruk service med steg i InntektService (#607) --- .../api/inntekt/InntektProducer.kt | 7 +- .../api/inntekt/InntektRoute.kt | 6 +- .../api/inntekt/InntektProducerTest.kt | 11 +- .../inntektsmelding/inntektservice/App.kt | 20 +- .../inntektservice/InntektService.kt | 239 ++++++++---------- .../inntektservice/InntektServiceTest.kt | 16 +- .../integrasjonstest/utils/EndToEndTest.kt | 2 +- 7 files changed, 141 insertions(+), 160 deletions(-) diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektProducer.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektProducer.kt index 21d7c4d7d..760ca5844 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektProducer.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektProducer.kt @@ -21,19 +21,20 @@ class InntektProducer( } fun publish( - clientId: UUID, + transaksjonId: UUID, request: InntektRequest, ) { MdcUtils.withLogFields( Log.klasse(this), Log.event(EventName.INNTEKT_REQUESTED), - Log.clientId(clientId), + Log.clientId(transaksjonId), Log.forespoerselId(request.forespoerselId), ) { rapid .publish( Key.EVENT_NAME to EventName.INNTEKT_REQUESTED.toJson(), - Key.CLIENT_ID to clientId.toJson(), + Key.UUID to transaksjonId.toJson(), + Key.DATA to "".toJson(), Key.FORESPOERSEL_ID to request.forespoerselId.toJson(), Key.SKJAERINGSTIDSPUNKT to request.skjaeringstidspunkt.toJson(), ).also { json -> diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektRoute.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektRoute.kt index 553013ffb..7d076054c 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektRoute.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektRoute.kt @@ -35,7 +35,7 @@ fun Route.inntektRoute( val inntektProducer = InntektProducer(rapid) post(Routes.INNTEKT) { - val clientId = UUID.randomUUID() + val transaksjonId = UUID.randomUUID() val request = call.receive() @@ -47,9 +47,9 @@ fun Route.inntektRoute( } try { - inntektProducer.publish(clientId, request) + inntektProducer.publish(transaksjonId, request) - val resultatJson = redisPoller.hent(clientId).fromJson(ResultJson.serializer()) + val resultatJson = redisPoller.hent(transaksjonId).fromJson(ResultJson.serializer()) sikkerLogger.info("Fikk inntektresultat:\n$resultatJson") val resultat = resultatJson.success?.fromJson(Inntekt.serializer()) diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektProducerTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektProducerTest.kt index 1982e19db..dd06fcc14 100644 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektProducerTest.kt +++ b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/inntekt/InntektProducerTest.kt @@ -1,7 +1,7 @@ package no.nav.helsearbeidsgiver.inntektsmelding.api.inntekt import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.maps.shouldContainAll +import io.kotest.matchers.maps.shouldContainExactly import no.nav.helse.rapids_rivers.testsupport.TestRapid import no.nav.helsearbeidsgiver.felles.EventName import no.nav.helsearbeidsgiver.felles.Key @@ -18,17 +18,18 @@ class InntektProducerTest : val inntektProducer = InntektProducer(testRapid) test("Publiserer melding på forventet format") { - val clientId = UUID.randomUUID() + val transaksjonId = UUID.randomUUID() val request = InntektRequest(UUID.randomUUID(), 18.januar) - inntektProducer.publish(clientId, request) + inntektProducer.publish(transaksjonId, request) val publisert = testRapid.firstMessage().toMap() - publisert shouldContainAll + publisert shouldContainExactly mapOf( Key.EVENT_NAME to EventName.INNTEKT_REQUESTED.toJson(), - Key.CLIENT_ID to clientId.toJson(), + Key.UUID to transaksjonId.toJson(), + Key.DATA to "".toJson(), Key.FORESPOERSEL_ID to request.forespoerselId.toJson(), Key.SKJAERINGSTIDSPUNKT to request.skjaeringstidspunkt.toJson(), ) diff --git a/inntektservice/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/App.kt b/inntektservice/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/App.kt index 767f1c585..e7f351909 100644 --- a/inntektservice/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/App.kt +++ b/inntektservice/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/App.kt @@ -2,25 +2,33 @@ package no.nav.helsearbeidsgiver.inntektsmelding.inntektservice import no.nav.helse.rapids_rivers.RapidApplication import no.nav.helse.rapids_rivers.RapidsConnection -import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisConnection +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisPrefix +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStoreClassSpecific import no.nav.helsearbeidsgiver.felles.rapidsrivers.registerShutdownLifecycle +import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceRiver import no.nav.helsearbeidsgiver.utils.log.logger private val logger = "helsearbeidsgiver-im-inntektservice".logger() fun main() { - val redisStore = RedisStore(Env.redisUrl) + val redisConnection = RedisConnection(Env.redisUrl) RapidApplication .create(System.getenv()) - .createInntektService(redisStore) + .createInntektService(redisConnection) .registerShutdownLifecycle { - redisStore.shutdown() + redisConnection.close() }.start() } -fun RapidsConnection.createInntektService(redisStore: RedisStore): RapidsConnection = +fun RapidsConnection.createInntektService(redisConnection: RedisConnection): RapidsConnection = also { logger.info("Starter ${InntektService::class.simpleName}...") - InntektService(this, redisStore) + ServiceRiver( + InntektService( + rapid = this, + redisStore = RedisStoreClassSpecific(redisConnection, RedisPrefix.InntektService), + ), + ).connect(this) } diff --git a/inntektservice/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/InntektService.kt b/inntektservice/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/InntektService.kt index 0be6c9ccc..df9fbd366 100644 --- a/inntektservice/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/InntektService.kt +++ b/inntektservice/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/InntektService.kt @@ -11,14 +11,11 @@ import no.nav.helsearbeidsgiver.felles.ResultJson import no.nav.helsearbeidsgiver.felles.Tekst import no.nav.helsearbeidsgiver.felles.json.les import no.nav.helsearbeidsgiver.felles.json.toJson -import no.nav.helsearbeidsgiver.felles.rapidsrivers.FailKanal -import no.nav.helsearbeidsgiver.felles.rapidsrivers.LagreDataRedisRiver -import no.nav.helsearbeidsgiver.felles.rapidsrivers.LagreStartDataRedisRiver -import no.nav.helsearbeidsgiver.felles.rapidsrivers.composite.CompositeEventListener import no.nav.helsearbeidsgiver.felles.rapidsrivers.model.Fail import no.nav.helsearbeidsgiver.felles.rapidsrivers.publish import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisKey -import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStoreClassSpecific +import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceMed2Steg import no.nav.helsearbeidsgiver.felles.utils.Log import no.nav.helsearbeidsgiver.utils.json.serializer.LocalDateSerializer import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer @@ -27,16 +24,31 @@ 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.time.LocalDate import java.util.UUID +data class Steg0( + val transaksjonId: UUID, + val forespoerselId: UUID, + val skjaeringstidspunkt: LocalDate, +) + +data class Steg1( + val forespoersel: Forespoersel, +) + +data class Steg2( + val inntekt: Inntekt, +) + class InntektService( private val rapid: RapidsConnection, - override val redisStore: RedisStore, -) : CompositeEventListener() { - private val logger = logger() - private val sikkerLogger = sikkerLogger() + override val redisStore: RedisStoreClassSpecific, +) : ServiceMed2Steg() { + override val logger = logger() + override val sikkerLogger = sikkerLogger() - override val event = EventName.INNTEKT_REQUESTED + override val eventName = EventName.INNTEKT_REQUESTED override val startKeys = setOf( Key.FORESPOERSEL_ID, @@ -48,148 +60,105 @@ class InntektService( Key.INNTEKT, ) - init { - LagreStartDataRedisRiver(event, startKeys, rapid, redisStore, ::onPacket) - LagreDataRedisRiver(event, dataKeys, rapid, redisStore, ::onPacket) - FailKanal(event, rapid, ::onPacket) - } + override fun lesSteg0(melding: Map): Steg0 = + Steg0( + transaksjonId = Key.UUID.les(UuidSerializer, melding), + forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding), + skjaeringstidspunkt = Key.SKJAERINGSTIDSPUNKT.les(LocalDateSerializer, melding), + ) - override fun new(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - val forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding) + override fun lesSteg1(melding: Map): Steg1 = + Steg1( + forespoersel = Key.FORESPOERSEL_SVAR.les(Forespoersel.serializer(), melding), + ) - MdcUtils.withLogFields( - Log.klasse(this), - Log.event(event), - Log.transaksjonId(transaksjonId), - Log.forespoerselId(forespoerselId), - ) { - rapid - .publish( - Key.EVENT_NAME to event.toJson(), - Key.BEHOV to BehovType.HENT_TRENGER_IM.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.UUID to transaksjonId.toJson(), - ).also { - MdcUtils.withLogFields( - Log.behov(BehovType.HENT_TRENGER_IM), - ) { - sikkerLogger.info("Publiserte melding:\n${it.toPretty()}.") - } + override fun lesSteg2(melding: Map): Steg2 = + Steg2( + inntekt = Key.INNTEKT.les(Inntekt.serializer(), melding), + ) + + override fun utfoerSteg0(steg0: Steg0) { + rapid + .publish( + Key.EVENT_NAME to eventName.toJson(), + Key.BEHOV to BehovType.HENT_TRENGER_IM.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + ).also { + MdcUtils.withLogFields( + Log.behov(BehovType.HENT_TRENGER_IM), + ) { + sikkerLogger.info("Publiserte melding:\n${it.toPretty()}.") } - } + } } - override fun inProgress(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - val forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding) - - MdcUtils.withLogFields( - Log.klasse(this), - Log.event(event), - Log.transaksjonId(transaksjonId), - Log.forespoerselId(forespoerselId), - ) { - if (Key.FORESPOERSEL_SVAR in melding) { - val forespoersel = Key.FORESPOERSEL_SVAR.les(Forespoersel.serializer(), melding) - val skjaeringstidspunkt = Key.SKJAERINGSTIDSPUNKT.les(LocalDateSerializer, melding) - - rapid - .publish( - Key.EVENT_NAME to event.toJson(), - Key.BEHOV to BehovType.INNTEKT.toJson(), - Key.ORGNRUNDERENHET to forespoersel.orgnr.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.FNR to forespoersel.fnr.toJson(), - Key.SKJAERINGSTIDSPUNKT to skjaeringstidspunkt.toJson(), - Key.UUID to transaksjonId.toJson(), - ).also { - MdcUtils.withLogFields( - Log.behov(BehovType.INNTEKT), - ) { - sikkerLogger.info("Publiserte melding:\n${it.toPretty()}.") - } - } - } else { - sikkerLogger.error("Transaksjon er underveis, men mangler data. Dette bør aldri skje, ettersom vi kun venter på én datapakke.") + override fun utfoerSteg1( + steg0: Steg0, + steg1: Steg1, + ) { + rapid + .publish( + Key.EVENT_NAME to eventName.toJson(), + Key.BEHOV to BehovType.INNTEKT.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.ORGNRUNDERENHET to steg1.forespoersel.orgnr.toJson(), + Key.FNR to steg1.forespoersel.fnr.toJson(), + Key.SKJAERINGSTIDSPUNKT to steg0.skjaeringstidspunkt.toJson(), + ).also { + MdcUtils.withLogFields( + Log.behov(BehovType.INNTEKT), + ) { + sikkerLogger.info("Publiserte melding:\n${it.toPretty()}.") + } } - } } - override fun finalize(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - - val clientId = - RedisKey - .of(transaksjonId, event) - .read() - ?.let(UUID::fromString) - - if (clientId == null) { - sikkerLogger.error("Kunne ikke finne clientId for transaksjonId $transaksjonId i Redis!") - logger.error("Kunne ikke finne clientId for transaksjonId $transaksjonId i Redis!") - } else { - val inntekt = Key.INNTEKT.les(Inntekt.serializer(), melding) - - val resultJson = - ResultJson( - success = inntekt.toJson(Inntekt.serializer()), - ).toJson(ResultJson.serializer()) - - RedisKey.of(clientId).write(resultJson) - - MdcUtils.withLogFields( - Log.clientId(clientId), - Log.transaksjonId(transaksjonId), - ) { - sikkerLogger.info("$event fullført.") - } - } + override fun utfoerSteg2( + steg0: Steg0, + steg1: Steg1, + steg2: Steg2, + ) { + val resultJson = + ResultJson( + success = steg2.inntekt.toJson(Inntekt.serializer()), + ).toJson(ResultJson.serializer()) + + redisStore.set(RedisKey.of(steg0.transaksjonId), resultJson) + + sikkerLogger.info("$eventName fullført.") } override fun onError( melding: Map, fail: Fail, ) { - val clientId = - RedisKey - .of(fail.transaksjonId, event) - .read() - ?.let(UUID::fromString) - - if (clientId == null) { - MdcUtils.withLogFields( - Log.transaksjonId(fail.transaksjonId), - ) { - sikkerLogger.error("Forsøkte å terminere, men fant ikke clientID for transaksjon ${fail.transaksjonId} i Redis") - logger.error("Forsøkte å terminere, men fant ikke clientID for transaksjon ${fail.transaksjonId} i Redis") - } - } else { - val feilmelding = Tekst.TEKNISK_FEIL_FORBIGAAENDE - val resultJson = - ResultJson( - failure = feilmelding.toJson(), - ).toJson(ResultJson.serializer()) - - "Returnerer feilmelding: '$feilmelding'".also { - logger.error(it) - sikkerLogger.error(it) - } + val feilmelding = Tekst.TEKNISK_FEIL_FORBIGAAENDE + val resultJson = + ResultJson( + failure = feilmelding.toJson(), + ).toJson(ResultJson.serializer()) + + "Returnerer feilmelding: '$feilmelding'".also { + logger.error(it) + sikkerLogger.error(it) + } - RedisKey.of(clientId).write(resultJson) + redisStore.set(RedisKey.of(fail.transaksjonId), resultJson) - MdcUtils.withLogFields( - Log.clientId(clientId), - Log.transaksjonId(fail.transaksjonId), - ) { - sikkerLogger.error("$event terminert.") - } + MdcUtils.withLogFields( + Log.transaksjonId(fail.transaksjonId), + ) { + sikkerLogger.error("$eventName terminert.") } } - private fun RedisKey.write(json: JsonElement) { - redisStore.set(this, json.toString()) - } - - private fun RedisKey.read(): String? = redisStore.get(this) + override fun Steg0.loggfelt(): Map = + mapOf( + Log.klasse(this@InntektService), + Log.event(eventName), + Log.transaksjonId(transaksjonId), + Log.forespoerselId(forespoerselId), + ) } diff --git a/inntektservice/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/InntektServiceTest.kt b/inntektservice/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/InntektServiceTest.kt index 462719e5a..3ba5aa1af 100644 --- a/inntektservice/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/InntektServiceTest.kt +++ b/inntektservice/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/inntektservice/InntektServiceTest.kt @@ -3,7 +3,6 @@ package no.nav.helsearbeidsgiver.inntektsmelding.inntektservice import io.kotest.assertions.throwables.shouldNotThrowAny import io.kotest.matchers.result.shouldBeSuccess import io.mockk.clearAllMocks -import io.mockk.every import io.mockk.spyk import io.mockk.verify import kotlinx.serialization.builtins.serializer @@ -16,7 +15,9 @@ import no.nav.helsearbeidsgiver.felles.ResultJson import no.nav.helsearbeidsgiver.felles.json.toJson import no.nav.helsearbeidsgiver.felles.rapidsrivers.model.Fail import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisKey -import no.nav.helsearbeidsgiver.felles.test.mock.MockRedis +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisPrefix +import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceRiver +import no.nav.helsearbeidsgiver.felles.test.mock.MockRedisClassSpecific import no.nav.helsearbeidsgiver.utils.json.fromJson import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -24,13 +25,17 @@ import java.util.UUID class InntektServiceTest { private val testRapid = TestRapid() - private val mockRedis = MockRedis() + private val mockRedis = MockRedisClassSpecific(RedisPrefix.InntektService) private val service = spyk( InntektService(testRapid, mockRedis.store), ) + init { + ServiceRiver(service).connect(testRapid) + } + @BeforeEach fun setup() { testRapid.reset() @@ -41,11 +46,8 @@ class InntektServiceTest { @Test fun `svarer med feilmelding ved feil under henting av inntekt`() { val event = EventName.INNTEKT_REQUESTED - val clientId = UUID.randomUUID() val transaksjonId = UUID.randomUUID() - every { mockRedis.store.get(RedisKey.of(transaksjonId, event)) } returns clientId.toString() - val fail = Fail( feilmelding = "ikkeno", @@ -66,7 +68,7 @@ class InntektServiceTest { verify { mockRedis.store.set( - RedisKey.of(clientId), + RedisKey.of(transaksjonId), withArg { runCatching { it diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt index 006155bf4..e5fa07ed4 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt @@ -208,7 +208,7 @@ abstract class EndToEndTest : ContainerTest() { // Servicer createAktiveOrgnrService(redisConnection) createInnsending(redisStore, redisConnection) - createInntektService(redisStore) + createInntektService(redisConnection) createInntektSelvbestemtService(redisConnection) createLagreSelvbestemtImService(redisConnection) createSpinnService(redisConnection) From 82a0f40b4b4c9ef4973cb0d86e1ee1b007ead819 Mon Sep 17 00:00:00 2001 From: Mikael Bjerga <6940327+bjerga@users.noreply.github.com> Date: Thu, 18 Jul 2024 12:36:21 +0200 Subject: [PATCH 2/3] Bruk service med steg i InnsendingService (#608) * Bruk service med steg i InnsendingService * Fiks feil navn i loggmelding --- .../api/innsending/InnsendingProducer.kt | 7 +- .../api/innsending/InnsendingRoute.kt | 7 +- .../api/InnsendingProducerTest.kt | 7 +- .../inntektsmelding/innsending/App.kt | 17 +- .../innsending/InnsendingService.kt | 290 ++++++++++-------- .../innsending/KvitteringService.kt | 22 +- .../integrasjonstest/InnsendingIT.kt | 51 ++- .../integrasjonstest/InnsendingServiceIT.kt | 53 ++-- .../integrasjonstest/mock/MockData.kt | 4 +- .../integrasjonstest/utils/EndToEndTest.kt | 2 +- 10 files changed, 235 insertions(+), 225 deletions(-) diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingProducer.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingProducer.kt index 2048a91e5..55deae275 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingProducer.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingProducer.kt @@ -21,7 +21,7 @@ class InnsendingProducer( } fun publish( - clientId: UUID, + transaksjonId: UUID, forespoerselId: UUID, request: Innsending, arbeidsgiverFnr: Fnr, @@ -29,14 +29,15 @@ class InnsendingProducer( rapid .publish( Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(), - Key.CLIENT_ID to clientId.toJson(), + Key.UUID to transaksjonId.toJson(), + Key.DATA to "".toJson(), Key.FORESPOERSEL_ID to forespoerselId.toJson(), Key.ORGNRUNDERENHET to request.orgnrUnderenhet.toJson(), Key.IDENTITETSNUMMER to request.identitetsnummer.toJson(), Key.ARBEIDSGIVER_ID to arbeidsgiverFnr.toJson(), Key.SKJEMA_INNTEKTSMELDING to request.toJson(Innsending.serializer()), ).also { - logger.info("Publiserte til kafka forespørselId: $forespoerselId og clientId=$clientId") + logger.info("Publiserte til kafka forespørselId: $forespoerselId og transaksjonId=$transaksjonId") sikkerLogger.info("Publiserte til kafka forespørselId: $forespoerselId json=${it.toPretty()}") } } diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt index 78a9fa03e..2e442177a 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt @@ -47,7 +47,7 @@ fun Route.innsendingRoute( .register() post(Routes.INNSENDING + "/{forespoerselId}") { - val clientId = UUID.randomUUID() + val transaksjonId = UUID.randomUUID() val forespoerselId = call.parameters["forespoerselId"] @@ -73,10 +73,9 @@ fun Route.innsendingRoute( request.validate() val innloggerFnr = call.request.lesFnrFraAuthToken() - producer.publish(clientId, forespoerselId, request, innloggerFnr) - logger.info("Publiserte til rapid med forespørselId: $forespoerselId og clientId=$clientId") + producer.publish(transaksjonId, forespoerselId, request, innloggerFnr) - val resultatJson = redisPoller.hent(clientId).fromJson(ResultJson.serializer()) + val resultatJson = redisPoller.hent(transaksjonId).fromJson(ResultJson.serializer()) sikkerLogger.info("Fikk resultat for innsending:\n$resultatJson") if (resultatJson.success != null) { diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/InnsendingProducerTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/InnsendingProducerTest.kt index 2af5777e4..90f63535f 100644 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/InnsendingProducerTest.kt +++ b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/InnsendingProducerTest.kt @@ -23,17 +23,18 @@ class InnsendingProducerTest : val producer = InnsendingProducer(testRapid) test("publiserer melding på forventet format") { - val clientId = UUID.randomUUID() + val transaksjonId = UUID.randomUUID() val forespoerselId = UUID.randomUUID() val avsenderFnr = Fnr.genererGyldig() - producer.publish(clientId, forespoerselId, gyldigInnsendingRequest, avsenderFnr) + producer.publish(transaksjonId, forespoerselId, gyldigInnsendingRequest, avsenderFnr) testRapid.inspektør.size shouldBeExactly 1 testRapid.firstMessage().toMap() shouldContainExactly mapOf( Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(), - Key.CLIENT_ID to clientId.toJson(), + Key.UUID to transaksjonId.toJson(), + Key.DATA to "".toJson(), Key.FORESPOERSEL_ID to forespoerselId.toJson(), Key.ORGNRUNDERENHET to gyldigInnsendingRequest.orgnrUnderenhet.toJson(), Key.IDENTITETSNUMMER to gyldigInnsendingRequest.identitetsnummer.toJson(), diff --git a/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/App.kt b/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/App.kt index e944bfa15..29b3a8d8e 100644 --- a/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/App.kt +++ b/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/App.kt @@ -4,7 +4,6 @@ import no.nav.helse.rapids_rivers.RapidApplication import no.nav.helse.rapids_rivers.RapidsConnection import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisConnection import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisPrefix -import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStoreClassSpecific import no.nav.helsearbeidsgiver.felles.rapidsrivers.registerShutdownLifecycle import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceRiver @@ -13,25 +12,25 @@ import no.nav.helsearbeidsgiver.utils.log.logger private val logger = "helsearbeidsgiver-im-innsending".logger() fun main() { - val redisStore = RedisStore(Env.redisUrl) val redisConnection = RedisConnection(Env.redisUrl) RapidApplication .create(System.getenv()) - .createInnsending(redisStore, redisConnection) + .createInnsending(redisConnection) .registerShutdownLifecycle { - redisStore.shutdown() redisConnection.close() }.start() } -fun RapidsConnection.createInnsending( - redisStore: RedisStore, - redisConnection: RedisConnection, -): RapidsConnection = +fun RapidsConnection.createInnsending(redisConnection: RedisConnection): RapidsConnection = also { logger.info("Starter ${InnsendingService::class.simpleName}...") - InnsendingService(this, redisStore) + ServiceRiver( + InnsendingService( + rapid = this, + redisStore = RedisStoreClassSpecific(redisConnection, RedisPrefix.InnsendingService), + ), + ).connect(this) logger.info("Starter ${KvitteringService::class.simpleName}...") ServiceRiver( diff --git a/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/InnsendingService.kt b/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/InnsendingService.kt index 6f453ea08..b93ff7fb3 100644 --- a/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/InnsendingService.kt +++ b/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/InnsendingService.kt @@ -15,14 +15,11 @@ import no.nav.helsearbeidsgiver.felles.json.les import no.nav.helsearbeidsgiver.felles.json.lesOrNull import no.nav.helsearbeidsgiver.felles.json.toJson import no.nav.helsearbeidsgiver.felles.json.toMap -import no.nav.helsearbeidsgiver.felles.rapidsrivers.FailKanal -import no.nav.helsearbeidsgiver.felles.rapidsrivers.LagreDataRedisRiver -import no.nav.helsearbeidsgiver.felles.rapidsrivers.LagreStartDataRedisRiver -import no.nav.helsearbeidsgiver.felles.rapidsrivers.composite.CompositeEventListener import no.nav.helsearbeidsgiver.felles.rapidsrivers.model.Fail import no.nav.helsearbeidsgiver.felles.rapidsrivers.publish import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisKey -import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStoreClassSpecific +import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceMed2Steg import no.nav.helsearbeidsgiver.felles.utils.Log import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer import no.nav.helsearbeidsgiver.utils.json.toJson @@ -30,16 +27,43 @@ 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 no.nav.helsearbeidsgiver.utils.wrapper.Fnr +import no.nav.helsearbeidsgiver.utils.wrapper.Orgnr import java.util.UUID +data class Steg0( + val transaksjonId: UUID, + val forespoerselId: UUID, + val orgnr: Orgnr, + val sykmeldtFnr: Fnr, + val avsenderFnr: Fnr, + val skjema: Innsending, +) + +sealed class Steg1 { + data class Komplett( + val forespoersel: Forespoersel, + val orgNavn: String, + val sykmeldt: PersonDato, + val avsender: PersonDato, + ) : Steg1() + + data object Delvis : Steg1() +} + +data class Steg2( + val inntektsmelding: Inntektsmelding, + val erDuplikat: Boolean, +) + class InnsendingService( private val rapid: RapidsConnection, - override val redisStore: RedisStore, -) : CompositeEventListener() { - private val logger = logger() - private val sikkerLogger = sikkerLogger() + override val redisStore: RedisStoreClassSpecific, +) : ServiceMed2Steg() { + override val logger = logger() + override val sikkerLogger = sikkerLogger() - override val event = EventName.INSENDING_STARTED + override val eventName = EventName.INSENDING_STARTED override val startKeys = setOf( Key.FORESPOERSEL_ID, @@ -51,7 +75,6 @@ class InnsendingService( override val dataKeys = setOf( Key.VIRKSOMHET, - Key.ARBEIDSFORHOLD, Key.ARBEIDSGIVER_INFORMASJON, Key.ARBEIDSTAKER_INFORMASJON, Key.INNTEKTSMELDING_DOKUMENT, @@ -59,88 +82,85 @@ class InnsendingService( Key.FORESPOERSEL_SVAR, ) - private val step1Keys = - setOf( - Key.VIRKSOMHET, - Key.ARBEIDSFORHOLD, - Key.ARBEIDSTAKER_INFORMASJON, - Key.ARBEIDSGIVER_INFORMASJON, - Key.FORESPOERSEL_SVAR, + override fun lesSteg0(melding: Map): Steg0 = + Steg0( + transaksjonId = Key.UUID.les(UuidSerializer, melding), + forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding), + orgnr = Key.ORGNRUNDERENHET.les(Orgnr.serializer(), melding), + sykmeldtFnr = Key.IDENTITETSNUMMER.les(Fnr.serializer(), melding), + avsenderFnr = Key.ARBEIDSGIVER_ID.les(Fnr.serializer(), melding), + skjema = Key.SKJEMA_INNTEKTSMELDING.les(Innsending.serializer(), melding), ) - init { - LagreStartDataRedisRiver(event, startKeys, rapid, redisStore, ::onPacket) - LagreDataRedisRiver(event, dataKeys, rapid, redisStore, ::onPacket) - FailKanal(event, rapid, ::onPacket) - } + override fun lesSteg1(melding: Map): Steg1 { + val forespoersel = runCatching { Key.FORESPOERSEL_SVAR.les(Forespoersel.serializer(), melding) } + val orgNavn = runCatching { Key.VIRKSOMHET.les(String.serializer(), melding) } + val sykmeldt = runCatching { Key.ARBEIDSTAKER_INFORMASJON.les(PersonDato.serializer(), melding) } + val avsender = runCatching { Key.ARBEIDSGIVER_INFORMASJON.les(PersonDato.serializer(), melding) } - override fun new(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - val forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding) - val orgnr = Key.ORGNRUNDERENHET.les(String.serializer(), melding) - val sykmeldtFnr = Key.IDENTITETSNUMMER.les(String.serializer(), melding) - val innsenderFnr = Key.ARBEIDSGIVER_ID.les(String.serializer(), melding) - - logger.info("InnsendingService: emitting behov HENT_TRENGER_IM") - rapid.publish( - Key.EVENT_NAME to event.toJson(), - Key.BEHOV to BehovType.HENT_TRENGER_IM.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.UUID to transaksjonId.toJson(), - ) + val results = listOf(forespoersel, orgNavn, sykmeldt, avsender) - logger.info("InnsendingService: emitting behov Virksomhet") - rapid.publish( - Key.EVENT_NAME to event.toJson(), - Key.BEHOV to BehovType.VIRKSOMHET.toJson(), - Key.ORGNRUNDERENHET to orgnr.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - ) + return if (results.all { it.isSuccess }) { + Steg1.Komplett( + forespoersel = forespoersel.getOrThrow(), + orgNavn = orgNavn.getOrThrow(), + sykmeldt = sykmeldt.getOrThrow(), + avsender = avsender.getOrThrow(), + ) + } else if (results.any { it.isSuccess }) { + Steg1.Delvis + } else { + throw results.firstNotNullOf { it.exceptionOrNull() } + } + } - logger.info("InnsendingService: emitting behov ARBEIDSFORHOLD") - rapid.publish( - Key.EVENT_NAME to event.toJson(), - Key.BEHOV to BehovType.ARBEIDSFORHOLD.toJson(), - Key.IDENTITETSNUMMER to sykmeldtFnr.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), + override fun lesSteg2(melding: Map): Steg2 = + Steg2( + inntektsmelding = Key.INNTEKTSMELDING_DOKUMENT.les(Inntektsmelding.serializer(), melding), + erDuplikat = Key.ER_DUPLIKAT_IM.les(Boolean.serializer(), melding), ) - logger.info("InnsendingService: emitting behov FULLT_NAVN") - rapid.publish( - Key.EVENT_NAME to event.toJson(), - Key.BEHOV to BehovType.FULLT_NAVN.toJson(), - Key.IDENTITETSNUMMER to sykmeldtFnr.toJson(), - Key.ARBEIDSGIVER_ID to innsenderFnr.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - ) + override fun utfoerSteg0(steg0: Steg0) { + rapid + .publish( + Key.EVENT_NAME to eventName.toJson(), + Key.BEHOV to BehovType.HENT_TRENGER_IM.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + ).also { loggBehovPublisert(BehovType.HENT_TRENGER_IM, it) } + + rapid + .publish( + Key.EVENT_NAME to eventName.toJson(), + Key.BEHOV to BehovType.VIRKSOMHET.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.ORGNRUNDERENHET to steg0.orgnr.toJson(), + ).also { loggBehovPublisert(BehovType.VIRKSOMHET, it) } + + rapid + .publish( + Key.EVENT_NAME to eventName.toJson(), + Key.BEHOV to BehovType.FULLT_NAVN.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.IDENTITETSNUMMER to steg0.sykmeldtFnr.toJson(), + Key.ARBEIDSGIVER_ID to steg0.avsenderFnr.toJson(), + ).also { loggBehovPublisert(BehovType.FULLT_NAVN, it) } } - override fun inProgress(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - val forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding) - val skjema = Key.SKJEMA_INNTEKTSMELDING.les(Innsending.serializer(), melding) - - if (Key.FORESPOERSEL_SVAR in melding.keys) { - // Logger for å danne et bilde av tiden det tar å hente forespørsler. - logger.info("InnsendingService: forespørsel svar mottatt") - } - - if (step1Keys.all(melding::containsKey)) { - val forespoersel = Key.FORESPOERSEL_SVAR.les(Forespoersel.serializer(), melding) - val virksomhetNavn = Key.VIRKSOMHET.les(String.serializer(), melding) - val sykmeldt = Key.ARBEIDSTAKER_INFORMASJON.les(PersonDato.serializer(), melding) - val innsender = Key.ARBEIDSGIVER_INFORMASJON.les(PersonDato.serializer(), melding) - + override fun utfoerSteg1( + steg0: Steg0, + steg1: Steg1, + ) { + if (steg1 is Steg1.Komplett) { val inntektsmelding = mapInntektsmelding( - forespoersel = forespoersel, - skjema = skjema, - fulltnavnArbeidstaker = sykmeldt.navn, - virksomhetNavn = virksomhetNavn, - innsenderNavn = innsender.navn, + forespoersel = steg1.forespoersel, + skjema = steg0.skjema, + fulltnavnArbeidstaker = steg1.sykmeldt.navn, + virksomhetNavn = steg1.orgNavn, + innsenderNavn = steg1.avsender.navn, ) if (inntektsmelding.bestemmendeFraværsdag.isBefore(inntektsmelding.inntektsdato)) { @@ -150,44 +170,44 @@ class InnsendingService( } } - logger.info("InnsendingService: emitting behov PERSISTER_IM") - - rapid.publish( - Key.EVENT_NAME to event.toJson(), - Key.BEHOV to BehovType.PERSISTER_IM.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.INNTEKTSMELDING to inntektsmelding.toJson(Inntektsmelding.serializer()), - ) + rapid + .publish( + Key.EVENT_NAME to eventName.toJson(), + Key.BEHOV to BehovType.PERSISTER_IM.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.INNTEKTSMELDING to inntektsmelding.toJson(Inntektsmelding.serializer()), + ).also { loggBehovPublisert(BehovType.PERSISTER_IM, it) } } } - override fun finalize(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - val forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding) - val erDuplikat = Key.ER_DUPLIKAT_IM.les(Boolean.serializer(), melding) - val inntektsmeldingJson = Key.INNTEKTSMELDING_DOKUMENT.les(JsonElement.serializer(), melding) - - val clientId = redisStore.get(RedisKey.of(transaksjonId, event))!!.let(UUID::fromString) - - logger.info("publiserer under clientID $clientId") + override fun utfoerSteg2( + steg0: Steg0, + steg1: Steg1, + steg2: Steg2, + ) { + val resultJson = + ResultJson( + success = steg2.inntektsmelding.toJson(Inntektsmelding.serializer()), + ).toJson(ResultJson.serializer()) - val resultJson = ResultJson(success = inntektsmeldingJson) - redisStore.set(RedisKey.of(clientId), resultJson.toJsonStr()) + redisStore.set(RedisKey.of(steg0.transaksjonId), resultJson) - if (!erDuplikat) { - logger.info("Publiserer INNTEKTSMELDING_DOKUMENT under uuid $transaksjonId") - logger.info("InnsendingService: emitting event INNTEKTSMELDING_MOTTATT") - rapid - .publish( + if (!steg2.erDuplikat) { + val publisert = + rapid.publish( Key.EVENT_NAME to EventName.INNTEKTSMELDING_MOTTATT.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.INNTEKTSMELDING_DOKUMENT to inntektsmeldingJson, - ).also { - logger.info("Submitting INNTEKTSMELDING_MOTTATT") - sikkerLogger.info("Submitting INNTEKTSMELDING_MOTTATT ${it.toPretty()}") - } + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.INNTEKTSMELDING_DOKUMENT to steg2.inntektsmelding.toJson(Inntektsmelding.serializer()), + ) + + MdcUtils.withLogFields( + Log.event(EventName.INNTEKTSMELDING_MOTTATT), + ) { + logger.info("Publiserte melding.") + sikkerLogger.info("Publiserte melding:\n${publisert.toPretty()}") + } } } @@ -222,27 +242,37 @@ class InnsendingService( if (datafeil.isNotEmpty()) { datafeil.onEach { (key, defaultVerdi) -> - redisStore.set(RedisKey.of(fail.transaksjonId, key), defaultVerdi.toString()) + redisStore.set(RedisKey.of(fail.transaksjonId, key), defaultVerdi) } val meldingMedDefault = datafeil.toMap().plus(melding) - inProgress(meldingMedDefault) + onData(meldingMedDefault) } else { - val clientId = - redisStore - .get(RedisKey.of(fail.transaksjonId, event)) - ?.let(UUID::fromString) - - if (clientId == null) { - MdcUtils.withLogFields( - Log.transaksjonId(fail.transaksjonId), - ) { - sikkerLogger.error("Forsøkte å terminere, men clientId mangler i Redis. forespoerselId=${fail.forespoerselId}") - } - } else { - val resultJson = ResultJson(failure = fail.feilmelding.toJson()) - redisStore.set(RedisKey.of(clientId), resultJson.toJsonStr()) + val resultJson = ResultJson(failure = fail.feilmelding.toJson()) + + redisStore.set(RedisKey.of(fail.transaksjonId), resultJson.toJson(ResultJson.serializer())) + } + } + + override fun Steg0.loggfelt(): Map = + mapOf( + Log.klasse(this@InnsendingService), + Log.event(eventName), + Log.transaksjonId(transaksjonId), + Log.forespoerselId(forespoerselId), + ) + + private fun loggBehovPublisert( + behovType: BehovType, + publisert: JsonElement, + ) { + MdcUtils.withLogFields( + Log.behov(behovType), + ) { + "Publiserte melding med behov $behovType.".let { + logger.info(it) + sikkerLogger.info("$it\n${publisert.toPretty()}") } } } diff --git a/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/KvitteringService.kt b/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/KvitteringService.kt index 36f4bd31d..a4de974a3 100644 --- a/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/KvitteringService.kt +++ b/innsending/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/innsending/KvitteringService.kt @@ -26,20 +26,10 @@ import no.nav.helsearbeidsgiver.utils.log.logger import no.nav.helsearbeidsgiver.utils.log.sikkerLogger import java.util.UUID -data class Steg0( - val transaksjonId: UUID, - val forespoerselId: UUID, -) - -data class Steg1( - val inntektsmeldingDokument: Inntektsmelding?, - val eksternInntektsmelding: EksternInntektsmelding?, -) - class KvitteringService( private val rapid: RapidsConnection, override val redisStore: RedisStoreClassSpecific, -) : ServiceMed1Steg() { +) : ServiceMed1Steg() { override val logger = logger() override val sikkerLogger = sikkerLogger() @@ -54,6 +44,16 @@ class KvitteringService( Key.EKSTERN_INNTEKTSMELDING, ) + data class Steg0( + val transaksjonId: UUID, + val forespoerselId: UUID, + ) + + data class Steg1( + val inntektsmeldingDokument: Inntektsmelding?, + val eksternInntektsmelding: EksternInntektsmelding?, + ) + override fun lesSteg0(melding: Map): Steg0 = Steg0( transaksjonId = Key.UUID.les(UuidSerializer, melding), diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt index ae5171a24..71dd90549 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt @@ -5,7 +5,6 @@ import io.kotest.matchers.maps.shouldContainKey import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe import io.mockk.coEvery -import io.mockk.every import io.mockk.verify import kotlinx.serialization.builtins.serializer import no.nav.helsearbeidsgiver.dokarkiv.domene.OpprettOgFerdigstillResponse @@ -19,7 +18,6 @@ import no.nav.helsearbeidsgiver.felles.json.toJson import no.nav.helsearbeidsgiver.felles.rapidsrivers.pritopic.Pri import no.nav.helsearbeidsgiver.felles.test.mock.mockForespurtData import no.nav.helsearbeidsgiver.felles.test.mock.tilForespoersel -import no.nav.helsearbeidsgiver.felles.utils.randomUuid import no.nav.helsearbeidsgiver.inntektsmelding.helsebro.domene.ForespoerselSvar import no.nav.helsearbeidsgiver.inntektsmelding.innsending.mapInntektsmelding import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.mock.mockInnsending @@ -30,7 +28,8 @@ import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.maxMekker import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer import no.nav.helsearbeidsgiver.utils.json.toJson -import no.nav.helsearbeidsgiver.utils.test.mock.mockStatic +import no.nav.helsearbeidsgiver.utils.test.wrapper.genererGyldig +import no.nav.helsearbeidsgiver.utils.wrapper.Fnr import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance @@ -68,18 +67,16 @@ class InnsendingIT : EndToEndTest() { dokumenter = emptyList(), ) - mockStatic(::randomUuid) { - every { randomUuid() } returns transaksjonId - publish( - Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(), - Key.CLIENT_ID to UUID.randomUUID().toJson(), - Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), - Key.ORGNRUNDERENHET to Mock.skjema.orgnrUnderenhet.toJson(), - Key.IDENTITETSNUMMER to Mock.skjema.identitetsnummer.toJson(), - Key.ARBEIDSGIVER_ID to Mock.skjema.identitetsnummer.toJson(), - Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(Innsending.serializer()), - ) - } + publish( + Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(), + Key.UUID to transaksjonId.toJson(), + Key.DATA to "".toJson(), + Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), + Key.ORGNRUNDERENHET to Mock.skjema.orgnrUnderenhet.toJson(), + Key.IDENTITETSNUMMER to Mock.skjema.identitetsnummer.toJson(), + Key.ARBEIDSGIVER_ID to Mock.skjema.identitetsnummer.toJson(), + Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(Innsending.serializer()), + ) messages .filter(EventName.INSENDING_STARTED) @@ -167,18 +164,16 @@ class InnsendingIT : EndToEndTest() { coEvery { brregClient.hentVirksomhetNavn(any()) } returns "Bedrift A/S" - mockStatic(::randomUuid) { - every { randomUuid() } returns transaksjonId - publish( - Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(), - Key.CLIENT_ID to UUID.randomUUID().toJson(), - Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), - Key.ORGNRUNDERENHET to Mock.skjema.orgnrUnderenhet.toJson(), - Key.IDENTITETSNUMMER to bjarneBetjent.ident!!.toJson(), - Key.ARBEIDSGIVER_ID to maxMekker.ident!!.toJson(), - Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(Innsending.serializer()), - ) - } + publish( + Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(), + Key.UUID to transaksjonId.toJson(), + Key.DATA to "".toJson(), + Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), + Key.ORGNRUNDERENHET to Mock.skjema.orgnrUnderenhet.toJson(), + Key.IDENTITETSNUMMER to bjarneBetjent.ident!!.toJson(), + Key.ARBEIDSGIVER_ID to maxMekker.ident!!.toJson(), + Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(Innsending.serializer()), + ) messages .filter(EventName.INSENDING_STARTED) @@ -254,7 +249,7 @@ class InnsendingIT : EndToEndTest() { const val OPPGAVE_ID = "neglisjert-sommer" val forespoerselId: UUID = UUID.randomUUID() - val skjema = mockInnsending().copy(identitetsnummer = "fnr-bjarne") + val skjema = mockInnsending().copy(identitetsnummer = Fnr.genererGyldig().verdi) private val forespoersel = skjema.tilForespoersel(UUID.randomUUID()) diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt index 15d112998..78a644008 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt @@ -5,7 +5,6 @@ import io.kotest.matchers.maps.shouldContainKey import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe import io.mockk.coEvery -import io.mockk.every import kotlinx.serialization.builtins.serializer import kotlinx.serialization.json.JsonElement import no.nav.helsearbeidsgiver.dokarkiv.domene.OpprettOgFerdigstillResponse @@ -22,14 +21,15 @@ import no.nav.helsearbeidsgiver.felles.json.toJson import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisKey import no.nav.helsearbeidsgiver.felles.test.mock.gyldigInnsendingRequest import no.nav.helsearbeidsgiver.felles.test.mock.mockForespurtData -import no.nav.helsearbeidsgiver.felles.utils.randomUuid import no.nav.helsearbeidsgiver.inntektsmelding.helsebro.domene.ForespoerselSvar import no.nav.helsearbeidsgiver.inntektsmelding.helsebro.toForespoersel import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.EndToEndTest import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer import no.nav.helsearbeidsgiver.utils.json.toJson -import no.nav.helsearbeidsgiver.utils.test.mock.mockStatic +import no.nav.helsearbeidsgiver.utils.test.wrapper.genererGyldig +import no.nav.helsearbeidsgiver.utils.wrapper.Fnr +import no.nav.helsearbeidsgiver.utils.wrapper.Orgnr import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import java.util.UUID @@ -38,11 +38,11 @@ import java.util.UUID class InnsendingServiceIT : EndToEndTest() { @Test fun `Test at innsending er mottatt`() { - forespoerselRepository.lagreForespoersel(Mock.forespoerselId.toString(), Mock.ORGNR) + forespoerselRepository.lagreForespoersel(Mock.forespoerselId.toString(), Mock.orgnr.verdi) forespoerselRepository.oppdaterSakId(Mock.forespoerselId.toString(), Mock.SAK_ID) forespoerselRepository.oppdaterOppgaveId(Mock.forespoerselId.toString(), Mock.OPPGAVE_ID) - val transaksjonId: UUID = randomUuid() + val transaksjonId: UUID = UUID.randomUUID() mockForespoerselSvarFraHelsebro( eventName = EventName.INSENDING_STARTED, @@ -61,18 +61,16 @@ class InnsendingServiceIT : EndToEndTest() { dokumenter = emptyList(), ) - mockStatic(::randomUuid) { - every { randomUuid() } returns transaksjonId - publish( - Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(), - Key.CLIENT_ID to Mock.clientId.toJson(), - Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), - Key.ORGNRUNDERENHET to Mock.ORGNR.toJson(), - Key.IDENTITETSNUMMER to Mock.FNR.toJson(), - Key.ARBEIDSGIVER_ID to Mock.FNR_AG.toJson(), - Key.SKJEMA_INNTEKTSMELDING to gyldigInnsendingRequest.toJson(Innsending.serializer()), - ) - } + publish( + Key.EVENT_NAME to EventName.INSENDING_STARTED.toJson(), + Key.UUID to transaksjonId.toJson(), + Key.DATA to "".toJson(), + Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), + Key.ORGNRUNDERENHET to Mock.orgnr.toJson(), + Key.IDENTITETSNUMMER to Mock.fnr.toJson(), + Key.ARBEIDSGIVER_ID to Mock.fnrAg.toJson(), + Key.SKJEMA_INNTEKTSMELDING to gyldigInnsendingRequest.toJson(Innsending.serializer()), + ) // Forespørsel hentet messages @@ -98,18 +96,6 @@ class InnsendingServiceIT : EndToEndTest() { it[Key.VIRKSOMHET]?.fromJson(String.serializer()) shouldBe "Bedrift A/S" } - // Arbeidsforhold hentet - messages - .filter(EventName.INSENDING_STARTED) - .filter(Key.ARBEIDSFORHOLD) - .firstAsMap() - .verifiserTransaksjonId(transaksjonId) - .verifiserForespoerselId() - .also { - it shouldContainKey Key.DATA - it[Key.ARBEIDSFORHOLD].shouldNotBeNull() - } - // Sykmeldt og innsender hentet messages .filter(EventName.INSENDING_STARTED) @@ -182,7 +168,7 @@ class InnsendingServiceIT : EndToEndTest() { // API besvart gjennom redis shouldNotThrowAny { redisStore - .get(RedisKey.of(Mock.clientId)) + .get(RedisKey.of(transaksjonId)) .shouldNotBeNull() .fromJson(ResultJson.serializer()) .success @@ -202,13 +188,12 @@ class InnsendingServiceIT : EndToEndTest() { } private object Mock { - const val ORGNR = "stolt-krakk" - const val FNR = "kongelig-albatross" - const val FNR_AG = "uutgrunnelig-koffert" const val SAK_ID = "tjukk-kalender" const val OPPGAVE_ID = "kunstig-demon" - val clientId: UUID = UUID.randomUUID() + val orgnr = Orgnr.genererGyldig() + val fnr = Fnr.genererGyldig() + val fnrAg = Fnr.genererGyldig() val forespoerselId: UUID = UUID.randomUUID() val vedtaksperiodeId: UUID = UUID.randomUUID() diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/mock/MockData.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/mock/MockData.kt index d58a9d1d3..f86c28821 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/mock/MockData.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/mock/MockData.kt @@ -22,8 +22,8 @@ import java.util.UUID fun mockInnsending(): Innsending = Innsending( - orgnrUnderenhet = "orgnr-bål", - identitetsnummer = "fnr-fredrik", + orgnrUnderenhet = Orgnr.genererGyldig().verdi, + identitetsnummer = Fnr.genererGyldig().verdi, behandlingsdager = listOf(LocalDate.now().plusDays(5)), egenmeldingsperioder = listOf( diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt index e5fa07ed4..c753b53fa 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt @@ -207,7 +207,7 @@ abstract class EndToEndTest : ContainerTest() { imTestRapid.apply { // Servicer createAktiveOrgnrService(redisConnection) - createInnsending(redisStore, redisConnection) + createInnsending(redisConnection) createInntektService(redisConnection) createInntektSelvbestemtService(redisConnection) createLagreSelvbestemtImService(redisConnection) From e67290debb1a9176ddf8c81dbed2ff4b1dfb56f2 Mon Sep 17 00:00:00 2001 From: Mikael Bjerga <6940327+bjerga@users.noreply.github.com> Date: Thu, 18 Jul 2024 15:17:10 +0200 Subject: [PATCH 3/3] Bruk service med steg i ManuellOpprettSakService (#609) * Bruk service med steg i ManuellOpprettSakService * Fiks integrasjonstest --- .../redis/RedisStoreClassSpecific.kt | 1 + .../felles/rapidsrivers/service/Service.kt | 38 ++++ .../integrasjonstest/NotifikasjonIT.kt | 7 +- .../integrasjonstest/utils/EndToEndTest.kt | 2 +- .../inntektsmelding/notifikasjon/App.kt | 15 +- .../service/ManuellOpprettSakService.kt | 204 +++++++++++------- 6 files changed, 182 insertions(+), 85 deletions(-) diff --git a/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/redis/RedisStoreClassSpecific.kt b/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/redis/RedisStoreClassSpecific.kt index 798672b5d..1c11f54f4 100644 --- a/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/redis/RedisStoreClassSpecific.kt +++ b/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/redis/RedisStoreClassSpecific.kt @@ -90,6 +90,7 @@ enum class RedisPrefix { InntektService, KvitteringService, LagreSelvbestemtImService, + ManuellOpprettSakService, OpprettOppgaveService, OpprettSakService, SpinnService, diff --git a/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/service/Service.kt b/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/service/Service.kt index 83ee5627f..6f73d9aff 100644 --- a/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/service/Service.kt +++ b/felles/src/main/kotlin/no/nav/helsearbeidsgiver/felles/rapidsrivers/service/Service.kt @@ -141,9 +141,47 @@ abstract class ServiceMed3Steg : ServiceMed2Steg() { } } +abstract class ServiceMed4Steg : ServiceMed3Steg() { + protected abstract fun lesSteg4(melding: Map): S4 + + protected abstract fun utfoerSteg4( + steg0: S0, + steg1: S1, + steg2: S2, + steg3: S3, + steg4: S4, + ) + + override fun onData(melding: Map) { + runCatching { + Quintuple( + first = lesSteg0(melding), + second = lesSteg1(melding), + third = lesSteg2(melding), + fourth = lesSteg3(melding), + fifth = lesSteg4(melding), + ) + }.onSuccess { + medLoggfelt(it.first) { + utfoerSteg4(it.first, it.second, it.third, it.fourth, it.fifth) + } + }.onFailure { + super.onData(melding) + } + } +} + private class Quadruple( val first: S0, val second: S1, val third: S2, val fourth: S3, ) + +private class Quintuple( + val first: S0, + val second: S1, + val third: S2, + val fourth: S3, + val fifth: S4, +) diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/NotifikasjonIT.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/NotifikasjonIT.kt index 60f8fa92e..17e4bc085 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/NotifikasjonIT.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/NotifikasjonIT.kt @@ -137,7 +137,7 @@ class NotifikasjonIT : EndToEndTest() { @Test fun `Oppretter og lagrer sak ved manuell rekjøring`() { - var transactionId: UUID + val transaksjonId: UUID = UUID.randomUUID() coEvery { arbeidsgiverNotifikasjonKlient.opprettNySak(any(), any(), any(), any(), any(), any(), any(), any()) @@ -145,6 +145,8 @@ class NotifikasjonIT : EndToEndTest() { publish( Key.EVENT_NAME to EventName.MANUELL_OPPRETT_SAK_REQUESTED.toJson(), + Key.UUID to transaksjonId.toJson(), + Key.DATA to "".toJson(), Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), ) @@ -154,13 +156,12 @@ class NotifikasjonIT : EndToEndTest() { .firstAsMap() .also { it[Key.FORESPOERSEL_ID]?.fromJson(UuidSerializer) shouldBe Mock.forespoerselId - transactionId = it[Key.UUID]?.fromJson(UuidSerializer).shouldNotBeNull() } publish( Key.EVENT_NAME to EventName.MANUELL_OPPRETT_SAK_REQUESTED.toJson(), + Key.UUID to transaksjonId.toJson(), Key.DATA to "".toJson(), - Key.UUID to transactionId.toJson(), Key.FORESPOERSEL_SVAR to mockForespoersel().copy(fnr = Mock.FNR, orgnr = Mock.ORGNR).toJson(Forespoersel.serializer()), ) diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt index c753b53fa..7fc269ca9 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/utils/EndToEndTest.kt @@ -230,7 +230,7 @@ abstract class EndToEndTest : ContainerTest() { createInntekt(inntektClient) createJournalfoerImRiver(dokarkivClient) createMarkerForespoerselBesvart(mockPriProducer) - createNotifikasjonRivers(NOTIFIKASJON_LINK, selvbestemtRepo, redisStore, arbeidsgiverNotifikasjonKlient) + createNotifikasjonRivers(NOTIFIKASJON_LINK, selvbestemtRepo, redisStore, redisConnection, arbeidsgiverNotifikasjonKlient) createPdl(pdlKlient) } } diff --git a/notifikasjon/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/notifikasjon/App.kt b/notifikasjon/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/notifikasjon/App.kt index ebc13783b..169d6b8d7 100644 --- a/notifikasjon/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/notifikasjon/App.kt +++ b/notifikasjon/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/notifikasjon/App.kt @@ -4,8 +4,12 @@ import no.nav.helse.rapids_rivers.RapidApplication import no.nav.helse.rapids_rivers.RapidsConnection import no.nav.helsearbeidsgiver.arbeidsgivernotifikasjon.ArbeidsgiverNotifikasjonKlient import no.nav.helsearbeidsgiver.felles.db.exposed.Database +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisConnection +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisPrefix import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStoreClassSpecific import no.nav.helsearbeidsgiver.felles.rapidsrivers.registerShutdownLifecycle +import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceRiver import no.nav.helsearbeidsgiver.inntektsmelding.notifikasjon.db.SelvbestemtRepo import no.nav.helsearbeidsgiver.inntektsmelding.notifikasjon.river.ForespoerselLagretRiver import no.nav.helsearbeidsgiver.inntektsmelding.notifikasjon.river.OppgaveFerdigLoeser @@ -24,6 +28,7 @@ private val logger = "im-notifikasjon".logger() fun main() { val redisStore = RedisStore(Env.redisUrl) + val redisConnection = RedisConnection(Env.redisUrl) val database = Database("NAIS_DATABASE_IM_NOTIFIKASJON_NOTIFIKASJON") @@ -39,9 +44,11 @@ fun main() { Env.linkUrl, selvbestemtRepo, redisStore, + redisConnection, buildClient(), ).registerShutdownLifecycle { redisStore.shutdown() + redisConnection.close() logger.info("Stoppsignal mottatt, lukker databasetilkobling.") database.dataSource.close() @@ -52,6 +59,7 @@ fun RapidsConnection.createNotifikasjonRivers( linkUrl: String, selvbestemtRepo: SelvbestemtRepo, redisStore: RedisStore, + redisConnection: RedisConnection, arbeidsgiverNotifikasjonKlient: ArbeidsgiverNotifikasjonKlient, ): RapidsConnection = also { @@ -77,7 +85,12 @@ fun RapidsConnection.createNotifikasjonRivers( OppgaveFerdigLoeser(this, arbeidsgiverNotifikasjonKlient) logger.info("Starter ${ManuellOpprettSakService::class.simpleName}...") - ManuellOpprettSakService(this, redisStore) + ServiceRiver( + ManuellOpprettSakService( + rapid = this, + redisStore = RedisStoreClassSpecific(redisConnection, RedisPrefix.ManuellOpprettSakService), + ), + ).connect(this) logger.info("Starter ${SlettSakLoeser::class.simpleName}...") SlettSakLoeser(this, arbeidsgiverNotifikasjonKlient) diff --git a/notifikasjon/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/notifikasjon/service/ManuellOpprettSakService.kt b/notifikasjon/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/notifikasjon/service/ManuellOpprettSakService.kt index 5188ecd2a..ed7204d6a 100644 --- a/notifikasjon/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/notifikasjon/service/ManuellOpprettSakService.kt +++ b/notifikasjon/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/notifikasjon/service/ManuellOpprettSakService.kt @@ -10,24 +10,46 @@ import no.nav.helsearbeidsgiver.felles.Key import no.nav.helsearbeidsgiver.felles.PersonDato import no.nav.helsearbeidsgiver.felles.json.les import no.nav.helsearbeidsgiver.felles.json.toJson -import no.nav.helsearbeidsgiver.felles.rapidsrivers.FailKanal -import no.nav.helsearbeidsgiver.felles.rapidsrivers.LagreDataRedisRiver -import no.nav.helsearbeidsgiver.felles.rapidsrivers.LagreStartDataRedisRiver -import no.nav.helsearbeidsgiver.felles.rapidsrivers.composite.CompositeEventListener import no.nav.helsearbeidsgiver.felles.rapidsrivers.model.Fail import no.nav.helsearbeidsgiver.felles.rapidsrivers.publish -import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore +import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStoreClassSpecific +import no.nav.helsearbeidsgiver.felles.rapidsrivers.service.ServiceMed4Steg +import no.nav.helsearbeidsgiver.felles.utils.Log import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer import no.nav.helsearbeidsgiver.utils.json.toJson +import no.nav.helsearbeidsgiver.utils.log.logger import no.nav.helsearbeidsgiver.utils.log.sikkerLogger +import java.util.UUID + +data class Steg0( + val transaksjonId: UUID, + val forespoerselId: UUID, +) + +data class Steg1( + val forespoersel: Forespoersel, +) + +data class Steg2( + val sykmeldt: PersonDato, +) + +data class Steg3( + val sakId: String, +) + +data class Steg4( + val persistertSakId: String, +) class ManuellOpprettSakService( private val rapid: RapidsConnection, - override val redisStore: RedisStore, -) : CompositeEventListener() { - private val sikkerLogger = sikkerLogger() + override val redisStore: RedisStoreClassSpecific, +) : ServiceMed4Steg() { + override val logger = logger() + override val sikkerLogger = sikkerLogger() - override val event = EventName.MANUELL_OPPRETT_SAK_REQUESTED + override val eventName = EventName.MANUELL_OPPRETT_SAK_REQUESTED override val startKeys = setOf( Key.FORESPOERSEL_ID, @@ -41,91 +63,105 @@ class ManuellOpprettSakService( Key.PERSISTERT_SAK_ID, ) - private val step2Keys = setOf(Key.FORESPOERSEL_SVAR) - private val step3Keys = setOf(Key.ARBEIDSTAKER_INFORMASJON) - private val step4Keys = setOf(Key.SAK_ID) + override fun lesSteg0(melding: Map): Steg0 = + Steg0( + transaksjonId = Key.UUID.les(UuidSerializer, melding), + forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding), + ) - init { - LagreStartDataRedisRiver(event, startKeys, rapid, redisStore, ::onPacket) - LagreDataRedisRiver(event, dataKeys, rapid, redisStore, ::onPacket) - FailKanal(event, rapid, ::onPacket) - } + override fun lesSteg1(melding: Map): Steg1 = + Steg1( + forespoersel = Key.FORESPOERSEL_SVAR.les(Forespoersel.serializer(), melding), + ) - override fun new(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - val forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding) + override fun lesSteg2(melding: Map): Steg2 = + Steg2( + sykmeldt = Key.ARBEIDSTAKER_INFORMASJON.les(PersonDato.serializer(), melding), + ) + + override fun lesSteg3(melding: Map): Steg3 = + Steg3( + sakId = Key.SAK_ID.les(String.serializer(), melding), + ) + override fun lesSteg4(melding: Map): Steg4 = + Steg4( + persistertSakId = Key.PERSISTERT_SAK_ID.les(String.serializer(), melding), + ) + + override fun utfoerSteg0(steg0: Steg0) { rapid.publish( - Key.EVENT_NAME to event.toJson(), + Key.EVENT_NAME to eventName.toJson(), Key.BEHOV to BehovType.HENT_TRENGER_IM.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), ) } - override fun inProgress(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - val forespoerselId = Key.FORESPOERSEL_ID.les(String.serializer(), melding) - val forespoersel = Key.FORESPOERSEL_SVAR.les(Forespoersel.serializer(), melding) - - when { - step4Keys.all(melding::containsKey) -> { - val sakId = Key.SAK_ID.les(String.serializer(), melding) - - rapid.publish( - Key.EVENT_NAME to event.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.BEHOV to BehovType.PERSISTER_SAK_ID.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.SAK_ID to sakId.toJson(), - ) - - if (forespoersel.erBesvart) { - rapid.publish( - Key.EVENT_NAME to EventName.FORESPOERSEL_BESVART.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.SAK_ID to sakId.toJson(), - ) - } - } - - step3Keys.all(melding::containsKey) -> { - val arbeidstaker = Key.ARBEIDSTAKER_INFORMASJON.les(PersonDato.serializer(), melding) - - rapid.publish( - Key.EVENT_NAME to event.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.BEHOV to BehovType.OPPRETT_SAK.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.ORGNRUNDERENHET to forespoersel.orgnr.toJson(), - Key.ARBEIDSTAKER_INFORMASJON to arbeidstaker.toJson(PersonDato.serializer()), - ) - } - - step2Keys.all(melding::containsKey) -> { - rapid.publish( - Key.EVENT_NAME to event.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.BEHOV to BehovType.FULLT_NAVN.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.IDENTITETSNUMMER to forespoersel.fnr.toJson(), - ) - } - } + override fun utfoerSteg1( + steg0: Steg0, + steg1: Steg1, + ) { + rapid.publish( + Key.EVENT_NAME to eventName.toJson(), + Key.BEHOV to BehovType.FULLT_NAVN.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.IDENTITETSNUMMER to steg1.forespoersel.fnr.toJson(), + ) } - override fun finalize(melding: Map) { - val transaksjonId = Key.UUID.les(UuidSerializer, melding) - val forespoerselId = Key.FORESPOERSEL_ID.les(UuidSerializer, melding) + override fun utfoerSteg2( + steg0: Steg0, + steg1: Steg1, + steg2: Steg2, + ) { + rapid.publish( + Key.EVENT_NAME to eventName.toJson(), + Key.BEHOV to BehovType.OPPRETT_SAK.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.ORGNRUNDERENHET to steg1.forespoersel.orgnr.toJson(), + Key.ARBEIDSTAKER_INFORMASJON to steg2.sykmeldt.toJson(PersonDato.serializer()), + ) + } - val sakId = Key.SAK_ID.les(String.serializer(), melding) + override fun utfoerSteg3( + steg0: Steg0, + steg1: Steg1, + steg2: Steg2, + steg3: Steg3, + ) { + rapid.publish( + Key.EVENT_NAME to eventName.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.BEHOV to BehovType.PERSISTER_SAK_ID.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.SAK_ID to steg3.sakId.toJson(), + ) + + if (steg1.forespoersel.erBesvart) { + rapid.publish( + Key.EVENT_NAME to EventName.FORESPOERSEL_BESVART.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.SAK_ID to steg3.sakId.toJson(), + ) + } + } + override fun utfoerSteg4( + steg0: Steg0, + steg1: Steg1, + steg2: Steg2, + steg3: Steg3, + steg4: Steg4, + ) { rapid.publish( Key.EVENT_NAME to EventName.SAK_OPPRETTET.toJson(), - Key.UUID to transaksjonId.toJson(), - Key.FORESPOERSEL_ID to forespoerselId.toJson(), - Key.SAK_ID to sakId.toJson(), + Key.UUID to steg0.transaksjonId.toJson(), + Key.FORESPOERSEL_ID to steg0.forespoerselId.toJson(), + Key.SAK_ID to steg4.persistertSakId.toJson(), ) } @@ -135,4 +171,12 @@ class ManuellOpprettSakService( ) { sikkerLogger.error("Mottok feil:\n$fail") } + + override fun Steg0.loggfelt(): Map = + mapOf( + Log.klasse(this@ManuellOpprettSakService), + Log.event(eventName), + Log.transaksjonId(transaksjonId), + Log.forespoerselId(forespoerselId), + ) }