Skip to content

Commit

Permalink
Merge branch 'main' into graphql_op_error_metric
Browse files Browse the repository at this point in the history
  • Loading branch information
kenglxn authored Dec 20, 2024
2 parents 47731c7 + ef69602 commit e1d664d
Show file tree
Hide file tree
Showing 15 changed files with 526 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -706,14 +706,7 @@ class BrukerRepositoryImpl(
is OppgaveUtført -> oppdaterModellEtterOppgaveUtført(hendelse, metadata)
is OppgaveUtgått -> oppdaterModellEtterOppgaveUtgått(hendelse)
is SoftDelete -> oppdaterModellEtterDelete(hendelse.aggregateId, hendelse.grupperingsid, hendelse.merkelapp)
is HardDelete -> oppdaterModellEtterDelete(
hendelse.aggregateId,
hendelse.grupperingsid,
hendelse.merkelapp
) { tx ->
registrerHardDelete(tx, hendelse)
}

is HardDelete -> oppdaterModellEtterDelete(hendelse.aggregateId,hendelse.grupperingsid,hendelse.merkelapp)
is EksterntVarselFeilet -> Unit
is EksterntVarselVellykket -> Unit
is EksterntVarselKansellert -> Unit
Expand Down Expand Up @@ -834,8 +827,7 @@ class BrukerRepositoryImpl(
private suspend fun oppdaterModellEtterDelete(
aggregateId: UUID,
grupperingsid: String?,
merkelapp: String?,
callback: (tx: Transaction) -> Unit = {}
merkelapp: String?
) {
database.transaction({
throw RuntimeException("Delete", it)
Expand All @@ -859,7 +851,7 @@ class BrukerRepositoryImpl(
uuid(aggregateId)
}

callback(this)
registrerDelete(this, aggregateId)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ class DataproduktModel(
) {
uuid(hendelse.aggregateId)
}
registrerHardDelete(this, hendelse)
registrerDelete(this, hendelse.aggregateId)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,12 @@ open class HardDeletedRepository(private val database: Database) {

}

fun registrerHardDelete(tx: Transaction, hendelse: HendelseModel.Hendelse) {
if (hendelse !is HendelseModel.HardDelete) {
return
}

fun registrerDelete(tx: Transaction, aggregateId: UUID) {
tx.executeUpdate("""
insert into hard_deleted_aggregates(aggregate_id) values (?)
on conflict do nothing
""") {
uuid(hendelse.aggregateId)
uuid(aggregateId)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ class ProdusentRepositoryImpl(

private suspend fun oppdaterModellEtterHardDelete(hardDelete: HardDelete) {
database.transaction {
registrerHardDelete(this, hardDelete)
registrerDelete(this, hardDelete.aggregateId)
executeQuery("""
select aggregate_type from (
select 'SAK' as aggregate_type from sak where id = ?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel.KalenderavtaleOpp
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.graphql.*
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.logger
import no.nav.arbeidsgiver.notifikasjon.produsent.ProdusentModel
import no.nav.arbeidsgiver.notifikasjon.produsent.ProdusentModel.Sak
import no.nav.arbeidsgiver.notifikasjon.produsent.ProdusentRepository
import no.nav.arbeidsgiver.notifikasjon.produsent.api.MutationKalenderavtale.KalenderavtaleTilstand.AVLYST
import no.nav.arbeidsgiver.notifikasjon.produsent.api.MutationKalenderavtale.KalenderavtaleTilstand.VENTER_SVAR_FRA_ARBEIDSGIVER
Expand Down Expand Up @@ -209,20 +210,20 @@ internal class MutationKalenderavtale(
nyKalenderavtale: NyKalenderavtaleInput,
): NyKalenderavtaleResultat {
val produsent = hentProdusent(context) { error -> return error }
val sakId: UUID = nyKalenderavtale.grupperingsid.let { grupperingsid ->
val sak: Sak = nyKalenderavtale.grupperingsid.let { grupperingsid ->
hentSak(
produsentRepository = produsentRepository,
grupperingsid = grupperingsid,
merkelapp = nyKalenderavtale.merkelapp
) { error -> return error }.id
) { error -> return error }
}

val id = UUID.randomUUID()
val nyKalenderavtaleHendelse = nyKalenderavtale.somKalenderavtaleOpprettetHendelse(
id = id,
produsentId = produsent.id,
kildeAppNavn = context.appName,
sakId = sakId,
sakId = sak.id,
) { error -> return error }

tilgangsstyrNyNotifikasjon(
Expand All @@ -231,6 +232,10 @@ internal class MutationKalenderavtale(
nyKalenderavtale.merkelapp
) { error -> return error }

validerMottakereMotSak(sak, nyKalenderavtale.virksomhetsnummer, nyKalenderavtale.mottakere) { error ->
return error
}

val eksisterende = produsentRepository.hentNotifikasjon(
eksternId = nyKalenderavtaleHendelse.eksternId,
merkelapp = nyKalenderavtaleHendelse.merkelapp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import graphql.schema.idl.RuntimeWiring
import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel.BeskjedOpprettet
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.graphql.*
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.logger
import no.nav.arbeidsgiver.notifikasjon.produsent.ProdusentModel.Sak
import no.nav.arbeidsgiver.notifikasjon.produsent.ProdusentRepository
import no.nav.arbeidsgiver.notifikasjon.produsent.tilProdusentModel
import java.util.*
Expand Down Expand Up @@ -79,11 +80,11 @@ internal class MutationNyBeskjed(
nyBeskjed: NyBeskjedInput,
): NyBeskjedResultat {
val produsent = hentProdusent(context) { error -> return error }
val sakId : UUID? = nyBeskjed.metadata.grupperingsid?.let { grupperingsid ->
val sak : Sak? = nyBeskjed.metadata.grupperingsid?.let { grupperingsid ->
runCatching {
hentSak(produsentRepository, grupperingsid, nyBeskjed.notifikasjon.merkelapp) {
TODO("make sak required by returning this error")
}.id
}
}.getOrNull()
}
val id = UUID.randomUUID()
Expand All @@ -92,7 +93,7 @@ internal class MutationNyBeskjed(
id = id,
produsentId = produsent.id,
kildeAppNavn = context.appName,
sakId = sakId,
sakId = sak?.id,
)
} catch (e: UkjentRolleException) {
return Error.UkjentRolle(e.message!!)
Expand All @@ -106,6 +107,10 @@ internal class MutationNyBeskjed(
return error
}

validerMottakereMotSak(sak, nyBeskjed.metadata.virksomhetsnummer, nyBeskjed.mottakere) { error ->
return error
}

val eksisterende = produsentRepository.hentNotifikasjon(
eksternId = domeneNyBeskjed.eksternId,
merkelapp = domeneNyBeskjed.merkelapp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel.OppgaveOpprettet
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.graphql.*
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.logger
import no.nav.arbeidsgiver.notifikasjon.produsent.ProdusentModel
import no.nav.arbeidsgiver.notifikasjon.produsent.ProdusentModel.Sak
import no.nav.arbeidsgiver.notifikasjon.produsent.ProdusentRepository
import no.nav.arbeidsgiver.notifikasjon.produsent.tilProdusentModel
import java.time.LocalDate
Expand Down Expand Up @@ -96,11 +97,11 @@ internal class MutationNyOppgave(
nyOppgave: NyOppgaveInput,
): NyOppgaveResultat {
val produsent = hentProdusent(context) { error -> return error }
val sakId : UUID? = nyOppgave.metadata.grupperingsid?.let { grupperingsid ->
val sak : Sak? = nyOppgave.metadata.grupperingsid?.let { grupperingsid ->
runCatching {
hentSak(produsentRepository, grupperingsid, nyOppgave.notifikasjon.merkelapp) {
TODO("make sak required by returning this error")
}.id
}
}.getOrNull()
}
val id = UUID.randomUUID()
Expand All @@ -109,7 +110,7 @@ internal class MutationNyOppgave(
id = id,
produsentId = produsent.id,
kildeAppNavn = context.appName,
sakId = sakId,
sakId = sak?.id,
)
} catch (e: UkjentRolleException){
return Error.UkjentRolle(e.message!!)
Expand All @@ -123,6 +124,10 @@ internal class MutationNyOppgave(
nyOppgave.notifikasjon.merkelapp,
) { error -> return error }

validerMottakereMotSak(sak, nyOppgave.metadata.virksomhetsnummer, nyOppgave.mottakere) { error ->
return error
}

val eksisterende = produsentRepository.hentNotifikasjon(
eksternId = domeneNyOppgave.eksternId,
merkelapp = domeneNyOppgave.merkelapp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,37 @@ internal inline fun tilgangsstyrProdusent(
return produsent
}

private inline fun validerMottakerMotSak(
sak: ProdusentModel.Sak,
virksomhetsnummer: String,
mottakerInput: MottakerInput,
onError: (Error.UgyldigMottaker) -> Nothing
) {
var mottaker = mottakerInput.tilHendelseModel(virksomhetsnummer)
if (mottaker !in sak.mottakere) {
onError(
Error.UgyldigMottaker(
"""
| Ugyldig mottaker '${mottakerInput}'.
| Mottaker må finnes på sak.
""".trimMargin()
)
)
}
}

internal inline fun validerMottakereMotSak(
sak: ProdusentModel.Sak?,
virksomhetsnummer: String,
mottakere: List<MottakerInput>,
onError: (Error.UgyldigMottaker) -> Nothing
) {
if (sak == null) return
for (mottaker in mottakere) {
validerMottakerMotSak(sak, virksomhetsnummer, mottaker, onError)
}
}

fun String.ensurePrefix(prefix: String) =
prefix + removePrefix(prefix)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,57 @@ class BrukerModelIdempotensTests : DescribeSpec({
}

assertDeleted(database, sakId, notifikasjonId, grupperingsid, merkelapp)
}

describe("soft delete på sak sletter alt og kan replayes uten sakOpprettet") {
val database = testDatabase(Bruker.databaseConfig)
val brukerRepository = BrukerRepositoryImpl(database)
val merkelapp = "idempotenstest"
val grupperingsid = "gr-42"
val sakId = uuid("42")
val notifikasjonId = uuid("314")

val sakOpprettet = brukerRepository.sakOpprettet(
sakId = sakId,
virksomhetsnummer = TEST_VIRKSOMHET_1,
merkelapp = merkelapp,
grupperingsid = grupperingsid,
mottakere = listOf(TEST_MOTTAKER_1, TEST_MOTTAKER_2),
)

val hendelsesforløp = listOf(
sakOpprettet,
brukerRepository.nyStatusSak(sakOpprettet, idempotensKey = "idempotensKey"),
brukerRepository . beskjedOpprettet (
sakId = sakId,
notifikasjonId = notifikasjonId,
virksomhetsnummer = TEST_VIRKSOMHET_1,
merkelapp = merkelapp,
grupperingsid = grupperingsid,
mottakere = listOf(TEST_MOTTAKER_1, TEST_MOTTAKER_2),
),
HendelseModel.SoftDelete(
hendelseId = UUID.randomUUID(),
virksomhetsnummer = TEST_VIRKSOMHET_1,
aggregateId = sakId,
produsentId = "",
kildeAppNavn = "",
deletedAt = OffsetDateTime.now(),
grupperingsid = grupperingsid,
merkelapp = merkelapp,
).also {
brukerRepository.oppdaterModellEtterHendelse(it)
}
)

assertDeleted(database, sakId, notifikasjonId, grupperingsid, merkelapp)

// replay events utenom sakOpprettet
hendelsesforløp.drop(1).forEach {
brukerRepository.oppdaterModellEtterHendelse(it)
}

assertDeleted(database, sakId, notifikasjonId, grupperingsid, merkelapp)
}
})

Expand Down Expand Up @@ -157,4 +206,13 @@ private suspend fun DescribeSpecContainerScope.assertDeleted(
asMap()
}.size shouldBe 0
}
it("sak_status is deleted"){
database.nonTransactionalExecuteQuery(
"""
select * from sak_status where sak_id = '${notifikasjonId}'
"""
) {
asMap()
}.size shouldBe 0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ val stubProdusentRegister: ProdusentRegister = object : ProdusentRegister {
tillatteMerkelapper = listOf("tag", "tag2"),
tillatteMottakere = listOf(
ServicecodeDefinisjon(code = "5441", version = "1"),
ServicecodeDefinisjon(code = "1", version = "1"),
RessursIdDefinisjon(ressursId = "test-fager"),
NærmesteLederDefinisjon,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import io.kotest.matchers.collections.shouldBeIn
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.shouldBe
import io.ktor.server.testing.*
import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel.AltinnMottaker
import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel.EksterntVarselFeilet
import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel.EksterntVarselVellykket
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.graphql.GraphQLRequest
Expand Down Expand Up @@ -94,7 +95,7 @@ class EksternVarselApiTests: DescribeSpec({
}
mottaker: {
altinn: {
serviceCode: "5441"
serviceCode: "1"
serviceEdition: "1"
}
}
Expand Down Expand Up @@ -124,7 +125,7 @@ class EksternVarselApiTests: DescribeSpec({
nyNotifikasjon: nyKalenderavtale(
mottakere: {
altinn: {
serviceCode: "5441"
serviceCode: "1"
serviceEdition: "1"
}
}
Expand Down Expand Up @@ -364,7 +365,14 @@ class EksternVarselApiTests: DescribeSpec({
produsentModel.oppdaterModellEtterHendelse(EksempelHendelse.SakOpprettet.copy(
virksomhetsnummer = "0",
merkelapp = "tag",
grupperingsid = "0"
grupperingsid = "0",
mottakere = listOf(
AltinnMottaker(
virksomhetsnummer = "0",
serviceCode = "1",
serviceEdition = "1"
),
)
))
val nyNotifikasjonResult = engine.produsentApi(GraphQLRequest(
query = nyNotifikasjonMutation(nyKalenderavtale),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import java.util.*

class IdempotensOppførselForProdusentApiTests : DescribeSpec({

val virksomhetsnummer = "1234"
val mottaker = AltinnMottaker(serviceCode = "5441", serviceEdition = "1", virksomhetsnummer = virksomhetsnummer)
val virksomhetsnummer = "1"
val mottaker = AltinnMottaker(serviceCode = "1", serviceEdition = "1", virksomhetsnummer = virksomhetsnummer)
val eksternId = "42"
val grupperingsid = "42"

Expand Down
Loading

0 comments on commit e1d664d

Please sign in to comment.