Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IS-2727: Use sen fase bulk endpoint #439

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .nais/naiserator-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ spec:
- application: ismanglendemedvirkning
- application: istilgangskontroll
- application: ishuskelapp
- application: ismeroppfolging
azure:
application:
allowAllUsers: true
Expand Down Expand Up @@ -107,6 +108,10 @@ spec:
value: "dev-gcp.teamsykefravr.ismanglendemedvirkning"
- name: MANGLENDEMEDVIRKNING_URL
value: "http://ismanglendemedvirkning"
- name: ISMEROPPFOLGING_CLIENT_ID
value: "dev-gcp.teamsykefravr.ismeroppfolging"
- name: ISMEROPPFOLGING_URL
value: "http://ismeroppfolging"
- name: ISTILGANGSKONTROLL_CLIENT_ID
value: "dev-gcp.teamsykefravr.istilgangskontroll"
- name: ISTILGANGSKONTROLL_HOST
Expand Down
5 changes: 5 additions & 0 deletions .nais/naiserator-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ spec:
- application: ismanglendemedvirkning
- application: istilgangskontroll
- application: ishuskelapp
- application: ismeroppfolging
azure:
application:
allowAllUsers: true
Expand Down Expand Up @@ -108,6 +109,10 @@ spec:
value: "prod-gcp.teamsykefravr.ismanglendemedvirkning"
- name: MANGLENDEMEDVIRKNING_URL
value: "http://ismanglendemedvirkning"
- name: ISMEROPPFOLGING_CLIENT_ID
value: "prod-gcp.teamsykefravr.ismeroppfolging"
- name: ISMEROPPFOLGING_URL
value: "http://ismeroppfolging"
- name: ISTILGANGSKONTROLL_CLIENT_ID
value: "prod-gcp.teamsykefravr.istilgangskontroll"
- name: ISTILGANGSKONTROLL_HOST
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/no/nav/syfo/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import no.nav.syfo.personstatus.infrastructure.clients.arbeidsuforhet.Arbeidsufo
import no.nav.syfo.personstatus.infrastructure.clients.manglendemedvirkning.ManglendeMedvirkningClient
import no.nav.syfo.personstatus.infrastructure.clients.azuread.AzureAdClient
import no.nav.syfo.personstatus.infrastructure.clients.behandlendeenhet.BehandlendeEnhetClient
import no.nav.syfo.personstatus.infrastructure.clients.meroppfolging.MerOppfolgingClient
import no.nav.syfo.personstatus.infrastructure.clients.oppfolgingsoppgave.OppfolgingsoppgaveClient
import no.nav.syfo.personstatus.infrastructure.clients.pdl.PdlClient
import no.nav.syfo.personstatus.infrastructure.clients.veiledertilgang.VeilederTilgangskontrollClient
Expand Down Expand Up @@ -72,6 +73,10 @@ fun main() {
azureAdClient = azureAdClient,
clientEnvironment = environment.clients.manglendeMedvirkning,
)
val merOppfolgingClient = MerOppfolgingClient(
azureAdClient = azureAdClient,
clientEnvironment = environment.clients.ismeroppfolging,
)
val veilederTilgangskontrollClient = VeilederTilgangskontrollClient(
azureAdClient = azureAdClient,
istilgangskontrollEnv = environment.clients.istilgangskontroll,
Expand Down Expand Up @@ -114,6 +119,7 @@ fun main() {
aktivitetskravClient = aktivitetskravClient,
manglendeMedvirkningClient = manglendeMedvirkningClient,
arbeidsuforhetvurderingClient = arbeidsuforhetvurderingClient,
merOppfolgingClient = merOppfolgingClient,
),
)
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/no/nav/syfo/ApplicationEnvironment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ data class Environment(
baseUrl = getEnvVar("MANGLENDEMEDVIRKNING_URL"),
clientId = getEnvVar("MANGLENDEMEDVIRKNING_CLIENT_ID"),
),
ismeroppfolging = ClientEnvironment(
baseUrl = getEnvVar("ISMEROPPFOLGING_URL"),
clientId = getEnvVar("ISMEROPPFOLGING_CLIENT_ID"),
),
istilgangskontroll = ClientEnvironment(
baseUrl = getEnvVar("ISTILGANGSKONTROLL_HOST"),
clientId = getEnvVar("ISTILGANGSKONTROLL_CLIENT_ID"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import no.nav.syfo.personstatus.application.arbeidsuforhet.Arbeidsuforhetvurderi
import no.nav.syfo.personstatus.application.arbeidsuforhet.IArbeidsuforhetvurderingClient
import no.nav.syfo.personstatus.application.manglendemedvirkning.IManglendeMedvirkningClient
import no.nav.syfo.personstatus.application.manglendemedvirkning.ManglendeMedvirkningResponseDTO
import no.nav.syfo.personstatus.application.meroppfolging.IMeroppfolgingClient
import no.nav.syfo.personstatus.application.meroppfolging.SenOppfolgingKandidaterResponseDTO
import no.nav.syfo.personstatus.application.oppfolgingsoppgave.IOppfolgingsoppgaveClient
import no.nav.syfo.personstatus.application.oppfolgingsoppgave.OppfolgingsoppgaverResponseDTO
import no.nav.syfo.personstatus.domain.PersonIdent
Expand All @@ -22,6 +24,7 @@ class PersonoversiktOppgaverService(
private val manglendeMedvirkningClient: IManglendeMedvirkningClient,
private val aktivitetskravClient: IAktivitetskravClient,
private val oppfolgingsoppgaveClient: IOppfolgingsoppgaveClient,
private val merOppfolgingClient: IMeroppfolgingClient,
) {
private val log = LoggerFactory.getLogger(this::class.java)

Expand Down Expand Up @@ -50,6 +53,11 @@ class PersonoversiktOppgaverService(
token = token,
personStatuser = personer,
)
val senOppfolgingKandidater = getSenOppfolgingKandidaterForPersons(
callId = callId,
token = token,
personStatuser = personer,
)

return personer.associate {
it.fnr to PersonoversiktAktiveOppgaver(
Expand All @@ -65,6 +73,9 @@ class PersonoversiktOppgaverService(
manglendeMedvirkning = manglendeMedvirkning.await()
?.vurderinger
?.get(it.fnr),
senOppfolgingKandidat = senOppfolgingKandidater.await()
?.kandidater
?.get(it.fnr),
)
}
}
Expand Down Expand Up @@ -152,4 +163,24 @@ class PersonoversiktOppgaverService(
null
}
}

private fun getSenOppfolgingKandidaterForPersons(
callId: String,
token: String,
personStatuser: List<PersonOversiktStatus>,
): Deferred<SenOppfolgingKandidaterResponseDTO?> =
CoroutineScope(Dispatchers.IO).async {
val personidenterWithActiveSenOppfolgingKandidat = personStatuser
.filter { it.isAktivSenOppfolgingKandidat }
.map { PersonIdent(it.fnr) }
if (personidenterWithActiveSenOppfolgingKandidat.isNotEmpty()) {
merOppfolgingClient.getSenOppfolgingKandidater(
callId = callId,
token = token,
personidenter = personidenterWithActiveSenOppfolgingKandidat,
)
} else {
null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ fun Route.registerPersonoversiktApiV2(
oppfolgingsoppgave = aktiveOppgaver?.oppfolgingsoppgave,
aktivitetskravvurdering = aktiveOppgaver?.aktivitetskrav,
manglendeMedvirkning = aktiveOppgaver?.manglendeMedvirkning,
senOppfolgingKandidat = aktiveOppgaver?.senOppfolgingKandidat,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package no.nav.syfo.personstatus.api.v2.model
import no.nav.syfo.personstatus.application.aktivitetskrav.AktivitetskravDTO
import no.nav.syfo.personstatus.application.arbeidsuforhet.ArbeidsuforhetvurderingDTO
import no.nav.syfo.personstatus.application.manglendemedvirkning.ManglendeMedvirkningDTO
import no.nav.syfo.personstatus.application.meroppfolging.SenOppfolgingKandidatDTO
import no.nav.syfo.personstatus.application.oppfolgingsoppgave.OppfolgingsoppgaveDTO
import java.time.LocalDate

Expand All @@ -22,7 +23,8 @@ data class PersonOversiktStatusDTO(
val arbeidsuforhetvurdering: ArbeidsuforhetvurderingDTO?,
val friskmeldingTilArbeidsformidlingFom: LocalDate?,
val oppfolgingsoppgave: OppfolgingsoppgaveDTO?,
val isAktivSenOppfolgingKandidat: Boolean,
val isAktivSenOppfolgingKandidat: Boolean, // TODO: Denne kan fjernes når frontend bruker senOppfolgingKandidat
val senOppfolgingKandidat: SenOppfolgingKandidatDTO?,
val aktivitetskravvurdering: AktivitetskravDTO?,
val manglendeMedvirkning: ManglendeMedvirkningDTO?,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package no.nav.syfo.personstatus.application
import no.nav.syfo.personstatus.application.aktivitetskrav.AktivitetskravDTO
import no.nav.syfo.personstatus.application.arbeidsuforhet.ArbeidsuforhetvurderingDTO
import no.nav.syfo.personstatus.application.manglendemedvirkning.ManglendeMedvirkningDTO
import no.nav.syfo.personstatus.application.meroppfolging.SenOppfolgingKandidatDTO
import no.nav.syfo.personstatus.application.oppfolgingsoppgave.OppfolgingsoppgaveDTO

data class PersonoversiktAktiveOppgaver(
val arbeidsuforhet: ArbeidsuforhetvurderingDTO?,
val oppfolgingsoppgave: OppfolgingsoppgaveDTO?,
val aktivitetskrav: AktivitetskravDTO?,
val manglendeMedvirkning: ManglendeMedvirkningDTO?,
val senOppfolgingKandidat: SenOppfolgingKandidatDTO?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package no.nav.syfo.personstatus.application.meroppfolging

import no.nav.syfo.personstatus.domain.PersonIdent

interface IMeroppfolgingClient {
suspend fun getSenOppfolgingKandidater(
callId: String,
token: String,
personidenter: List<PersonIdent>,
): SenOppfolgingKandidaterResponseDTO?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package no.nav.syfo.personstatus.application.meroppfolging

import java.time.LocalDateTime
import java.util.*

data class SenOppfolgingKandidaterRequestDTO(
val personidenter: List<String>
)

data class SenOppfolgingKandidaterResponseDTO(
val kandidater: Map<String, SenOppfolgingKandidatDTO>
)

data class SenOppfolgingKandidatDTO(
val uuid: UUID,
val personident: String,
val varselAt: LocalDateTime?,
val svar: SvarResponseDTO?,
)

data class SvarResponseDTO(
val svarAt: LocalDateTime,
val onskerOppfolging: OnskerOppfolging,
)

enum class OnskerOppfolging {
JA,
NEI,
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import no.nav.syfo.personstatus.api.v2.model.PersonOversiktStatusDTO
import no.nav.syfo.personstatus.application.aktivitetskrav.AktivitetskravDTO
import no.nav.syfo.personstatus.application.arbeidsuforhet.ArbeidsuforhetvurderingDTO
import no.nav.syfo.personstatus.application.manglendemedvirkning.ManglendeMedvirkningDTO
import no.nav.syfo.personstatus.application.meroppfolging.SenOppfolgingKandidatDTO
import no.nav.syfo.personstatus.application.oppfolgingsoppgave.OppfolgingsoppgaveDTO
import no.nav.syfo.util.isBeforeOrEqual
import no.nav.syfo.util.toLocalDateOslo
Expand Down Expand Up @@ -91,6 +92,7 @@ fun PersonOversiktStatus.toPersonOversiktStatusDTO(
oppfolgingsoppgave: OppfolgingsoppgaveDTO?,
aktivitetskravvurdering: AktivitetskravDTO?,
manglendeMedvirkning: ManglendeMedvirkningDTO?,
senOppfolgingKandidat: SenOppfolgingKandidatDTO?,
) =
PersonOversiktStatusDTO(
veilederIdent = veilederIdent,
Expand All @@ -111,6 +113,7 @@ fun PersonOversiktStatus.toPersonOversiktStatusDTO(
isAktivSenOppfolgingKandidat = isAktivSenOppfolgingKandidat,
aktivitetskravvurdering = aktivitetskravvurdering,
manglendeMedvirkning = manglendeMedvirkning,
senOppfolgingKandidat = senOppfolgingKandidat,
)

fun PersonOversiktStatus.hasActiveBehandlerdialogOppgave(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ data class ClientsEnvironment(
val aktivitetskrav: ClientEnvironment,
val istilgangskontroll: ClientEnvironment,
val ishuskelapp: ClientEnvironment,
val ismeroppfolging: ClientEnvironment,
)

data class ClientEnvironment(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package no.nav.syfo.personstatus.infrastructure.clients.meroppfolging

import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.micrometer.core.instrument.Counter
import net.logstash.logback.argument.StructuredArguments
import no.nav.syfo.personstatus.application.meroppfolging.IMeroppfolgingClient
import no.nav.syfo.personstatus.application.meroppfolging.SenOppfolgingKandidaterRequestDTO
import no.nav.syfo.personstatus.application.meroppfolging.SenOppfolgingKandidaterResponseDTO
import no.nav.syfo.personstatus.domain.PersonIdent
import no.nav.syfo.personstatus.infrastructure.METRICS_NS
import no.nav.syfo.personstatus.infrastructure.METRICS_REGISTRY
import no.nav.syfo.personstatus.infrastructure.clients.ClientEnvironment
import no.nav.syfo.personstatus.infrastructure.clients.azuread.AzureAdClient
import no.nav.syfo.personstatus.infrastructure.clients.httpClientDefault
import no.nav.syfo.util.NAV_CALL_ID_HEADER
import no.nav.syfo.util.bearerHeader
import no.nav.syfo.util.callIdArgument
import org.slf4j.LoggerFactory

class MerOppfolgingClient(
private val azureAdClient: AzureAdClient,
private val clientEnvironment: ClientEnvironment,
private val httpClient: HttpClient = httpClientDefault(),
) : IMeroppfolgingClient {

override suspend fun getSenOppfolgingKandidater(
callId: String,
token: String,
personidenter: List<PersonIdent>
): SenOppfolgingKandidaterResponseDTO? {
val oboToken = azureAdClient.getOnBehalfOfToken(
scopeClientId = clientEnvironment.clientId,
token,
)?.accessToken ?: throw RuntimeException("Failed to get OBO-token for sen oppfolging kandidater")
val requestDTO = SenOppfolgingKandidaterRequestDTO(personidenter.map { it.value })

return try {
val response = httpClient.post("${clientEnvironment.baseUrl}$MEROPPFOLGING_SENOPPFOLGING_KANDIDATER_API_PATH") {
header(HttpHeaders.Authorization, bearerHeader(oboToken))
header(NAV_CALL_ID_HEADER, callId)
accept(ContentType.Application.Json)
contentType(ContentType.Application.Json)
setBody(requestDTO)
}
when (response.status) {
HttpStatusCode.OK -> {
COUNT_CALL_MEROPPFOLGING_SUCCESS.increment()
response.body<SenOppfolgingKandidaterResponseDTO>()
}
HttpStatusCode.NotFound -> {
log.error("Resource not found")
COUNT_CALL_MEROPPFOLGING_FAIL.increment()
null
}
else -> {
log.error("Unhandled status code: ${response.status}")
COUNT_CALL_MEROPPFOLGING_FAIL.increment()
null
}
}
} catch (e: ClientRequestException) {
handleUnexpectedResponseException(e.response, callId)
throw e
} catch (e: ServerResponseException) {
handleUnexpectedResponseException(e.response, callId)
throw e
}
}

private fun handleUnexpectedResponseException(
response: HttpResponse,
callId: String,
) {
log.error(
"Error while requesting from ismeroppfolging with {}, {}",
StructuredArguments.keyValue("statusCode", response.status.value.toString()),
callIdArgument(callId)
)
COUNT_CALL_MEROPPFOLGING_FAIL.increment()
}

companion object {
const val MEROPPFOLGING_SENOPPFOLGING_KANDIDATER_API_PATH = "/api/internad/v1/senoppfolging/get-kandidater"
private val log = LoggerFactory.getLogger(this::class.java)

private const val CALL_MEROPPFOLGING_BASE = "${METRICS_NS}_call_ismeroppfolging"
private const val CALL_MEROPPFOLGING_SUCCESS = "${CALL_MEROPPFOLGING_BASE}_success_count"
private const val CALL_MEROPPFOLGING_FAIL = "${CALL_MEROPPFOLGING_BASE}_fail_count"

val COUNT_CALL_MEROPPFOLGING_SUCCESS: Counter = Counter
.builder(CALL_MEROPPFOLGING_SUCCESS)
.description("Counts the number of successful calls to ismeroppfolging")
.register(METRICS_REGISTRY)
val COUNT_CALL_MEROPPFOLGING_FAIL: Counter = Counter
.builder(CALL_MEROPPFOLGING_FAIL)
.description("Counts the number of failed calls to ismeroppfolging")
.register(METRICS_REGISTRY)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ object PersonoversiktStatusApiV2Spek : Spek({
personOversiktStatus.fnr shouldBeEqualTo personident
personOversiktStatus.enhet shouldBeEqualTo NAV_ENHET
personOversiktStatus.isAktivSenOppfolgingKandidat shouldBeEqualTo true
personOversiktStatus.senOppfolgingKandidat shouldNotBe null
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import no.nav.syfo.personstatus.infrastructure.clients.aktivitetskrav.Aktivitets
import no.nav.syfo.personstatus.infrastructure.clients.arbeidsuforhet.ArbeidsuforhetvurderingClient
import no.nav.syfo.personstatus.infrastructure.clients.manglendemedvirkning.ManglendeMedvirkningClient
import no.nav.syfo.personstatus.infrastructure.clients.azuread.AzureAdClient
import no.nav.syfo.personstatus.infrastructure.clients.meroppfolging.MerOppfolgingClient
import no.nav.syfo.personstatus.infrastructure.clients.oppfolgingsoppgave.OppfolgingsoppgaveClient
import no.nav.syfo.personstatus.infrastructure.database.repository.PersonOversiktStatusRepository

Expand Down Expand Up @@ -59,6 +60,11 @@ class InternalMockEnvironment private constructor() {
clientEnvironment = environment.clients.aktivitetskrav,
httpClient = externalMockEnvironment.mockHttpClient
)
private val merOppfolgingClient = MerOppfolgingClient(
azureAdClient = azureAdClient,
clientEnvironment = environment.clients.ismeroppfolging,
httpClient = externalMockEnvironment.mockHttpClient
)
private val eregClient = EregClient(
clientEnvironment = environment.clients.ereg,
redisStore = redisStore,
Expand Down
Loading