Skip to content

Commit

Permalink
Merge branch 'main' into valider-mottaker-mot-sak
Browse files Browse the repository at this point in the history
  • Loading branch information
anderslysne committed Dec 19, 2024
2 parents 47e207e + 2af5f3b commit 69d64da
Show file tree
Hide file tree
Showing 16 changed files with 165 additions and 76 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 @@ -2,7 +2,6 @@ package no.nav.arbeidsgiver.notifikasjon.infrastruktur

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import com.zaxxer.hikari.metrics.prometheus.PrometheusMetricsTrackerFactory
import kotlinx.coroutines.*
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.json.laxObjectMapper
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.json.writeValueAsStringSupportingTypeInfoInCollections
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package no.nav.arbeidsgiver.notifikasjon.infrastruktur.graphql
import graphql.language.StringValue
import graphql.schema.*
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.ISO8601Period
import no.nav.arbeidsgiver.notifikasjon.tid.atOsloAsOffsetDateTime
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoField
import java.time.temporal.TemporalAccessor
import java.time.temporal.TemporalQuery

Expand Down Expand Up @@ -64,8 +67,14 @@ object Scalars {
val ISO8601DateTime: GraphQLScalarType =
dateTimeScalar(
name = "ISO8601DateTime",
dateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME,
temporalQuery = OffsetDateTime::from
dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME,
temporalQuery = {
if (it.isSupported(ChronoField.OFFSET_SECONDS)) {
OffsetDateTime.from(it).withOffsetSameInstant(ZoneOffset.UTC)
} else {
LocalDateTime.from(it).atOsloAsOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC)
}
}
)

val ISO8601LocalDateTime: GraphQLScalarType =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ class HendelsesstrømKafkaImpl(
*/
private val brokenHendelseId: Set<UUID> = setOf(
UUID.fromString("75977ac3-5ccd-42d2-ada0-93482462b8a9"),

// soft delete rett etter opprettelse gjør at partisjon er stuck i prod.
// se også https://github.com/navikt/arbeidsgiver-notifikasjon-produsent-api/pull/800
UUID.fromString("34a375aa-d967-4327-911b-177afcce9d6e"),
)

override suspend fun forEach(
Expand Down
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 @@ -14,8 +14,8 @@ 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
import no.nav.arbeidsgiver.notifikasjon.produsent.tilProdusentModel
import no.nav.arbeidsgiver.notifikasjon.tid.inOsloLocalDateTime
import java.time.Instant
import java.time.LocalDateTime
import java.time.OffsetDateTime
import java.util.*

Expand All @@ -41,10 +41,10 @@ internal class MutationKalenderavtale(
tekst = env.getTypedArgument<String>("tekst"),
lenke = env.getTypedArgument<String>("lenke"),
mottakere = env.getTypedArgument<List<MottakerInput>>("mottakere"),
startTidspunkt = env.getTypedArgument<LocalDateTime>("startTidspunkt"),
sluttTidspunkt = env.getTypedArgumentOrNull<LocalDateTime>("sluttTidspunkt"),
startTidspunkt = env.getTypedArgument<OffsetDateTime>("startTidspunkt"),
sluttTidspunkt = env.getTypedArgumentOrNull<OffsetDateTime>("sluttTidspunkt"),
lokasjon = env.getTypedArgumentOrNull<NyKalenderavtaleInput.LokasjonInput?>("lokasjon"),
erDigitalt = env.getTypedArgumentOrNull<Boolean>("erDigitalt") ?: false,
erDigitalt = env.getTypedArgumentOrNull<Boolean>("erDigitalt") == true,
tilstand = env.getTypedArgumentOrDefault<KalenderavtaleTilstand>("tilstand") { VENTER_SVAR_FRA_ARBEIDSGIVER },
eksterneVarsler = env.getTypedArgumentOrDefault<List<EksterntVarselInput>>("eksterneVarsler") { emptyList() },
paaminnelse = env.getTypedArgumentOrNull<PaaminnelseInput>("paaminnelse"),
Expand All @@ -61,8 +61,8 @@ internal class MutationKalenderavtale(
nyTilstand = env.getTypedArgumentOrNull<KalenderavtaleTilstand>("nyTilstand"),
nyTekst = env.getTypedArgumentOrNull<String>("nyTekst"),
nyLenke = env.getTypedArgumentOrNull<String>("nyLenke"),
nyttStartTidspunkt = env.getTypedArgumentOrNull<LocalDateTime>("nyttStartTidspunkt"),
nyttSluttTidspunkt = env.getTypedArgumentOrNull<LocalDateTime>("nyttSluttTidspunkt"),
nyttStartTidspunkt = env.getTypedArgumentOrNull<OffsetDateTime>("nyttStartTidspunkt"),
nyttSluttTidspunkt = env.getTypedArgumentOrNull<OffsetDateTime>("nyttSluttTidspunkt"),
nyLokasjon = env.getTypedArgumentOrNull<NyKalenderavtaleInput.LokasjonInput?>("nyLokasjon"),
nyErDigitalt = env.getTypedArgumentOrNull<Boolean>("nyErDigitalt"),
eksterneVarsler = env.getTypedArgumentOrDefault<List<EksterntVarselInput>>("eksterneVarsler") { emptyList() }.ifEmpty { null },
Expand All @@ -82,8 +82,8 @@ internal class MutationKalenderavtale(
nyTilstand = env.getTypedArgumentOrNull<KalenderavtaleTilstand>("nyTilstand"),
nyTekst = env.getTypedArgumentOrNull<String>("nyTekst"),
nyLenke = env.getTypedArgumentOrNull<String>("nyLenke"),
nyttStartTidspunkt = env.getTypedArgumentOrNull<LocalDateTime>("nyttStartTidspunkt"),
nyttSluttTidspunkt = env.getTypedArgumentOrNull<LocalDateTime>("nyttSluttTidspunkt"),
nyttStartTidspunkt = env.getTypedArgumentOrNull<OffsetDateTime>("nyttStartTidspunkt"),
nyttSluttTidspunkt = env.getTypedArgumentOrNull<OffsetDateTime>("nyttSluttTidspunkt"),
nyLokasjon = env.getTypedArgumentOrNull<NyKalenderavtaleInput.LokasjonInput?>("nyLokasjon"),
nyErDigitalt = env.getTypedArgumentOrNull<Boolean>("nyErDigitalt"),
eksterneVarsler = env.getTypedArgumentOrDefault<List<EksterntVarselInput>>("eksterneVarsler") { emptyList() }.ifEmpty { null },
Expand Down Expand Up @@ -121,8 +121,8 @@ internal class MutationKalenderavtale(
val tekst: String,
val lenke: String,
val mottakere: List<MottakerInput>,
val startTidspunkt: LocalDateTime,
val sluttTidspunkt: LocalDateTime?,
val startTidspunkt: OffsetDateTime,
val sluttTidspunkt: OffsetDateTime?,
val lokasjon: LokasjonInput?,
val erDigitalt: Boolean,
val tilstand: KalenderavtaleTilstand,
Expand Down Expand Up @@ -158,8 +158,8 @@ internal class MutationKalenderavtale(
virksomhetsnummer = virksomhetsnummer,
produsentId = produsentId,
kildeAppNavn = kildeAppNavn,
startTidspunkt = startTidspunkt,
sluttTidspunkt = sluttTidspunkt,
startTidspunkt = startTidspunkt.inOsloLocalDateTime(),
sluttTidspunkt = sluttTidspunkt?.inOsloLocalDateTime(),
tilstand = tilstand.tilHendelseModel(),
lokasjon = lokasjon?.tilHendelseModel(),
erDigitalt = erDigitalt,
Expand All @@ -169,7 +169,7 @@ internal class MutationKalenderavtale(
påminnelse = paaminnelse?.tilDomene(
notifikasjonOpprettetTidspunkt = opprettetTidspunkt,
frist = null,
startTidspunkt = startTidspunkt,
startTidspunkt = startTidspunkt.inOsloLocalDateTime(),
virksomhetsnummer = virksomhetsnummer,
),
)
Expand Down Expand Up @@ -291,14 +291,14 @@ internal class MutationKalenderavtale(
)
} else if (
nyttStartTidspunkt != null &&
nyttStartTidspunkt!!.isAfter(eksisterende.sluttTidspunkt)
nyttStartTidspunkt!!.inOsloLocalDateTime().isAfter(eksisterende.sluttTidspunkt)
) {
onValidationError(
Error.UgyldigKalenderavtale("startTidspunkt må være før sluttTidspunkt")
)
} else if (
nyttSluttTidspunkt != null
&& nyttSluttTidspunkt!!.isBefore(eksisterende.startTidspunkt)
&& nyttSluttTidspunkt!!.inOsloLocalDateTime().isBefore(eksisterende.startTidspunkt)
) {
onValidationError(
Error.UgyldigKalenderavtale("startTidspunkt må være før sluttTidspunkt")
Expand All @@ -315,16 +315,16 @@ internal class MutationKalenderavtale(
tilstand = nyTilstand?.tilHendelseModel(),
lenke = nyLenke,
tekst = nyTekst,
startTidspunkt = nyttStartTidspunkt,
sluttTidspunkt = nyttSluttTidspunkt,
startTidspunkt = nyttStartTidspunkt?.inOsloLocalDateTime(),
sluttTidspunkt = nyttSluttTidspunkt?.inOsloLocalDateTime(),
lokasjon = nyLokasjon?.tilHendelseModel(),
erDigitalt = nyErDigitalt,
hardDelete = hardDelete?.tilHendelseModel(),
eksterneVarsler = eksterneVarsler?.map { it.tilHendelseModel(eksisterende.virksomhetsnummer) } ?: emptyList(),
påminnelse = if (nyTilstand == AVLYST) null else paaminnelse?.tilDomene(
notifikasjonOpprettetTidspunkt = eksisterende.opprettetTidspunkt,
frist = null,
startTidspunkt = nyttStartTidspunkt ?: eksisterende.startTidspunkt,
startTidspunkt = (nyttStartTidspunkt?.inOsloLocalDateTime() ?: eksisterende.startTidspunkt),
virksomhetsnummer = eksisterende.virksomhetsnummer,
),
idempotenceKey = idempotenceKey,
Expand All @@ -337,8 +337,8 @@ internal class MutationKalenderavtale(
abstract val nyTilstand: KalenderavtaleTilstand?
abstract val nyTekst: String?
abstract val nyLenke: String?
abstract val nyttStartTidspunkt: LocalDateTime?
abstract val nyttSluttTidspunkt: LocalDateTime?
abstract val nyttStartTidspunkt: OffsetDateTime?
abstract val nyttSluttTidspunkt: OffsetDateTime?
abstract val nyLokasjon: NyKalenderavtaleInput.LokasjonInput?
abstract val nyErDigitalt: Boolean?
abstract val hardDelete: HardDeleteUpdateInput?
Expand Down Expand Up @@ -370,8 +370,8 @@ internal class MutationKalenderavtale(
override val nyTilstand: KalenderavtaleTilstand?,
override val nyTekst: String?,
override val nyLenke: String?,
override val nyttStartTidspunkt: LocalDateTime?,
override val nyttSluttTidspunkt: LocalDateTime?,
override val nyttStartTidspunkt: OffsetDateTime?,
override val nyttSluttTidspunkt: OffsetDateTime?,
override val nyLokasjon: NyKalenderavtaleInput.LokasjonInput?,
override val nyErDigitalt: Boolean?,
override val eksterneVarsler: List<EksterntVarselInput>?,
Expand All @@ -386,8 +386,8 @@ internal class MutationKalenderavtale(
override val nyTilstand: KalenderavtaleTilstand?,
override val nyTekst: String?,
override val nyLenke: String?,
override val nyttStartTidspunkt: LocalDateTime?,
override val nyttSluttTidspunkt: LocalDateTime?,
override val nyttStartTidspunkt: OffsetDateTime?,
override val nyttSluttTidspunkt: OffsetDateTime?,
override val nyLokasjon: NyKalenderavtaleInput.LokasjonInput?,
override val nyErDigitalt: Boolean?,
override val eksterneVarsler: List<EksterntVarselInput>?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel
import no.nav.arbeidsgiver.notifikasjon.hendelse.HendelseModel.KalenderavtaleTilstand
import no.nav.arbeidsgiver.notifikasjon.infrastruktur.local_database.*
import no.nav.arbeidsgiver.notifikasjon.skedulert_påminnelse.Notifikasjontilstand.*
import no.nav.arbeidsgiver.notifikasjon.tid.inOsloLocalDateTime
import java.sql.Connection
import java.time.Instant
import java.time.LocalDate
Expand Down
13 changes: 6 additions & 7 deletions app/src/main/resources/produsent.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ directive @MaxValue(upToIncluding: Int) on ARGUMENT_DEFINITION
directive @NorwegianMobilePhoneNumber on INPUT_FIELD_DEFINITION | ARGUMENT_DEFINITION

"""
DateTime med offset etter ISO8601-standaren. F.eks. '2011-12-03T10:15:30+01:00'.
Er representert som String.
DateTime etter ISO8601-standaren. F.eks. '2011-12-03T10:15:30+01:00'.
Dersom tidssone/offset ikke er oppgitt, så antar vi at tidspunktet er Oslo-tid ('Europe/Oslo').
"""
scalar ISO8601DateTime

Expand Down Expand Up @@ -254,12 +253,12 @@ type KalenderavtaleData {
"""
Når avtalen starter.
"""
startTidspunkt: ISO8601LocalDateTime!
startTidspunkt: ISO8601DateTime!

"""
Når avtalen slutter.
"""
sluttTidspunkt: ISO8601LocalDateTime
sluttTidspunkt: ISO8601DateTime

"""
Her kan dere oppgi en fysisk adresse som brukeren kan møte opp på dersom dere har det.
Expand Down Expand Up @@ -449,12 +448,12 @@ type Mutation {
"""
Når avtalen starter.
"""
startTidspunkt: ISO8601LocalDateTime!
startTidspunkt: ISO8601DateTime!

"""
Når avtalen slutter.
"""
sluttTidspunkt: ISO8601LocalDateTime
sluttTidspunkt: ISO8601DateTime

"""
Her kan dere oppgi en fysisk adresse som brukeren kan møte opp på dersom dere har det.
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
}
}
Loading

0 comments on commit 69d64da

Please sign in to comment.