diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/Application.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/Application.kt index 60da302f..1f7fc38b 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/Application.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/Application.kt @@ -5,10 +5,6 @@ import io.ktor.server.engine.addShutdownHook import io.ktor.server.engine.embeddedServer import io.ktor.server.netty.Netty import io.ktor.server.routing.routing -import no.nav.paw.bekreftelse.api.config.APPLICATION_CONFIG_FILE_NAME -import no.nav.paw.bekreftelse.api.config.ApplicationConfig -import no.nav.paw.bekreftelse.api.config.SERVER_CONFIG_FILE_NAME -import no.nav.paw.bekreftelse.api.config.ServerConfig import no.nav.paw.bekreftelse.api.context.ApplicationContext import no.nav.paw.bekreftelse.api.plugins.configureAuthentication import no.nav.paw.bekreftelse.api.plugins.configureHTTP @@ -22,24 +18,22 @@ import no.nav.paw.bekreftelse.api.routes.metricsRoutes import no.nav.paw.bekreftelse.api.routes.swaggerRoutes import no.nav.paw.bekreftelse.api.utils.buildApplicationLogger import no.nav.paw.config.env.appNameOrDefaultForLocal -import no.nav.paw.config.env.currentRuntimeEnvironment -import no.nav.paw.config.hoplite.loadNaisOrLocalConfiguration import no.nav.paw.health.route.healthRoutes fun main() { val logger = buildApplicationLogger - val serverConfig = loadNaisOrLocalConfiguration(SERVER_CONFIG_FILE_NAME) - val applicationConfig = loadNaisOrLocalConfiguration(APPLICATION_CONFIG_FILE_NAME) + val applicationContext = ApplicationContext.create() + val appName = applicationContext.serverConfig.runtimeEnvironment.appNameOrDefaultForLocal() - logger.info("Starter: ${currentRuntimeEnvironment.appNameOrDefaultForLocal()}") + logger.info("Starter: $appName") - with(serverConfig) { + with(applicationContext.serverConfig) { embeddedServer(Netty, port = port) { - module(applicationConfig) + module(applicationContext) }.apply { addShutdownHook { - logger.info("Avslutter ${applicationConfig.runtimeEnvironment.appNameOrDefaultForLocal()}") + logger.info("Avslutter $appName") stop(gracePeriodMillis, timeoutMillis) } start(wait = true) @@ -47,9 +41,7 @@ fun main() { } } -fun Application.module(applicationConfig: ApplicationConfig) { - val applicationContext = ApplicationContext.create(applicationConfig) - +fun Application.module(applicationContext: ApplicationContext) { configureMetrics(applicationContext) configureHTTP(applicationContext) configureAuthentication(applicationContext) diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/config/ApplicationConfig.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/config/ApplicationConfig.kt index 036dd1bd..37715fd1 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/config/ApplicationConfig.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/config/ApplicationConfig.kt @@ -1,11 +1,8 @@ package no.nav.paw.bekreftelse.api.config -import no.nav.paw.config.env.RuntimeEnvironment -import no.nav.paw.config.env.currentRuntimeEnvironment import no.nav.paw.config.kafka.KafkaConfig import no.nav.paw.kafkakeygenerator.auth.AzureM2MConfig import no.nav.paw.kafkakeygenerator.client.KafkaKeyConfig -import java.net.InetAddress const val APPLICATION_CONFIG_FILE_NAME = "application_config.toml" @@ -16,10 +13,7 @@ data class ApplicationConfig( val azureM2M: AzureM2MConfig, val poaoClientConfig: ServiceClientConfig, val kafkaKeysClient: KafkaKeyConfig, - val kafkaClients: KafkaConfig, - // Env - val runtimeEnvironment: RuntimeEnvironment = currentRuntimeEnvironment, - val hostname: String = InetAddress.getLocalHost().hostName + val kafkaClients: KafkaConfig ) data class AutorisasjonConfig( diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/config/ServerConfig.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/config/ServerConfig.kt index 0ddda9b8..033bef47 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/config/ServerConfig.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/config/ServerConfig.kt @@ -1,12 +1,17 @@ package no.nav.paw.bekreftelse.api.config +import no.nav.paw.config.env.RuntimeEnvironment +import no.nav.paw.config.env.currentRuntimeEnvironment + const val SERVER_CONFIG_FILE_NAME = "server_config.toml" data class ServerConfig( val port: Int, + val host: String, val callGroupSize: Int, val workerGroupSize: Int, val connectionGroupSize: Int, val gracePeriodMillis: Long, - val timeoutMillis: Long + val timeoutMillis: Long, + val runtimeEnvironment: RuntimeEnvironment = currentRuntimeEnvironment ) diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/context/ApplicationContext.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/context/ApplicationContext.kt index 3759363d..6ffe5e91 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/context/ApplicationContext.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/context/ApplicationContext.kt @@ -5,7 +5,10 @@ import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.serialization.jackson.jackson import io.micrometer.prometheusmetrics.PrometheusConfig import io.micrometer.prometheusmetrics.PrometheusMeterRegistry +import no.nav.paw.bekreftelse.api.config.APPLICATION_CONFIG_FILE_NAME import no.nav.paw.bekreftelse.api.config.ApplicationConfig +import no.nav.paw.bekreftelse.api.config.SERVER_CONFIG_FILE_NAME +import no.nav.paw.bekreftelse.api.config.ServerConfig import no.nav.paw.bekreftelse.api.consumer.BekreftelseHttpConsumer import no.nav.paw.bekreftelse.api.plugins.buildKafkaStreams import no.nav.paw.bekreftelse.api.producer.BekreftelseKafkaProducer @@ -13,6 +16,7 @@ import no.nav.paw.bekreftelse.api.services.AuthorizationService import no.nav.paw.bekreftelse.api.services.BekreftelseService import no.nav.paw.bekreftelse.api.topology.buildBekreftelseTopology import no.nav.paw.bekreftelse.api.utils.configureJackson +import no.nav.paw.config.hoplite.loadNaisOrLocalConfiguration import no.nav.paw.health.repository.HealthIndicatorRepository import no.nav.paw.kafkakeygenerator.auth.azureAdM2MTokenClient import no.nav.paw.kafkakeygenerator.client.KafkaKeysClient @@ -22,6 +26,7 @@ import no.nav.poao_tilgang.client.PoaoTilgangHttpClient import org.apache.kafka.streams.KafkaStreams data class ApplicationContext( + val serverConfig: ServerConfig, val applicationConfig: ApplicationConfig, val kafkaKeysClient: KafkaKeysClient, val prometheusMeterRegistry: PrometheusMeterRegistry, @@ -31,9 +36,12 @@ data class ApplicationContext( val bekreftelseService: BekreftelseService ) { companion object { - fun create(applicationConfig: ApplicationConfig): ApplicationContext { + fun create(): ApplicationContext { + val serverConfig = loadNaisOrLocalConfiguration(SERVER_CONFIG_FILE_NAME) + val applicationConfig = loadNaisOrLocalConfiguration(APPLICATION_CONFIG_FILE_NAME) + val azureM2MTokenClient = azureAdM2MTokenClient( - applicationConfig.runtimeEnvironment, applicationConfig.azureM2M + serverConfig.runtimeEnvironment, applicationConfig.azureM2M ) val kafkaKeysClient = kafkaKeysClient(applicationConfig.kafkaKeysClient) { @@ -59,10 +67,16 @@ data class ApplicationContext( ) ) - val authorizationService = AuthorizationService(applicationConfig, kafkaKeysClient, poaoTilgangClient) + val authorizationService = AuthorizationService( + serverConfig, + applicationConfig, + kafkaKeysClient, + poaoTilgangClient + ) val bekreftelseTopology = buildBekreftelseTopology(applicationConfig, prometheusMeterRegistry) val bekreftelseKafkaStreams = buildKafkaStreams( + serverConfig, applicationConfig, healthIndicatorRepository, bekreftelseTopology @@ -80,6 +94,7 @@ data class ApplicationContext( ) return ApplicationContext( + serverConfig, applicationConfig, kafkaKeysClient, prometheusMeterRegistry, diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/DataIkkeFunnetException.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/DataIkkeFunnetException.kt index df5c7062..f74b5d54 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/DataIkkeFunnetException.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/DataIkkeFunnetException.kt @@ -4,4 +4,4 @@ import io.ktor.http.HttpStatusCode import no.nav.paw.error.exception.ServerResponseException class DataIkkeFunnetException(message: String) : - ServerResponseException(HttpStatusCode.BadRequest, "PAW_DATA_IKKE_FUNNET", message, null) \ No newline at end of file + ServerResponseException(HttpStatusCode.NotFound, "PAW_DATA_IKKE_FUNNET", message, null) \ No newline at end of file diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/DataTilhoererIkkeBrukerException.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/DataTilhoererIkkeBrukerException.kt new file mode 100644 index 00000000..82e19440 --- /dev/null +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/DataTilhoererIkkeBrukerException.kt @@ -0,0 +1,7 @@ +package no.nav.paw.bekreftelse.api.exception + +import io.ktor.http.HttpStatusCode +import no.nav.paw.error.exception.ServerResponseException + +class DataTilhoererIkkeBrukerException(message: String) : + ServerResponseException(HttpStatusCode.BadRequest, "PAW_DATA_TILHOERER_IKKE_BRUKER", message, null) \ No newline at end of file diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/SystemfeilException.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/SystemfeilException.kt new file mode 100644 index 00000000..5973871e --- /dev/null +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/exception/SystemfeilException.kt @@ -0,0 +1,7 @@ +package no.nav.paw.bekreftelse.api.exception + +import io.ktor.http.HttpStatusCode +import no.nav.paw.error.exception.ServerResponseException + +class SystemfeilException(message: String) : + ServerResponseException(HttpStatusCode.InternalServerError, "PAW_SYSTEMFEIL", message, null) \ No newline at end of file diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/plugins/HTTP.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/plugins/HTTP.kt index 1e15b990..18a27d51 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/plugins/HTTP.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/plugins/HTTP.kt @@ -24,7 +24,7 @@ fun Application.configureHTTP(applicationContext: ApplicationContext) { install(CORS) { val origins = applicationContext.applicationConfig.autorisasjon.getCorsAllowOrigins() - when (applicationContext.applicationConfig.runtimeEnvironment) { + when (applicationContext.serverConfig.runtimeEnvironment) { is Nais -> { origins.forEach { allowHost(it) } } diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/plugins/KafkaStreams.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/plugins/KafkaStreams.kt index 28dbd810..fa2d8599 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/plugins/KafkaStreams.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/plugins/KafkaStreams.kt @@ -9,6 +9,7 @@ import io.ktor.server.application.hooks.MonitoringEvent import io.ktor.server.application.log import io.ktor.util.KtorDsl import no.nav.paw.bekreftelse.api.config.ApplicationConfig +import no.nav.paw.bekreftelse.api.config.ServerConfig import no.nav.paw.config.kafka.streams.KafkaStreamsFactory import no.nav.paw.error.handler.withApplicationTerminatingExceptionHandler import no.nav.paw.health.listener.withHealthIndicatorStateListener @@ -44,6 +45,7 @@ val KafkaStreamsPlugin: ApplicationPlugin = } fun buildKafkaStreams( + serverConfig: ServerConfig, applicationConfig: ApplicationConfig, healthIndicatorRepository: HealthIndicatorRepository, topology: Topology @@ -52,12 +54,12 @@ fun buildKafkaStreams( val readinessIndicator = healthIndicatorRepository.addReadinessIndicator(ReadinessHealthIndicator()) val streamsFactory = KafkaStreamsFactory( - applicationConfig.kafkaTopology.applicationIdSuffix, - applicationConfig.kafkaClients + applicationIdSuffix = applicationConfig.kafkaTopology.applicationIdSuffix, + config = applicationConfig.kafkaClients, ) .withDefaultKeySerde(Serdes.Long()::class) .withDefaultValueSerde(SpecificAvroSerde::class) - .apply { properties["application.server"] = applicationConfig.hostname } + .withServerConfig(serverConfig.host, serverConfig.port) val kafkaStreams = KafkaStreams( topology, diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/services/AuthorizationService.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/services/AuthorizationService.kt index 81a008f9..e714942d 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/services/AuthorizationService.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/services/AuthorizationService.kt @@ -2,6 +2,7 @@ package no.nav.paw.bekreftelse.api.services import io.opentelemetry.instrumentation.annotations.WithSpan import no.nav.paw.bekreftelse.api.config.ApplicationConfig +import no.nav.paw.bekreftelse.api.config.ServerConfig import no.nav.paw.bekreftelse.api.context.RequestContext import no.nav.paw.bekreftelse.api.context.SecurityContext import no.nav.paw.bekreftelse.api.exception.BearerTokenManglerException @@ -28,6 +29,7 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory class AuthorizationService( + private val serverConfig: ServerConfig, private val applicationConfig: ApplicationConfig, private val kafkaKeysClient: KafkaKeysClient, private val poaoTilgangClient: PoaoTilgangClient @@ -79,7 +81,7 @@ class AuthorizationService( } else { logger.debug("NAV-ansatt har benyttet {}-tilgang til informasjon om bruker", tilgangType) auditLogger.audit( - applicationConfig.runtimeEnvironment, + serverConfig.runtimeEnvironment, sluttbruker.identitetsnummer, navAnsatt, tilgangType, diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/services/BekreftelseService.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/services/BekreftelseService.kt index 36f8bc5c..a755e9a1 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/services/BekreftelseService.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/services/BekreftelseService.kt @@ -5,6 +5,8 @@ import no.nav.paw.bekreftelse.api.config.ApplicationConfig import no.nav.paw.bekreftelse.api.consumer.BekreftelseHttpConsumer import no.nav.paw.bekreftelse.api.context.SecurityContext import no.nav.paw.bekreftelse.api.exception.DataIkkeFunnetException +import no.nav.paw.bekreftelse.api.exception.DataTilhoererIkkeBrukerException +import no.nav.paw.bekreftelse.api.exception.SystemfeilException import no.nav.paw.bekreftelse.api.model.BekreftelseRequest import no.nav.paw.bekreftelse.api.model.InternState import no.nav.paw.bekreftelse.api.model.TilgjengeligBekreftelserResponse @@ -32,7 +34,7 @@ class BekreftelseService( private fun getInternStateStore(): ReadOnlyKeyValueStore { if (!kafkaStreams.state().isRunningOrRebalancing) { - throw IllegalStateException("Kafka Streams kjører ikke") + throw SystemfeilException("Kafka Streams kjører ikke") } if (internStateStore == null) { internStateStore = kafkaStreams.store( @@ -42,7 +44,7 @@ class BekreftelseService( ) ) } - return checkNotNull(internStateStore) { "Intern state store er ikke initiert" } + return internStateStore ?: throw SystemfeilException("Intern state store er ikke initiert") } @WithSpan @@ -59,7 +61,7 @@ class BekreftelseService( val internState = getInternStateStore().get(securityContext.sluttbruker.arbeidssoekerId) if (internState != null) { - logger.info("Fant ${internState.tilgjendeligeBekreftelser.size} tilgjengelige bekreftelser") + logger.info("Fant ${internState.tilgjendeligeBekreftelser.size} tilgjengelige bekreftelser i lokal state") return internState.tilgjendeligeBekreftelser.toResponse() } else { return finnTilgjengeligBekreftelserFraAnnenNode(securityContext, request) @@ -83,7 +85,10 @@ class BekreftelseService( val tilgjengeligBekreftelse = internState.tilgjendeligeBekreftelser .firstOrNull { it.bekreftelseId == request.bekreftelseId } if (tilgjengeligBekreftelse != null) { - logger.info("Rapportering med id ${request.bekreftelseId} funnet") + logger.info("Mottok svar for bekreftelse som er i lokal state") + if (tilgjengeligBekreftelse.arbeidssoekerId != securityContext.sluttbruker.arbeidssoekerId) { + throw DataTilhoererIkkeBrukerException("Bekreftelse tilhører ikke bruker") + } val bekreftelse = request.asApi( periodeId = tilgjengeligBekreftelse.periodeId, gjelderFra = tilgjengeligBekreftelse.gjelderFra, @@ -92,7 +97,7 @@ class BekreftelseService( ) bekreftelseKafkaProducer.produceMessage(securityContext.sluttbruker.kafkaKey, bekreftelse) } else { - // TODO Rekreftelse ikke funnet. Hva gjør vi? + throw DataIkkeFunnetException("Fant ingen bekreftelse for gitt id") } } else { sendBekreftelseTilAnnenNode(securityContext, request) @@ -105,19 +110,23 @@ class BekreftelseService( ): TilgjengeligBekreftelserResponse { val metadata = kafkaStreams.queryMetadataForKey( applicationConfig.kafkaTopology.internStateStoreName, - securityContext.sluttbruker.kafkaKey, + securityContext.sluttbruker.arbeidssoekerId, Serdes.Long().serializer() ) if (metadata == null || metadata == KeyQueryMetadata.NOT_AVAILABLE) { - logger.warn("Fant ikke metadata for arbeidsoeker, $metadata") - throw DataIkkeFunnetException("Fant ikke data for arbeidsoeker") + logger.error("Fant ikke metadata for arbeidsoeker, $metadata") + throw SystemfeilException("Fant ikke metadata for arbeidsøker i Kafka Streams") } else { - return bekreftelseHttpConsumer.finnTilgjengeligBekreftelser( - host = metadata.activeHost().host(), + val hostInfo = metadata.activeHost() + val host = "${hostInfo.host()}:${hostInfo.port()}" + val tilgjendeligeBekreftelser = bekreftelseHttpConsumer.finnTilgjengeligBekreftelser( + host = host, bearerToken = securityContext.accessToken.jwt, request = request ) + logger.info("Fant ${tilgjendeligeBekreftelser.size} tilgjengelige bekreftelser på node $host") + return tilgjendeligeBekreftelser } } @@ -127,16 +136,19 @@ class BekreftelseService( ) { val metadata = kafkaStreams.queryMetadataForKey( applicationConfig.kafkaTopology.internStateStoreName, - securityContext.sluttbruker.kafkaKey, + securityContext.sluttbruker.arbeidssoekerId, Serdes.Long().serializer() ) if (metadata == null || metadata == KeyQueryMetadata.NOT_AVAILABLE) { - logger.warn("Fant ikke metadata for arbeidsoeker, $metadata") - throw DataIkkeFunnetException("Fant ikke data for arbeidsoeker") + logger.error("Fant ikke metadata for arbeidsoeker, $metadata") + throw SystemfeilException("Fant ikke metadata for arbeidsøker i Kafka Streams") } else { + val hostInfo = metadata.activeHost() + val host = "${hostInfo.host()}:${hostInfo.port()}" + logger.info("Mottok svar for bekreftelse som er på node $host") bekreftelseHttpConsumer.sendBekreftelse( - host = metadata.activeHost().host(), + host = "${hostInfo.host()}:${hostInfo.port()}", bearerToken = securityContext.accessToken.jwt, request = request ) diff --git a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/topology/BekreftelseHendelseTopology.kt b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/topology/BekreftelseHendelseTopology.kt index e5db9d46..edffa623 100644 --- a/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/topology/BekreftelseHendelseTopology.kt +++ b/apps/bekreftelse-api/src/main/kotlin/no/nav/paw/bekreftelse/api/topology/BekreftelseHendelseTopology.kt @@ -32,9 +32,8 @@ private fun StreamsBuilder.addBekreftelseKStream( applicationConfig: ApplicationConfig, meterRegistry: MeterRegistry ) { - stream( - applicationConfig.kafkaTopology.bekreftelseHendelsesloggTopic, - Consumed.with(Serdes.Long(), BekreftelseHendelseSerde()) - ) - .oppdaterBekreftelseHendelseState(applicationConfig.kafkaTopology.internStateStoreName, meterRegistry) + with(applicationConfig.kafkaTopology) { + stream(bekreftelseHendelsesloggTopic, Consumed.with(Serdes.Long(), BekreftelseHendelseSerde())) + .oppdaterBekreftelseHendelseState(internStateStoreName, meterRegistry) + } } \ No newline at end of file diff --git a/apps/bekreftelse-api/src/main/resources/local/server_config.toml b/apps/bekreftelse-api/src/main/resources/local/server_config.toml index 5f9044d0..05d64634 100644 --- a/apps/bekreftelse-api/src/main/resources/local/server_config.toml +++ b/apps/bekreftelse-api/src/main/resources/local/server_config.toml @@ -1,4 +1,5 @@ port = 8080 +host = "localhost" callGroupSize = 16 workerGroupSize = 8 connectionGroupSize = 8 diff --git a/apps/bekreftelse-api/src/main/resources/nais/server_config.toml b/apps/bekreftelse-api/src/main/resources/nais/server_config.toml index 5f9044d0..682b1e11 100644 --- a/apps/bekreftelse-api/src/main/resources/nais/server_config.toml +++ b/apps/bekreftelse-api/src/main/resources/nais/server_config.toml @@ -1,4 +1,5 @@ port = 8080 +host = "${HOSTNAME}" callGroupSize = 16 workerGroupSize = 8 connectionGroupSize = 8 diff --git a/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/ApplicationTestContext.kt b/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/ApplicationTestContext.kt index e70f5a77..5ccf18fa 100644 --- a/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/ApplicationTestContext.kt +++ b/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/ApplicationTestContext.kt @@ -20,6 +20,8 @@ import no.nav.paw.bekreftelse.api.config.ApplicationConfig import no.nav.paw.bekreftelse.api.config.AuthProvider import no.nav.paw.bekreftelse.api.config.AuthProviderClaims import no.nav.paw.bekreftelse.api.config.AuthProviders +import no.nav.paw.bekreftelse.api.config.SERVER_CONFIG_FILE_NAME +import no.nav.paw.bekreftelse.api.config.ServerConfig import no.nav.paw.bekreftelse.api.consumer.BekreftelseHttpConsumer import no.nav.paw.bekreftelse.api.context.ApplicationContext import no.nav.paw.bekreftelse.api.context.resolveRequest @@ -49,6 +51,7 @@ import org.apache.kafka.streams.state.ReadOnlyKeyValueStore class ApplicationTestContext { val testData = TestDataGenerator() + val serverConfig = loadNaisOrLocalConfiguration(SERVER_CONFIG_FILE_NAME) val applicationConfig = loadNaisOrLocalConfiguration(APPLICATION_CONFIG_FILE_NAME) val prometheusMeterRegistry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT) val kafkaStreamsMock = mockk() @@ -57,7 +60,8 @@ class ApplicationTestContext { val poaoTilgangClientMock = mockk() val bekreftelseKafkaProducerMock = mockk() val bekreftelseHttpConsumerMock = mockk() - val authorizationService = AuthorizationService(applicationConfig, kafkaKeysClientMock, poaoTilgangClientMock) + val authorizationService = + AuthorizationService(serverConfig, applicationConfig, kafkaKeysClientMock, poaoTilgangClientMock) val bekreftelseServiceMock = mockk() val bekreftelseServiceReal = BekreftelseService( applicationConfig, @@ -69,6 +73,7 @@ class ApplicationTestContext { fun ApplicationTestBuilder.configureTestApplication(bekreftelseService: BekreftelseService) { val applicationContext = ApplicationContext( + serverConfig, applicationConfig.copy(authProviders = mockOAuth2Server.createAuthProviders()), kafkaKeysClientMock, prometheusMeterRegistry, diff --git a/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/TestDataGenerator.kt b/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/TestDataGenerator.kt index 1c7a4318..5f0f6893 100644 --- a/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/TestDataGenerator.kt +++ b/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/TestDataGenerator.kt @@ -10,6 +10,13 @@ import java.util.* class TestDataGenerator { + val fnr1 = "01017012345" + val fnr2 = "02017012345" + val arbeidsoekerId1 = 10001L + val arbeidsoekerId2 = 10002L + val kafkaKey1 = -10001L + val kafkaKey2 = -10002L + fun nyTilgjengeligBekreftelse( periodeId: UUID = UUID.randomUUID(), bekreftelseId: UUID = UUID.randomUUID(), @@ -45,5 +52,5 @@ class TestDataGenerator { fun nyKeyQueryMetadata( ) = KeyQueryMetadata(nyHostInfo(), emptySet(), 1) - fun nyHostInfo() = HostInfo("localhost", 9092) + fun nyHostInfo() = HostInfo("localhost", 8080) } \ No newline at end of file diff --git a/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/routes/BekreftelseRoutesTest.kt b/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/routes/BekreftelseRoutesTest.kt index 71fd343d..3463daed 100644 --- a/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/routes/BekreftelseRoutesTest.kt +++ b/apps/bekreftelse-api/src/test/kotlin/no/nav/paw/bekreftelse/api/routes/BekreftelseRoutesTest.kt @@ -37,7 +37,6 @@ class BekreftelseRoutesTest : FreeSpec({ with(ApplicationTestContext()) { beforeSpec { clearAllMocks() - coEvery { kafkaKeysClientMock.getIdAndKey(any()) } returns KafkaKeysResponse(1, 1) mockOAuth2Server.start() } @@ -55,11 +54,15 @@ class BekreftelseRoutesTest : FreeSpec({ mockOAuth2Server.shutdown() } - /* - * SLUTTBRUKER TESTER - */ + /* + * SLUTTBRUKER TESTER + */ "Test suite for sluttbruker" - { "Skal få 500 om Kafka Streams ikke kjører" { + coEvery { kafkaKeysClientMock.getIdAndKey(any()) } returns KafkaKeysResponse( + testData.arbeidsoekerId1, + testData.kafkaKey1 + ) every { kafkaStreamsMock.state() } returns KafkaStreams.State.NOT_RUNNING testApplication { @@ -80,12 +83,16 @@ class BekreftelseRoutesTest : FreeSpec({ response.status shouldBe HttpStatusCode.InternalServerError val body = response.body() body.status shouldBe HttpStatusCode.InternalServerError - body.code shouldBe "PAW_UKJENT_FEIL" + body.code shouldBe "PAW_SYSTEMFEIL" verify { kafkaStreamsMock.state() } } } "Skal få 500 om ingen state store funnet" { + coEvery { kafkaKeysClientMock.getIdAndKey(any()) } returns KafkaKeysResponse( + testData.arbeidsoekerId1, + testData.kafkaKey1 + ) every { kafkaStreamsMock.state() } returns KafkaStreams.State.RUNNING every { kafkaStreamsMock.store(any>()) } returns null @@ -107,13 +114,17 @@ class BekreftelseRoutesTest : FreeSpec({ response.status shouldBe HttpStatusCode.InternalServerError val body = response.body() body.status shouldBe HttpStatusCode.InternalServerError - body.code shouldBe "PAW_UKJENT_FEIL" + body.code shouldBe "PAW_SYSTEMFEIL" verify { kafkaStreamsMock.state() } verify { kafkaStreamsMock.store(any>()) } } } "Skal hente tilgjengelige bekreftelser fra intern state store" { + coEvery { kafkaKeysClientMock.getIdAndKey(any()) } returns KafkaKeysResponse( + testData.arbeidsoekerId1, + testData.kafkaKey1 + ) every { kafkaStreamsMock.state() } returns KafkaStreams.State.RUNNING every { kafkaStreamsMock.store(any>()) } returns stateStoreMock every { stateStoreMock.get(any()) } returns InternState( @@ -147,6 +158,10 @@ class BekreftelseRoutesTest : FreeSpec({ } "Skal hente tilgjengelige bekreftelser fra annen node" { + coEvery { kafkaKeysClientMock.getIdAndKey(any()) } returns KafkaKeysResponse( + testData.arbeidsoekerId1, + testData.kafkaKey1 + ) every { kafkaStreamsMock.state() } returns KafkaStreams.State.RUNNING every { kafkaStreamsMock.store(any>()) } returns stateStoreMock every { stateStoreMock.get(any()) } returns null @@ -204,12 +219,19 @@ class BekreftelseRoutesTest : FreeSpec({ } "Skal motta bekreftelse via intern state store" { - val request = testData.nyBekreftelseRequest(identitetsnummer = "01017012345") + coEvery { kafkaKeysClientMock.getIdAndKey(any()) } returns KafkaKeysResponse( + testData.arbeidsoekerId1, + testData.kafkaKey1 + ) + val request = testData.nyBekreftelseRequest(identitetsnummer = testData.fnr1) every { kafkaStreamsMock.state() } returns KafkaStreams.State.RUNNING every { kafkaStreamsMock.store(any>()) } returns stateStoreMock every { stateStoreMock.get(any()) } returns InternState( listOf( - testData.nyBekreftelseTilgjengelig(bekreftelseId = request.bekreftelseId) + testData.nyBekreftelseTilgjengelig( + bekreftelseId = request.bekreftelseId, + arbeidsoekerId = testData.arbeidsoekerId1 + ) ) ) coEvery { @@ -226,7 +248,7 @@ class BekreftelseRoutesTest : FreeSpec({ val token = mockOAuth2Server.issueToken( claims = mapOf( "acr" to "idporten-loa-high", - "pid" to "01017012345" + "pid" to testData.fnr1 ) ) @@ -252,7 +274,11 @@ class BekreftelseRoutesTest : FreeSpec({ } "Skal motta bekreftelse og overføre den til annen node" { - val request = testData.nyBekreftelseRequest(identitetsnummer = "01017012345") + coEvery { kafkaKeysClientMock.getIdAndKey(any()) } returns KafkaKeysResponse( + testData.arbeidsoekerId2, + testData.kafkaKey2 + ) + val request = testData.nyBekreftelseRequest(identitetsnummer = testData.fnr2) every { kafkaStreamsMock.state() } returns KafkaStreams.State.RUNNING every { kafkaStreamsMock.store(any>()) } returns stateStoreMock every { stateStoreMock.get(any()) } returns null @@ -278,7 +304,7 @@ class BekreftelseRoutesTest : FreeSpec({ val token = mockOAuth2Server.issueToken( claims = mapOf( "acr" to "idporten-loa-high", - "pid" to "01017012345" + "pid" to testData.fnr2 ) ) diff --git a/lib/kafka-streams/src/main/kotlin/no/nav/paw/config/kafka/streams/KafkaStreamsFactory.kt b/lib/kafka-streams/src/main/kotlin/no/nav/paw/config/kafka/streams/KafkaStreamsFactory.kt index cc267612..fc665530 100644 --- a/lib/kafka-streams/src/main/kotlin/no/nav/paw/config/kafka/streams/KafkaStreamsFactory.kt +++ b/lib/kafka-streams/src/main/kotlin/no/nav/paw/config/kafka/streams/KafkaStreamsFactory.kt @@ -33,9 +33,9 @@ class KafkaStreamsFactory private constructor( StreamsConfig.BOOTSTRAP_SERVERS_CONFIG to config.brokers, StreamsConfig.APPLICATION_ID_CONFIG to ("${config.applicationIdPrefix}_$applicationIdSuffix") ) + - schemaRegistry + - authentication + - additionalProperties + schemaRegistry + + authentication + + additionalProperties val properties: Properties get() = @@ -64,6 +64,12 @@ class KafkaStreamsFactory private constructor( additionalProperties = additionalProperties + (StreamsConfig.PROCESSING_GUARANTEE_CONFIG to StreamsConfig.EXACTLY_ONCE_V2) ) + fun withServerConfig(host: String, post: Int) = KafkaStreamsFactory( + applicationIdSuffix = applicationIdSuffix, + config = config, + additionalProperties = additionalProperties + (StreamsConfig.APPLICATION_SERVER_CONFIG to "$host:$post") + ) + fun createSpecificAvroSerde(): SpecificAvroSerde = SpecificAvroSerde().apply { configure(schemaRegistry, false)