-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
IS-2577: Add pdlClient to get name in api for journalforing
- Loading branch information
1 parent
50ae3f9
commit 06f0098
Showing
15 changed files
with
381 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
src/main/kotlin/no/nav/syfo/infrastructure/clients/pdl/PdlClient.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package no.nav.syfo.infrastructure.clients.pdl | ||
|
||
import io.ktor.client.* | ||
import io.ktor.client.call.* | ||
import io.ktor.client.request.* | ||
import io.ktor.client.statement.* | ||
import io.ktor.http.* | ||
import io.micrometer.core.instrument.Counter | ||
import no.nav.syfo.domain.Personident | ||
import no.nav.syfo.infrastructure.clients.ClientEnvironment | ||
import no.nav.syfo.infrastructure.clients.azuread.AzureAdClient | ||
import no.nav.syfo.infrastructure.bearerHeader | ||
import no.nav.syfo.infrastructure.clients.pdl.dto.* | ||
import no.nav.syfo.infrastructure.clients.httpClientDefault | ||
import no.nav.syfo.infrastructure.metric.METRICS_NS | ||
import no.nav.syfo.infrastructure.metric.METRICS_REGISTRY | ||
import org.slf4j.LoggerFactory | ||
|
||
class PdlClient( | ||
private val azureAdClient: AzureAdClient, | ||
private val pdlEnvironment: ClientEnvironment, | ||
private val httpClient: HttpClient = httpClientDefault(), | ||
) { | ||
|
||
suspend fun getPerson(personident: Personident): PdlPerson { | ||
val token = azureAdClient.getSystemToken(pdlEnvironment.clientId) | ||
?: throw RuntimeException("Failed to send request to PDL: No token was found") | ||
val request = PdlHentPersonRequest(getPdlQuery(), PdlHentPersonRequestVariables(personident.value)) | ||
|
||
val response: HttpResponse = httpClient.post(pdlEnvironment.baseUrl) { | ||
setBody(request) | ||
header(HttpHeaders.ContentType, "application/json") | ||
header(HttpHeaders.Authorization, bearerHeader(token.accessToken)) | ||
header(BEHANDLINGSNUMMER_HEADER_KEY, BEHANDLINGSNUMMER_HEADER_VALUE) | ||
} | ||
|
||
val person = when (response.status) { | ||
HttpStatusCode.OK -> { | ||
val pdlPersonReponse = response.body<PdlPersonResponse>() | ||
if (!pdlPersonReponse.errors.isNullOrEmpty()) { | ||
Metrics.COUNT_CALL_PDL_PERSON_FAIL.increment() | ||
pdlPersonReponse.errors.forEach { | ||
logger.error("Error while requesting person from PersonDataLosningen: ${it.errorMessage()}") | ||
} | ||
null | ||
} else { | ||
Metrics.COUNT_CALL_PDL_PERSON_SUCCESS.increment() | ||
pdlPersonReponse.data?.hentPerson | ||
} | ||
} | ||
|
||
else -> { | ||
Metrics.COUNT_CALL_PDL_PERSON_FAIL.increment() | ||
logger.error("Request with url: ${pdlEnvironment.baseUrl} failed with reponse code ${response.status.value}") | ||
null | ||
} | ||
} | ||
|
||
return person ?: throw RuntimeException("PDL did not return a person for given fnr") | ||
} | ||
|
||
private fun getPdlQuery(): String = | ||
this::class.java.getResource(PDL_QUERY_PATH)!! | ||
.readText() | ||
.replace("[\n\r]", "") | ||
|
||
companion object { | ||
private const val PDL_QUERY_PATH = "/pdl/hentPerson.graphql" | ||
|
||
// Se behandlingskatalog https://behandlingskatalog.intern.nav.no/ | ||
// Behandling: Sykefraværsoppfølging: Vurdere behov for oppfølging og rett til sykepenger etter §§ 8-4 og 8-8 | ||
private const val BEHANDLINGSNUMMER_HEADER_KEY = "behandlingsnummer" | ||
private const val BEHANDLINGSNUMMER_HEADER_VALUE = "B426" | ||
|
||
private val logger = LoggerFactory.getLogger(PdlClient::class.java) | ||
} | ||
} | ||
|
||
private class Metrics { | ||
companion object { | ||
const val CALL_PDL_PERSON_BASE = "${METRICS_NS}_call_pdl_person" | ||
const val CALL_PDL_PERSON_SUCCESS = "${CALL_PDL_PERSON_BASE}_success_count" | ||
const val CALL_PDL_PERSON_FAIL = "${CALL_PDL_PERSON_BASE}_fail_count" | ||
|
||
val COUNT_CALL_PDL_PERSON_SUCCESS: Counter = Counter.builder(CALL_PDL_PERSON_SUCCESS) | ||
.description("Counts the number of successful calls to pdl - person") | ||
.register(METRICS_REGISTRY) | ||
val COUNT_CALL_PDL_PERSON_FAIL: Counter = Counter.builder(CALL_PDL_PERSON_FAIL) | ||
.description("Counts the number of failed calls to pdl - person") | ||
.register(METRICS_REGISTRY) | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/kotlin/no/nav/syfo/infrastructure/clients/pdl/dto/PdlError.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package no.nav.syfo.infrastructure.clients.pdl.dto | ||
|
||
data class PdlError( | ||
val message: String, | ||
val locations: List<PdlErrorLocation>, | ||
val path: List<String>?, | ||
val extensions: PdlErrorExtension, | ||
) | ||
|
||
data class PdlErrorLocation( | ||
val line: Int?, | ||
val column: Int?, | ||
) | ||
|
||
data class PdlErrorExtension( | ||
val code: String?, | ||
val classification: String, | ||
) | ||
|
||
fun PdlError.errorMessage(): String { | ||
return "${this.message} with code: ${extensions.code} and classification: ${extensions.classification}" | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/kotlin/no/nav/syfo/infrastructure/clients/pdl/dto/PdlHentPersonRequest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package no.nav.syfo.infrastructure.clients.pdl.dto | ||
|
||
data class PdlHentPersonRequest( | ||
val query: String, | ||
val variables: PdlHentPersonRequestVariables | ||
) | ||
|
||
data class PdlHentPersonRequestVariables( | ||
val ident: String, | ||
val navnHistorikk: Boolean = false | ||
) |
51 changes: 51 additions & 0 deletions
51
src/main/kotlin/no/nav/syfo/infrastructure/clients/pdl/dto/PdlPersonResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package no.nav.syfo.infrastructure.clients.pdl.dto | ||
|
||
import java.util.* | ||
|
||
data class PdlPersonResponse( | ||
val errors: List<PdlError>?, | ||
val data: PdlHentPerson? | ||
) | ||
|
||
data class PdlHentPerson( | ||
val hentPerson: PdlPerson? | ||
) | ||
|
||
data class PdlPerson( | ||
val navn: List<PdlPersonNavn>, | ||
) { | ||
val fullName: String = navn.firstOrNull()?.fullName() | ||
?: throw RuntimeException("PDL returned empty navn for given fnr") | ||
} | ||
|
||
data class PdlPersonNavn( | ||
val fornavn: String, | ||
val mellomnavn: String?, | ||
val etternavn: String | ||
) { | ||
fun fullName(): String { | ||
val fornavn = fornavn.lowerCapitalize() | ||
val etternavn = etternavn.lowerCapitalize() | ||
|
||
return if (mellomnavn.isNullOrBlank()) { | ||
"$fornavn $etternavn" | ||
} else { | ||
"$fornavn ${mellomnavn.lowerCapitalize()} $etternavn" | ||
} | ||
} | ||
} | ||
|
||
fun String.lowerCapitalize() = | ||
this.split(" ").joinToString(" ") { name -> | ||
val nameWithDash = name.split("-") | ||
if (nameWithDash.size > 1) { | ||
nameWithDash.joinToString("-") { it.capitalizeName() } | ||
} else { | ||
name.capitalizeName() | ||
} | ||
} | ||
|
||
private fun String.capitalizeName() = | ||
this.lowercase(Locale.getDefault()).replaceFirstChar { | ||
if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
query($ident: ID!, $navnHistorikk: Boolean!){ | ||
hentPerson(ident: $ident) { | ||
navn(historikk: $navnHistorikk) { | ||
fornavn | ||
mellomnavn | ||
etternavn | ||
forkortetNavn | ||
originaltNavn { | ||
fornavn | ||
mellomnavn | ||
etternavn | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package no.nav.syfo.generator | ||
|
||
import no.nav.syfo.UserConstants | ||
import no.nav.syfo.infrastructure.clients.pdl.dto.* | ||
|
||
fun generatePdlPersonResponse(pdlPersonNavn: PdlPersonNavn? = null, errors: List<PdlError>? = null) = PdlPersonResponse( | ||
errors = errors, | ||
data = generatePdlHentPerson(pdlPersonNavn) | ||
) | ||
|
||
fun generatePdlPersonNavn(): PdlPersonNavn = PdlPersonNavn( | ||
fornavn = UserConstants.PERSON_FORNAVN, | ||
mellomnavn = UserConstants.PERSON_MELLOMNAVN, | ||
etternavn = UserConstants.PERSON_ETTERNAVN, | ||
) | ||
|
||
fun generatePdlHentPerson( | ||
pdlPersonNavn: PdlPersonNavn?, | ||
): PdlHentPerson = PdlHentPerson( | ||
hentPerson = PdlPerson( | ||
navn = if (pdlPersonNavn != null) listOf(pdlPersonNavn) else emptyList(), | ||
) | ||
) | ||
|
||
fun generatePdlError() = listOf( | ||
PdlError( | ||
message = "Error in PDL", | ||
locations = emptyList(), | ||
path = null, | ||
extensions = PdlErrorExtension( | ||
code = null, | ||
classification = "", | ||
) | ||
) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
src/test/kotlin/no/nav/syfo/infrastructure/mock/PdlMock.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package no.nav.syfo.infrastructure.mock | ||
|
||
import io.ktor.client.engine.mock.* | ||
import io.ktor.client.request.* | ||
import no.nav.syfo.UserConstants | ||
import no.nav.syfo.domain.Personident | ||
import no.nav.syfo.generator.generatePdlError | ||
import no.nav.syfo.generator.generatePdlPersonNavn | ||
import no.nav.syfo.generator.generatePdlPersonResponse | ||
import no.nav.syfo.infrastructure.clients.pdl.dto.PdlHentPersonRequest | ||
import no.nav.syfo.infrastructure.clients.pdl.dto.PdlPersonNavn | ||
|
||
suspend fun MockRequestHandleScope.pdlMockResponse(request: HttpRequestData): HttpResponseData { | ||
val pdlRequest = request.receiveBody<PdlHentPersonRequest>() | ||
return when (Personident(pdlRequest.variables.ident)) { | ||
UserConstants.ARBEIDSTAKER_PERSONIDENT_NO_NAME -> respond(generatePdlPersonResponse(pdlPersonNavn = null)) | ||
UserConstants.ARBEIDSTAKER_PERSONIDENT_NAME_WITH_DASH -> respond( | ||
generatePdlPersonResponse( | ||
PdlPersonNavn( | ||
fornavn = UserConstants.PERSON_FORNAVN_DASH, | ||
mellomnavn = UserConstants.PERSON_MELLOMNAVN, | ||
etternavn = UserConstants.PERSON_ETTERNAVN, | ||
) | ||
) | ||
) | ||
UserConstants.ARBEIDSTAKER_PERSONIDENT_PDL_FAILS -> respond(generatePdlPersonResponse(errors = generatePdlError())) | ||
else -> respond(generatePdlPersonResponse(generatePdlPersonNavn())) | ||
} | ||
} |
Oops, something went wrong.