Skip to content

Commit

Permalink
IS-2632: Generate pdf for vurdering (#18)
Browse files Browse the repository at this point in the history
* IS-2632: Generate pdf for vurdering

* IS-2632: Fix PR feedback
  • Loading branch information
andersrognstad authored Aug 28, 2024
1 parent 9ee0938 commit f1c7e3a
Show file tree
Hide file tree
Showing 20 changed files with 401 additions and 35 deletions.
1 change: 1 addition & 0 deletions .nais/naiserator-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ spec:
- host: "dokarkiv.dev-fss-pub.nais.io"
rules:
- application: istilgangskontroll
- application: ispdfgen
gcp:
sqlInstances:
- type: POSTGRES_15
Expand Down
1 change: 1 addition & 0 deletions .nais/naiserator-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ spec:
- host: "dokarkiv.prod-fss-pub.nais.io"
rules:
- application: istilgangskontroll
- application: ispdfgen
gcp:
sqlInstances:
- type: POSTGRES_15
Expand Down
12 changes: 12 additions & 0 deletions src/main/kotlin/no/nav/syfo/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import no.nav.syfo.api.apiModule
import no.nav.syfo.application.VurderingService
import no.nav.syfo.infrastructure.clients.azuread.AzureAdClient
import no.nav.syfo.infrastructure.clients.dokarkiv.DokarkivClient
import no.nav.syfo.infrastructure.clients.pdfgen.PdfGenClient
import no.nav.syfo.infrastructure.clients.pdfgen.VurderingPdfService
import no.nav.syfo.infrastructure.clients.pdl.PdlClient
import no.nav.syfo.infrastructure.clients.veiledertilgang.VeilederTilgangskontrollClient
import no.nav.syfo.infrastructure.clients.wellknown.getWellKnown
Expand Down Expand Up @@ -49,6 +51,10 @@ fun main() {
azureAdClient = azureAdClient,
clientEnvironment = environment.clients.istilgangskontroll,
)
val pdfGenClient = PdfGenClient(
pdfGenBaseUrl = environment.clients.ispdfgen.baseUrl,
)

val vurderingProducer = VurderingProducer(
producer = KafkaProducer(kafkaAivenProducerConfig<VurderingRecordSerializer>(kafkaEnvironment = environment.kafka))
)
Expand All @@ -57,6 +63,11 @@ fun main() {
pdlClient = pdlClient,
)

val vurderingPdfService = VurderingPdfService(
pdfGenClient = pdfGenClient,
pdlClient = pdlClient,
)

val applicationEngineEnvironment =
applicationEngineEnvironment {
log = logger
Expand All @@ -83,6 +94,7 @@ fun main() {
journalforingService = journalforingService,
vurderingRepository = vurderingRepository,
vurderingProducer = vurderingProducer,
vurderingPdfService = vurderingPdfService,
)
)
}
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 @@ -2,6 +2,7 @@ package no.nav.syfo

import no.nav.syfo.infrastructure.clients.ClientEnvironment
import no.nav.syfo.infrastructure.clients.ClientsEnvironment
import no.nav.syfo.infrastructure.clients.OpenClientEnvironment
import no.nav.syfo.infrastructure.clients.azuread.AzureEnvironment
import no.nav.syfo.infrastructure.database.DatabaseEnvironment
import no.nav.syfo.infrastructure.kafka.KafkaEnvironment
Expand Down Expand Up @@ -39,6 +40,9 @@ data class Environment(
baseUrl = getEnvVar("DOKARKIV_URL"),
clientId = getEnvVar("DOKARKIV_CLIENT_ID")
),
ispdfgen = OpenClientEnvironment(
baseUrl = "http://ispdfgen"
),
),
val kafka: KafkaEnvironment = KafkaEnvironment(
aivenBootstrapServers = getEnvVar("KAFKA_BROKERS"),
Expand Down
10 changes: 10 additions & 0 deletions src/main/kotlin/no/nav/syfo/application/IVurderingPdfService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package no.nav.syfo.application

import no.nav.syfo.domain.ManglendeMedvirkningVurdering

interface IVurderingPdfService {
suspend fun createVurderingPdf(
vurdering: ManglendeMedvirkningVurdering,
callId: String,
): ByteArray
}
10 changes: 7 additions & 3 deletions src/main/kotlin/no/nav/syfo/application/VurderingService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ class VurderingService(
private val journalforingService: IJournalforingService,
private val vurderingRepository: IVurderingRepository,
private val vurderingProducer: IVurderingProducer,
private val vurderingPdfService: IVurderingPdfService,
) {

fun createNewVurdering(
suspend fun createNewVurdering(
personident: Personident,
veilederident: Veilederident,
vurderingType: VurderingType,
Expand All @@ -33,11 +34,14 @@ class VurderingService(
type = vurderingType,
)

// TODO: Get vurdering pdf from ispdfgen
val pdf = vurderingPdfService.createVurderingPdf(
vurdering = newVurdering,
callId = callId,
)

val savedVurdering = vurderingRepository.saveManglendeMedvirkningVurdering(
vurdering = newVurdering,
vurderingPdf = byteArrayOf(),
vurderingPdf = pdf,
)

vurderingProducer.publishVurdering(savedVurdering)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ data class ClientsEnvironment(
val istilgangskontroll: ClientEnvironment,
val pdl: ClientEnvironment,
val dokarkiv: ClientEnvironment,
val ispdfgen: OpenClientEnvironment,
)

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

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.infrastructure.NAV_CALL_ID_HEADER
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 PdfGenClient(
private val httpClient: HttpClient = httpClientDefault(),
private val pdfGenBaseUrl: String
) {

suspend fun createForhandsvarselPdf(
callId: String,
forhandsvarselPdfDTO: VurderingPdfDTO,
): ByteArray =
getPdf(
callId = callId,
payload = forhandsvarselPdfDTO,
pdfUrl = "$pdfGenBaseUrl$API_BASE_PATH$FORHANDSVARSEL_PATH"
) ?: throw RuntimeException("Failed to request pdf for forhandsvarsel, callId: $callId")

suspend fun createVurderingPdf(
callId: String,
vurderingPdfDTO: VurderingPdfDTO,
): ByteArray =
getPdf(
callId = callId,
payload = vurderingPdfDTO,
pdfUrl = "$pdfGenBaseUrl$API_BASE_PATH$VURDERING_PATH"
) ?: throw RuntimeException("Failed to request pdf for vurdering, callId: $callId")

suspend fun createStansPdf(
callId: String,
stansPdfDTO: VurderingPdfDTO,
): ByteArray =
getPdf(
callId = callId,
payload = stansPdfDTO,
pdfUrl = "$pdfGenBaseUrl$API_BASE_PATH$STANS_PATH"
) ?: throw RuntimeException("Failed to request pdf for stans, callId: $callId")

private suspend inline fun <reified Payload> getPdf(
callId: String,
payload: Payload,
pdfUrl: String,
): ByteArray? =
try {
val response: HttpResponse = httpClient.post(pdfUrl) {
header(NAV_CALL_ID_HEADER, callId)
accept(ContentType.Application.Json)
contentType(ContentType.Application.Json)
setBody(payload)
}
Metrics.COUNT_CALL_PDFGEN_SUCCESS.increment()
response.body()
} catch (e: ResponseException) {
handleUnexpectedResponseException(pdfUrl, e.response, callId)
}

private fun handleUnexpectedResponseException(
url: String,
response: HttpResponse,
callId: String,
): ByteArray? {
log.error(
"Error while requesting PDF from ispdfgen with {}, {}, {}",
StructuredArguments.keyValue("statusCode", response.status.value.toString()),
StructuredArguments.keyValue("url", url),
StructuredArguments.keyValue("callId", callId),
)
Metrics.COUNT_CALL_PDFGEN_FAIL.increment()
return null
}

companion object {
private const val API_BASE_PATH = "/api/v1/genpdf/ismanglendemedvirkning"
const val FORHANDSVARSEL_PATH = "/forhandsvarsel-om-stans-av-sykepenger"
const val VURDERING_PATH = "/vurdering-av-manglende-medvirkning"
const val STANS_PATH = "/innstilling-om-stans"

private val log = LoggerFactory.getLogger(PdfGenClient::class.java)
}
}

private object Metrics {
private const val CALL_PDFGEN_BASE = "${METRICS_NS}_call_ispdfgen"

private const val CALL_PDFGEN_SUCCESS = "${CALL_PDFGEN_BASE}_success_count"
private const val CALL_PDFGEN_FAIL = "${CALL_PDFGEN_BASE}_fail_count"

val COUNT_CALL_PDFGEN_SUCCESS: Counter = Counter
.builder(CALL_PDFGEN_SUCCESS)
.description("Counts the number of successful calls to ispdfgen")
.register(METRICS_REGISTRY)
val COUNT_CALL_PDFGEN_FAIL: Counter = Counter
.builder(CALL_PDFGEN_FAIL)
.description("Counts the number of failed calls to ispdfgen")
.register(METRICS_REGISTRY)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package no.nav.syfo.infrastructure.clients.pdfgen

import no.nav.syfo.domain.DocumentComponent
import no.nav.syfo.domain.Personident
import no.nav.syfo.domain.sanitizeForPdfGen
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.*

data class VurderingPdfDTO private constructor(
val mottakerNavn: String,
val mottakerFodselsnummer: String,
val datoSendt: String,
val documentComponents: List<DocumentComponent>,
) {
constructor(
mottakerNavn: String,
mottakerPersonident: Personident,
documentComponents: List<DocumentComponent>,
) : this(
mottakerNavn = mottakerNavn,
mottakerFodselsnummer = mottakerPersonident.value,
datoSendt = LocalDate.now().format(formatter),
documentComponents = documentComponents.sanitizeForPdfGen()
)

companion object {
private val formatter = DateTimeFormatter.ofPattern("dd. MMMM yyyy", Locale("no", "NO"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package no.nav.syfo.infrastructure.clients.pdfgen

import no.nav.syfo.application.IVurderingPdfService
import no.nav.syfo.domain.ManglendeMedvirkningVurdering
import no.nav.syfo.domain.VurderingType
import no.nav.syfo.infrastructure.clients.pdl.PdlClient

class VurderingPdfService(
private val pdfGenClient: PdfGenClient,
private val pdlClient: PdlClient,
) : IVurderingPdfService {

override suspend fun createVurderingPdf(
vurdering: ManglendeMedvirkningVurdering,
callId: String,
): ByteArray {
val personNavn = pdlClient.getPerson(vurdering.personident).fullName
val vurderingPdfDTO = VurderingPdfDTO(
documentComponents = vurdering.document,
mottakerNavn = personNavn,
mottakerPersonident = vurdering.personident,
)

return when (vurdering.vurderingType) {
VurderingType.FORHANDSVARSEL -> pdfGenClient.createForhandsvarselPdf(
callId = callId,
forhandsvarselPdfDTO = vurderingPdfDTO,
)
VurderingType.OPPFYLT, VurderingType.IKKE_AKTUELL -> pdfGenClient.createVurderingPdf(
callId = callId,
vurderingPdfDTO = vurderingPdfDTO,
)
VurderingType.STANS -> pdfGenClient.createStansPdf(
callId = callId,
stansPdfDTO = vurderingPdfDTO,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ private fun ResultSet.toPVarsel(): PVarsel =
publishedAt = getObject("published_at", OffsetDateTime::class.java),
)

private fun ResultSet.toPVurderingPdf(): PVurderingPdf =
fun ResultSet.toPVurderingPdf(): PVurderingPdf =
PVurderingPdf(
id = getInt("id"),
uuid = UUID.fromString(getString("uuid")),
Expand Down
5 changes: 5 additions & 0 deletions src/test/kotlin/no/nav/syfo/ExternalMockEnvironment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package no.nav.syfo

import no.nav.syfo.infrastructure.clients.azuread.AzureAdClient
import no.nav.syfo.infrastructure.clients.dokarkiv.DokarkivClient
import no.nav.syfo.infrastructure.clients.pdfgen.PdfGenClient
import no.nav.syfo.infrastructure.clients.pdl.PdlClient
import no.nav.syfo.infrastructure.clients.wellknown.WellKnown
import no.nav.syfo.infrastructure.database.TestDatabase
Expand Down Expand Up @@ -38,6 +39,10 @@ class ExternalMockEnvironment private constructor() {
dokarkivEnvironment = environment.clients.dokarkiv,
httpClient = mockHttpClient,
)
val pdfgenClient = PdfGenClient(
pdfGenBaseUrl = environment.clients.ispdfgen.baseUrl,
httpClient = mockHttpClient,
)
val vurderingRepository = VurderingRepository(database)

companion object {
Expand Down
6 changes: 5 additions & 1 deletion src/test/kotlin/no/nav/syfo/TestEnvironment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package no.nav.syfo

import no.nav.syfo.infrastructure.clients.ClientEnvironment
import no.nav.syfo.infrastructure.clients.ClientsEnvironment
import no.nav.syfo.infrastructure.clients.OpenClientEnvironment
import no.nav.syfo.infrastructure.clients.azuread.AzureEnvironment
import no.nav.syfo.infrastructure.database.DatabaseEnvironment
import no.nav.syfo.infrastructure.kafka.KafkaEnvironment
Expand Down Expand Up @@ -40,7 +41,10 @@ fun testEnvironment() = Environment(
dokarkiv = ClientEnvironment(
baseUrl = "dokarkivUrl",
clientId = "dokarkivClientId",
)
),
ispdfgen = OpenClientEnvironment(
baseUrl = "ispdfgenUrl",
),
),
electorPath = "electorPath",
)
Expand Down
6 changes: 6 additions & 0 deletions src/test/kotlin/no/nav/syfo/api/TestApiModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.ktor.server.application.*
import io.mockk.mockk
import no.nav.syfo.ExternalMockEnvironment
import no.nav.syfo.application.VurderingService
import no.nav.syfo.infrastructure.clients.pdfgen.VurderingPdfService
import no.nav.syfo.infrastructure.clients.veiledertilgang.VeilederTilgangskontrollClient
import no.nav.syfo.infrastructure.journalforing.JournalforingService
import no.nav.syfo.infrastructure.kafka.VurderingProducer
Expand All @@ -21,6 +22,10 @@ fun Application.testApiModule(
)
val mockVurderingProducer = mockk<KafkaProducer<String, VurderingRecord>>(relaxed = true)
val vurderingProducer = VurderingProducer(producer = mockVurderingProducer)
val vurderingPdfService = VurderingPdfService(
pdfGenClient = externalMockEnvironment.pdfgenClient,
pdlClient = externalMockEnvironment.pdlClient,
)
val journalforingService = JournalforingService(
dokarkivClient = externalMockEnvironment.dokarkivClient,
pdlClient = externalMockEnvironment.pdlClient,
Expand All @@ -30,6 +35,7 @@ fun Application.testApiModule(
journalforingService = journalforingService,
vurderingRepository = externalMockEnvironment.vurderingRepository,
vurderingProducer = vurderingProducer,
vurderingPdfService = vurderingPdfService,
)

this.apiModule(
Expand Down
Loading

0 comments on commit f1c7e3a

Please sign in to comment.