diff --git a/.github/workflows/master.yml b/.github/workflows/master-gcp.yml similarity index 81% rename from .github/workflows/master.yml rename to .github/workflows/master-gcp.yml index fe4f243f1..e53ed5b8a 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master-gcp.yml @@ -30,19 +30,21 @@ jobs: POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres steps: - - uses: actions/checkout@v1 - - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: - java-version: '17' + java-version: 17 + distribution: temurin + cache: gradle - name: Cache Gradle wrapper - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.gradle/wrapper key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle-wrapper- - name: Cache Gradle packages - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-cache-${{ hashFiles('build.gradle') }} @@ -55,7 +57,7 @@ jobs: ORG_GRADLE_PROJECT_githubPassword: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Login to GitHub Packages Docker Registry - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} @@ -69,10 +71,11 @@ jobs: name: Deploy to PREPROD needs: build runs-on: ubuntu-latest + permissions: + id-token: write steps: - - uses: actions/checkout@v1 - - uses: nais/deploy/actions/deploy@v1 + - uses: actions/checkout@v4 + - uses: nais/deploy/actions/deploy@v2 env: - APIKEY: ${{ secrets.NAIS_DEPLOY_APIKEY }} - CLUSTER: dev-fss - RESOURCE: deploy/dev.yaml + CLUSTER: dev-gcp + RESOURCE: deploy/dev-gcp.yaml diff --git a/README.md b/README.md index b90e9cd61..c5cf61a5b 100644 --- a/README.md +++ b/README.md @@ -79,16 +79,15 @@ SRVSYFOINNTEKTSMELDING_PASSWORD=dummy Prosjektet bruker en [Ktlint](https://ktlint.github.io/)-plugin for Gradle som håndhever kodestilregler. Nyttige kommandoer er: -- `gradle ktlintCheck` (sier ifra om brudd på kodestilreglene) -- `gradle ktlintFormat` (retter opp i brudd på kodestilreglene) +- `gradle lintKotlin` (sier ifra om brudd på kodestilreglene) +- `gradle formatKotlin` (retter opp i brudd på kodestilreglene) Det anbefales hver utvikler å konfigurere en pre-commit hook som automatisk sjekker endrede filer for brudd på kodestilreglene. Alternativt kan man sette opp automatisk formattering. Kommandoene for dette er: -- `gradle addKtlintCheckGitPreCommitHook` (automatisk sjekk) -- `gradle addKtlintFormatGitPreCommitHook` (automatisk formattering) +- `gradle installKotlinterPrePushHook` (automatisk formattering) -Les mer om pluginen [her](https://github.com/JLLeitschuh/ktlint-gradle). +Les mer om pluginen [her](https://github.com/jeremymailen/kotlinter-gradle). ## Database Applikasjonen bruker Postgres database med JPA grensesnitt OG et JDBC grensesnitt. Skjermbildet nedenfor viser samtlige diff --git a/build.gradle.kts b/build.gradle.kts index 7ae2c92e0..4adb1f91e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -50,7 +50,7 @@ plugins { kotlin("jvm") version "1.9.21" kotlin("plugin.serialization") version "1.9.21" id("com.github.ben-manes.versions") version "0.50.0" - id("org.jlleitschuh.gradle.ktlint") version "11.0.0" + id("org.jmailen.kotlinter") version "3.8.0" id("org.flywaydb.flyway") version "10.1.0" jacoco application diff --git a/deploy/dev-gcp.yaml b/deploy/dev-gcp.yaml new file mode 100644 index 000000000..48236528b --- /dev/null +++ b/deploy/dev-gcp.yaml @@ -0,0 +1,105 @@ +apiVersion: nais.io/v1alpha1 +kind: Application +metadata: + name: spinosaurus + namespace: helsearbeidsgiver + labels: + team: helsearbeidsgiver +spec: + ingresses: + - https://spinosaurus.intern.dev.nav.no + image: {{image}} + port: 8080 + prometheus: + enabled: false + path: /metrics + liveness: + failureThreshold: 3 + initialDelay: 60 + path: /health/is-alive + periodSeconds: 10 + timeout: 1 + readiness: + failureThreshold: 3 + initialDelay: 60 + path: /health/is-ready + periodSeconds: 10 + timeout: 1 + replicas: + max: 1 + min: 1 + resources: + limits: + memory: 1024Mi + requests: + cpu: 500m + memory: 386Mi + + secureLogs: + enabled: true + kafka: + pool: nav-dev + azure: + application: + enabled: true + + gcp: + sqlInstances: + - type: POSTGRES_11 + databases: + - name: spinosaurus + diskAutoresize: true + + accessPolicy: + outbound: + rules: + - application: helsearbeidsgiver-proxy + namespace: helsearbeidsgiver + cluster: dev-fss + external: + - host: data.brreg.no + - host: norg2.dev-fss-pub.nais.io + - host: oppgave-q1.dev-fss-pub.nais.io + - host: pdl-api.dev-fss-pub.nais.io + - host: dokarkiv.dev-fss-pub.nais.io + - host: saf.dev-fss-pub.nais.io + inbound: + rules: + - application: im-bro-spinn + - application: sparkel-dokumenter + namespace: tbd + + env: + - name: KOIN_PROFILE + value: "DEV" + - name: RUN_BACKGROUND_WORKERS + value: "true" + - name: KAFKA_JOARK_HENDELSE_TOPIC + value: "teamdokumenthandtering.aapen-dok-journalfoering-q1" + - name: KAFKA_UTSATT_OPPGAVE_TOPIC + value: "tbd.spre-oppgaver" + - name: DOKARKIV_URL + value: "https://dokarkiv.dev-fss-pub.nais.io/rest/journalpostapi/v1" + - name: OPPGAVEBEHANDLING_URL + value: "https://oppgave-q1.dev-fss-pub.nais.io/api/v1/oppgaver" + - name: PDL_URL + value: "https://pdl-api.dev-fss-pub.nais.io/graphql" + - name: NORG2_URL + value: https://helsearbeidsgiver-proxy.dev-fss-pub.nais.io/norg + - name: SAF_DOKUMENT_URL + value: "https://saf.dev-fss-pub.nais.io/rest" + - name: SAF_JOURNAL_URL + value: "https://saf.dev-fss-pub.nais.io/graphql" + - name: ENHETSREGISTERET_URL + value: "https://data.brreg.no/enhetsregisteret/api/underenheter/" + - name: DOKARKIV_SCOPE + value: api://dev-fss.teamdokumenthandtering.dokarkiv-q1/.default + - name: SAF_SCOPE + value: api://dev-fss.teamdokumenthandtering.saf-q1/.default + - name: OPPGAVE_SCOPE + value: api://dev-fss.oppgavehandtering.oppgave-q1/.default + - name: PDL_SCOPE + value: api://dev-fss.pdl.pdl-api/.default + - name: PROXY_SCOPE + value: api://dev-fss.helsearbeidsgiver.helsearbeidsgiver-proxy/.default + diff --git a/deploy/prod.yaml b/deploy/prod.yaml index f48eb8746..f385b9218 100644 --- a/deploy/prod.yaml +++ b/deploy/prod.yaml @@ -104,7 +104,7 @@ spec: - name: PDL_URL value: "https://pdl-api.nais.adeo.no/graphql" - name: NORG2_URL - value: "https://norg2.nais.adeo.no/norg2/api/v1" + value: "https://norg2.nais.adeo.no/norg2/api/v1/arbeidsfordeling/enheter/bestmatch" - name: SAF_DOKUMENT_URL value: "https://saf.intern.nav.no/rest" - name: SAF_JOURNAL_URL diff --git a/docker/local/Dockerfile b/docker/local/Dockerfile index ff53cf2e6..e8e4ce59b 100644 --- a/docker/local/Dockerfile +++ b/docker/local/Dockerfile @@ -1,4 +1,4 @@ -FROM postgres:12 +FROM postgres:14 RUN localedef -i nb_NO -c -f UTF-8 -A /usr/share/locale/locale.alias nb_NO.UTF-8 ENV LANG nb_NO.utf8 diff --git a/src/main/kotlin/no/nav/syfo/App.kt b/src/main/kotlin/no/nav/syfo/App.kt index 18fccdcf1..a28b8bf19 100644 --- a/src/main/kotlin/no/nav/syfo/App.kt +++ b/src/main/kotlin/no/nav/syfo/App.kt @@ -9,8 +9,6 @@ import io.ktor.server.netty.Netty import io.ktor.server.netty.NettyApplicationEngine import no.nav.helse.arbeidsgiver.bakgrunnsjobb.BakgrunnsjobbService import no.nav.helse.arbeidsgiver.kubernetes.KubernetesProbeManager -import no.nav.helse.arbeidsgiver.system.AppEnv -import no.nav.helse.arbeidsgiver.system.getEnvironment import no.nav.helse.arbeidsgiver.system.getString import no.nav.helsearbeidsgiver.utils.log.logger import no.nav.syfo.integration.kafka.UtsattOppgaveConsumer @@ -37,17 +35,20 @@ class SpinnApplication(val port: Int = 8080) : KoinComponent { private var webserver: NettyApplicationEngine? = null private var appConfig: HoconApplicationConfig = HoconApplicationConfig(ConfigFactory.load()) - private val runtimeEnvironment = appConfig.getEnvironment() + private val runtimeEnvironment = appConfig.getString("koin.profile") fun start() { - if (runtimeEnvironment == AppEnv.PREPROD || runtimeEnvironment == AppEnv.PROD) { + logger.info("Environment: $runtimeEnvironment") + if (runtimeEnvironment != "LOCAL" && runtimeEnvironment != "TEST") { logger.info("Sover i 30s i påvente av SQL proxy sidecar") Thread.sleep(30000) } startKoin { modules(selectModuleBasedOnProfile(appConfig)) } migrateDatabase() - configAndStartBackgroundWorkers() - startKafkaConsumer() + if (System.getenv("NAIS_CLUSTER_NAME") != "prod-gcp") { + configAndStartBackgroundWorkers() + startKafkaConsumer() + } configAndStartWebserver() } diff --git a/src/main/kotlin/no/nav/syfo/client/OppgaveClient.kt b/src/main/kotlin/no/nav/syfo/client/OppgaveClient.kt index e6c281b6d..99fa72aa6 100644 --- a/src/main/kotlin/no/nav/syfo/client/OppgaveClient.kt +++ b/src/main/kotlin/no/nav/syfo/client/OppgaveClient.kt @@ -27,18 +27,18 @@ const val BEHANDLINGSTEMA_UTBETALING_TIL_BRUKER = "ab0458" const val BEHANDLINGSTYPE_UTLAND = "ae0106" const val BEHANDLINGSTYPE_NORMAL = "ab0061" -class OppgaveClient constructor( +class OppgaveClient( val oppgavebehndlingUrl: String, - val tokenConsumer: TokenConsumer, val httpClient: HttpClient, - val metrikk: Metrikk + val metrikk: Metrikk, + val getAccessToken: () -> String ) { private val logger = this.logger() private suspend fun opprettOppgave(opprettOppgaveRequest: OpprettOppgaveRequest): OpprettOppgaveResponse = retry("opprett_oppgave") { httpClient.post(oppgavebehndlingUrl) { contentType(ContentType.Application.Json) - this.header("Authorization", "Bearer ${tokenConsumer.token}") + this.header("Authorization", "Bearer ${getAccessToken()}") this.header("X-Correlation-ID", MdcUtils.getCallId()) body = opprettOppgaveRequest } @@ -49,7 +49,7 @@ class OppgaveClient constructor( val callId = MdcUtils.getCallId() logger.info("Henter oppgave med CallId $callId") httpClient.get(oppgavebehndlingUrl) { - this.header("Authorization", "Bearer ${tokenConsumer.token}") + this.header("Authorization", "Bearer ${getAccessToken()}") this.header("X-Correlation-ID", callId) parameter("tema", TEMA) parameter("oppgavetype", oppgavetype) diff --git a/src/main/kotlin/no/nav/syfo/client/norg/Norg2Client.kt b/src/main/kotlin/no/nav/syfo/client/norg/Norg2Client.kt index 434a4a6b7..9f0ac8f0f 100644 --- a/src/main/kotlin/no/nav/syfo/client/norg/Norg2Client.kt +++ b/src/main/kotlin/no/nav/syfo/client/norg/Norg2Client.kt @@ -7,7 +7,6 @@ import io.ktor.http.ContentType import io.ktor.http.contentType import io.ktor.http.withCharset import kotlinx.coroutines.runBlocking -import no.nav.helse.arbeidsgiver.integrasjoner.AccessTokenProvider import java.time.LocalDate /** @@ -22,20 +21,19 @@ import java.time.LocalDate */ open class Norg2Client( private val url: String, - private val stsClient: AccessTokenProvider, - private val httpClient: HttpClient + private val httpClient: HttpClient, + private val getAccessToken: () -> String ) { /** * Oppslag av informasjon om ruting av arbeidsoppgaver til enheter. */ open suspend fun hentAlleArbeidsfordelinger(request: ArbeidsfordelingRequest, callId: String?): List { - val stsToken = stsClient.getToken() return runBlocking { - httpClient.post>(url + "/arbeidsfordeling/enheter/bestmatch") { + httpClient.post>(url) { contentType(ContentType.Application.Json.withCharset(Charsets.UTF_8)) - header("Authorization", "Bearer $stsToken") header("X-Correlation-ID", callId) + header("Authorization", "Bearer ${getAccessToken()}") body = request } } diff --git a/src/main/kotlin/no/nav/syfo/integration/oauth2/OAuth2ClientPropertiesConfig.kt b/src/main/kotlin/no/nav/syfo/integration/oauth2/OAuth2ClientPropertiesConfig.kt index a9ced6191..e32a250f2 100644 --- a/src/main/kotlin/no/nav/syfo/integration/oauth2/OAuth2ClientPropertiesConfig.kt +++ b/src/main/kotlin/no/nav/syfo/integration/oauth2/OAuth2ClientPropertiesConfig.kt @@ -6,7 +6,7 @@ import no.nav.security.token.support.client.core.ClientAuthenticationProperties import no.nav.security.token.support.client.core.ClientProperties import no.nav.security.token.support.client.core.OAuth2GrantType import java.net.URI - +// TODO: Kan fjernes etter hvert, ligger som private funksjoner i DevKoinProfile (må verifiseres) class OAuth2ClientPropertiesConfig( applicationConfig: ApplicationConfig ) { @@ -19,7 +19,7 @@ class OAuth2ClientPropertiesConfig( URI(clientConfig.propertyToString("token_endpoint_url")), wellKnownUrl?.let { URI(it) }, OAuth2GrantType(clientConfig.propertyToString("grant_type")), - clientConfig.propertyToStringOrNull("scope")?.split(","), + clientConfig.propertyToStringOrNull("proxyscope")?.split(","), ClientAuthenticationProperties( clientConfig.propertyToString("authentication.client_id"), ClientAuthenticationMethod( diff --git a/src/main/kotlin/no/nav/syfo/koin/DevKoinProfile.kt b/src/main/kotlin/no/nav/syfo/koin/DevKoinProfile.kt new file mode 100644 index 000000000..67ea201e1 --- /dev/null +++ b/src/main/kotlin/no/nav/syfo/koin/DevKoinProfile.kt @@ -0,0 +1,285 @@ +package no.nav.syfo.koin + +import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod +import com.zaxxer.hikari.HikariConfig +import com.zaxxer.hikari.HikariDataSource +import io.ktor.config.ApplicationConfig +import no.nav.helse.arbeidsgiver.bakgrunnsjobb.BakgrunnsjobbRepository +import no.nav.helse.arbeidsgiver.bakgrunnsjobb.BakgrunnsjobbService +import no.nav.helse.arbeidsgiver.bakgrunnsjobb.PostgresBakgrunnsjobbRepository +import no.nav.helse.arbeidsgiver.integrasjoner.AccessTokenProvider +import no.nav.helse.arbeidsgiver.integrasjoner.OAuth2TokenProvider +import no.nav.helse.arbeidsgiver.integrasjoner.pdl.PdlClient +import no.nav.helse.arbeidsgiver.integrasjoner.pdl.PdlClientImpl +import no.nav.helse.arbeidsgiver.system.getString +import no.nav.security.token.support.client.core.ClientAuthenticationProperties +import no.nav.security.token.support.client.core.ClientProperties +import no.nav.security.token.support.client.core.OAuth2GrantType +import no.nav.security.token.support.client.core.oauth2.ClientCredentialsTokenClient +import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenService +import no.nav.security.token.support.client.core.oauth2.OnBehalfOfTokenClient +import no.nav.security.token.support.client.core.oauth2.TokenExchangeClient +import no.nav.syfo.MetrikkVarsler +import no.nav.syfo.behandling.InntektsmeldingBehandler +import no.nav.syfo.client.BrregClient +import no.nav.syfo.client.BrregClientImp +import no.nav.syfo.client.OppgaveClient +import no.nav.syfo.client.dokarkiv.DokArkivClient +import no.nav.syfo.client.norg.Norg2Client +import no.nav.syfo.client.saf.SafDokumentClient +import no.nav.syfo.client.saf.SafJournalpostClient +import no.nav.syfo.integration.kafka.UtsattOppgaveConsumer +import no.nav.syfo.integration.kafka.commonAivenProperties +import no.nav.syfo.integration.kafka.joarkAivenProperties +import no.nav.syfo.integration.kafka.journalpost.JournalpostHendelseConsumer +import no.nav.syfo.integration.kafka.utsattOppgaveAivenProperties +import no.nav.syfo.integration.oauth2.DefaultOAuth2HttpClient +import no.nav.syfo.integration.oauth2.TokenResolver +import no.nav.syfo.producer.InntektsmeldingAivenProducer +import no.nav.syfo.prosesser.FinnAlleUtgaandeOppgaverProcessor +import no.nav.syfo.prosesser.FjernInntektsmeldingByBehandletProcessor +import no.nav.syfo.prosesser.JoarkInntektsmeldingHendelseProsessor +import no.nav.syfo.repository.ArbeidsgiverperiodeRepository +import no.nav.syfo.repository.ArbeidsgiverperiodeRepositoryImp +import no.nav.syfo.repository.DuplikatRepository +import no.nav.syfo.repository.DuplikatRepositoryImpl +import no.nav.syfo.repository.FeiletRepositoryImp +import no.nav.syfo.repository.FeiletService +import no.nav.syfo.repository.InntektsmeldingRepository +import no.nav.syfo.repository.InntektsmeldingRepositoryImp +import no.nav.syfo.repository.UtsattOppgaveRepositoryImp +import no.nav.syfo.service.BehandleInngaaendeJournalConsumer +import no.nav.syfo.service.BehandlendeEnhetConsumer +import no.nav.syfo.service.InngaaendeJournalConsumer +import no.nav.syfo.service.InntektsmeldingService +import no.nav.syfo.service.JournalConsumer +import no.nav.syfo.service.JournalpostService +import no.nav.syfo.simba.InntektsmeldingConsumer +import no.nav.syfo.util.Metrikk +import no.nav.syfo.utsattoppgave.FeiletUtsattOppgaveMeldingProsessor +import no.nav.syfo.utsattoppgave.UtsattOppgaveDAO +import no.nav.syfo.utsattoppgave.UtsattOppgaveService +import org.apache.kafka.clients.consumer.ConsumerConfig +import org.apache.kafka.common.serialization.StringDeserializer +import org.koin.core.qualifier.named +import org.koin.core.scope.Scope +import org.koin.dsl.bind +import org.koin.dsl.module +import java.net.URI +import javax.sql.DataSource + +fun devConfig(config: ApplicationConfig) = module { + + val clientConfig = config.configList("no.nav.security.jwt.client.registration.clients").first() + single(named("PROXY")) { + + oauth2TokenProvider( + clientConfig, + clientConfig.getString("proxyscope") + ) + } bind AccessTokenProvider::class + + single(named("OPPGAVE")) { + oauth2TokenProvider( + clientConfig, + clientConfig.getString("oppgavescope") + ) + } bind AccessTokenProvider::class + + single(named("DOKARKIV")) { + oauth2TokenProvider( + clientConfig, + clientConfig.getString("dokarkivscope") + ) + } bind AccessTokenProvider::class + + single(named("SAF")) { + oauth2TokenProvider( + clientConfig, + clientConfig.getString("safscope") + ) + } bind AccessTokenProvider::class + + single(named("PDL")) { + oauth2TokenProvider( + clientConfig, + clientConfig.getString("pdlscope") + ) + } bind AccessTokenProvider::class + + externalSystemClients(config) + single { + HikariDataSource( + HikariConfig().apply { + jdbcUrl = config.getjdbcUrlFromProperties() + username = config.getString("database.username") + password = config.getString("database.password") + maximumPoolSize = 2 + minimumIdle = 1 + idleTimeout = 10001 + connectionTimeout = 2000 + maxLifetime = 30001 + driverClassName = "org.postgresql.Driver" + } + ) + } bind DataSource::class + + single { + JoarkInntektsmeldingHendelseProsessor( + get(), get(), get(), get(), get() + ) + } bind JoarkInntektsmeldingHendelseProsessor::class + single { ArbeidsgiverperiodeRepositoryImp(get()) } bind ArbeidsgiverperiodeRepository::class + + single { + InntektsmeldingBehandler( + get(), get(), get(), get(), get(), get() + ) + } bind InntektsmeldingBehandler::class + + single { InngaaendeJournalConsumer(get()) } bind InngaaendeJournalConsumer::class + single { BehandleInngaaendeJournalConsumer(get()) } bind BehandleInngaaendeJournalConsumer::class + single { JournalConsumer(get(), get(), get()) } bind JournalConsumer::class + single { Metrikk() } bind Metrikk::class + single { BehandlendeEnhetConsumer(get(), get(), get()) } bind BehandlendeEnhetConsumer::class + single { JournalpostService(get(), get(), get(), get(), get(), get()) } bind JournalpostService::class + + single { InntektsmeldingRepositoryImp(get()) } bind InntektsmeldingRepository::class + single { InntektsmeldingService(get(), get()) } bind InntektsmeldingService::class + + single { + JournalpostHendelseConsumer( + joarkAivenProperties(), config.getString("kafka_joark_hendelse_topic"), get(), get(), get() + ) + } + single { + UtsattOppgaveConsumer( + utsattOppgaveAivenProperties(), config.getString("kafka_utsatt_oppgave_topic"), get(), get(), get() + ) + } + + single { + InntektsmeldingAivenProducer( + commonAivenProperties() + ) + } + + single { DuplikatRepositoryImpl(get()) } bind DuplikatRepository::class + single { UtsattOppgaveDAO(UtsattOppgaveRepositoryImp(get())) } + single { + val tokenProvider = get(qualifier = named("OPPGAVE")) + OppgaveClient(config.getString("oppgavebehandling_url"), get(), get(), tokenProvider::getToken) + } bind OppgaveClient::class + single { UtsattOppgaveService(get(), get(), get(), get(), get(), get()) } bind UtsattOppgaveService::class + single { FeiletUtsattOppgaveMeldingProsessor(get(), get()) } + + single { + FjernInntektsmeldingByBehandletProcessor( + InntektsmeldingRepositoryImp(get()), config.getString("lagringstidMåneder").toInt() + ) + } bind FjernInntektsmeldingByBehandletProcessor::class + single { FinnAlleUtgaandeOppgaverProcessor(get(), get(), get(), get(), get(), get()) } bind FinnAlleUtgaandeOppgaverProcessor::class + + single { FeiletService(FeiletRepositoryImp(get())) } bind FeiletService::class + + single { PostgresBakgrunnsjobbRepository(get()) } bind BakgrunnsjobbRepository::class + single { BakgrunnsjobbService(get(), bakgrunnsvarsler = MetrikkVarsler()) } + + single { + PdlClientImpl( + config.getString("pdl_url"), + get(qualifier = named("PDL")), + get(), + get() + ) + } bind PdlClient::class + + single { + Norg2Client( + config.getString("norg2_url"), + get(), + get(qualifier = named("PROXY"))::getToken, + ) + } bind Norg2Client::class + + single { + SafJournalpostClient( + get(), + config.getString("saf_journal_url"), + get(qualifier = named("SAF")), + ) + } bind SafJournalpostClient::class + + single { + SafDokumentClient( + config.getString("saf_dokument_url"), + get(), + get(qualifier = named("SAF")), + ) + } bind SafDokumentClient::class + + single { + DokArkivClient( + config.getString("dokarkiv_url"), + get(qualifier = named("DOKARKIV")), + get() + ) + } bind DokArkivClient::class + + single { BrregClientImp(get(qualifier = named("proxyHttpClient")), config.getString("berreg_enhet_url")) } bind BrregClient::class +// TODO: trekk ut topic og consumerConfig-properties + single { + InntektsmeldingConsumer( + commonAivenProperties() + mapOf( + ConsumerConfig.AUTO_OFFSET_RESET_CONFIG to "earliest", + ConsumerConfig.CLIENT_ID_CONFIG to "syfoinntektsmelding-im-consumer", + ConsumerConfig.GROUP_ID_CONFIG to "syfoinntektsmelding-im-v1", + ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG to StringDeserializer::class.java, + ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG to StringDeserializer::class.java + ), + "helsearbeidsgiver.inntektsmelding", + get(), + get(), + get(), + get() + ) + } +} + +private fun Scope.oauth2TokenProvider(config: ApplicationConfig, scope: String): OAuth2TokenProvider = + OAuth2TokenProvider( + oauth2Service = accessTokenService(this), + clientProperties = config.azureAdConfig(scope) + ) + +private fun accessTokenService(scope: Scope): OAuth2AccessTokenService = + DefaultOAuth2HttpClient(scope.get()).let { + OAuth2AccessTokenService( + TokenResolver(), + OnBehalfOfTokenClient(it), + ClientCredentialsTokenClient(it), + TokenExchangeClient(it) + ) + } + +private fun ApplicationConfig.azureAdConfig(scope: String): ClientProperties { + return ClientProperties( + getString("token_endpoint_url").let(::URI), + getString("well_known_url").let(::URI), + getString("grant_type").let(::OAuth2GrantType), + scope.split(","), + authProps(), + null, + null + ) +} + +private fun ApplicationConfig.authProps(): ClientAuthenticationProperties { + val prefix = "authentication" + return ClientAuthenticationProperties( + getString("$prefix.client_id"), + getString("$prefix.client_auth_method").let(::ClientAuthenticationMethod), + getString("$prefix.client_secret"), + null + ) +} diff --git a/src/main/kotlin/no/nav/syfo/koin/ExternalSystemsModule.kt b/src/main/kotlin/no/nav/syfo/koin/ExternalSystemsModule.kt index a8462acd0..5f211488c 100644 --- a/src/main/kotlin/no/nav/syfo/koin/ExternalSystemsModule.kt +++ b/src/main/kotlin/no/nav/syfo/koin/ExternalSystemsModule.kt @@ -25,7 +25,6 @@ fun Module.externalSystemClients(config: ApplicationConfig) { ClientCredentialsTokenClient(oauthHttpClient), TokenExchangeClient(oauthHttpClient) ) - val azureAdConfig = clientConfig.clientConfig["azure_ad"] ?: error("Fant ikke config i application.conf") OAuth2TokenProvider(accessTokenService, azureAdConfig) } bind AccessTokenProvider::class diff --git a/src/main/kotlin/no/nav/syfo/koin/Fakes.kt b/src/main/kotlin/no/nav/syfo/koin/Fakes.kt index ada2cb21f..ce951d5c9 100644 --- a/src/main/kotlin/no/nav/syfo/koin/Fakes.kt +++ b/src/main/kotlin/no/nav/syfo/koin/Fakes.kt @@ -114,12 +114,8 @@ fun Module.mockExternalDependecies() { single { object : Norg2Client( "", - object : AccessTokenProvider { - override fun getToken(): String { - return "token" - } - }, - get() + get(), + get()::getToken ) { override suspend fun hentAlleArbeidsfordelinger( request: ArbeidsfordelingRequest, diff --git a/src/main/kotlin/no/nav/syfo/koin/KoinProfiles.kt b/src/main/kotlin/no/nav/syfo/koin/KoinProfiles.kt index bdb2bcf4b..e59beade4 100644 --- a/src/main/kotlin/no/nav/syfo/koin/KoinProfiles.kt +++ b/src/main/kotlin/no/nav/syfo/koin/KoinProfiles.kt @@ -25,7 +25,7 @@ import org.koin.dsl.module fun selectModuleBasedOnProfile(config: ApplicationConfig): List { val envModule = when (config.property("koin.profile").getString()) { "LOCAL" -> localDevConfig(config) - "PREPROD" -> preprodConfig(config) + "DEV" -> devConfig(config) "PROD" -> prodConfig(config) else -> localDevConfig(config) } diff --git a/src/main/kotlin/no/nav/syfo/koin/LocalKoinProfile.kt b/src/main/kotlin/no/nav/syfo/koin/LocalKoinProfile.kt index 9725e6f41..7423caa8c 100644 --- a/src/main/kotlin/no/nav/syfo/koin/LocalKoinProfile.kt +++ b/src/main/kotlin/no/nav/syfo/koin/LocalKoinProfile.kt @@ -103,7 +103,7 @@ fun localDevConfig(config: ApplicationConfig) = module { single { BehandlendeEnhetConsumer(get(), get(), get()) } bind BehandlendeEnhetConsumer::class single { DuplikatRepositoryImpl(get()) } bind DuplikatRepository::class single { UtsattOppgaveDAO(UtsattOppgaveRepositoryMockk()) } - single { OppgaveClient(config.getString("oppgavebehandling_url"), get(), get(), get()) } bind OppgaveClient::class + single { OppgaveClient(config.getString("oppgavebehandling_url"), get(), get(), get()::token) } bind OppgaveClient::class single { UtsattOppgaveService(get(), get(), get(), get(), get(), get()) } bind UtsattOppgaveService::class single { FeiletUtsattOppgaveMeldingProsessor(get(), get()) } diff --git a/src/main/kotlin/no/nav/syfo/koin/PreprodKoinProfile.kt b/src/main/kotlin/no/nav/syfo/koin/PreprodKoinProfile.kt index 1524730ad..50d47be64 100644 --- a/src/main/kotlin/no/nav/syfo/koin/PreprodKoinProfile.kt +++ b/src/main/kotlin/no/nav/syfo/koin/PreprodKoinProfile.kt @@ -56,15 +56,16 @@ import org.koin.dsl.bind import org.koin.dsl.module import javax.sql.DataSource +// TODO: kan fjernes fun preprodConfig(config: ApplicationConfig) = module { externalSystemClients(config) single { - val vaultconfig = HikariConfig() - vaultconfig.jdbcUrl = config.getjdbcUrlFromProperties() - vaultconfig.minimumIdle = 1 - vaultconfig.maximumPoolSize = 2 + val hikariConfig = HikariConfig() + hikariConfig.jdbcUrl = config.getjdbcUrlFromProperties() + hikariConfig.minimumIdle = 1 + hikariConfig.maximumPoolSize = 2 HikariCPVaultUtil.createHikariDataSourceWithVaultIntegration( - vaultconfig, + hikariConfig, config.getString("database.vault.mountpath"), config.getString("database.vault.admin"), ) @@ -72,11 +73,7 @@ fun preprodConfig(config: ApplicationConfig) = module { single { JoarkInntektsmeldingHendelseProsessor( - get(), - get(), - get(), - get(), - get() + get(), get(), get(), get(), get() ) } bind JoarkInntektsmeldingHendelseProsessor::class single { ArbeidsgiverperiodeRepositoryImp(get()) } bind ArbeidsgiverperiodeRepository::class @@ -91,12 +88,7 @@ fun preprodConfig(config: ApplicationConfig) = module { } bind TokenConsumer::class single { InntektsmeldingBehandler( - get(), - get(), - get(), - get(), - get(), - get() + get(), get(), get(), get(), get(), get() ) } bind InntektsmeldingBehandler::class @@ -112,17 +104,12 @@ fun preprodConfig(config: ApplicationConfig) = module { single { JournalpostHendelseConsumer( - joarkAivenProperties(), - config.getString("kafka_joark_hendelse_topic"), - get(), - get(), - get() + joarkAivenProperties(), config.getString("kafka_joark_hendelse_topic"), get(), get(), get() ) } single { UtsattOppgaveConsumer( - utsattOppgaveAivenProperties(), - config.getString("kafka_utsatt_oppgave_topic"), get(), get(), get() + utsattOppgaveAivenProperties(), config.getString("kafka_utsatt_oppgave_topic"), get(), get(), get() ) } @@ -134,14 +121,13 @@ fun preprodConfig(config: ApplicationConfig) = module { single { DuplikatRepositoryImpl(get()) } bind DuplikatRepository::class single { UtsattOppgaveDAO(UtsattOppgaveRepositoryImp(get())) } - single { OppgaveClient(config.getString("oppgavebehandling_url"), get(), get(), get()) } bind OppgaveClient::class + single { OppgaveClient(config.getString("oppgavebehandling_url"), get(), get()) { get().token } } bind OppgaveClient::class single { UtsattOppgaveService(get(), get(), get(), get(), get(), get()) } bind UtsattOppgaveService::class single { FeiletUtsattOppgaveMeldingProsessor(get(), get()) } single { FjernInntektsmeldingByBehandletProcessor( - InntektsmeldingRepositoryImp(get()), - config.getString("lagringstidMåneder").toInt() + InntektsmeldingRepositoryImp(get()), config.getString("lagringstidMåneder").toInt() ) } bind FjernInntektsmeldingByBehandletProcessor::class single { FinnAlleUtgaandeOppgaverProcessor(get(), get(), get(), get(), get(), get()) } bind FinnAlleUtgaandeOppgaverProcessor::class @@ -168,13 +154,13 @@ fun preprodConfig(config: ApplicationConfig) = module { single { Norg2Client( config.getString("norg2_url"), + get(), RestSTSAccessTokenProvider( config.getString("security_token.username"), config.getString("security_token.password"), config.getString("security_token_service_token_url"), get() - ), - get() + )::getToken, ) } bind Norg2Client::class diff --git a/src/main/kotlin/no/nav/syfo/koin/ProdKoinProfile.kt b/src/main/kotlin/no/nav/syfo/koin/ProdKoinProfile.kt index 616b21cd8..02031c806 100644 --- a/src/main/kotlin/no/nav/syfo/koin/ProdKoinProfile.kt +++ b/src/main/kotlin/no/nav/syfo/koin/ProdKoinProfile.kt @@ -120,7 +120,7 @@ fun prodConfig(config: ApplicationConfig) = module { single { DuplikatRepositoryImpl(get()) } bind DuplikatRepository::class single { UtsattOppgaveDAO(UtsattOppgaveRepositoryImp(get())) } - single { OppgaveClient(config.getString("oppgavebehandling_url"), get(), get(), get()) } bind OppgaveClient::class + single { OppgaveClient(config.getString("oppgavebehandling_url"), get(), get(), get()::token) } bind OppgaveClient::class single { UtsattOppgaveService(get(), get(), get(), get(), get(), get()) } bind UtsattOppgaveService::class single { FeiletUtsattOppgaveMeldingProsessor(get(), get()) } @@ -154,13 +154,13 @@ fun prodConfig(config: ApplicationConfig) = module { single { Norg2Client( config.getString("norg2_url"), + get(), RestSTSAccessTokenProvider( config.getString("security_token.username"), config.getString("security_token.password"), config.getString("security_token_service_token_url"), get() - ), - get() + )::getToken ) } bind Norg2Client::class diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index a058875b7..b845f6390 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -47,20 +47,26 @@ security_token { database { username = "spinn" username = ${?DATABASE_USERNAME} + username = ${?NAIS_DATABASE_SPINOSAURUS_SPINOSAURUS_USERNAME} + password = "spinn" password = ${?DATABASE_PASSWORD} + password = ${?NAIS_DATABASE_SPINOSAURUS_SPINOSAURUS_PASSWORD} name = "spinn" name = ${?DATABASE_NAME} + name = ${?NAIS_DATABASE_SPINOSAURUS_SPINOSAURUS_DATABASE} host = "localhost" host = ${?DATABASE_HOST} + host = ${?NAIS_DATABASE_SPINOSAURUS_SPINOSAURUS_HOST} port = 5432 port = ${?DATABASE_PORT} + port = ${?NAIS_DATABASE_SPINOSAURUS_SPINOSAURUS_PORT} - vault { + vault { role="syfoinntektsmelding-user" admin="syfoinntektsmelding-admin" mountpath = "" @@ -92,10 +98,12 @@ client { token_endpoint_url: "https://login.microsoftonline.com/966ac572-f5b7-4bbe-aa88-c76419c0f851/oauth2/v2.0/token" token_endpoint_url: ${?AZURE_OPENID_CONFIG_TOKEN_ENDPOINT} grant_type: client_credentials - scope: "api://5ccfebdd-40b0-424b-9306-3383bd0febd7/.default" // UUID=ClientID for proxyappen - scope: ${?PROXY_SCOPE} // UUID=ClientID for proxyappen + proxyscope: ${?PROXY_SCOPE} + oppgavescope: ${?OPPGAVE_SCOPE} + dokarkivscope: ${?DOKARKIV_SCOPE} + safscope: ${?SAF_SCOPE} + pdlscope: ${?PDL_SCOPE} authentication: { - client_id: "2cf25df8-3940-4c5d-9e8e-8be4b316ddda" client_id: ${?AZURE_APP_CLIENT_ID} client_secret: "secret-injected-by-nais" client_secret: ${?AZURE_APP_CLIENT_SECRET} @@ -107,25 +115,12 @@ client { } } -aadaccesstoken_url: "https://login.microsoftonline.com/navq.onmicrosoft.com/oauth2/token" -aadaccesstoken_url: ${?AADACCESSTOKEN_URL} - -aad_syfoinntektsmelding_clientid_username: "56813e1b-97db-4da9-bcc1-a53d0a677ca2" -aad_syfoinntektsmelding_clientid_username: ${?AAD_SYFOINNTEKTSMELDING_CLIENTID_USERNAME} - -aad_syfoinntektsmelding_clientid_password: "" -aad_syfoinntektsmelding_clientid_password: ${?AAD_SYFOINNTEKTSMELDING_CLIENTID_PASSWORD} - aad_preauthorized_apps = "[{\"clientId\":\"appId\",\"name\":\"thisapp\"},{\"clientId\":\"appId2\",\"name\":\"otherapp\"}]}" aad_preauthorized_apps = ${?AZURE_APP_PRE_AUTHORIZED_APPS} inntektsmelding_lagringstid_maneder: "3" -opprett_sak_url:"http://sak.teamdokumenthandtering.svc.nais.local/api/v1/saker" -opprett_sak_url: ${?OPPRETT_SAK_URL} - kafka_bootstrap_servers: "localhost:9092" -kafka_bootstrap_servers: ${?KAFKA_BOOTSTRAP_SERVERS} oppgavebehandling_url: "https://oppgave.nais.preprod.local/api/v1/oppgaver" oppgavebehandling_url: ${?OPPGAVEBEHANDLING_URL} diff --git a/src/test/kotlin/no/nav/syfo/client/OppgaveClientTest.kt b/src/test/kotlin/no/nav/syfo/client/OppgaveClientTest.kt index 19f1ab7e3..46f853cd9 100644 --- a/src/test/kotlin/no/nav/syfo/client/OppgaveClientTest.kt +++ b/src/test/kotlin/no/nav/syfo/client/OppgaveClientTest.kt @@ -23,7 +23,6 @@ private const val FORDELINGSOPPGAVE_ID = 5678 class OppgaveClientTest { - private var tokenConsumer = mockk(relaxed = true) private var metrikk = mockk(relaxed = true) private lateinit var oppgaveClient: OppgaveClient @@ -32,7 +31,7 @@ class OppgaveClientTest { fun henterEksisterendeOppgave() { runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagOppgaveResponse()), metrikk) { "mockToken" } val resultat = oppgaveClient.opprettOppgave("123", "tildeltEnhet", "aktoerid", false, false, BehandlingsTema.REFUSJON_MED_DATO) assertThat(resultat.oppgaveId).isEqualTo(OPPGAVE_ID) assertThat(resultat.duplikat).isTrue @@ -43,7 +42,7 @@ class OppgaveClientTest { fun oppretterNyOppgave() { runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } val resultat = oppgaveClient.opprettOppgave("123", "tildeltEnhet", "aktoerid", false, false, BehandlingsTema.REFUSJON_MED_DATO) val requestVerdier = hentRequestInnhold(oppgaveClient.httpClient) assertThat(resultat.oppgaveId).isNotEqualTo(OPPGAVE_ID) @@ -58,7 +57,7 @@ class OppgaveClientTest { fun oppretterNyFordelingsOppgave() { runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } val resultat = oppgaveClient.opprettFordelingsOppgave("journalpostId") val requestVerdier = hentRequestInnhold(oppgaveClient.httpClient) assertThat(resultat.oppgaveId).isNotEqualTo(FORDELINGSOPPGAVE_ID) @@ -72,7 +71,7 @@ class OppgaveClientTest { fun henterEksisterendeFordelingsOppgave() { runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagFordelingsOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagFordelingsOppgaveResponse()), metrikk) { "mockToken" } val resultat = oppgaveClient.opprettFordelingsOppgave("journalpostId") assertThat(resultat.oppgaveId).isEqualTo(FORDELINGSOPPGAVE_ID) assertThat(resultat.duplikat).isTrue @@ -83,13 +82,13 @@ class OppgaveClientTest { fun skal_opprette_utland() { runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } oppgaveClient.opprettOppgave("123", "tildeltEnhet", "aktoerid", true, false, BehandlingsTema.REFUSJON_MED_DATO) val requestVerdier = hentRequestInnhold(oppgaveClient.httpClient) assertThat(requestVerdier?.behandlingstype).isEqualTo("ae0106") } runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } oppgaveClient.opprettOppgave("123", "tildeltEnhet", "aktoerid", true, false, BehandlingsTema.REFUSJON_UTEN_DATO) val requestVerdier = hentRequestInnhold(oppgaveClient.httpClient) assertThat(requestVerdier?.behandlingstype).isEqualTo("ae0106") @@ -100,7 +99,7 @@ class OppgaveClientTest { fun skal_opprette_speil() { runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } oppgaveClient.opprettOppgave("123", "tildeltEnhet", "aktoerid", true, true, BehandlingsTema.REFUSJON_UTEN_DATO) val requestVerdier = hentRequestInnhold(oppgaveClient.httpClient) assertThat(requestVerdier?.behandlingstema).isEqualTo("ab0455") @@ -110,7 +109,7 @@ class OppgaveClientTest { @Test fun henterRiktigFerdigstillelsesFrist() { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } val onsdag = LocalDate.of(2019, Month.NOVEMBER, 27) val fredag = LocalDate.of(2019, Month.NOVEMBER, 29) val lørdag = LocalDate.of(2019, Month.NOVEMBER, 30) @@ -126,19 +125,19 @@ class OppgaveClientTest { fun skal_utbetale_til_bruker() { runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } oppgaveClient.opprettOppgave("123", "tildeltEnhet", "aktoerid", false, false, BehandlingsTema.REFUSJON_MED_DATO) val requestVerdier = hentRequestInnhold(oppgaveClient.httpClient) assertThat(requestVerdier?.behandlingstema).isEqualTo("ab0458") } runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } oppgaveClient.opprettOppgave("123", "tildeltEnhet", "aktoerid", false, false, BehandlingsTema.IKKE_REFUSJON) val requestVerdier = hentRequestInnhold(oppgaveClient.httpClient) assertThat(requestVerdier?.behandlingstema).isEqualTo("ab0458") } runBlocking { - oppgaveClient = OppgaveClient("url", tokenConsumer, buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) + oppgaveClient = OppgaveClient("url", buildHttpClientJson(HttpStatusCode.OK, lagTomOppgaveResponse()), metrikk) { "mockToken" } oppgaveClient.opprettOppgave("123", "tildeltEnhet", "aktoerid", false, false, BehandlingsTema.REFUSJON_LITEN_LØNN) val requestVerdier = hentRequestInnhold(oppgaveClient.httpClient) assertThat(requestVerdier?.behandlingstema).isEqualTo("ab0458") diff --git a/src/test/kotlin/no/nav/syfo/client/norg/Norg2ClientTest.kt b/src/test/kotlin/no/nav/syfo/client/norg/Norg2ClientTest.kt index ddd475755..f1346a7c7 100644 --- a/src/test/kotlin/no/nav/syfo/client/norg/Norg2ClientTest.kt +++ b/src/test/kotlin/no/nav/syfo/client/norg/Norg2ClientTest.kt @@ -1,9 +1,7 @@ package no.nav.syfo.client.norg import io.ktor.http.HttpStatusCode -import io.mockk.mockk import kotlinx.coroutines.runBlocking -import no.nav.helse.arbeidsgiver.integrasjoner.AccessTokenProvider import no.nav.syfo.client.buildHttpClientJson import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -13,13 +11,11 @@ class Norg2ClientTest { private lateinit var norgClient: Norg2Client - private val mockStsClient = mockk(relaxed = true) - @Test fun hentAlleArbeidsfordelinger() { runBlocking { - norgClient = Norg2Client("url", mockStsClient, buildHttpClientJson(HttpStatusCode.OK, lagResponse())) + norgClient = Norg2Client("url", buildHttpClientJson(HttpStatusCode.OK, lagResponse())) { "norg-token" } val arbeidsfordelinger = norgClient.hentAlleArbeidsfordelinger(lagRequest(), "123") assertThat(arbeidsfordelinger.size).isEqualTo(1) assertThat(arbeidsfordelinger[0].enhetNr).isEqualTo("1234")