diff --git a/pom.xml b/pom.xml
index 3c0eefc97..5052bc294 100644
--- a/pom.xml
+++ b/pom.xml
@@ -239,14 +239,19 @@
no.nav.security
- token-validation-core
+ token-client-spring
${token-validation-spring.version}
no.nav.familie.felles
- http-client
+ log
${felles.version}
+
+ no.nav.security
+ token-validation-core
+ ${token-validation-spring.version}
+
ch.qos.logback
logback-classic
diff --git a/src/main/kotlin/no/nav/familie/tilbake/config/ApplicationConfig.kt b/src/main/kotlin/no/nav/familie/tilbake/config/ApplicationConfig.kt
index 2c129488d..fe237b433 100644
--- a/src/main/kotlin/no/nav/familie/tilbake/config/ApplicationConfig.kt
+++ b/src/main/kotlin/no/nav/familie/tilbake/config/ApplicationConfig.kt
@@ -2,12 +2,6 @@ package no.nav.familie.tilbake.config
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
-import no.nav.familie.http.client.RetryOAuth2HttpClient
-import no.nav.familie.http.config.RestTemplateAzure
-import no.nav.familie.log.filter.LogFilter
-import no.nav.familie.prosessering.config.ProsesseringInfoProvider
-import no.nav.security.token.support.client.core.http.OAuth2HttpClient
-import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenResponse
import no.nav.security.token.support.client.spring.oauth2.EnableOAuth2Client
import no.nav.security.token.support.spring.SpringTokenValidationContextHolder
import no.nav.security.token.support.spring.api.EnableJwtTokenValidation
@@ -21,19 +15,18 @@ import org.springframework.boot.web.servlet.server.ServletWebServerFactory
import org.springframework.cache.annotation.EnableCaching
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
-import org.springframework.context.annotation.Import
import org.springframework.context.annotation.Primary
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
import org.springframework.scheduling.annotation.EnableScheduling
-import org.springframework.web.client.RestClient
import org.springframework.web.client.RestTemplate
import java.time.Duration
import java.time.temporal.ChronoUnit
+import no.nav.familie.log.filter.LogFilter
+import no.nav.familie.prosessering.config.ProsesseringInfoProvider
@SpringBootConfiguration
-@ComponentScan(ApplicationConfig.PAKKE_NAVN, "no.nav.familie.sikkerhet", "no.nav.familie.prosessering", "no.nav.familie.unleash")
+@ComponentScan(ApplicationConfig.PAKKE_NAVN, "no.nav.familie.prosessering", "no.nav.familie.unleash")
@EnableJwtTokenValidation(ignore = ["org.springframework", "org.springdoc"])
-@Import(RestTemplateAzure::class)
@EnableOAuth2Client(cacheEnabled = true)
@EnableScheduling
@EnableCaching
@@ -65,28 +58,11 @@ class ApplicationConfig {
fun restTemplateBuilder(objectMapper: ObjectMapper): RestTemplateBuilder {
val jackson2HttpMessageConverter = MappingJackson2HttpMessageConverter(objectMapper)
return RestTemplateBuilder()
- .setConnectTimeout(Duration.of(2, ChronoUnit.SECONDS))
- .setReadTimeout(Duration.of(30, ChronoUnit.SECONDS))
+ .connectTimeout(Duration.of(2, ChronoUnit.SECONDS))
+ .readTimeout(Duration.of(30, ChronoUnit.SECONDS))
.additionalMessageConverters(listOf(jackson2HttpMessageConverter) + RestTemplate().messageConverters)
}
- /**
- * Overskriver OAuth2HttpClient som settes opp i token-support som ikke kan få med objectMapper fra felles
- * pga. .setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE)
- * og [OAuth2AccessTokenResponse] som burde settes med setters, då feltnavn heter noe annet enn feltet i json
- */
- @Bean
- @Primary
- fun oAuth2HttpClient(): OAuth2HttpClient =
- RetryOAuth2HttpClient(
- RestClient.create(
- RestTemplateBuilder()
- .setConnectTimeout(Duration.of(2, ChronoUnit.SECONDS))
- .setReadTimeout(Duration.of(4, ChronoUnit.SECONDS))
- .build(),
- ),
- )
-
@Bean
fun prosesseringInfoProvider(
@Value("\${rolle.prosessering}") prosesseringRolle: String,
diff --git a/src/main/kotlin/no/nav/familie/tilbake/config/HttpClientConfig.kt b/src/main/kotlin/no/nav/familie/tilbake/config/HttpClientConfig.kt
new file mode 100644
index 000000000..71428d304
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/config/HttpClientConfig.kt
@@ -0,0 +1,36 @@
+package no.nav.familie.tilbake.config
+
+import no.nav.familie.tilbake.http.BearerTokenClientInterceptor
+import no.nav.familie.tilbake.http.ConsumerIdClientInterceptor
+import no.nav.familie.tilbake.http.MdcValuesPropagatingClientInterceptor
+import org.springframework.boot.web.client.RestTemplateBuilder
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.client.RestOperations
+
+@Configuration
+class HttpClientConfig {
+ private val restTemplateBuilder = RestTemplateBuilder()
+
+ @Bean("azure")
+ fun restTemplateEntraIDBearer(
+ consumerIdClientInterceptor: ConsumerIdClientInterceptor,
+ bearerTokenClientInterceptor: BearerTokenClientInterceptor,
+ ): RestOperations = restTemplateBuilder
+ .additionalInterceptors(
+ consumerIdClientInterceptor,
+ bearerTokenClientInterceptor,
+ MdcValuesPropagatingClientInterceptor(),
+ ).build()
+
+ @Bean("azureClientCredential")
+ fun restTemplateClientCredentialEntraIdBearer(
+ consumerIdClientInterceptor: ConsumerIdClientInterceptor,
+ bearerTokenClientInterceptor: BearerTokenClientInterceptor,
+ ): RestOperations = restTemplateBuilder
+ .additionalInterceptors(
+ consumerIdClientInterceptor,
+ bearerTokenClientInterceptor,
+ MdcValuesPropagatingClientInterceptor()
+ ).build()
+}
diff --git "a/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/pdf/Journalf\303\270ringService.kt" "b/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/pdf/Journalf\303\270ringService.kt"
index f9673706e..30bee6094 100644
--- "a/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/pdf/Journalf\303\270ringService.kt"
+++ "b/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/pdf/Journalf\303\270ringService.kt"
@@ -44,6 +44,7 @@ class JournalføringService(
fun hentJournalposter(behandlingId: UUID): List {
val behandling = behandlingRepository.findById(behandlingId).orElseThrow()
val fagsak = behandling.let { fagsakRepository.findById(it.fagsakId).orElseThrow() }
+ val logContext = SecureLog.Context.medBehandling(fagsak.eksternFagsakId, behandling.id.toString())
val journalposter =
fagsak.let {
integrasjonerClient.hentJournalposterForBruker(
@@ -56,6 +57,7 @@ class JournalføringService(
),
tema = listOf(hentTema(fagsystem = fagsak.fagsystem)),
),
+ logContext,
)
}
return journalposter.filter { it.sak?.fagsakId == fagsak.eksternFagsakId }
diff --git a/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/pdf/PdfBrevService.kt b/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/pdf/PdfBrevService.kt
index 102b72fb2..3285b11db 100644
--- a/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/pdf/PdfBrevService.kt
+++ b/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/pdf/PdfBrevService.kt
@@ -1,6 +1,5 @@
package no.nav.familie.tilbake.dokumentbestilling.felles.pdf
-import no.nav.familie.http.client.RessursException
import no.nav.familie.kontrakter.felles.dokdist.Distribusjonstidspunkt
import no.nav.familie.kontrakter.felles.dokdist.Distribusjonstype
import no.nav.familie.kontrakter.felles.objectMapper
@@ -26,6 +25,7 @@ import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import java.util.Base64
import java.util.Properties
+import no.nav.familie.tilbake.http.RessursException
@Service
class PdfBrevService(
diff --git "a/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/task/DistribuerDokumentVedD\303\270dsfallTask.kt" "b/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/task/DistribuerDokumentVedD\303\270dsfallTask.kt"
index 1b23efd45..d54b5acbf 100644
--- "a/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/task/DistribuerDokumentVedD\303\270dsfallTask.kt"
+++ "b/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/task/DistribuerDokumentVedD\303\270dsfallTask.kt"
@@ -1,6 +1,5 @@
package no.nav.familie.tilbake.dokumentbestilling.felles.task
-import no.nav.familie.http.client.RessursException
import no.nav.familie.kontrakter.felles.Fagsystem
import no.nav.familie.kontrakter.felles.dokdist.Distribusjonstidspunkt
import no.nav.familie.kontrakter.felles.dokdist.Distribusjonstype
@@ -19,6 +18,7 @@ import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import java.time.LocalDateTime
import java.util.UUID
+import no.nav.familie.tilbake.http.RessursException
const val ANTALL_SEKUNDER_I_EN_UKE = 604800L
diff --git a/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/task/PubliserJournalpostTask.kt b/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/task/PubliserJournalpostTask.kt
index fb1fe3a1a..3b9b611aa 100644
--- a/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/task/PubliserJournalpostTask.kt
+++ b/src/main/kotlin/no/nav/familie/tilbake/dokumentbestilling/felles/task/PubliserJournalpostTask.kt
@@ -1,6 +1,5 @@
package no.nav.familie.tilbake.dokumentbestilling.felles.task
-import no.nav.familie.http.client.RessursException
import no.nav.familie.kontrakter.felles.Fagsystem
import no.nav.familie.kontrakter.felles.dokdist.Distribusjonstidspunkt
import no.nav.familie.kontrakter.felles.dokdist.Distribusjonstype
@@ -17,6 +16,7 @@ import no.nav.familie.tilbake.log.TracedLogger
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Service
import java.util.UUID
+import no.nav.familie.tilbake.http.RessursException
@Service
@TaskStepBeskrivelse(
diff --git a/src/main/kotlin/no/nav/familie/tilbake/http/AbstractBearerTokenInterceptor.kt b/src/main/kotlin/no/nav/familie/tilbake/http/AbstractBearerTokenInterceptor.kt
new file mode 100644
index 000000000..a6736d489
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/http/AbstractBearerTokenInterceptor.kt
@@ -0,0 +1,32 @@
+package no.nav.familie.tilbake.http
+
+import com.nimbusds.oauth2.sdk.GrantType
+import java.net.URI
+import no.nav.security.token.support.client.core.ClientProperties
+import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenService
+import no.nav.security.token.support.client.spring.ClientConfigurationProperties
+import no.nav.security.token.support.core.exceptions.JwtTokenValidatorException
+import org.springframework.http.client.ClientHttpRequestInterceptor
+
+abstract class AbstractBearerTokenInterceptor(
+ protected val oAuth2AccessTokenService: OAuth2AccessTokenService,
+ protected val clientConfigurationProperties: ClientConfigurationProperties,
+) : ClientHttpRequestInterceptor {
+ protected fun genererAccessToken(clientProperties: ClientProperties): String {
+ return oAuth2AccessTokenService
+ .getAccessToken(clientProperties).access_token ?: throw JwtTokenValidatorException("Kunne ikke hente accesstoken")
+ }
+
+
+ protected fun ClientConfigurationProperties.findByURI(uri: URI) = registration
+ .values
+ .filter { uri.toString().startsWith(it.resourceUrl.toString()) }
+
+ protected fun clientPropertiesForGrantType(
+ values: List,
+ grantType: GrantType,
+ uri: URI,
+ ): ClientProperties =
+ values.firstOrNull { grantType == it.grantType }
+ ?: error("could not find oauth2 client config for uri=$uri and grant type=$grantType")
+}
diff --git a/src/main/kotlin/no/nav/familie/tilbake/http/AbstractPingableRestClient.kt b/src/main/kotlin/no/nav/familie/tilbake/http/AbstractPingableRestClient.kt
new file mode 100644
index 000000000..fc85b00fd
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/http/AbstractPingableRestClient.kt
@@ -0,0 +1,115 @@
+import com.fasterxml.jackson.module.kotlin.readValue
+import io.micrometer.core.instrument.Counter
+import io.micrometer.core.instrument.Metrics
+import io.micrometer.core.instrument.Timer
+import java.net.URI
+import java.util.concurrent.TimeUnit
+import no.nav.familie.kontrakter.felles.Ressurs
+import no.nav.familie.kontrakter.felles.objectMapper
+import no.nav.familie.tilbake.http.RessursException
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.springframework.http.HttpEntity
+import org.springframework.http.HttpHeaders
+import org.springframework.http.HttpMethod
+import org.springframework.http.ResponseEntity
+import org.springframework.web.client.HttpClientErrorException
+import org.springframework.web.client.HttpServerErrorException
+import org.springframework.web.client.ResourceAccessException
+import org.springframework.web.client.RestClientResponseException
+import org.springframework.web.client.RestOperations
+import org.springframework.web.client.exchange
+
+abstract class AbstractPingableRestClient(
+ val operations: RestOperations,
+ metricsPrefix: String,
+) {
+ private val secureLogger = LoggerFactory.getLogger("secureLogger")
+ protected val log: Logger = LoggerFactory.getLogger(this::class.java)
+ private val responstid: Timer = Metrics.timer("$metricsPrefix.tid")
+ private val responsSuccess: Counter = Metrics.counter("$metricsPrefix.response", "status", "success")
+ private val responsFailure: Counter = Metrics.counter("$metricsPrefix.response", "status", "failure")
+
+ inline fun getForEntity(
+ uri: URI,
+ httpHeaders: HttpHeaders? = null,
+ ): T = executeMedMetrics(uri) { operations.exchange(uri, HttpMethod.GET, HttpEntity(null, httpHeaders)) }
+
+ inline fun postForEntity(
+ uri: URI,
+ payload: Any,
+ httpHeaders: HttpHeaders? = null,
+ ): T = executeMedMetrics(uri) { operations.exchange(uri, HttpMethod.POST, HttpEntity(payload, httpHeaders)) }
+
+ inline fun putForEntity(
+ uri: URI,
+ payload: Any,
+ httpHeaders: HttpHeaders? = null,
+ ): T = executeMedMetrics(uri) { operations.exchange(uri, HttpMethod.PUT, HttpEntity(payload, httpHeaders)) }
+
+ inline fun patchForEntity(
+ uri: URI,
+ payload: Any,
+ httpHeaders: HttpHeaders? = null,
+ ): T = executeMedMetrics(uri) { operations.exchange(uri, HttpMethod.PATCH, HttpEntity(payload, httpHeaders)) }
+
+ inline fun deleteForEntity(
+ uri: URI,
+ payload: Any? = null,
+ httpHeaders: HttpHeaders? = null,
+ ): T = executeMedMetrics(uri) { operations.exchange(uri, HttpMethod.DELETE, HttpEntity(payload, httpHeaders)) }
+
+ private fun validerOgPakkUt(
+ respons: ResponseEntity,
+ uri: URI,
+ ): T {
+ if (!respons.statusCode.is2xxSuccessful) {
+ secureLogger.info("Kall mot $uri feilet: ${respons.body}")
+ log.info("Kall mot $uri feilet: ${respons.statusCode}")
+ throw HttpServerErrorException(respons.statusCode, "", respons.body?.toString()?.toByteArray(), Charsets.UTF_8)
+ }
+ return respons.body as T
+ }
+
+ fun executeMedMetrics(
+ uri: URI,
+ function: () -> ResponseEntity,
+ ): T {
+ try {
+ val startTime = System.nanoTime()
+ val responseEntity = function.invoke()
+ responstid.record(System.nanoTime() - startTime, TimeUnit.NANOSECONDS)
+ responsSuccess.increment()
+ return validerOgPakkUt(responseEntity, uri)
+ } catch (e: RestClientResponseException) {
+ responsFailure.increment()
+ secureLogger.warn("RestClientResponseException ved kall mot uri=$uri", e)
+ lesRessurs(e)?.let { throw RessursException(it, e) } ?: throw e
+ } catch (e: HttpClientErrorException) {
+ responsFailure.increment()
+ secureLogger.warn("HttpClientErrorException ved kall mot uri=$uri", e)
+ lesRessurs(e)?.let { throw RessursException(it, e) } ?: throw e
+ } catch (e: ResourceAccessException) {
+ responsFailure.increment()
+ secureLogger.warn("ResourceAccessException ved kall mot uri=$uri", e)
+ throw e
+ } catch (e: Exception) {
+ responsFailure.increment()
+ secureLogger.warn("Feil ved kall mot uri=$uri", e)
+ throw RuntimeException("Feil ved kall mot uri=$uri", e)
+ }
+ }
+
+ private fun lesRessurs(e: RestClientResponseException): Ressurs? =
+ try {
+ if (e.responseBodyAsString.contains("status")) {
+ objectMapper.readValue>(e.responseBodyAsString)
+ } else {
+ null
+ }
+ } catch (ex: Exception) {
+ null
+ }
+
+ override fun toString(): String = this::class.simpleName + " [operations=" + operations + "]"
+}
diff --git a/src/main/kotlin/no/nav/familie/tilbake/http/BearerTokenClientCredentialClientInterceptor.kt b/src/main/kotlin/no/nav/familie/tilbake/http/BearerTokenClientCredentialClientInterceptor.kt
new file mode 100644
index 000000000..a9714763c
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/http/BearerTokenClientCredentialClientInterceptor.kt
@@ -0,0 +1,27 @@
+package no.nav.familie.tilbake.http
+
+import com.nimbusds.oauth2.sdk.GrantType
+import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenService
+import no.nav.security.token.support.client.spring.ClientConfigurationProperties
+import org.springframework.http.HttpRequest
+import org.springframework.http.client.ClientHttpRequestExecution
+import org.springframework.http.client.ClientHttpResponse
+import org.springframework.stereotype.Component
+
+@Component
+class BearerTokenClientCredentialsClientInterceptor(
+ oAuth2AccessTokenService: OAuth2AccessTokenService,
+ clientConfigurationProperties: ClientConfigurationProperties,
+) : AbstractBearerTokenInterceptor(oAuth2AccessTokenService, clientConfigurationProperties) {
+ override fun intercept(
+ request: HttpRequest,
+ body: ByteArray,
+ execution: ClientHttpRequestExecution,
+ ): ClientHttpResponse {
+ val clientProperties = clientPropertiesForGrantType(clientConfigurationProperties.findByURI(request.uri), GrantType.CLIENT_CREDENTIALS, request.uri)
+ request.headers.setBearerAuth(
+ genererAccessToken(clientProperties)
+ )
+ return execution.execute(request, body)
+ }
+}
diff --git a/src/main/kotlin/no/nav/familie/tilbake/http/BearerTokenClientInterceptor.kt b/src/main/kotlin/no/nav/familie/tilbake/http/BearerTokenClientInterceptor.kt
new file mode 100644
index 000000000..4688626fc
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/http/BearerTokenClientInterceptor.kt
@@ -0,0 +1,50 @@
+package no.nav.familie.tilbake.http
+
+import com.nimbusds.oauth2.sdk.GrantType
+import java.net.URI
+import no.nav.security.token.support.client.core.ClientProperties
+import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenService
+import no.nav.security.token.support.client.spring.ClientConfigurationProperties
+import no.nav.security.token.support.core.exceptions.JwtTokenValidatorException
+import no.nav.security.token.support.spring.SpringTokenValidationContextHolder
+import org.springframework.http.HttpRequest
+import org.springframework.http.client.ClientHttpRequestExecution
+import org.springframework.http.client.ClientHttpResponse
+import org.springframework.stereotype.Component
+
+@Component("entraTokenInterceptor")
+class BearerTokenClientInterceptor(
+ oAuth2AccessTokenService: OAuth2AccessTokenService,
+ clientConfigurationProperties: ClientConfigurationProperties,
+) : AbstractBearerTokenInterceptor(oAuth2AccessTokenService, clientConfigurationProperties) {
+ override fun intercept(
+ request: HttpRequest,
+ body: ByteArray,
+ execution: ClientHttpRequestExecution,
+ ): ClientHttpResponse {
+ request.headers.setBearerAuth(genererAccessToken(clientPropertiesFor(request.uri)))
+ return execution.execute(request, body)
+ }
+
+ private fun clientPropertiesFor(uri: URI): ClientProperties {
+ val clientProperties = clientConfigurationProperties.findByURI(uri)
+ return if (clientProperties.size == 1) {
+ clientProperties.first()
+ } else {
+ clientPropertiesForGrantType(clientProperties, clientCredentialOrJwtBearer(), uri)
+ }
+ }
+
+ private fun clientCredentialOrJwtBearer() = if (erSystembruker()) GrantType.CLIENT_CREDENTIALS else GrantType.JWT_BEARER
+
+ private fun erSystembruker(): Boolean {
+ return try {
+ val preferredUsername =
+ SpringTokenValidationContextHolder().getTokenValidationContext().getClaims("azuread").get("preferred_username")
+ return preferredUsername == null
+ } catch (e: Throwable) {
+ // Ingen request context. Skjer ved kall som har opphav i kjørende applikasjon. Ping etc.
+ true
+ }
+ }
+}
diff --git a/src/main/kotlin/no/nav/familie/tilbake/http/ConsumerIdClientInterceptor.kt b/src/main/kotlin/no/nav/familie/tilbake/http/ConsumerIdClientInterceptor.kt
new file mode 100644
index 000000000..e504f528c
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/http/ConsumerIdClientInterceptor.kt
@@ -0,0 +1,22 @@
+package no.nav.familie.tilbake.http
+
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.http.HttpRequest
+import org.springframework.http.client.ClientHttpRequestExecution
+import org.springframework.http.client.ClientHttpRequestInterceptor
+import org.springframework.http.client.ClientHttpResponse
+import org.springframework.stereotype.Component
+
+@Component
+class ConsumerIdClientInterceptor(
+ @Value("\${application.name}") private val appName: String
+) : ClientHttpRequestInterceptor {
+ override fun intercept(
+ request: HttpRequest,
+ body: ByteArray,
+ execution: ClientHttpRequestExecution,
+ ): ClientHttpResponse {
+ request.headers.add("Nav-Consumer-Id", appName)
+ return execution.execute(request, body)
+ }
+}
diff --git a/src/main/kotlin/no/nav/familie/tilbake/http/MdcValuesPropagatingClientInterceptor.kt b/src/main/kotlin/no/nav/familie/tilbake/http/MdcValuesPropagatingClientInterceptor.kt
new file mode 100644
index 000000000..4dd5d6be8
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/http/MdcValuesPropagatingClientInterceptor.kt
@@ -0,0 +1,19 @@
+package no.nav.familie.tilbake.http
+
+import java.util.UUID
+import org.slf4j.MDC
+import org.springframework.http.HttpRequest
+import org.springframework.http.client.ClientHttpRequestExecution
+import org.springframework.http.client.ClientHttpRequestInterceptor
+import org.springframework.http.client.ClientHttpResponse
+
+class MdcValuesPropagatingClientInterceptor : ClientHttpRequestInterceptor {
+ override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse {
+ val callId = MDC.get("callId") ?: UUID.randomUUID().toString()
+ val requestId = MDC.get("requestId") ?: callId
+ request.headers.add("Nav-Call-Id", callId)
+ request.headers.add("X-Request-ID", requestId)
+
+ return execution.execute(request, body)
+ }
+}
diff --git a/src/main/kotlin/no/nav/familie/tilbake/http/RessursException.kt b/src/main/kotlin/no/nav/familie/tilbake/http/RessursException.kt
new file mode 100644
index 000000000..7456afe7f
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/http/RessursException.kt
@@ -0,0 +1,11 @@
+package no.nav.familie.tilbake.http
+
+import no.nav.familie.kontrakter.felles.Ressurs
+import org.springframework.http.HttpStatus
+import org.springframework.web.client.RestClientResponseException
+
+class RessursException(
+ val ressurs: Ressurs,
+ cause: RestClientResponseException,
+ val httpStatus: HttpStatus = HttpStatus.valueOf(cause.statusCode.value()),
+) : RuntimeException(cause)
diff --git a/src/main/kotlin/no/nav/familie/tilbake/integration/familie/IntegrasjonerClient.kt b/src/main/kotlin/no/nav/familie/tilbake/integration/familie/IntegrasjonerClient.kt
index c08c7ae89..3e27b72aa 100644
--- a/src/main/kotlin/no/nav/familie/tilbake/integration/familie/IntegrasjonerClient.kt
+++ b/src/main/kotlin/no/nav/familie/tilbake/integration/familie/IntegrasjonerClient.kt
@@ -1,6 +1,6 @@
package no.nav.familie.tilbake.integration.familie
-import no.nav.familie.http.client.AbstractPingableRestClient
+import AbstractPingableRestClient
import no.nav.familie.kontrakter.felles.Fagsystem
import no.nav.familie.kontrakter.felles.Fil
import no.nav.familie.kontrakter.felles.Ressurs
@@ -34,19 +34,13 @@ import org.springframework.stereotype.Component
import org.springframework.web.client.RestOperations
import org.springframework.web.util.UriComponentsBuilder
import java.net.URI
+import no.nav.familie.tilbake.log.SecureLog
@Component
class IntegrasjonerClient(
@Qualifier("azure") restOperations: RestOperations,
private val integrasjonerConfig: IntegrasjonerConfig,
) : AbstractPingableRestClient(restOperations, "familie.integrasjoner") {
- override val pingUri: URI =
- UriComponentsBuilder
- .fromUri(integrasjonerConfig.integrasjonUri)
- .path(IntegrasjonerConfig.PATH_PING)
- .build()
- .toUri()
-
private val arkiverUri: URI =
UriComponentsBuilder
.fromUri(integrasjonerConfig.integrasjonUri)
@@ -265,11 +259,16 @@ class IntegrasjonerClient(
)
}
- fun hentJournalposterForBruker(journalposterForBrukerRequest: JournalposterForBrukerRequest): List {
- secureLogger.info(
- "henter journalposter for bruker med ident ${journalposterForBrukerRequest.brukerId} " +
- "og data $journalposterForBrukerRequest",
- )
+ fun hentJournalposterForBruker(
+ journalposterForBrukerRequest: JournalposterForBrukerRequest,
+ logContext: SecureLog.Context,
+ ): List {
+ SecureLog.medContext(logContext) {
+ info(
+ "henter journalposter for bruker med ident ${journalposterForBrukerRequest.brukerId} " +
+ "og data $journalposterForBrukerRequest",
+ )
+ }
return postForEntity>>(hentJournalpostUri(), journalposterForBrukerRequest).getDataOrThrow()
}
diff --git a/src/main/kotlin/no/nav/familie/tilbake/integration/pdl/PdlClient.kt b/src/main/kotlin/no/nav/familie/tilbake/integration/pdl/PdlClient.kt
index 065b068a0..b645dcae4 100644
--- a/src/main/kotlin/no/nav/familie/tilbake/integration/pdl/PdlClient.kt
+++ b/src/main/kotlin/no/nav/familie/tilbake/integration/pdl/PdlClient.kt
@@ -1,6 +1,6 @@
package no.nav.familie.tilbake.integration.pdl
-import no.nav.familie.http.client.AbstractPingableRestClient
+import AbstractPingableRestClient
import no.nav.familie.kontrakter.felles.Fagsystem
import no.nav.familie.kontrakter.felles.Tema
import no.nav.familie.kontrakter.felles.objectMapper
@@ -54,7 +54,9 @@ class PdlClient(
logger.medContext(logContext) {
warn("Advarsel ved henting av personinfo fra PDL. Se securelogs for detaljer.")
}
- secureLogger.warn("Advarsel ved henting av personinfo fra PDL: ${respons.extensions?.warnings}")
+ SecureLog.medContext(logContext) {
+ warn("Advarsel ved henting av personinfo fra PDL: ${respons.extensions?.warnings}")
+ }
}
if (!respons.harFeil()) {
return respons.data.person!!.let {
@@ -100,7 +102,9 @@ class PdlClient(
logger.medContext(logContext) {
warn("Advarsel ved henting av personidenter fra PDL. Se securelogs for detaljer.")
}
- secureLogger.warn("Advarsel ved henting av personidenter fra PDL: ${response.extensions?.warnings}")
+ SecureLog.medContext(logContext) {
+ warn("Advarsel ved henting av personidenter fra PDL: ${response.extensions?.warnings}")
+ }
}
if (!response.harFeil()) return response
throw Feil(
@@ -139,13 +143,6 @@ class PdlClient(
add("behandlingsnummer", tema.behandlingsnummer)
}
- override val pingUri: URI
- get() = pdlConfig.pdlUri
-
- override fun ping() {
- operations.optionsForAllow(pingUri)
- }
-
private fun mapTilTema(fagsystem: Fagsystem): Tema =
when (fagsystem) {
Fagsystem.EF -> Tema.ENF
diff --git "a/src/main/kotlin/no/nav/familie/tilbake/integration/\303\270konomi/OppdragClient.kt" "b/src/main/kotlin/no/nav/familie/tilbake/integration/\303\270konomi/OppdragClient.kt"
index 853d26181..5258db750 100644
--- "a/src/main/kotlin/no/nav/familie/tilbake/integration/\303\270konomi/OppdragClient.kt"
+++ "b/src/main/kotlin/no/nav/familie/tilbake/integration/\303\270konomi/OppdragClient.kt"
@@ -1,6 +1,6 @@
package no.nav.familie.tilbake.integration.økonomi
-import no.nav.familie.http.client.AbstractPingableRestClient
+import AbstractPingableRestClient
import no.nav.familie.kontrakter.felles.Ressurs
import no.nav.familie.kontrakter.felles.getDataOrThrow
import no.nav.familie.kontrakter.felles.objectMapper
@@ -83,13 +83,6 @@ class DefaultOppdragClient(
OppdragClient {
private val logger = TracedLogger.getLogger()
- override val pingUri: URI =
- UriComponentsBuilder
- .fromUri(familieOppdragUrl)
- .path(PING_PATH)
- .build()
- .toUri()
-
private fun iverksettelseUri(behandlingId: UUID): URI =
UriComponentsBuilder
.fromUri(familieOppdragUrl)
diff --git a/src/main/kotlin/no/nav/familie/tilbake/sikkerhet/OIDCUtil.kt b/src/main/kotlin/no/nav/familie/tilbake/sikkerhet/OIDCUtil.kt
new file mode 100644
index 000000000..40284fdf6
--- /dev/null
+++ b/src/main/kotlin/no/nav/familie/tilbake/sikkerhet/OIDCUtil.kt
@@ -0,0 +1,5 @@
+package no.nav.familie.tilbake.sikkerhet
+
+class OIDCUtil {
+
+}
diff --git a/src/test/kotlin/no/nav/familie/tilbake/config/IntegrasjonerClientConfig.kt b/src/test/kotlin/no/nav/familie/tilbake/config/IntegrasjonerClientConfig.kt
index 39df503b9..472cfce09 100644
--- a/src/test/kotlin/no/nav/familie/tilbake/config/IntegrasjonerClientConfig.kt
+++ b/src/test/kotlin/no/nav/familie/tilbake/config/IntegrasjonerClientConfig.kt
@@ -5,7 +5,6 @@ import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.slot
-import no.nav.familie.http.client.RessursException
import no.nav.familie.kontrakter.felles.Ressurs
import no.nav.familie.kontrakter.felles.dokarkiv.ArkiverDokumentResponse
import no.nav.familie.kontrakter.felles.dokarkiv.v2.ArkiverDokumentRequest
@@ -29,6 +28,7 @@ import org.springframework.http.HttpStatus
import org.springframework.web.client.RestClientResponseException
import java.time.LocalDateTime
import java.util.UUID
+import no.nav.familie.tilbake.http.RessursException
@Configuration
@Profile("mock-integrasjoner")
@@ -100,7 +100,7 @@ class IntegrasjonerClientConfig {
every { integrasjonerClient.hentDokument(any(), any()) } returns readMockfileFromResources()
- every { integrasjonerClient.hentJournalposterForBruker(any()) }
+ every { integrasjonerClient.hentJournalposterForBruker(any(), any()) }
.returns(
listOf(
Journalpost(