Skip to content

Commit

Permalink
Deler opp flyten i forskjellige steg
Browse files Browse the repository at this point in the history
Mulighet for å stoppe på et gitt steg og tilrettelegger for å kunne gjenoppta kjøring fra et gitt steg. Resultat lagres mellom hvert steg slik at man ikke ruller tilbake mer enn gjeldende steg ved eventuelle feil.
  • Loading branch information
matiasvinjevoll committed Oct 4, 2024
1 parent 47a4cc5 commit 7de87f2
Show file tree
Hide file tree
Showing 18 changed files with 306 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import no.nav.aap.brev.domene.Brevbestilling
import no.nav.aap.brev.domene.BrevbestillingReferanse
import no.nav.aap.brev.domene.Brevtype
import no.nav.aap.brev.domene.Språk
import no.nav.aap.brev.domene.ProsesseringStatus

interface BrevbestillingRepository {
fun opprettBestilling(
Expand All @@ -20,4 +21,9 @@ interface BrevbestillingRepository {
referanse: BrevbestillingReferanse,
brev: Brev,
)
}

fun oppdaterProsesseringStatus(
referanse: BrevbestillingReferanse,
prosesseringStatus: ProsesseringStatus,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import no.nav.aap.brev.domene.Brevbestilling
import no.nav.aap.brev.domene.BrevbestillingReferanse
import no.nav.aap.brev.domene.Brevtype
import no.nav.aap.brev.domene.Språk
import no.nav.aap.brev.domene.ProsesseringStatus
import no.nav.aap.brev.exception.BestillingForBehandlingEksistererException
import no.nav.aap.komponenter.dbconnect.DBConnection
import no.nav.aap.komponenter.httpklient.json.DefaultJsonMapper
Expand Down Expand Up @@ -61,6 +62,7 @@ class BrevbestillingRepositoryImpl(private val connection: DBConnection) : Brevb
behandlingReferanse = BehandlingReferanse(row.getUUID("BEHANDLING_REFERANSE")),
brevtype = row.getEnum("BREVTYPE"),
språk = row.getEnum("SPRAK"),
prosesseringStatus = row.getEnumOrNull("PROSESSERING_STATUS"),
)
}
}
Expand All @@ -80,4 +82,17 @@ class BrevbestillingRepositoryImpl(private val connection: DBConnection) : Brevb
}
}

override fun oppdaterProsesseringStatus(
referanse: BrevbestillingReferanse,
prosesseringStatus: ProsesseringStatus,
) {
connection.execute(
"UPDATE BREVBESTILLING SET PROSESSERING_STATUS = ? WHERE REFERANSE = ?"
) {
setParams {
setEnumName(1, prosesseringStatus)
setUUID(2, referanse.referanse)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class BrevbestillingService(

val jobb =
JobbInput(ProsesserBrevbestillingJobbUtfører)
.medCallId()
.medCallId()
.medParameter(BESTILLING_REFERANSE_PARAMETER_NAVN, referanse.referanse.toString())

jobbRepository.leggTil(jobb)
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/kotlin/no/nav/aap/brev/domene/Brevbestilling.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ data class Brevbestilling(
val behandlingReferanse: BehandlingReferanse,
val brevtype: Brevtype,
val språk: Språk,
)
val prosesseringStatus: ProsesseringStatus?,
)
11 changes: 11 additions & 0 deletions app/src/main/kotlin/no/nav/aap/brev/domene/ProsesseringStatus.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package no.nav.aap.brev.domene

enum class ProsesseringStatus {
STARTET,
INNHOLD_HENTET,
FAKTAGRUNNLAG_HENTET,
BREV_FERDIGSTILT,
JOURNALFORT,
DISTRIBUERT,
FERDIG
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package no.nav.aap.brev.prosessering

import no.nav.aap.brev.BrevbestillingRepositoryImpl
import no.nav.aap.brev.domene.BrevbestillingReferanse
import no.nav.aap.brev.innhold.SanityBrevinnholdGateway
import no.nav.aap.komponenter.dbconnect.DBConnection
import no.nav.aap.motor.Jobb
import no.nav.aap.motor.JobbInput
Expand All @@ -25,8 +23,7 @@ class ProsesserBrevbestillingJobbUtfører(
override fun konstruer(connection: DBConnection): JobbUtfører {
return ProsesserBrevbestillingJobbUtfører(
ProsesserStegService(
brevbestillingRepository = BrevbestillingRepositoryImpl(connection),
brevinnholdGateway = SanityBrevinnholdGateway(),
connection = connection,
)
)
}
Expand All @@ -43,4 +40,4 @@ class ProsesserBrevbestillingJobbUtfører(
return "Ansvarlig for å gjennomføre bestilling av brev"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,112 @@
package no.nav.aap.brev.prosessering

import no.nav.aap.brev.BrevbestillingRepository
import no.nav.aap.brev.BrevbestillingRepositoryImpl
import no.nav.aap.brev.domene.BrevbestillingReferanse
import no.nav.aap.brev.innhold.BrevinnholdGateway
import no.nav.aap.brev.domene.ProsesseringStatus
import no.nav.aap.brev.prosessering.steg.DistribuerJournalpostSteg
import no.nav.aap.brev.prosessering.steg.FerdigSteg
import no.nav.aap.brev.prosessering.steg.FerdigstillBrevSteg
import no.nav.aap.brev.prosessering.steg.HentFaktagrunnlagSteg
import no.nav.aap.brev.prosessering.steg.HentInnholdSteg
import no.nav.aap.brev.prosessering.steg.JournalførBrevSteg
import no.nav.aap.brev.prosessering.steg.StarterSteg
import no.nav.aap.brev.prosessering.steg.Steg
import no.nav.aap.brev.prosessering.steg.StegResultat
import no.nav.aap.brev.prosessering.steg.StegUtfører
import no.nav.aap.komponenter.dbconnect.DBConnection
import org.slf4j.LoggerFactory

class ProsesserStegService(
private val brevbestillingRepository: BrevbestillingRepository,
private val brevinnholdGateway: BrevinnholdGateway,
private val connection: DBConnection
) {
private val log = LoggerFactory.getLogger(ProsesserStegService::class.java)
private val brevbestillingRepository = BrevbestillingRepositoryImpl(connection)

private val flyt = ProsesseringFlyt.Builder()
.med(steg = StarterSteg, utfall = ProsesseringStatus.STARTET)
.med(steg = HentInnholdSteg, utfall = ProsesseringStatus.INNHOLD_HENTET)
.med(steg = HentFaktagrunnlagSteg, utfall = ProsesseringStatus.FAKTAGRUNNLAG_HENTET)
.med(steg = FerdigstillBrevSteg, utfall = ProsesseringStatus.BREV_FERDIGSTILT)
.med(steg = JournalførBrevSteg, utfall = ProsesseringStatus.JOURNALFORT)
.med(steg = DistribuerJournalpostSteg, utfall = ProsesseringStatus.DISTRIBUERT)
.med(steg = FerdigSteg, utfall = ProsesseringStatus.FERDIG)
.build()

data class Kontekst(val referanse: BrevbestillingReferanse)

fun prosesserBestilling(kontekst: Kontekst) {

val referanse = kontekst.referanse
val bestilling = brevbestillingRepository.hent(referanse)

log.info("Henter brevinnhold for bestillingsreferanse=$referanse")
val brev = brevinnholdGateway.hentBrevmal(bestilling.brevtype, bestilling.språk)
prosesserTilStop(
kontekst = StegUtfører.Kontekst(referanse),
stegene = flyt.fraStatus(bestilling.prosesseringStatus),
)
}

private fun prosesserTilStop(kontekst: StegUtfører.Kontekst, stegene: List<Steg>) {
stegene.forEach { steg ->
val stegResultat = steg.konstruer(connection).utfør(kontekst)

if (stegResultat == StegResultat.STOPP) {
return
}

brevbestillingRepository.oppdaterProsesseringStatus(kontekst.referanse, flyt.utfall(steg))

connection.markerSavepoint()
}
}

}

class ProsesseringFlyt private constructor(
private val rekkefølge: List<Steg>,
private val stegTilUtfall: HashMap<Steg, ProsesseringStatus>,
private val utfallTilSteg: HashMap<ProsesseringStatus, Steg>,
) {

fun fraStatus(prosesseringStatus: ProsesseringStatus?): List<Steg> {
if (prosesseringStatus == null) {
return rekkefølge
}
val stegForUtfall = utfallTilSteg[prosesseringStatus]
?: throw IllegalStateException("Uforventet oppslag av udefinert steg for status $prosesseringStatus")
return rekkefølge.dropWhile { it != stegForUtfall }.drop(1)
}

fun utfall(steg: Steg): ProsesseringStatus {
return stegTilUtfall[steg]
?: throw IllegalStateException("Uforventet oppslag av udefinert utfall for steg $steg")
}

class Builder {
private val rekkefølge = mutableListOf<Steg>()
private val stegTilUtfall = mutableMapOf<Steg, ProsesseringStatus>()
private val utfallTilSteg = mutableMapOf<ProsesseringStatus, Steg>()

fun med(steg: Steg, utfall: ProsesseringStatus): Builder {
if (rekkefølge.contains(steg)) {
throw IllegalStateException("Steg $steg er allerede lagt til: $rekkefølge")
}
rekkefølge.add(steg)
stegTilUtfall.put(steg, utfall)
utfallTilSteg.put(utfall, steg)

return this
}

fun build(): ProsesseringFlyt {
if (rekkefølge.isEmpty()) {
throw IllegalStateException("Ingen steg å prosessere.")
}

brevbestillingRepository.oppdaterBrev(referanse, brev)
return ProsesseringFlyt(
rekkefølge = rekkefølge,
stegTilUtfall = HashMap(stegTilUtfall),
utfallTilSteg = HashMap(utfallTilSteg),
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.nav.aap.brev.prosessering.steg

import no.nav.aap.brev.prosessering.steg.StegUtfører.Kontekst
import no.nav.aap.komponenter.dbconnect.DBConnection
import org.slf4j.LoggerFactory

class DistribuerJournalpostSteg() : StegUtfører {
private val log = LoggerFactory.getLogger(DistribuerJournalpostSteg::class.java)
override fun utfør(kontekst: Kontekst): StegResultat {
log.info("DistribuerJournalpostSteg")
return StegResultat.FULLFØRT
}

companion object : Steg {
override fun konstruer(connection: DBConnection): StegUtfører {
return DistribuerJournalpostSteg()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.nav.aap.brev.prosessering.steg

import no.nav.aap.brev.prosessering.steg.StegUtfører.Kontekst
import no.nav.aap.komponenter.dbconnect.DBConnection
import org.slf4j.LoggerFactory

class FerdigSteg() : StegUtfører {
private val log = LoggerFactory.getLogger(FerdigSteg::class.java)
override fun utfør(kontekst: Kontekst): StegResultat {
log.info("Prosessering er ferdig.")
return StegResultat.FULLFØRT
}

companion object : Steg {
override fun konstruer(connection: DBConnection): StegUtfører {
return FerdigSteg()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.nav.aap.brev.prosessering.steg

import no.nav.aap.brev.prosessering.steg.StegUtfører.Kontekst
import no.nav.aap.komponenter.dbconnect.DBConnection
import org.slf4j.LoggerFactory

class FerdigstillBrevSteg() : StegUtfører {
private val log = LoggerFactory.getLogger(FerdigstillBrevSteg::class.java)
override fun utfør(kontekst: Kontekst): StegResultat {
log.info("FerdigstillBrevSteg")
return StegResultat.FULLFØRT
}

companion object : Steg {
override fun konstruer(connection: DBConnection): StegUtfører {
return FerdigstillBrevSteg()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.nav.aap.brev.prosessering.steg

import no.nav.aap.brev.prosessering.steg.StegUtfører.Kontekst
import no.nav.aap.komponenter.dbconnect.DBConnection
import org.slf4j.LoggerFactory

class HentFaktagrunnlagSteg() : StegUtfører {
private val log = LoggerFactory.getLogger(HentFaktagrunnlagSteg::class.java)
override fun utfør(kontekst: Kontekst): StegResultat {
log.info("HentFaktagrunnlagSteg")
return StegResultat.FULLFØRT
}

companion object : Steg {
override fun konstruer(connection: DBConnection): StegUtfører {
return HentFaktagrunnlagSteg()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package no.nav.aap.brev.prosessering.steg

import no.nav.aap.brev.BrevbestillingRepository
import no.nav.aap.brev.BrevbestillingRepositoryImpl
import no.nav.aap.brev.innhold.BrevinnholdGateway
import no.nav.aap.brev.innhold.SanityBrevinnholdGateway
import no.nav.aap.brev.prosessering.steg.StegUtfører.Kontekst
import no.nav.aap.komponenter.dbconnect.DBConnection
import org.slf4j.LoggerFactory

class HentInnholdSteg(
private val brevinnholdGateway: BrevinnholdGateway,
private val brevbestillingRepository: BrevbestillingRepository
) : StegUtfører {
private val log = LoggerFactory.getLogger(HentInnholdSteg::class.java)
override fun utfør(kontekst: Kontekst): StegResultat {
log.info("Henter brevinnhold for bestillingsreferanse=${kontekst.referanse}")

val bestilling = brevbestillingRepository.hent(kontekst.referanse)
val brev = brevinnholdGateway.hentBrevmal(bestilling.brevtype, bestilling.språk)

brevbestillingRepository.oppdaterBrev(bestilling.referanse, brev)

return StegResultat.FULLFØRT
}

companion object : Steg {
override fun konstruer(connection: DBConnection): StegUtfører {
return HentInnholdSteg(
brevinnholdGateway = SanityBrevinnholdGateway(),
brevbestillingRepository = BrevbestillingRepositoryImpl(connection),
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.nav.aap.brev.prosessering.steg

import no.nav.aap.brev.prosessering.steg.StegUtfører.Kontekst
import no.nav.aap.komponenter.dbconnect.DBConnection
import org.slf4j.LoggerFactory

class JournalførBrevSteg() : StegUtfører {
private val log = LoggerFactory.getLogger(JournalførBrevSteg::class.java)
override fun utfør(kontekst: Kontekst): StegResultat {
log.info("JournalførBrevSteg")
return StegResultat.FULLFØRT
}

companion object : Steg {
override fun konstruer(connection: DBConnection): StegUtfører {
return JournalførBrevSteg()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.nav.aap.brev.prosessering.steg

import no.nav.aap.brev.prosessering.steg.StegUtfører.Kontekst
import no.nav.aap.komponenter.dbconnect.DBConnection
import org.slf4j.LoggerFactory

class StarterSteg() : StegUtfører {
private val log = LoggerFactory.getLogger(StarterSteg::class.java)
override fun utfør(kontekst: Kontekst): StegResultat {
log.info("Prosessering har startet.")
return StegResultat.FULLFØRT
}

companion object : Steg {
override fun konstruer(connection: DBConnection): StegUtfører {
return StarterSteg()
}
}
}
7 changes: 7 additions & 0 deletions app/src/main/kotlin/no/nav/aap/brev/prosessering/steg/Steg.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package no.nav.aap.brev.prosessering.steg

import no.nav.aap.komponenter.dbconnect.DBConnection

sealed interface Steg {
fun konstruer(connection: DBConnection): StegUtfører
}
Loading

0 comments on commit 7de87f2

Please sign in to comment.