Skip to content

Commit

Permalink
Add job
Browse files Browse the repository at this point in the history
  • Loading branch information
Vitenok committed Dec 12, 2024
1 parent e432f3f commit 6f4c48d
Show file tree
Hide file tree
Showing 24 changed files with 548 additions and 160 deletions.
4 changes: 3 additions & 1 deletion nais/job-trigger-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
labels:
team: team-esyfo
spec:
image: {{ image }}
image: { { image } }
accessPolicy:
outbound:
rules:
Expand All @@ -21,3 +21,5 @@ spec:
value: "true"
- name: ESYFOVARSEL_JOB_TRIGGER_URL
value: http://esyfovarsel/job/trigger
- name: REVARSLE_UNREAD_AKTIVITETSKRAV_PLIKT
value: "true"
6 changes: 4 additions & 2 deletions nais/job-trigger-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ metadata:
labels:
team: team-esyfo
spec:
image: {{ image }}
image: { { image } }
accessPolicy:
outbound:
rules:
- application: esyfovarsel
schedule: "05 09,18 * * *"
schedule: "05 09,18 * * *" # runs at 9:05 and 18:05 daily
filesFrom:
- secret: esyfovarsel-serviceuser
env:
Expand All @@ -21,3 +21,5 @@ spec:
value: "true"
- name: ESYFOVARSEL_JOB_TRIGGER_URL
value: http://esyfovarsel/job/trigger
- name: REVARSLE_UNREAD_AKTIVITETSKRAV_PLIKT
value: "false"
9 changes: 9 additions & 0 deletions src/main/kotlin/no/nav/syfo/BootstrapApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ import no.nav.syfo.consumer.syfosmregister.SykmeldingerConsumer
import no.nav.syfo.db.Database
import no.nav.syfo.db.DatabaseInterface
import no.nav.syfo.db.grantAccessToIAMUsers
import no.nav.syfo.job.SendForcedAktivitetspliktLetterJob
import no.nav.syfo.job.closeExpiredMicrofrontendsJob
import no.nav.syfo.job.sendForcedPhysicalAktivitetspliktLetterJob
import no.nav.syfo.kafka.common.launchKafkaListener
import no.nav.syfo.kafka.consumers.testdata.reset.TestdataResetConsumer
import no.nav.syfo.kafka.consumers.varselbus.VarselBusKafkaConsumer
Expand Down Expand Up @@ -75,6 +77,7 @@ fun main() {
if (isJob()) {
val env = getJobEnv()
closeExpiredMicrofrontendsJob(env)
sendForcedPhysicalAktivitetspliktLetterJob(env)
} else {
val server = embeddedServer(
factory = Netty,
Expand Down Expand Up @@ -174,6 +177,8 @@ fun createEngineEnvironment(): ApplicationEngineEnvironment = applicationEngineE
database = database,
)

val sendForcedAktivitetspliktLetterJob = SendForcedAktivitetspliktLetterJob(database, senderFacade)

val varselBusService =
VarselBusService(
senderFacade,
Expand All @@ -200,6 +205,7 @@ fun createEngineEnvironment(): ApplicationEngineEnvironment = applicationEngineE
serverModule(
env,
mikrofrontendService,
sendForcedAktivitetspliktLetterJob,
)

kafkaModule(
Expand All @@ -220,6 +226,7 @@ private fun getDkifConsumer(urlEnv: UrlEnv, azureADConsumer: AzureAdTokenConsume
fun Application.serverModule(
env: Environment,
mikrofrontendService: MikrofrontendService,
sendForcedAktivitetspliktLetterJob: SendForcedAktivitetspliktLetterJob,
) {
install(ContentNegotiation) {
jackson {
Expand All @@ -243,13 +250,15 @@ fun Application.serverModule(
runningRemotely {
setupRoutesWithAuthentication(
mikrofrontendService,
sendForcedAktivitetspliktLetterJob,
env.authEnv,
)
}

runningLocally {
setupLocalRoutesWithAuthentication(
mikrofrontendService,
sendForcedAktivitetspliktLetterJob,
env.authEnv,
)
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/no/nav/syfo/Environment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ fun getJobEnv() =
} else {
JobEnv(
jobTriggerUrl = getEnvVar("ESYFOVARSEL_JOB_TRIGGER_URL"),
revarsleUnreadAktivitetskravPlikt = getBooleanEnvVar("REVARSLE_UNREAD_AKTIVITETSKRAV_PLIKT"),
serviceuserUsername = File("$serviceuserMounthPath/username").readText(),
serviceuserPassword = File("$serviceuserMounthPath/password").readText(),
)
Expand Down Expand Up @@ -176,6 +177,7 @@ data class ToggleEnv(

data class JobEnv(
val jobTriggerUrl: String,
val revarsleUnreadAktivitetskravPlikt: Boolean,
val serviceuserUsername: String,
val serviceuserPassword: String,
)
Expand Down
9 changes: 8 additions & 1 deletion src/main/kotlin/no/nav/syfo/api/job/JobRest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,24 @@ import io.ktor.server.routing.Route
import io.ktor.server.routing.accept
import io.ktor.server.routing.post
import kotlinx.coroutines.launch
import no.nav.syfo.job.SendForcedAktivitetspliktLetterJob
import no.nav.syfo.service.microfrontend.MikrofrontendService

const val urlPathJobTrigger = "/job/trigger"

fun Route.registerJobTriggerApi(mikrofrontendService: MikrofrontendService) {
fun Route.registerJobTriggerApi(
mikrofrontendService: MikrofrontendService,
sendForcedAktivitetspliktLetterJob: SendForcedAktivitetspliktLetterJob,
) {
accept(ContentType.Application.Json) {
post(urlPathJobTrigger) {
call.respond(HttpStatusCode.OK)
launch {
mikrofrontendService.findAndCloseExpiredMikrofrontends()
}
launch {
sendForcedAktivitetspliktLetterJob.sendForcedLetterFromJob()
}
}
}
}
7 changes: 5 additions & 2 deletions src/main/kotlin/no/nav/syfo/auth/Authentication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import java.net.URL
import java.util.concurrent.TimeUnit
import no.nav.syfo.AuthEnv
import no.nav.syfo.api.job.registerJobTriggerApi
import no.nav.syfo.job.SendForcedAktivitetspliktLetterJob
import no.nav.syfo.service.microfrontend.MikrofrontendService
import org.slf4j.Logger
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -105,6 +106,7 @@ private fun JWTCredential.inExpectedAudience(expectedAudience: List<String>) = e

fun Application.setupLocalRoutesWithAuthentication(
mikrofrontendService: MikrofrontendService,
sendForcedAktivitetspliktLetterJob: SendForcedAktivitetspliktLetterJob,
authEnv: AuthEnv,
) {
install(Authentication) {
Expand All @@ -121,13 +123,14 @@ fun Application.setupLocalRoutesWithAuthentication(

routing {
authenticate("auth-basic") {
registerJobTriggerApi(mikrofrontendService)
registerJobTriggerApi(mikrofrontendService, sendForcedAktivitetspliktLetterJob)
}
}
}

fun Application.setupRoutesWithAuthentication(
mikrofrontendService: MikrofrontendService,
sendForcedAktivitetspliktLetterJob: SendForcedAktivitetspliktLetterJob,
authEnv: AuthEnv,
) {
val wellKnownTokenX = getWellKnown(authEnv.tokenXWellKnownUrl)
Expand All @@ -140,7 +143,7 @@ fun Application.setupRoutesWithAuthentication(

routing {
authenticate("auth-basic") {
registerJobTriggerApi(mikrofrontendService)
registerJobTriggerApi(mikrofrontendService, sendForcedAktivitetspliktLetterJob)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package no.nav.syfo.consumer.distribuerjournalpost

import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.client.call.body
import io.ktor.client.request.headers
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpStatusCode
import io.ktor.http.append
import no.nav.syfo.UrlEnv
import no.nav.syfo.auth.AzureAdTokenConsumer
import no.nav.syfo.utils.httpClient
Expand All @@ -13,12 +18,12 @@ class JournalpostdistribusjonConsumer(urlEnv: UrlEnv, private val azureAdTokenCo
private val dokdistfordelingUrl = urlEnv.dokdistfordelingUrl
private val dokdistfordelingScope = urlEnv.dokdistfordelingScope

private val log = LoggerFactory.getLogger("no.nav.syfo.consumer.JournalpostdistribusjonConsumer")
private val log = LoggerFactory.getLogger(JournalpostdistribusjonConsumer::class.java)

suspend fun distribuerJournalpost(
journalpostId: String,
uuid: String,
distribusjonstype: DistibusjonsType
distribusjonstype: DistibusjonsType,
): JournalpostdistribusjonResponse {
val requestURL = "$dokdistfordelingUrl/rest/v1/distribuerjournalpost"
val token = azureAdTokenConsumer.getToken(dokdistfordelingScope)
Expand Down Expand Up @@ -50,4 +55,41 @@ class JournalpostdistribusjonConsumer(urlEnv: UrlEnv, private val azureAdTokenCo
)
}
}

suspend fun distribuerTvungetJournalpost(
journalpostId: String,
uuid: String,
distribusjonstype: DistibusjonsType,
): JournalpostdistribusjonResponse {
val requestURL = "$dokdistfordelingUrl/rest/v1/distribuerjournalpost"
val token = azureAdTokenConsumer.getToken(dokdistfordelingScope)
val request = JournalpostdistribusjonRequest(
journalpostId = journalpostId,
distribusjonstype = distribusjonstype.name,
tvingSentralPrint = true,
)

return try {
val response = client.post(requestURL) {
headers {
append(HttpHeaders.Accept, ContentType.Application.Json)
append(HttpHeaders.ContentType, ContentType.Application.Json)
append(HttpHeaders.Authorization, "Bearer $token")
}
setBody(request)
}

if (response.status == HttpStatusCode.OK) {
log.info("Sent document to forced print")
response.body()
} else {
throw RuntimeException("Failed to send document with uuid $uuid to forced print. journalpostId: $journalpostId. Response status: ${response.status}. Response: $response")
}
} catch (e: Exception) {
throw RuntimeException(
"Exception while calling distribuerTvungetJournalpost with uuid $uuid and journalpostId: $journalpostId. Error message: ${e.message}",
e,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ data class JournalpostdistribusjonRequest(
val bestillendeFagsystem: String = "UKJENT",
val dokumentProdApp: String = "esyfovarsel",
val distribusjonstype: String,
val distribusjonstidspunkt: String = "UMIDDELBART"
val distribusjonstidspunkt: String = "UMIDDELBART",
val tvingSentralPrint: Boolean? = false,
)
22 changes: 20 additions & 2 deletions src/main/kotlin/no/nav/syfo/db/DatabaseUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package no.nav.syfo.db
import java.sql.ResultSet
import no.nav.syfo.db.domain.PMikrofrontendSynlighet
import no.nav.syfo.db.domain.PUtsendtVarsel
import no.nav.syfo.db.domain.PUtsendtVarselFeilet

fun <T> ResultSet.toList(mapper: ResultSet.() -> T) = mutableListOf<T>().apply {
while (next()) {
Expand All @@ -19,10 +20,11 @@ fun ResultSet.toPUtsendtVarsel() = PUtsendtVarsel(
type = getString("type"),
kanal = getString("kanal"),
utsendtTidspunkt = getTimestamp("utsendt_tidspunkt").toLocalDateTime(),
ferdigstiltTidspunkt = getTimestamp("ferdigstilt_tidspunkt")?.toLocalDateTime(),
planlagtVarselId = getString("planlagt_varsel_id"),
eksternReferanse = getString("ekstern_ref"),
arbeidsgivernotifikasjonMerkelapp = getString("arbeidsgivernotifikasjon_merkelapp")
ferdigstiltTidspunkt = getTimestamp("ferdigstilt_tidspunkt")?.toLocalDateTime(),
arbeidsgivernotifikasjonMerkelapp = getString("arbeidsgivernotifikasjon_merkelapp"),
isForcedLetter = getBoolean("is_forced_letter")
)

fun ResultSet.toPMikrofrontendSynlighet() = PMikrofrontendSynlighet(
Expand All @@ -33,3 +35,19 @@ fun ResultSet.toPMikrofrontendSynlighet() = PMikrofrontendSynlighet(
opprettet = getTimestamp("opprettet").toLocalDateTime(),
sistEndret = getTimestamp("sist_endret").toLocalDateTime()
)

fun ResultSet.toPUtsendtVarselFeilet() = PUtsendtVarselFeilet(
uuid = getString("uuid"),
uuidEksternReferanse = getString("uuid_ekstern_referanse"),
arbeidstakerFnr = getString("arbeidstaker_fnr"),
narmesteLederFnr = getString("narmesteleder_fnr"),
orgnummer = getString("orgnummer"),
hendelsetypeNavn = getString("hendelsetype_navn"),
arbeidsgivernotifikasjonMerkelapp = getString("arbeidsgivernotifikasjon_merkelapp"),
brukernotifikasjonerMeldingType = getString("brukernotifikasjoner_melding_type"),
journalpostId = getString("journalpost_id"),
kanal = getString("kanal"),
feilmelding = getString("feilmelding"),
utsendtForsokTidspunkt = getTimestamp("utsendt_forsok_tidspunkt").toLocalDateTime(),
isForcedLetter = getBoolean("is_forced_letter"),
)
56 changes: 22 additions & 34 deletions src/main/kotlin/no/nav/syfo/db/UtsendtVarselDAO.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package no.nav.syfo.db

import no.nav.syfo.db.domain.PUtsendtVarsel
import no.nav.syfo.domain.PersonIdent
import java.sql.Timestamp
import java.time.LocalDateTime
import java.util.*
import no.nav.syfo.db.domain.PUtsendtVarsel
import no.nav.syfo.domain.PersonIdent

fun DatabaseInterface.storeUtsendtVarsel(PUtsendtVarsel: PUtsendtVarsel) {
val insertStatement = """INSERT INTO UTSENDT_VARSEL (
Expand All @@ -16,7 +16,8 @@ fun DatabaseInterface.storeUtsendtVarsel(PUtsendtVarsel: PUtsendtVarsel) {
kanal,
utsendt_tidspunkt,
ekstern_ref,
arbeidsgivernotifikasjon_merkelapp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
arbeidsgivernotifikasjon_merkelapp,
is_forced_letter) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""".trimIndent()

connection.use { connection ->
Expand All @@ -30,6 +31,7 @@ fun DatabaseInterface.storeUtsendtVarsel(PUtsendtVarsel: PUtsendtVarsel) {
it.setTimestamp(7, Timestamp.valueOf(PUtsendtVarsel.utsendtTidspunkt))
it.setString(8, PUtsendtVarsel.eksternReferanse)
it.setString(9, PUtsendtVarsel.arbeidsgivernotifikasjonMerkelapp)
it.setBoolean(10, PUtsendtVarsel.isForcedLetter)
it.executeUpdate()
}

Expand All @@ -54,6 +56,23 @@ fun DatabaseInterface.fetchUferdigstilteVarsler(
}
}

fun DatabaseInterface.fetchAlleUferdigstilteAktivitetspliktVarsler(
): List<PUtsendtVarsel> {
val queryStatement = """SELECT *
FROM UTSENDT_VARSEL
WHERE type = 'SM_AKTIVITETSPLIKT'
AND kanal = 'BRUKERNOTIFIKASJON'
and is_forced_letter = false
AND ferdigstilt_tidspunkt is null
""".trimIndent()

return connection.use { connection ->
connection.prepareStatement(queryStatement).use {
it.executeQuery().toList { toPUtsendtVarsel() }
}
}
}

fun DatabaseInterface.fetchUtsendtVarselByFnr(fnr: String): List<PUtsendtVarsel> {
val queryStatement = """SELECT *
FROM UTSENDT_VARSEL
Expand Down Expand Up @@ -100,34 +119,3 @@ fun DatabaseInterface.deleteUtsendtVarselByFnr(fnr: PersonIdent) {
}
}

fun DatabaseInterface.storeUtsendtMerVeiledningVarselBackup(PUtsendtVarsel: PUtsendtVarsel) {
val insertStatement = """INSERT INTO UTSENDT_MER_VEILEDNING_VARSEL_BACKUP (
uuid,
narmesteLeder_fnr,
fnr,
orgnummer,
type,
kanal,
utsendt_tidspunkt,
ekstern_ref,
arbeidsgivernotifikasjon_merkelapp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""".trimIndent()

connection.use { connection ->
connection.prepareStatement(insertStatement).use {
it.setObject(1, UUID.fromString(PUtsendtVarsel.uuid))
it.setString(2, PUtsendtVarsel.narmesteLederFnr)
it.setString(3, PUtsendtVarsel.fnr)
it.setString(4, PUtsendtVarsel.orgnummer)
it.setString(5, PUtsendtVarsel.type)
it.setString(6, PUtsendtVarsel.kanal)
it.setTimestamp(7, Timestamp.valueOf(PUtsendtVarsel.utsendtTidspunkt))
it.setString(8, PUtsendtVarsel.eksternReferanse)
it.setString(9, PUtsendtVarsel.arbeidsgivernotifikasjonMerkelapp)
it.executeUpdate()
}

connection.commit()
}
}

Loading

0 comments on commit 6f4c48d

Please sign in to comment.