Skip to content

Commit

Permalink
Innførte value klasser for arbeidssøker id og record key
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsmsa committed Oct 11, 2024
1 parent d0a5d73 commit 1abe715
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.opentelemetry.instrumentation.annotations.WithSpan
import no.nav.paw.kafkakeygenerator.FailureCode.CONFLICT
import no.nav.paw.kafkakeygenerator.FailureCode.DB_NOT_FOUND
import no.nav.paw.kafkakeygenerator.pdl.PdlIdentitesTjeneste
import no.nav.paw.kafkakeygenerator.vo.ArbeidssoekerId
import no.nav.paw.kafkakeygenerator.vo.CallId
import no.nav.paw.kafkakeygenerator.vo.Identitetsnummer

Expand All @@ -13,15 +14,15 @@ class Applikasjon(
) {

@WithSpan
suspend fun hent(callId: CallId, identitet: Identitetsnummer): Either<Failure, Long> {
suspend fun hent(callId: CallId, identitet: Identitetsnummer): Either<Failure, ArbeidssoekerId> {
return kafkaKeys.hent(identitet)
.recover(DB_NOT_FOUND) {
sjekkMotAliaser(callId, identitet)
}
}

@WithSpan
suspend fun hentEllerOpprett(callId: CallId, identitet: Identitetsnummer): Either<Failure, Long> {
suspend fun hentEllerOpprett(callId: CallId, identitet: Identitetsnummer): Either<Failure, ArbeidssoekerId> {
return hent(callId, identitet)
.recover(DB_NOT_FOUND) {
kafkaKeys.opprett(identitet)
Expand All @@ -31,7 +32,7 @@ class Applikasjon(
}

@WithSpan
private suspend fun sjekkMotAliaser(callId: CallId, identitet: Identitetsnummer): Either<Failure, Long> {
private suspend fun sjekkMotAliaser(callId: CallId, identitet: Identitetsnummer): Either<Failure, ArbeidssoekerId> {
return identitetsTjeneste.hentIdentiter(callId, identitet)
.flatMap(kafkaKeys::hent)
.flatMap { ids ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package no.nav.paw.kafkakeygenerator

import no.nav.paw.kafkakeygenerator.database.IdentitetTabell
import no.nav.paw.kafkakeygenerator.database.KafkaKeysTabell
import no.nav.paw.kafkakeygenerator.vo.ArbeidssoekerId
import no.nav.paw.kafkakeygenerator.vo.Identitetsnummer
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList
import org.jetbrains.exposed.sql.transactions.transaction

class KafkaKeys(private val database: Database) {

fun hent(identiteter: List<String>): Either<Failure, Map<String, Long>> =
fun hent(identiteter: List<String>): Either<Failure, Map<String, ArbeidssoekerId>> =
attempt {
transaction(database) {
IdentitetTabell
Expand All @@ -22,9 +21,9 @@ class KafkaKeys(private val database: Database) {
}
}.mapToFailure { exception ->
Failure("database", FailureCode.INTERNAL_TECHINCAL_ERROR, exception)
}
}.map { resultMap -> resultMap.mapValues { ArbeidssoekerId(it.value) } }

fun hent(identitet: Identitetsnummer): Either<Failure, Long> =
fun hent(identitet: Identitetsnummer): Either<Failure, ArbeidssoekerId> =
attempt {
transaction(database) {
IdentitetTabell
Expand All @@ -34,14 +33,16 @@ class KafkaKeys(private val database: Database) {
}
}.mapToFailure { exception ->
Failure("database", FailureCode.INTERNAL_TECHINCAL_ERROR, exception)
}.flatMap { id -> id?.let(::right) ?: left(Failure("database", FailureCode.DB_NOT_FOUND)) }
}
.map { id -> id?.let(::ArbeidssoekerId) }
.flatMap { id -> id?.let(::right) ?: left(Failure("database", FailureCode.DB_NOT_FOUND)) }

fun lagre(identitet: Identitetsnummer, kkel: Long): Either<Failure, Unit> =
fun lagre(identitet: Identitetsnummer, arbeidssoekerId: ArbeidssoekerId): Either<Failure, Unit> =
attempt {
transaction(database) {
IdentitetTabell.insertIgnore {
it[identitetsnummer] = identitet.value
it[kafkaKey] = nøkkel
it[kafkaKey] = arbeidssoekerId.value
}.insertedCount
}
}
Expand All @@ -51,7 +52,7 @@ class KafkaKeys(private val database: Database) {
.flatMap { if (it == 1) right(Unit) else left(Failure("database", FailureCode.CONFLICT)) }


fun opprett(identitet: Identitetsnummer): Either<Failure, Long> =
fun opprett(identitet: Identitetsnummer): Either<Failure, ArbeidssoekerId> =
attempt {
transaction(database) {
val nøkkel = KafkaKeysTabell.insert { }[KafkaKeysTabell.id]
Expand All @@ -63,5 +64,7 @@ class KafkaKeys(private val database: Database) {
}
}.mapToFailure { exception ->
Failure("database", FailureCode.INTERNAL_TECHINCAL_ERROR, exception)
}.flatMap { id -> id?.let(::right) ?: left(Failure("database", FailureCode.CONFLICT)) }
}
.map { id -> id?.let(::ArbeidssoekerId) }
.flatMap { id -> id?.let(::right) ?: left(Failure("database", FailureCode.CONFLICT)) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ private suspend fun PipelineContext<Unit, ApplicationCall>.handleRequest(
val request = call.receive<RecordKeyLookupRequestV1>()
val result = applikasjon.hent(callId, Identitetsnummer(request.ident))
.map(::publicTopicKeyFunction)
.map(::RecordKeyLookupResponseV1)
.map(::recordKeyLookupResponseV1)
.onLeft { failure ->
if (failure.code in listOf(FailureCode.INTERNAL_TECHINCAL_ERROR, FailureCode.CONFLICT)) {
logger.error("kode: '{}', system: '{}'", failure.code, failure.system, failure.exception)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package no.nav.paw.kafkakeygenerator.api.oppslag

import no.nav.paw.kafkakeygenerator.vo.RecordKey

data class RecordKeyLookupResponseV1(
val key: Long
)

fun recordKeyLookupResponseV1(
key: RecordKey
) = RecordKeyLookupResponseV1(
key = key.value
)
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private suspend fun PipelineContext<Unit, ApplicationCall>.handleRequest(
when (val resultat = applikasjon.hentEllerOpprett(callId, Identitetsnummer(request.ident))) {
is Right -> {
call.respond(
OK, ResponseV2(
OK, responseV2(
id = resultat.right,
key = publicTopicKeyFunction(resultat.right)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package no.nav.paw.kafkakeygenerator.api.v2

import no.nav.paw.kafkakeygenerator.vo.ArbeidssoekerId
import no.nav.paw.kafkakeygenerator.vo.RecordKey

//Endring av denne verdien krever replay av eventlog til nye topics!!
const val PUBLIC_KEY_MODULO_VALUE = 7_500

//Endring av denne funksjonen krever replay av eventlog til nye topics!!
fun publicTopicKeyFunction(internalKey: Long): Long =
"internal_key_$internalKey".hashCode().toLong() % PUBLIC_KEY_MODULO_VALUE
fun publicTopicKeyFunction(arbeidssoekerId: ArbeidssoekerId): RecordKey =
RecordKey("internal_key_${arbeidssoekerId.value}".hashCode().toLong() % PUBLIC_KEY_MODULO_VALUE)
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package no.nav.paw.kafkakeygenerator.api.v2

import no.nav.paw.kafkakeygenerator.vo.ArbeidssoekerId
import no.nav.paw.kafkakeygenerator.vo.RecordKey

data class ResponseV2(
val id: Long,
val key: Long
)

fun responseV2(
id: ArbeidssoekerId,
key: RecordKey
) = ResponseV2(
id = id.value,
key = key.value
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package no.nav.paw.kafkakeygenerator.vo

@JvmInline
value class ArbeidssoekerId(val value: Long)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package no.nav.paw.kafkakeygenerator.vo

@JvmInline
value class RecordKey(val value: Long)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.ktor.client.*
import io.ktor.client.engine.mock.*
import kotlinx.coroutines.runBlocking
import no.nav.paw.kafkakeygenerator.pdl.PdlIdentitesTjeneste
import no.nav.paw.kafkakeygenerator.vo.ArbeidssoekerId
import no.nav.paw.kafkakeygenerator.vo.CallId
import no.nav.paw.kafkakeygenerator.vo.Identitetsnummer
import no.nav.paw.pdl.PdlClient
Expand All @@ -27,7 +28,7 @@ class ApplikasjonsTest : StringSpec({
kafkaKeys = KafkaKeys(Database.connect(dataSource)),
identitetsTjeneste = PdlIdentitesTjeneste(pdlKlient)
)
fun hentEllerOpprett(identitetsnummer: String): Either<Failure, Long> = runBlocking {
fun hentEllerOpprett(identitetsnummer: String): Either<Failure, ArbeidssoekerId> = runBlocking {
app.hentEllerOpprett(CallId(UUID.randomUUID().toString()), Identitetsnummer(identitetsnummer))
}
"alle identer for person1 skal gi samme nøkkel" {
Expand All @@ -39,7 +40,7 @@ class ApplikasjonsTest : StringSpec({
person1_dnummer
).map(::hentEllerOpprett)
person1KafkaNøkler.filterIsInstance<Left<Failure>>().size shouldBe 0
person1KafkaNøkler.filterIsInstance<Right<Long>>()
person1KafkaNøkler.filterIsInstance<Right<ArbeidssoekerId>>()
.map { it.right }
.distinct().size shouldBe 1
}
Expand All @@ -50,7 +51,7 @@ class ApplikasjonsTest : StringSpec({
person2_fødselsnummer
).map(::hentEllerOpprett)
person2KafkaNøkler.filterIsInstance<Left<Failure>>().size shouldBe 0
person2KafkaNøkler.filterIsInstance<Right<Long>>()
person2KafkaNøkler.filterIsInstance<Right<ArbeidssoekerId>>()
.map { it.right }
.distinct().size shouldBe 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import io.kotest.core.spec.style.FreeSpec
import io.kotest.matchers.shouldBe
import no.nav.paw.kafkakeygenerator.api.v2.PUBLIC_KEY_MODULO_VALUE
import no.nav.paw.kafkakeygenerator.api.v2.publicTopicKeyFunction
import no.nav.paw.kafkakeygenerator.vo.ArbeidssoekerId
import no.nav.paw.kafkakeygenerator.vo.RecordKey

/**
* Enkel test som vil feile ved endring av publicTopicKeyFunction eller nooen av
Expand All @@ -15,13 +17,13 @@ class PublicKeyFunctionTest : FreeSpec({
"nøkkelen må aldri endres da dette krever replay av eventlog til nye topics" {
val expectedModuloValue = 7_500
PUBLIC_KEY_MODULO_VALUE shouldBe expectedModuloValue
publicTopicKeyFunction(0) shouldBe ("internal_key_0".hashCode().toLong() % expectedModuloValue)
publicTopicKeyFunction(expectedModuloValue.toLong()) shouldBe ("internal_key_7500".hashCode()
publicTopicKeyFunction(ArbeidssoekerId(0)).value shouldBe ("internal_key_0".hashCode().toLong() % expectedModuloValue)
publicTopicKeyFunction(ArbeidssoekerId(expectedModuloValue.toLong())).value shouldBe ("internal_key_7500".hashCode()
.toLong() % expectedModuloValue)
publicTopicKeyFunction(expectedModuloValue.toLong() + 1) shouldBe ("internal_key_7501".hashCode()
publicTopicKeyFunction(ArbeidssoekerId(expectedModuloValue.toLong() + 1)).value shouldBe ("internal_key_7501".hashCode()
.toLong() % expectedModuloValue)
(0 until expectedModuloValue).forEach { key ->
publicTopicKeyFunction(key.toLong()) shouldBe ("internal_key_$key".hashCode()
publicTopicKeyFunction(ArbeidssoekerId(key.toLong())).value shouldBe ("internal_key_$key".hashCode()
.toLong() % expectedModuloValue)
}
}
Expand Down

0 comments on commit 1abe715

Please sign in to comment.