Skip to content

Commit 5ef2949

Browse files
authored
Merge pull request #138 from navikt/dev/utvide-synk-jobb-for-arbeidssoekere
Dev/utvide synk jobb for arbeidssoekere
2 parents d2fb86a + 30a96c3 commit 5ef2949

39 files changed

+960
-95
lines changed

.github/workflows/arbeidssoekere-synk-jobb.yaml

-7
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,7 @@ on:
77
- dev/*
88
paths:
99
- 'jobs/arbeidssoekere-synk-jobb/**'
10-
- 'lib/**'
11-
- 'domain/**'
1210
- 'arbeidssoekere-synk-jobb.yaml'
13-
- 'gradle/**'
14-
- 'settings.gradle.kts'
15-
- 'gradle.properties'
16-
- 'gradlew'
17-
- 'gradlew.bat'
1811

1912
env:
2013
MODULE: arbeidssoekere-synk-jobb
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+
}

docker/postgres/config/initdb/postgres-init.sql

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ create user kafka_key_generator with password 'Paw1234';
22
create user bekreftelse_api with password 'Paw1234';
33
create user pawkafkakeymaintenance with password 'Paw1234';
44
create user hendelselogg_backup with password 'Paw1234';
5+
create user paw_arbeidssoekere_synk_jobb with password 'Paw1234';
56

67
create database pawkafkakeys with owner kafka_key_generator;
78
create database bekreftelser with owner bekreftelse_api;
89
create database pawkafkakeymaintenance with owner pawkafkakeymaintenance;
9-
create database hendelselogg_backup with owner hendelselogg_backup;
10+
create database hendelselogg_backup with owner hendelselogg_backup;
11+
create database paw_arbeidssoekere_synk_jobb with owner paw_arbeidssoekere_synk_jobb;

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

+22
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,38 @@ dependencies {
1010
// Project
1111
implementation(project(":lib:hoplite-config"))
1212
implementation(project(":lib:logging"))
13+
implementation(project(":lib:database"))
14+
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)
1321

1422
// Logging
1523
implementation(libs.nav.common.log)
1624

1725
// Jackson
1826
implementation(libs.jackson.kotlin)
27+
implementation(libs.jackson.datatypeJsr310)
1928
implementation(libs.jackson.dataformat.csv)
2029

30+
// Instrumentation
31+
implementation(libs.opentelemetry.api)
32+
implementation(libs.opentelemetry.annotations)
33+
34+
// Database
35+
implementation(libs.exposed.jdbc)
36+
implementation(libs.exposed.javaTime)
37+
implementation(libs.database.hikari.connectionPool)
38+
implementation(libs.database.postgres.driver)
39+
implementation(libs.database.flyway.postgres)
40+
2141
// Test
2242
testImplementation(libs.bundles.testLibsWithUnitTesting)
43+
testImplementation(libs.ktor.client.mock)
44+
testImplementation(libs.test.testContainers.postgresql)
2345
}
2446

2547
java {

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

+19-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@ spec:
1313
memory: 256Mi
1414
secureLogs:
1515
enabled: true
16+
observability:
17+
autoInstrumentation:
18+
enabled: true
19+
runtime: java
20+
azure:
21+
application:
22+
enabled: true
1623
filesFrom:
17-
- secret: paw-arbeidssoekere-csv
18-
mountPath: /var/run/secrets/paw-arbeidssoekere-csv
24+
- secret: paw-arbeidssoekere-synk-jobb-csv
25+
mountPath: /var/run/secrets/paw-arbeidssoekere-synk-jobb-csv
26+
gcp:
27+
sqlInstances:
28+
- type: POSTGRES_17
29+
tier: db-f1-micro
30+
databases:
31+
- name: pawarbeidssoekeresynk
32+
accessPolicy:
33+
outbound:
34+
rules:
35+
- application: paw-arbeidssokerregisteret-api-inngang

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

+32-9
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,47 @@ 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.service.SyncService
6-
import no.nav.paw.config.env.appNameOrDefaultForLocal
5+
import no.nav.paw.arbeidssoeker.synk.consumer.InngangHttpConsumer
6+
import no.nav.paw.arbeidssoeker.synk.repository.ArbeidssoekerSynkRepository
7+
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.hoplite.loadNaisOrLocalConfiguration
13+
import no.nav.paw.database.config.DATABASE_CONFIG
14+
import no.nav.paw.database.config.DatabaseConfig
15+
import no.nav.paw.database.factory.createHikariDataSource
816
import no.nav.paw.logging.logger.buildApplicationLogger
17+
import org.jetbrains.exposed.sql.Database
18+
import java.nio.file.Paths
919

1020
fun main() {
1121
val logger = buildApplicationLogger
12-
val jobConfig = loadNaisOrLocalConfiguration<JobConfig>(JOB_CONFIG)
13-
val syncService = SyncService(jobConfig)
14-
15-
val name = jobConfig.runtimeEnvironment.appNameOrDefaultForLocal(default = "local-job")
1622

1723
try {
18-
logger.info("Starter $name")
19-
syncService.syncArbeidssoekere()
24+
val jobConfig = loadNaisOrLocalConfiguration<JobConfig>(JOB_CONFIG)
25+
val databaseConfig = loadNaisOrLocalConfiguration<DatabaseConfig>(DATABASE_CONFIG)
26+
val azureAdM2MConfig = loadNaisOrLocalConfiguration<AzureAdM2MConfig>(AZURE_M2M_CONFIG)
27+
28+
logger.info("Initialiserer jobb")
29+
30+
val dataSource = createHikariDataSource(databaseConfig)
31+
dataSource.flywayMigrate()
32+
Database.connect(dataSource)
33+
val azureAdM2MTokenClient = createAzureAdM2MTokenClient(jobConfig.runtimeEnvironment, azureAdM2MConfig)
34+
val arbeidssoekerSynkRepository = ArbeidssoekerSynkRepository()
35+
val inngangHttpConsumer = InngangHttpConsumer(jobConfig.apiInngangBaseUrl) {
36+
azureAdM2MTokenClient.createMachineToMachineToken(jobConfig.apiInngangScope)
37+
}
38+
val arbeidssoekerSynkService =
39+
ArbeidssoekerSynkService(jobConfig, arbeidssoekerSynkRepository, inngangHttpConsumer)
40+
41+
logger.info("Starter jobb")
42+
arbeidssoekerSynkService.synkArbeidssoekere(Paths.get(jobConfig.syncFilePath))
2043
} catch (throwable: Throwable) {
2144
logger.error("Kjøring feilet", throwable)
2245
} finally {
23-
logger.info("Avslutter $name")
46+
logger.info("Avslutter jobb")
2447
}
2548
}

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ 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 markerForhaandsgodkjentAvAnsatt: Boolean,
11+
val apiInngangBaseUrl: String,
12+
val apiInngangScope: String,
1013
val runtimeEnvironment: RuntimeEnvironment = currentRuntimeEnvironment
1114
)
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,15 @@
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+
)
9+
10+
data class VersjonertArbeidssoeker(
11+
val version: String,
12+
val identitetsnummer: String,
13+
val originalStartTidspunkt: Instant,
14+
val forhaandsgodkjentAvAnsatt: Boolean = false,
15+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package no.nav.paw.arbeidssoeker.synk.model
2+
3+
import java.time.Instant
4+
5+
data class ArbeidssoekereSynkRow(
6+
val version: String,
7+
val identitetsnummer: String,
8+
val status: Int,
9+
val inserted: Instant,
10+
val updated: Instant? = null
11+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package no.nav.paw.arbeidssoeker.synk.model
2+
3+
import org.jetbrains.exposed.sql.Table
4+
import org.jetbrains.exposed.sql.javatime.timestamp
5+
6+
object ArbeidssoekereSynkTable : Table("arbeidssoekere_synk") {
7+
val version = varchar("version", 20)
8+
val identitetsnummer = varchar("identitetsnummer", 20)
9+
val status = integer("status")
10+
val inserted = timestamp("inserted")
11+
val updated = timestamp("updated")
12+
override val primaryKey: PrimaryKey = PrimaryKey(version, identitetsnummer)
13+
}

0 commit comments

Comments
 (0)