Skip to content

Commit 5172ab3

Browse files
committed
Oppdaterte kafka streams tilstands klassen til bekreftelse-tjeneste
1 parent 2826440 commit 5172ab3

File tree

21 files changed

+413
-316
lines changed

21 files changed

+413
-316
lines changed

Diff for: apps/bekreftelse-min-side-oppgaver/build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ dependencies {
1818
implementation(project(":domain:main-avro-schema"))
1919
implementation(libs.jackson.datatypeJsr310)
2020
implementation(libs.jackson.kotlin)
21-
implementation(libs.arrowCore)
21+
implementation(libs.arrow.core.core)
2222
implementation(libs.hoplite.yaml)
2323
implementation(libs.nav.common.log)
2424
implementation(libs.logbackClassic)

Diff for: apps/bekreftelse-tjeneste/build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ dependencies {
3030
implementation(libs.jackson.datatypeJsr310)
3131

3232
// Tooling
33-
implementation(libs.arrowCore)
33+
implementation(libs.arrow.core.core)
3434

3535
// Logging
3636
implementation(libs.logbackClassic)

Diff for: apps/bekreftelse-tjeneste/nais/nais-dev.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ spec:
1010
port: 8080
1111
env:
1212
- name: KAFKA_STREAMS_ID_SUFFIX
13-
value: "v2"
13+
value: "v3"
1414
- name: KAFKA_PAW_ARBEIDSSOKER_BEKREFTELSE_TOPIC
1515
value: "paw.arbeidssoker-bekreftelse-beta-v1"
1616
- name: KAFKA_PAW_ARBEIDSSOKER_BEKREFTELSE_HENDELSELOGG_TOPIC
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package no.nav.paw.bekreftelsetjeneste.tilstand
2+
3+
import arrow.core.NonEmptyList
4+
import java.time.Duration
5+
import java.time.Instant
6+
import java.util.*
7+
8+
@JvmRecord
9+
data class Bekreftelse(
10+
val tilstandsLogg: BekreftelseTilstandsLogg,
11+
val bekreftelseId: UUID,
12+
val gjelderFra: Instant,
13+
val gjelderTil: Instant
14+
)
15+
16+
inline fun <reified T: BekreftelseTilstand> Bekreftelse.tilstand(): T? = tilstandsLogg.get()
17+
18+
inline fun <reified T: BekreftelseTilstand> Bekreftelse.has(): Boolean = tilstand<T>() != null
19+
20+
fun Bekreftelse.sisteTilstand(): BekreftelseTilstand = tilstandsLogg.siste
21+
22+
operator fun Bekreftelse.plus(bekreftelseTilstand: BekreftelseTilstand): Bekreftelse =
23+
copy(tilstandsLogg = tilstandsLogg + bekreftelseTilstand)
24+
25+
fun opprettFoersteBekreftelse(
26+
periode: PeriodeInfo,
27+
interval: Duration,
28+
): Bekreftelse =
29+
Bekreftelse(
30+
BekreftelseTilstandsLogg(IkkeKlarForUtfylling(periode.startet), emptyList()),
31+
bekreftelseId = UUID.randomUUID(),
32+
gjelderFra = periode.startet,
33+
gjelderTil = fristForNesteBekreftelse(periode.startet, interval)
34+
)
35+
36+
37+
fun NonEmptyList<Bekreftelse>.opprettNesteTilgjengeligeBekreftelse(
38+
tilgjengeliggjort: Instant,
39+
interval: Duration
40+
): Bekreftelse {
41+
val sisteBekreftelse = maxBy { it.gjelderTil }
42+
return Bekreftelse(
43+
bekreftelseId = UUID.randomUUID(),
44+
gjelderFra = sisteBekreftelse.gjelderTil,
45+
gjelderTil = fristForNesteBekreftelse(sisteBekreftelse.gjelderTil, interval),
46+
tilstandsLogg = BekreftelseTilstandsLogg(
47+
siste = KlarForUtfylling(tilgjengeliggjort),
48+
tidligere = emptyList()
49+
)
50+
)
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package no.nav.paw.bekreftelsetjeneste.tilstand
2+
3+
import com.fasterxml.jackson.annotation.JsonSubTypes
4+
import com.fasterxml.jackson.annotation.JsonTypeInfo
5+
import java.time.Instant
6+
7+
@JsonTypeInfo(
8+
use = JsonTypeInfo.Id.NAME,
9+
include = JsonTypeInfo.As.PROPERTY,
10+
property = "type"
11+
)
12+
@JsonSubTypes(
13+
JsonSubTypes.Type(value = IkkeKlarForUtfylling::class, name = "IkkeKlarForUtfylling"),
14+
JsonSubTypes.Type(value = KlarForUtfylling::class, name = "KlarForUtfylling"),
15+
JsonSubTypes.Type(value = VenterSvar::class, name = "VenterSvar"),
16+
JsonSubTypes.Type(value = GracePeriodeUtloept::class, name = "GracePeriodeUtloept"),
17+
JsonSubTypes.Type(value = Levert::class, name = "Levert")
18+
)
19+
sealed interface BekreftelseTilstand {
20+
val timestamp: Instant
21+
}
22+
23+
data class GracePeriodeUtloept(override val timestamp: Instant) : BekreftelseTilstand
24+
data class GracePeriodeVarselet(override val timestamp: Instant) : BekreftelseTilstand
25+
data class IkkeKlarForUtfylling(override val timestamp: Instant) : BekreftelseTilstand
26+
data class KlarForUtfylling(override val timestamp: Instant) : BekreftelseTilstand
27+
data class Levert(override val timestamp: Instant) : BekreftelseTilstand
28+
data class VenterSvar(override val timestamp: Instant) : BekreftelseTilstand
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package no.nav.paw.bekreftelsetjeneste.tilstand
2+
3+
import arrow.core.NonEmptyList
4+
import arrow.core.nonEmptyListOf
5+
import org.slf4j.LoggerFactory
6+
7+
@JvmRecord
8+
data class BekreftelseTilstandsLogg(
9+
val siste: BekreftelseTilstand,
10+
val tidligere: List<BekreftelseTilstand>
11+
)
12+
13+
private val bekreftelseTilstandsLoggProblemerLogger = LoggerFactory.getLogger(BekreftelseTilstandsLogg::class.java)
14+
operator fun BekreftelseTilstandsLogg.plus(bekreftelseTilstand: BekreftelseTilstand): BekreftelseTilstandsLogg =
15+
(tidligere + siste + bekreftelseTilstand)
16+
.groupBy { it::class }
17+
.values
18+
.map { gruppe ->
19+
if (gruppe.size == 1) gruppe.first()
20+
else {
21+
bekreftelseTilstandsLoggProblemerLogger.warn("Flere tilstander av samme type i tilstandslogg: $gruppe, beholder den nyeste")
22+
gruppe.maxBy { it.timestamp }
23+
}
24+
}
25+
.let { alle ->
26+
val siste = alle.maxBy { it.timestamp }
27+
val tidligere = alle.filterNot { it == siste }.sortedBy { it.timestamp }
28+
BekreftelseTilstandsLogg(siste, tidligere)
29+
}
30+
31+
inline fun <reified T : BekreftelseTilstand> BekreftelseTilstandsLogg.get(): T? =
32+
tidligere.filterIsInstance<T>().firstOrNull() ?: siste as? T
33+
34+
fun BekreftelseTilstandsLogg.asList(): NonEmptyList<BekreftelseTilstand> = nonEmptyListOf(siste) + tidligere
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,13 @@
11
package no.nav.paw.bekreftelsetjeneste.tilstand
22

3-
import com.fasterxml.jackson.annotation.JsonSubTypes
4-
import com.fasterxml.jackson.annotation.JsonTypeInfo
53
import no.nav.paw.arbeidssokerregisteret.api.v1.Periode
6-
import java.time.Duration
7-
import java.time.Instant
8-
import java.util.*
94

105
@JvmRecord
116
data class InternTilstand(
127
val periode: PeriodeInfo,
138
val bekreftelser: List<Bekreftelse>
149
)
1510

16-
@JvmRecord
17-
data class Bekreftelse(
18-
val tilstand: Tilstand,
19-
val tilgjengeliggjort: Instant?,
20-
val fristUtloept: Instant?,
21-
val sisteVarselOmGjenstaaendeGraceTid: Instant?,
22-
val bekreftelseId: UUID,
23-
val gjelderFra: Instant,
24-
val gjelderTil: Instant
25-
)
26-
27-
@JsonTypeInfo(
28-
use = JsonTypeInfo.Id.NAME,
29-
include = JsonTypeInfo.As.PROPERTY,
30-
property = "type"
31-
)
32-
@JsonSubTypes(
33-
JsonSubTypes.Type(value = Tilstand.IkkeKlarForUtfylling::class, name = "IkkeKlarForUtfylling"),
34-
JsonSubTypes.Type(value = Tilstand.KlarForUtfylling::class, name = "KlarForUtfylling"),
35-
JsonSubTypes.Type(value = Tilstand.VenterSvar::class, name = "VenterSvar"),
36-
JsonSubTypes.Type(value = Tilstand.GracePeriodeUtloept::class, name = "GracePeriodeUtloept"),
37-
JsonSubTypes.Type(value = Tilstand.Levert::class, name = "Levert")
38-
)
39-
sealed class Tilstand {
40-
data object IkkeKlarForUtfylling : Tilstand()
41-
data object KlarForUtfylling : Tilstand()
42-
data object VenterSvar : Tilstand()
43-
data object GracePeriodeUtloept : Tilstand()
44-
data object Levert : Tilstand()
45-
}
46-
47-
@JvmRecord
48-
data class PeriodeInfo(
49-
val periodeId: UUID,
50-
val identitetsnummer: String,
51-
val arbeidsoekerId: Long,
52-
val recordKey: Long,
53-
val startet: Instant,
54-
val avsluttet: Instant?
55-
) {
56-
val erAvsluttet: Boolean
57-
get() = avsluttet != null
58-
}
59-
6011
fun initTilstand(
6112
id: Long,
6213
key: Long,
@@ -73,33 +24,3 @@ fun initTilstand(
7324
),
7425
bekreftelser = emptyList()
7526
)
76-
77-
fun initBekreftelsePeriode(
78-
periode: PeriodeInfo,
79-
interval: Duration,
80-
): Bekreftelse =
81-
Bekreftelse(
82-
tilstand = Tilstand.IkkeKlarForUtfylling,
83-
tilgjengeliggjort = null,
84-
fristUtloept = null,
85-
sisteVarselOmGjenstaaendeGraceTid = null,
86-
bekreftelseId = UUID.randomUUID(),
87-
gjelderFra = periode.startet,
88-
gjelderTil = fristForNesteBekreftelse(periode.startet, interval)
89-
)
90-
91-
fun List<Bekreftelse>.initNewBekreftelse(
92-
tilgjengeliggjort: Instant,
93-
interval: Duration
94-
): Bekreftelse {
95-
val sisteBekreftelse = maxBy { it.gjelderTil }
96-
97-
return sisteBekreftelse.copy(
98-
tilstand = Tilstand.KlarForUtfylling,
99-
tilgjengeliggjort = tilgjengeliggjort,
100-
sisteVarselOmGjenstaaendeGraceTid = null,
101-
bekreftelseId = UUID.randomUUID(),
102-
gjelderFra = sisteBekreftelse.gjelderTil,
103-
gjelderTil = fristForNesteBekreftelse(sisteBekreftelse.gjelderTil, interval)
104-
)
105-
}

Diff for: apps/bekreftelse-tjeneste/src/main/kotlin/no/nav/paw/bekreftelsetjeneste/tilstand/KontrolerFrister.kt

+35-12
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,53 @@ import java.time.Instant
88
const val MAKS_ANTALL_UTSTEENDE_BEKREFTELSER: Int = 100
99
private val maksAntallLogger = LoggerFactory.getLogger("maksAntallLogger")
1010
fun Bekreftelse.erKlarForUtfylling(now: Instant, tilgjengeligOffset: Duration): Boolean =
11-
now.isAfter(gjelderTil.minus(tilgjengeligOffset))
11+
when (sisteTilstand()) {
12+
is IkkeKlarForUtfylling -> now.isAfter(gjelderTil.minus(tilgjengeligOffset))
13+
else -> false
14+
}
15+
1216

1317
fun Bekreftelse.harFristUtloept(now: Instant, tilgjengeligOffset: Duration): Boolean =
14-
now.isAfter(tilgjengeliggjort?.plus(tilgjengeligOffset) ?: gjelderTil)
18+
when (val gjeldeneTilstand = sisteTilstand()) {
19+
is KlarForUtfylling -> now.isAfter(gjeldeneTilstand.timestamp.plus(tilgjengeligOffset))
20+
else -> false
21+
}
22+
1523

1624
fun Bekreftelse.erSisteVarselOmGjenstaaendeGraceTid(now: Instant, varselFoerGraceperiodeUtloept: Duration): Boolean =
17-
sisteVarselOmGjenstaaendeGraceTid == null && now.isAfter(fristUtloept?.plus(varselFoerGraceperiodeUtloept) ?: gjelderTil.plus(
18-
varselFoerGraceperiodeUtloept
19-
))
25+
when (val gjeldeneTilstand = sisteTilstand()) {
26+
is VenterSvar -> !has<GracePeriodeVarselet>() && now.isAfter(
27+
gjeldeneTilstand.timestamp.plus(
28+
varselFoerGraceperiodeUtloept
29+
)
30+
)
2031

21-
fun Bekreftelse.harGraceperiodeUtloept(now: Instant, graceperiode: Duration): Boolean =
22-
now.isAfter(fristUtloept?.plus(graceperiode) ?: gjelderTil.plus(graceperiode))
32+
else -> false
33+
}
2334

24-
fun NonEmptyList<Bekreftelse>.shouldCreateNewBekreftelse(now: Instant, interval: Duration, tilgjengeligOffset: Duration): Boolean =
35+
fun Bekreftelse.harGraceperiodeUtloept(now: Instant, graceperiode: Duration): Boolean =
36+
when (val gjeldeneTilstand = sisteTilstand()) {
37+
is VenterSvar -> now.isAfter(gjeldeneTilstand.timestamp.plus(graceperiode))
38+
is GracePeriodeVarselet -> tilstandsLogg.get<VenterSvar>()?.timestamp?.let { ts -> now.isAfter(ts.plus(graceperiode)) } ?: false
39+
else -> false
40+
}
41+
42+
43+
fun NonEmptyList<Bekreftelse>.shouldCreateNewBekreftelse(
44+
now: Instant,
45+
interval: Duration,
46+
tilgjengeligOffset: Duration
47+
): Boolean =
2548
(size < MAKS_ANTALL_UTSTEENDE_BEKREFTELSER)
2649
.also { underGrense ->
2750
if (!underGrense) {
2851
maksAntallLogger.warn("Maks antall bekreftelser er nådd!")
2952
}
3053
} &&
31-
maxBy { it.gjelderTil }
32-
.let {
33-
now.isAfter(it.gjelderTil.plus(interval.minus(tilgjengeligOffset)))
34-
}
54+
maxBy { it.gjelderTil }
55+
.let {
56+
now.isAfter(it.gjelderTil.plus(interval.minus(tilgjengeligOffset)))
57+
}
3558

3659

3760

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package no.nav.paw.bekreftelsetjeneste.tilstand
2+
3+
import java.time.Instant
4+
import java.util.*
5+
6+
@JvmRecord
7+
data class PeriodeInfo(
8+
val periodeId: UUID,
9+
val identitetsnummer: String,
10+
val arbeidsoekerId: Long,
11+
val recordKey: Long,
12+
val startet: Instant,
13+
val avsluttet: Instant?
14+
) {
15+
val erAvsluttet: Boolean
16+
get() = avsluttet != null
17+
}

Diff for: apps/bekreftelse-tjeneste/src/main/kotlin/no/nav/paw/bekreftelsetjeneste/tilstand/RegisterInstillinger.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fun fristForNesteBekreftelse(forrige: Instant, interval: Duration): Instant {
1313
}
1414

1515
fun Bekreftelse.gjenstaendeGraceperiode(timestamp: Instant, graceperiode: Duration): Duration {
16-
val utvidetGjelderTil = fristUtloept?.plus(graceperiode) ?: gjelderTil.plus(graceperiode)
16+
val utvidetGjelderTil = tilstand<VenterSvar>()?.timestamp?.plus(graceperiode) ?: gjelderTil.plus(graceperiode)
1717

1818
return if (timestamp.isAfter(utvidetGjelderTil)) {
1919
Duration.ZERO

0 commit comments

Comments
 (0)