Skip to content

Commit

Permalink
Bytt til ny kontrakt for innsending (#664)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjerga authored Aug 13, 2024
1 parent 39be743 commit 02d3769
Show file tree
Hide file tree
Showing 30 changed files with 229 additions and 1,051 deletions.
2 changes: 0 additions & 2 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ val ktorVersion: String by project
val lettuceVersion: String by project
val mockOauth2ServerVersion: String by project
val tokenSupportVersion: String by project
val valiktorVersion: String by project

tasks {
test {
Expand All @@ -27,7 +26,6 @@ dependencies {
implementation("io.ktor:ktor-server-status-pages:$ktorVersion")
implementation("no.nav.security:token-client-core:$tokenSupportVersion")
implementation("no.nav.security:token-validation-ktor-v2:$tokenSupportVersion")
implementation("org.valiktor:valiktor-core:$valiktorVersion")

testImplementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
testImplementation("io.ktor:ktor-client-core:$ktorVersion")
Expand Down
1 change: 0 additions & 1 deletion api/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@
# nyere versjon av mockOauth2ServerVersion finnes, men med bug
mockOauth2ServerVersion=0.5.3
tokenSupportVersion=4.1.3
valiktorVersion=0.12.0
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import io.ktor.server.routing.get
import io.ktor.server.routing.routing
import io.prometheus.client.CollectorRegistry
import io.prometheus.client.exporter.common.TextFormat
import java.util.Collections

fun Application.helsesjekkerRouting() {
routing {
Expand All @@ -23,7 +22,9 @@ fun Application.helsesjekkerRouting() {
val names =
call.request.queryParameters
.getAll("name[]")
?.toSet() ?: Collections.emptySet()
?.toSet()
.orEmpty()

call.respondTextWriter(ContentType.parse(TextFormat.CONTENT_TYPE_004)) {
TextFormat.write004(this, CollectorRegistry.defaultRegistry.filteredMetricFamilySamples(names))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respond
import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondBadRequest
import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondForbidden
import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondInternalServerError
import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.ValidationError
import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.ValidationResponse
import no.nav.helsearbeidsgiver.utils.json.fromJson
import no.nav.helsearbeidsgiver.utils.json.toJson
import java.util.UUID
Expand Down Expand Up @@ -98,16 +96,7 @@ fun Route.hentForespoerselRoute(
logger.error("Klarte ikke lese request.", it)
val response =
ResultJson(
failure =
ValidationResponse(
listOf(
ValidationError(
property = HentForespoerselRequest::uuid.name,
error = it.message.orEmpty(),
value = "<ukjent>",
),
),
).toJson(ValidationResponse.serializer()),
failure = "Mangler forespørsel-ID for å hente forespørsel.".toJson(),
)
respondBadRequest(response, ResultJson.serializer())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package no.nav.helsearbeidsgiver.inntektsmelding.api.innsending

import no.nav.helse.rapids_rivers.RapidsConnection
import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending
import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding
import no.nav.helsearbeidsgiver.felles.EventName
import no.nav.helsearbeidsgiver.felles.Key
import no.nav.helsearbeidsgiver.felles.json.toJson
Expand All @@ -22,8 +22,7 @@ class InnsendingProducer(

fun publish(
transaksjonId: UUID,
forespoerselId: UUID,
request: Innsending,
skjemaInntektsmelding: SkjemaInntektsmelding,
arbeidsgiverFnr: Fnr,
) {
rapid
Expand All @@ -32,13 +31,14 @@ class InnsendingProducer(
Key.UUID to transaksjonId.toJson(),
Key.DATA to
mapOf(
Key.FORESPOERSEL_ID to forespoerselId.toJson(),
// TODO fjern i mottaker, så her
Key.FORESPOERSEL_ID to skjemaInntektsmelding.forespoerselId.toJson(),
Key.ARBEIDSGIVER_FNR to arbeidsgiverFnr.toJson(),
Key.SKJEMA_INNTEKTSMELDING to request.toJson(Innsending.serializer()),
Key.SKJEMA_INNTEKTSMELDING to skjemaInntektsmelding.toJson(SkjemaInntektsmelding.serializer()),
).toJson(),
).also {
logger.info("Publiserte til kafka forespørselId: $forespoerselId og transaksjonId=$transaksjonId")
sikkerLogger.info("Publiserte til kafka forespørselId: $forespoerselId json=${it.toPretty()}")
logger.info("Publiserte til kafka forespørselId: ${skjemaInntektsmelding.forespoerselId} og transaksjonId=$transaksjonId")
sikkerLogger.info("Publiserte til kafka forespørselId: ${skjemaInntektsmelding.forespoerselId} json=${it.toPretty()}")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,15 @@ import io.ktor.server.request.receiveText
import io.ktor.server.routing.Route
import io.ktor.server.routing.post
import io.prometheus.client.Summary
import kotlinx.serialization.SerializationException
import kotlinx.serialization.builtins.serializer
import no.nav.helse.rapids_rivers.RapidsConnection
import no.nav.helsearbeidsgiver.domene.inntektsmelding.Utils.convert
import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending
import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.AarsakInnsending
import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding
import no.nav.helsearbeidsgiver.felles.Tekst
import no.nav.helsearbeidsgiver.felles.domene.ResultJson
import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisConnection
import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisPrefix
import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore
import no.nav.helsearbeidsgiver.inntektsmelding.api.RedisPoller
import no.nav.helsearbeidsgiver.inntektsmelding.api.RedisPollerTimeoutException
import no.nav.helsearbeidsgiver.inntektsmelding.api.Routes
import no.nav.helsearbeidsgiver.inntektsmelding.api.auth.Tilgangskontroll
import no.nav.helsearbeidsgiver.inntektsmelding.api.auth.lesFnrFraAuthToken
Expand All @@ -31,11 +26,8 @@ import no.nav.helsearbeidsgiver.inntektsmelding.api.sikkerLogger
import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respond
import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondBadRequest
import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondInternalServerError
import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.ValidationResponse
import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.validationResponseMapper
import no.nav.helsearbeidsgiver.utils.json.fromJson
import no.nav.helsearbeidsgiver.utils.json.parseJson
import org.valiktor.ConstraintViolationException
import java.util.UUID
import kotlin.system.measureTimeMillis

Expand All @@ -54,92 +46,82 @@ fun Route.innsendingRoute(
.help("innsending endpoint latency in seconds")
.register()

post(Routes.INNSENDING + "/{forespoerselId}") {
val transaksjonId = UUID.randomUUID()

val forespoerselId =
call.parameters["forespoerselId"]
?.runCatching(UUID::fromString)
?.getOrNull()

if (forespoerselId != null) {
val requestTimer = requestLatency.startTimer()
measureTimeMillis {
try {
val request =
call
.receiveText()
.parseJson()
// TODO ubrukt path param satt til optional. fjern i frontend, så her.
post(Routes.INNSENDING + "/{forespoerselId?}") {
val requestTimer = requestLatency.startTimer()
measureTimeMillis {
val transaksjonId = UUID.randomUUID()

val skjema =
call
.receiveText()
.runCatching {
parseJson()
.also { json ->
"Mottok innsending med forespørselId: $forespoerselId".let {
"Mottok inntektsmeldingsskjema.".let {
logger.info(it)
sikkerLogger.info("$it og request:\n$json")
}
}.let { json ->
runCatching {
json
.fromJson(SkjemaInntektsmelding.serializer())
.also {
val valideringsfeil = it.valider()
if (valideringsfeil.isNotEmpty()) {
val response = ValideringErrorResponse(valideringsfeil)

respondBadRequest(response, ValideringErrorResponse.serializer())
return@measureTimeMillis
}
}.convert(
sykmeldingsperioder = emptyList(),
aarsakInnsending = AarsakInnsending.Ny,
)
}.getOrElse { error ->
sikkerLogger.debug("Noe gikk galt med nytt skjema.", error)

json
.fromJson(Innsending.serializer())
.also {
it.validate()
}
}
}

tilgangskontroll.validerTilgangTilForespoersel(call.request, forespoerselId)
}.fromJson(SkjemaInntektsmelding.serializer())
}.getOrElse { error ->
"Klarte ikke parse json for inntektsmeldingsskjema.".also {
logger.error(it)
sikkerLogger.error(it, error)
}
null
}

val innloggerFnr = call.request.lesFnrFraAuthToken()
producer.publish(transaksjonId, forespoerselId, request, innloggerFnr)
when {
skjema == null -> {
respondBadRequest(JsonErrorResponse(), JsonErrorResponse.serializer())
}

val resultatJson = redisPoller.hent(transaksjonId).fromJson(ResultJson.serializer())
sikkerLogger.info("Fikk resultat for innsending:\n$resultatJson")
skjema.valider().isNotEmpty() -> {
val valideringsfeil = skjema.valider()

if (resultatJson.success != null) {
respond(HttpStatusCode.Created, InnsendingResponse(forespoerselId), InnsendingResponse.serializer())
} else {
val feilmelding = resultatJson.failure?.fromJson(String.serializer()) ?: Tekst.TEKNISK_FEIL_FORBIGAAENDE
respondInternalServerError(feilmelding, String.serializer())
}
} catch (e: ConstraintViolationException) {
logger.info("Fikk valideringsfeil for forespørselId: $forespoerselId")
respondBadRequest(validationResponseMapper(e.constraintViolations), ValidationResponse.serializer())
} catch (e: SerializationException) {
"Kunne ikke parse json for $forespoerselId".let {
"Fikk valideringsfeil: $valideringsfeil".also {
logger.error(it)
sikkerLogger.error(it, e)
respondBadRequest(JsonErrorResponse(forespoerselId.toString()), JsonErrorResponse.serializer())
sikkerLogger.error(it)
}
} catch (e: RedisPollerTimeoutException) {
logger.info("Fikk timeout for forespørselId: $forespoerselId", e)
respondInternalServerError(RedisTimeoutResponse(forespoerselId), RedisTimeoutResponse.serializer())

val response = ValideringErrorResponse(valideringsfeil)

respondBadRequest(response, ValideringErrorResponse.serializer())
}
}.also {
requestTimer.observeDuration()
logger.info("Api call to ${Routes.INNSENDING} took $it ms")
}
} else {
val feilmelding = "Forespørsel-ID mangler som stiparameter."

logger.error(feilmelding)
sikkerLogger.error(feilmelding)
else -> {
tilgangskontroll.validerTilgangTilForespoersel(call.request, skjema.forespoerselId)

val avsenderFnr = call.request.lesFnrFraAuthToken()

producer.publish(transaksjonId, skjema, avsenderFnr)

val resultat =
runCatching {
redisPoller.hent(transaksjonId)
}.map {
it.fromJson(ResultJson.serializer())
}

respondBadRequest(feilmelding, String.serializer())
resultat
.onSuccess {
sikkerLogger.info("Fikk resultat for innsending:\n$it")

if (it.success != null) {
respond(HttpStatusCode.Created, InnsendingResponse(skjema.forespoerselId), InnsendingResponse.serializer())
} else {
val feilmelding = it.failure?.fromJson(String.serializer()) ?: Tekst.TEKNISK_FEIL_FORBIGAAENDE
respondInternalServerError(feilmelding, String.serializer())
}
}.onFailure {
sikkerLogger.info("Fikk timeout for forespørselId: ${skjema.forespoerselId}", it)
respondInternalServerError(RedisTimeoutResponse(skjema.forespoerselId), RedisTimeoutResponse.serializer())
}
}
}
}.also {
requestTimer.observeDuration()
logger.info("Api call to ${Routes.INNSENDING} took $it ms")
}
}
}

This file was deleted.

Loading

0 comments on commit 02d3769

Please sign in to comment.