Skip to content

Commit 20e121e

Browse files
committed
Kjør jobb for å migrere digitale behovsmeldinger til V2
1 parent 5eb3f0e commit 20e121e

File tree

7 files changed

+130
-4
lines changed

7 files changed

+130
-4
lines changed

.github/workflows/deploy-dev.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
- "CODEOWNERS"
1010
branches:
1111
- main
12-
- sunset-v1
12+
- endepunkt-migrering-v2
1313

1414
jobs:
1515
build:

app/src/main/kotlin/no/nav/hjelpemidler/soknad/db/Application.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package no.nav.hjelpemidler.soknad.db
22

3+
import io.github.oshai.kotlinlogging.KotlinLogging
34
import io.ktor.http.ContentType
45
import io.ktor.serialization.jackson.JacksonConverter
56
import io.ktor.server.application.Application
@@ -16,6 +17,10 @@ import io.ktor.server.request.path
1617
import io.ktor.server.resources.Resources
1718
import io.ktor.server.routing.route
1819
import io.ktor.server.routing.routing
20+
import kotlinx.coroutines.Dispatchers
21+
import kotlinx.coroutines.delay
22+
import kotlinx.coroutines.launch
23+
import kotlinx.coroutines.runBlocking
1924
import no.nav.hjelpemidler.configuration.Environment
2025
import no.nav.hjelpemidler.database.PostgreSQL
2126
import no.nav.hjelpemidler.database.createDataSource
@@ -30,6 +35,11 @@ import no.nav.tms.token.support.azure.validation.azure
3035
import no.nav.tms.token.support.tokenx.validation.TokenXAuthenticator
3136
import no.nav.tms.token.support.tokenx.validation.tokenX
3237
import org.slf4j.event.Level
38+
import java.util.Timer
39+
import kotlin.concurrent.schedule
40+
import kotlin.system.measureTimeMillis
41+
42+
private val logg = KotlinLogging.logger { }
3343

3444
fun main() {
3545
embeddedServer(Netty, Configuration.PORT, module = Application::module).start(wait = true)
@@ -80,6 +90,8 @@ fun Application.module() {
8090
}
8191
}
8292
}
93+
94+
startDataMigrering(database, serviceContext)
8395
}
8496

8597
fun Application.felles() {
@@ -93,3 +105,24 @@ fun Application.felles() {
93105
}
94106
feilmelding()
95107
}
108+
109+
private fun startDataMigrering(database: Database, serviceContext: ServiceContext) {
110+
val timer = Timer("data-migrering-task", true)
111+
112+
timer.schedule(delay = 10_000) {
113+
runBlocking(Dispatchers.IO) {
114+
launch {
115+
var antallMigrert = 1
116+
while (antallMigrert > 0) {
117+
logg.info { "Kjører datamigreringsbatch." }
118+
val tidsbrukMs = measureTimeMillis {
119+
antallMigrert = serviceContext.søknadService.migrerTilDataV2()
120+
}
121+
logg.info { "Antall migrert: $antallMigrert (${tidsbrukMs}ms)" }
122+
delay(1_000)
123+
}
124+
logg.info { "Datamigrering ferdig." }
125+
}
126+
}
127+
}
128+
}

app/src/main/kotlin/no/nav/hjelpemidler/soknad/db/soknad/SøknadApi.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fun Route.søknadApi(
3434

3535
get<Søknader.SøknadId> {
3636
val søknadId = it.søknadId
37+
logg.info { "Kall til Søknader.SøknadId oppdaget." }
3738
val søknad = transaction { søknadStore.finnSøknad(søknadId, it.inkluderData) }
3839
if (søknad == null) {
3940
logg.info { "Fant ikke søknad med søknadId: $søknadId" }

app/src/main/kotlin/no/nav/hjelpemidler/soknad/db/soknad/SøknadService.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ class SøknadService(private val transaction: Transaction) {
4747
}
4848
}
4949

50+
suspend fun migrerTilDataV2(): Int {
51+
return transaction {
52+
try {
53+
søknadStore.migrerDataTilV2()
54+
} catch (e: Exception) {
55+
logg.error(e) { "Migrering til data_v2 feilet." }
56+
0
57+
}
58+
}
59+
}
60+
5061
suspend fun finnSak(søknadId: BehovsmeldingId): Fagsak? {
5162
return transaction {
5263
hotsakStore.finnSak(søknadId) ?: infotrygdStore.finnSak(søknadId)

app/src/main/kotlin/no/nav/hjelpemidler/soknad/db/store/SøknadStore.kt

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
package no.nav.hjelpemidler.soknad.db.store
22

33
import com.fasterxml.jackson.databind.JsonNode
4+
import com.fasterxml.jackson.module.kotlin.convertValue
45
import io.github.oshai.kotlinlogging.KotlinLogging
56
import kotlinx.coroutines.Dispatchers
67
import kotlinx.coroutines.runBlocking
78
import no.nav.hjelpemidler.behovsmeldingsmodell.BehovsmeldingStatus
9+
import no.nav.hjelpemidler.behovsmeldingsmodell.BehovsmeldingType
810
import no.nav.hjelpemidler.behovsmeldingsmodell.Behovsmeldingsgrunnlag
911
import no.nav.hjelpemidler.behovsmeldingsmodell.InnsenderbehovsmeldingMetadataDto
1012
import no.nav.hjelpemidler.behovsmeldingsmodell.SøknadDto
1113
import no.nav.hjelpemidler.behovsmeldingsmodell.v1.Behovsmelding
14+
import no.nav.hjelpemidler.behovsmeldingsmodell.v1.Brukerpassbytte
1215
import no.nav.hjelpemidler.behovsmeldingsmodell.v2.Innsenderbehovsmelding
16+
import no.nav.hjelpemidler.behovsmeldingsmodell.v2.mapping.tilBrukerpassbytteV2
1317
import no.nav.hjelpemidler.behovsmeldingsmodell.v2.mapping.tilInnsenderbehovsmeldingV2
1418
import no.nav.hjelpemidler.collections.enumSetOf
1519
import no.nav.hjelpemidler.collections.toStringArray
@@ -19,6 +23,7 @@ import no.nav.hjelpemidler.database.Row
1923
import no.nav.hjelpemidler.database.Store
2024
import no.nav.hjelpemidler.database.pgJsonbOf
2125
import no.nav.hjelpemidler.database.sql.Sql
26+
import no.nav.hjelpemidler.domain.person.Fødselsnummer
2227
import no.nav.hjelpemidler.http.slack.SlackClient
2328
import no.nav.hjelpemidler.http.slack.slackIconEmoji
2429
import no.nav.hjelpemidler.serialization.jackson.jsonMapper
@@ -33,6 +38,7 @@ import no.nav.hjelpemidler.soknad.db.metrics.StatusTemporal
3338
import java.math.BigInteger
3439
import java.time.DayOfWeek
3540
import java.time.Instant
41+
import java.time.LocalDate
3642
import java.time.LocalDateTime
3743
import java.time.ZoneId
3844
import java.util.UUID
@@ -413,6 +419,80 @@ class SøknadStore(private val tx: JdbcOperations, private val slackClient: Slac
413419
).actualRowCount
414420
}
415421

422+
fun migrerDataTilV2(): Int {
423+
424+
data class Data(
425+
val id: UUID,
426+
val data: JsonNode,
427+
val fnrInnsender: Fødselsnummer,
428+
val datoOpprettet: LocalDate,
429+
)
430+
431+
val behovsmeldingerV1 = tx.list(
432+
"""
433+
SELECT soknads_id, data, fnr_innsender, created
434+
FROM v1_soknad
435+
WHERE er_digital = true AND data_v2 IS NULL AND data IS NOT NULL
436+
FOR UPDATE SKIP LOCKED
437+
LIMIT 100
438+
""".trimIndent(),
439+
mapOf(),
440+
{ row ->
441+
val id = row.uuid("soknads_id")
442+
logg.info { "Klargjør $id for migrering." }
443+
Data(
444+
id = id,
445+
data = row.json<JsonNode>("data"),
446+
fnrInnsender = Fødselsnummer(row.string("fnr_innsender")),
447+
datoOpprettet = row.localDate("created")
448+
)
449+
},
450+
)
451+
452+
var count = 0
453+
behovsmeldingerV1.forEach { (id, data, fnrInnsender, datoOpprettet) ->
454+
logg.info { "Migrerer til data_v2 for behovsmelding '$id'" }
455+
val typeNode = data["behovsmeldingType"]
456+
val type = if (typeNode == null || typeNode.isNull()) {
457+
BehovsmeldingType.SØKNAD
458+
} else {
459+
BehovsmeldingType.valueOf(
460+
typeNode.asText("SØKNAD")
461+
)
462+
}
463+
464+
logg.info { "$id har type ${type.name}" }
465+
466+
val dataV2 = try {
467+
when (type) {
468+
BehovsmeldingType.BRUKERPASSBYTTE -> tilBrukerpassbytteV2(
469+
v1 = jsonMapper.convertValue<Brukerpassbytte>(data["brukerpassbytte"]),
470+
fnr = fnrInnsender,
471+
)
472+
473+
else -> tilInnsenderbehovsmeldingV2(jsonMapper.convertValue<Behovsmelding>(data), datoOpprettet)
474+
}
475+
} catch (e: Exception) {
476+
logg.error(e) { "Migrering til V2 feilet for $id. Skipper." }
477+
return@forEach
478+
}
479+
480+
logg.info { "Mappet $id til v2" }
481+
482+
tx.update(
483+
"""
484+
UPDATE v1_soknad SET data_v2 = :dataV2 WHERE soknads_id = :id
485+
""".trimIndent(),
486+
mapOf("id" to id, "dataV2" to pgJsonbOf(dataV2)),
487+
)
488+
489+
logg.info { "Lagret data_v2 for $id" }
490+
count++
491+
}
492+
493+
return count
494+
}
495+
416496
fun lagrePapirsøknad(grunnlag: Behovsmeldingsgrunnlag.Papir): Int {
417497
lagreStatus(grunnlag.søknadId, grunnlag.status)
418498
return tx.update(

behovsmeldingsmodell/src/main/kotlin/no/nav/hjelpemidler/behovsmeldingsmodell/v2/mapping/BrukerpassbytteMapper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fun tilBrukerpassbytteV2(v1: no.nav.hjelpemidler.behovsmeldingsmodell.v1.Brukerp
3131
hmsArtNr = v1.hjelpemiddel.artnr,
3232
artikkelnavn = v1.hjelpemiddel.navn,
3333
iso6Tittel = v1.hjelpemiddel.kategori,
34-
iso6 = v1.hjelpemiddel.kategorinummer?.let { Iso6(it) },
34+
iso6 = v1.hjelpemiddel.kategorinummer?.let { Iso6(it.take(6)) },
3535
)
3636

3737
return Brukerpassbytte(

behovsmeldingsmodell/src/main/kotlin/no/nav/hjelpemidler/behovsmeldingsmodell/v2/mapping/InnsenderbehovsmeldingMapper.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,15 @@ import no.nav.hjelpemidler.behovsmeldingsmodell.v2.Utlevertinfo
5151
import no.nav.hjelpemidler.behovsmeldingsmodell.v2.Varsel
5252
import no.nav.hjelpemidler.behovsmeldingsmodell.v2.Varseltype
5353
import no.nav.hjelpemidler.behovsmeldingsmodell.ÅrsakForAntall
54+
import java.time.LocalDate
5455

55-
fun tilInnsenderbehovsmeldingV2(v1: Behovsmelding): Innsenderbehovsmelding {
56+
fun tilInnsenderbehovsmeldingV2(v1: Behovsmelding, defaultDato: LocalDate? = null): Innsenderbehovsmelding {
5657
val id = v1.id ?: error("Behovsmelding v1 mangler id")
5758
val v1Bruker = v1.søknad?.bruker ?: error("Behovsmelding $id mangler søknad")
5859
return Innsenderbehovsmelding(
5960
id = id,
6061
type = v1.behovsmeldingType,
61-
innsendingsdato = v1.søknad.dato ?: error("Behovsmelding $id mangler dato"),
62+
innsendingsdato = v1.søknad.dato ?: defaultDato ?:error("Behovsmelding $id mangler dato"),
6263
bruker = Bruker(
6364
fnr = v1Bruker.fnr,
6465
navn = v1Bruker.navn,

0 commit comments

Comments
 (0)