Skip to content

Commit 7118501

Browse files
committed
Utvidet med kall til api-inngang, utbedret database-logikk, lagt til utvidede tester
1 parent b7c2fe9 commit 7118501

30 files changed

+696
-108
lines changed

apps/api-start-stopp-perioder/nais/nais-dev.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ spec:
6565
- application: arbeidssokerregistrering
6666
- application: arbeidssokerregistrering-for-veileder
6767
- application: aia-backend
68+
- application: paw-arbeidssoekere-synk-jobb
6869
outbound:
6970
rules:
70-
- application: poao-tilgang
71-
namespace: poao
7271
- application: paw-kafka-key-generator
73-
namespace: paw
7472
- application: paw-tilgangskontroll
73+
- application: poao-tilgang
74+
namespace: poao
7575
external:
7676
- host: pdl-api.dev-fss-pub.nais.io
7777

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"request": {
3+
"method": "POST",
4+
"urlPathPattern": "/api/v2/arbeidssoker/periode",
5+
"bodyPatterns": [
6+
{
7+
"matchesJsonPath": "$[?(@.identitetsnummer == '01017012345')]"
8+
}
9+
]
10+
},
11+
"response": {
12+
"status": 204,
13+
"headers": {
14+
"Content-Type": "application/json"
15+
}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"request": {
3+
"method": "POST",
4+
"urlPathPattern": "/api/v2/arbeidssoker/periode",
5+
"bodyPatterns": [
6+
{
7+
"matchesJsonPath": "$[?(@.identitetsnummer == '02017012345')]"
8+
}
9+
]
10+
},
11+
"response": {
12+
"status": 204,
13+
"headers": {
14+
"Content-Type": "application/json"
15+
}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"request": {
3+
"method": "POST",
4+
"urlPathPattern": "/api/v2/arbeidssoker/periode",
5+
"bodyPatterns": [
6+
{
7+
"matchesJsonPath": "$[?(@.identitetsnummer == '03017012345')]"
8+
}
9+
]
10+
},
11+
"response": {
12+
"status": 403,
13+
"headers": {
14+
"Content-Type": "application/json"
15+
},
16+
"jsonBody": {
17+
"melding": "Å nei du",
18+
"feilKode": "IKKE_TILGANG",
19+
"aarsakTilAvvisning": {
20+
"detaljer": [
21+
"ANSATT_IKKE_TILGANG"
22+
],
23+
"regler": [
24+
{
25+
"id": "IKKE_TILGANG",
26+
"beskrivelse": "Ansatt har ikke tilgang"
27+
}
28+
]
29+
}
30+
}
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"request": {
3+
"method": "POST",
4+
"urlPathPattern": "/api/v2/arbeidssoker/periode",
5+
"bodyPatterns": [
6+
{
7+
"matchesJsonPath": "$[?(@.identitetsnummer == '04017012345')]"
8+
}
9+
]
10+
},
11+
"response": {
12+
"status": 400,
13+
"headers": {
14+
"Content-Type": "application/json"
15+
},
16+
"jsonBody": {
17+
"melding": "Ikke prøv deg",
18+
"feilKode": "AVVIST",
19+
"aarsakTilAvvisning": {
20+
"detaljer": [
21+
"UGYLDIG_FEILRETTING"
22+
],
23+
"regler": [
24+
{
25+
"id": "ENDRE_FOR_ANNEN_BRUKER",
26+
"beskrivelse": "Ugyldig feilretting"
27+
}
28+
]
29+
}
30+
}
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"request": {
3+
"method": "POST",
4+
"urlPathPattern": "/api/v2/arbeidssoker/periode",
5+
"bodyPatterns": [
6+
{
7+
"matchesJsonPath": "$[?(@.identitetsnummer == '03017012345')]"
8+
}
9+
]
10+
},
11+
"response": {
12+
"status": 500,
13+
"headers": {
14+
"Content-Type": "application/json"
15+
},
16+
"jsonBody": {
17+
"melding": "Dette gikk skikkelig dårlig",
18+
"feilKode": "UKJENT_FEIL"
19+
}
20+
}
21+
}

jobs/arbeidssoekere-synk-jobb/README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,11 @@ konfig-filen.
1313
Informasjon om secrets fra [NAIS docs](https://docs.nais.io/services/secrets/).
1414

1515
```shell
16-
kubectl create secret generic paw-arbeidssoekere-csv --from-file=v1.csv=/tmp/paw-arbeidssoekere-csv/v1.csv
16+
kubectl create secret generic paw-arbeidssoekere-synk-jobb-csv --from-file=v1.csv=/tmp/paw-arbeidssoekere-synk-jobb-csv-v1.csv
17+
```
18+
19+
For å endre secret må den slettes og skapes på nytt.
20+
21+
```shell
22+
kubectl delete secret paw-arbeidssoekere-synk-jobb-csv
1723
```

jobs/arbeidssoekere-synk-jobb/build.gradle.kts

+7
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,19 @@ dependencies {
1212
implementation(project(":lib:logging"))
1313
implementation(project(":lib:database"))
1414
implementation(project(":lib:http-client-utils"))
15+
implementation(project(":lib:serialization"))
16+
17+
// Ktor
18+
implementation(libs.ktor.serialization.jackson)
19+
implementation(libs.ktor.client.cio)
20+
implementation(libs.ktor.client.contentNegotiation)
1521

1622
// Logging
1723
implementation(libs.nav.common.log)
1824

1925
// Jackson
2026
implementation(libs.jackson.kotlin)
27+
implementation(libs.jackson.datatypeJsr310)
2128
implementation(libs.jackson.dataformat.csv)
2229

2330
// Database

jobs/arbeidssoekere-synk-jobb/nais/nais-dev.yaml

+7-3
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ spec:
1414
secureLogs:
1515
enabled: true
1616
filesFrom:
17-
- secret: paw-arbeidssoekere-csv
18-
mountPath: /var/run/secrets/paw-arbeidssoekere-csv
17+
- secret: paw-arbeidssoekere-synk-jobb-csv
18+
mountPath: /var/run/secrets/paw-arbeidssoekere-synk-jobb-csv
1919
gcp:
2020
sqlInstances:
2121
- type: POSTGRES_17
2222
tier: db-f1-micro
2323
databases:
24-
- name: paw_arbeidssoekere_synk_jobb
24+
- name: pawarbeidssoekeresynk
25+
accessPolicy:
26+
outbound:
27+
rules:
28+
- application: paw-arbeidssokerregisteret-api-inngang

jobs/arbeidssoekere-synk-jobb/src/main/kotlin/no/nav/paw/arbeidssoeker/synk/Job.kt

+17-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ package no.nav.paw.arbeidssoeker.synk
22

33
import no.nav.paw.arbeidssoeker.synk.config.JOB_CONFIG
44
import no.nav.paw.arbeidssoeker.synk.config.JobConfig
5+
import no.nav.paw.arbeidssoeker.synk.consumer.InngangHttpConsumer
56
import no.nav.paw.arbeidssoeker.synk.repository.ArbeidssoekerSynkRepository
67
import no.nav.paw.arbeidssoeker.synk.service.ArbeidssoekerSynkService
8+
import no.nav.paw.arbeidssoeker.synk.utils.flywayMigrate
9+
import no.nav.paw.client.config.AZURE_M2M_CONFIG
10+
import no.nav.paw.client.config.AzureAdM2MConfig
11+
import no.nav.paw.client.factory.createAzureAdM2MTokenClient
712
import no.nav.paw.config.env.appNameOrDefaultForLocal
813
import no.nav.paw.config.hoplite.loadNaisOrLocalConfiguration
914
import no.nav.paw.database.config.DATABASE_CONFIG
@@ -15,19 +20,27 @@ import java.nio.file.Paths
1520

1621
fun main() {
1722
val logger = buildApplicationLogger
23+
1824
val jobConfig = loadNaisOrLocalConfiguration<JobConfig>(JOB_CONFIG)
1925
val databaseConfig = loadNaisOrLocalConfiguration<DatabaseConfig>(DATABASE_CONFIG)
26+
val azureAdM2MConfig = loadNaisOrLocalConfiguration<AzureAdM2MConfig>(AZURE_M2M_CONFIG)
27+
val name = jobConfig.runtimeEnvironment.appNameOrDefaultForLocal(default = "local-job")
28+
29+
logger.info("Initialiserer $name")
2030

2131
val dataSource = createHikariDataSource(databaseConfig)
32+
dataSource.flywayMigrate()
2233
Database.connect(dataSource)
34+
val azureAdM2MTokenClient = createAzureAdM2MTokenClient(jobConfig.runtimeEnvironment, azureAdM2MConfig)
2335
val arbeidssoekerSynkRepository = ArbeidssoekerSynkRepository()
24-
val arbeidssoekerSynkService = ArbeidssoekerSynkService(arbeidssoekerSynkRepository)
25-
26-
val name = jobConfig.runtimeEnvironment.appNameOrDefaultForLocal(default = "local-job")
36+
val inngangHttpConsumer = InngangHttpConsumer(jobConfig.apiInngangBaseUrl) {
37+
azureAdM2MTokenClient.createMachineToMachineToken(jobConfig.apiInngangScope)
38+
}
39+
val arbeidssoekerSynkService = ArbeidssoekerSynkService(arbeidssoekerSynkRepository, inngangHttpConsumer)
2740

2841
try {
2942
logger.info("Starter $name")
30-
arbeidssoekerSynkService.synkArbeidssoekere(Paths.get(jobConfig.mountPath))
43+
arbeidssoekerSynkService.synkArbeidssoekere(Paths.get(jobConfig.syncFilePath))
3144
} catch (throwable: Throwable) {
3245
logger.error("Kjøring feilet", throwable)
3346
} finally {

jobs/arbeidssoekere-synk-jobb/src/main/kotlin/no/nav/paw/arbeidssoeker/synk/config/JobConfig.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import no.nav.paw.config.env.currentRuntimeEnvironment
66
const val JOB_CONFIG = "job_config.toml"
77

88
data class JobConfig(
9-
val mountPath: String,
9+
val syncFilePath: String,
10+
val apiInngangBaseUrl: String,
11+
val apiInngangScope: String,
1012
val runtimeEnvironment: RuntimeEnvironment = currentRuntimeEnvironment
1113
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package no.nav.paw.arbeidssoeker.synk.consumer
2+
3+
import io.ktor.client.HttpClient
4+
import io.ktor.client.request.HttpRequestBuilder
5+
import io.ktor.client.request.bearerAuth
6+
import io.ktor.client.request.put
7+
import io.ktor.client.request.setBody
8+
import io.ktor.client.statement.HttpResponse
9+
import io.ktor.http.ContentType
10+
import io.ktor.http.contentType
11+
import kotlinx.coroutines.runBlocking
12+
import no.nav.paw.arbeidssoeker.synk.model.OpprettPeriodeRequest
13+
import no.nav.paw.client.factory.createHttpClient
14+
15+
class InngangHttpConsumer(
16+
baseUrl: String,
17+
private val httpClient: HttpClient = createHttpClient(),
18+
private val getAccessToken: () -> String
19+
) {
20+
private val periodeUrl = "$baseUrl/api/v2/arbeidssoker/periode"
21+
22+
fun opprettPeriode(request: OpprettPeriodeRequest): HttpResponse = runBlocking {
23+
httpClient.put(periodeUrl) {
24+
bearerAuth(getAccessToken())
25+
setJsonBody(request)
26+
}
27+
}
28+
29+
private inline fun <reified T> HttpRequestBuilder.setJsonBody(body: T) {
30+
contentType(ContentType.Application.Json)
31+
setBody(body)
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
11
package no.nav.paw.arbeidssoeker.synk.model
22

3-
data class Arbeidssoeker(val identitetsnummer: String)
3+
import java.time.Instant
4+
5+
data class Arbeidssoeker(
6+
val identitetsnummer: String,
7+
val originalStartTidspunkt: Instant,
8+
val forhaandsgodkjentAvAnsatt: Boolean = false,
9+
)
10+
11+
data class VersjonertArbeidssoeker(
12+
val version: String,
13+
val identitetsnummer: String,
14+
val originalStartTidspunkt: Instant,
15+
val forhaandsgodkjentAvAnsatt: Boolean = false,
16+
)
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package no.nav.paw.arbeidssoeker.synk.model
22

3-
import org.jetbrains.exposed.sql.ResultRow
43
import java.time.Instant
54

65
data class ArbeidssoekereSynkRow(
@@ -10,12 +9,3 @@ data class ArbeidssoekereSynkRow(
109
val inserted: Instant,
1110
val updated: Instant? = null
1211
)
13-
14-
fun ResultRow.asArbeidssoekereSynkRow(): ArbeidssoekereSynkRow =
15-
ArbeidssoekereSynkRow(
16-
version = this[ArbeidssoekereSynkTable.version],
17-
identitetsnummer = this[ArbeidssoekereSynkTable.identitetsnummer],
18-
status = this[ArbeidssoekereSynkTable.status],
19-
inserted = this[ArbeidssoekereSynkTable.inserted],
20-
updated = this[ArbeidssoekereSynkTable.updated]
21-
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package no.nav.paw.arbeidssoeker.synk.model
2+
3+
import io.ktor.http.HttpStatusCode
4+
import io.ktor.http.isSuccess
5+
import org.jetbrains.exposed.sql.ResultRow
6+
import java.time.Duration
7+
import java.time.Instant
8+
9+
fun Arbeidssoeker.asVersioned(version: String): VersjonertArbeidssoeker = VersjonertArbeidssoeker(
10+
version = version,
11+
identitetsnummer = identitetsnummer,
12+
originalStartTidspunkt = originalStartTidspunkt,
13+
forhaandsgodkjentAvAnsatt = forhaandsgodkjentAvAnsatt
14+
)
15+
16+
fun VersjonertArbeidssoeker.asOpprettPeriodeRequest(): OpprettPeriodeRequest = OpprettPeriodeRequest(
17+
identitetsnummer = this.identitetsnummer,
18+
periodeTilstand = PeriodeTilstand.STARTET,
19+
registreringForhaandsGodkjentAvAnsatt = this.forhaandsgodkjentAvAnsatt,
20+
feilretting = Feilretting(
21+
feilType = FeilType.FeilTidspunkt,
22+
melding = "Arbeidssøker migrert fra Arena",
23+
tidspunkt = this.originalStartTidspunkt
24+
)
25+
)
26+
27+
fun ResultRow.asArbeidssoekereSynkRow(): ArbeidssoekereSynkRow = ArbeidssoekereSynkRow(
28+
version = this[ArbeidssoekereSynkTable.version],
29+
identitetsnummer = this[ArbeidssoekereSynkTable.identitetsnummer],
30+
status = this[ArbeidssoekereSynkTable.status],
31+
inserted = this[ArbeidssoekereSynkTable.inserted],
32+
updated = this[ArbeidssoekereSynkTable.updated]
33+
)
34+
35+
fun Instant.millisSince(): Long = Duration.between(this, Instant.now()).toMillis()
36+
37+
fun Int.isNotSuccess(): Boolean = !HttpStatusCode.fromValue(this).isSuccess()

0 commit comments

Comments
 (0)