Skip to content

Commit

Permalink
Les nested data i ServiceRiver (#561)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjerga authored Jun 19, 2024
1 parent 2b1db55 commit f6ae2eb
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import no.nav.helsearbeidsgiver.felles.EventName
import no.nav.helsearbeidsgiver.felles.Key
import no.nav.helsearbeidsgiver.felles.json.krev
import no.nav.helsearbeidsgiver.felles.json.les
import no.nav.helsearbeidsgiver.felles.json.toMap
import no.nav.helsearbeidsgiver.felles.json.toPretty
import no.nav.helsearbeidsgiver.felles.loeser.ObjectRiver
import no.nav.helsearbeidsgiver.felles.rapidsrivers.model.Fail
Expand All @@ -24,8 +25,13 @@ class ServiceRiver(
private val logger = logger()
private val sikkerLogger = sikkerLogger()

override fun les(json: Map<Key, JsonElement>): ServiceMelding? =
when {
override fun les(json: Map<Key, JsonElement>): ServiceMelding? {
val nestedData = json[Key.DATA]
?.runCatching { toMap() }
?.getOrNull()
.orEmpty()

return when {
Key.FAIL in json -> {
FailMelding(
eventName = Key.EVENT_NAME.krev(service.eventName, EventName.serializer(), json),
Expand All @@ -34,6 +40,7 @@ class ServiceRiver(
)
}

// Støtter Key.DATA som flagg med datafelt på rot (metode på vei ut)
Key.DATA in json &&
(
service.startKeys.all(json::containsKey) ||
Expand All @@ -48,10 +55,24 @@ class ServiceRiver(
)
}

// Støtter Key.DATA som objekt som inneholder datafelt (metode på vei inn)
// TODO Når all data er nested under Key.DATA så kan startKeys og dataKeys få visibility protected
service.startKeys.all(nestedData::containsKey) ||
service.dataKeys.any(nestedData::containsKey) -> {
DataMelding(
eventName = Key.EVENT_NAME.krev(service.eventName, EventName.serializer(), json),
transaksjonId = Key.UUID.les(UuidSerializer, json),
dataMap = nestedData.filterKeys {
(service.startKeys + service.dataKeys).contains(it)
}
)
}

else -> {
null
}
}
}

override fun ServiceMelding.haandter(json: Map<Key, JsonElement>): Map<Key, JsonElement>? {
when (this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package no.nav.helsearbeidsgiver.felles.rapidsrivers.service
import io.kotest.core.spec.style.FunSpec
import io.kotest.datatest.withData
import io.kotest.matchers.ints.shouldBeExactly
import io.kotest.matchers.maps.shouldNotContainKey
import io.kotest.matchers.maps.shouldNotContainValue
import io.kotest.matchers.shouldBe
import io.mockk.clearAllMocks
Expand Down Expand Up @@ -41,16 +40,19 @@ class ServiceRiverTest : FunSpec({
testRapid.reset()
clearAllMocks()
mockRedis.setup()

// For å passere sjekk for inaktivitet
every {
mockRedis.store.getAll(any())
} returns Mock.values(mockService.startKeys).mapKeys { it.key.toString() }
}

context("fail-melding har presedens") {
withData(
mapOf(
"over start" to mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.FAIL to Mock.fail.toJson(Fail.serializer()),
Key.DATA to "".toJson()
)
.plus(Mock.values(mockService.startKeys)),

"over data" to mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Expand All @@ -59,14 +61,26 @@ class ServiceRiverTest : FunSpec({
)
.plus(Mock.values(mockService.dataKeys)),

"over start" to mapOf(
"over start med nested data" to mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.FAIL to Mock.fail.toJson(Fail.serializer()),
Key.DATA to Mock.values(mockService.startKeys).toJson()
),

"over nested data" to mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.FAIL to Mock.fail.toJson(Fail.serializer())
Key.FAIL to Mock.fail.toJson(Fail.serializer()),
Key.DATA to Mock.values(mockService.dataKeys).toJson()
)
.plus(Mock.values(mockService.startKeys))
)
) { innkommendeMelding ->
// For å passere sjekk for inaktivitet
every {
mockRedis.store.getAll(any())
} returns Mock.values(mockService.startKeys).mapKeys { it.key.toString() }

testRapid.sendJson(innkommendeMelding)

verify {
Expand Down Expand Up @@ -105,16 +119,45 @@ class ServiceRiverTest : FunSpec({
}
}

test("datamelding håndteres korrekt") {
val eksisterendeRedisValues = Mock.values(mockService.startKeys + Key.PERSONER)
test("datamelding med nested startdata håndteres korrekt") {
val transaksjonId = UUID.randomUUID()
val data = Mock.values(mockService.startKeys)

every {
mockRedis.store.getAll(any())
} returns eksisterendeRedisValues.mapKeys { it.key.toString() }
val innkommendeMelding = mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to transaksjonId.toJson(),
Key.DATA to data.toJson()
)

testRapid.sendJson(innkommendeMelding)

val redisStartValues = data.mapKeys {
RedisKey.of(transaksjonId, it.key)
}

val beriketMelding = data + innkommendeMelding

verifyOrder {
redisStartValues.forEach { (key, value) ->
mockRedis.store.set(key, value)
}
mockService.onData(beriketMelding)
}
verify(exactly = 0) {
mockService.onError(any(), any())
}
}

test("datamelding håndteres korrekt") {
val transaksjonId = UUID.randomUUID()
val virksomhetNavn = "Fredrikssons Fabrikk"

val eksisterendeRedisValues = Mock.values(mockService.startKeys + Key.PERSONER)

eksisterendeRedisValues.forEach {
mockRedis.store.set(RedisKey.of(transaksjonId, it.key), it.value)
}

val innkommendeMelding = mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to transaksjonId.toJson(),
Expand All @@ -124,10 +167,46 @@ class ServiceRiverTest : FunSpec({

testRapid.sendJson(innkommendeMelding)

val allKeys = (mockService.startKeys + mockService.dataKeys).map { RedisKey.of(transaksjonId, it) }.toSet()

val beriketMelding = eksisterendeRedisValues + innkommendeMelding

verifyOrder {
mockRedis.store.set(RedisKey.of(transaksjonId, Key.VIRKSOMHETER), virksomhetNavn.toJson())
mockRedis.store.getAll(allKeys)
mockService.onData(beriketMelding)
}
verify(exactly = 0) {
mockService.onError(any(), any())
}
}

test("datamelding med nested data håndteres korrekt") {
val transaksjonId = UUID.randomUUID()
val virksomhetNavn = "Fredrikssons Fabrikk"

val eksisterendeRedisValues = Mock.values(mockService.startKeys + Key.PERSONER)

eksisterendeRedisValues.forEach {
mockRedis.store.set(RedisKey.of(transaksjonId, it.key), it.value)
}

val data = mapOf(
Key.VIRKSOMHETER to virksomhetNavn.toJson()
)

val innkommendeMelding = mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to transaksjonId.toJson(),
Key.DATA to data.toJson()
)

testRapid.sendJson(innkommendeMelding)

val allKeys = (mockService.startKeys + mockService.dataKeys).map { RedisKey.of(transaksjonId, it) }.toSet()

val beriketMelding = eksisterendeRedisValues + data + innkommendeMelding

verifyOrder {
mockRedis.store.set(RedisKey.of(transaksjonId, Key.VIRKSOMHETER), virksomhetNavn.toJson())
mockRedis.store.getAll(allKeys)
Expand Down Expand Up @@ -191,7 +270,31 @@ class ServiceRiverTest : FunSpec({
}
}

test("redis-data med feil ignoreres") {
test("ved feil så publiseres ingenting (nested data)") {
every { mockRedis.store.set(any(), any()) } throws NullPointerException()

val innkommendeMelding = mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.DATA to mapOf(
Key.VIRKSOMHETER to "Barry Eagles Language Course".toJson()
).toJson()
)

testRapid.sendJson(innkommendeMelding)

testRapid.inspektør.size shouldBeExactly 0

verify {
mockRedis.store.set(any(), any())
}
verify(exactly = 0) {
mockService.onData(any())
mockService.onError(any(), any())
}
}

test("redis-data med ugyldig key ignoreres") {
val validJson = "gyldig json pga. -->".toJson()

val validRedisValues = Mock.values(mockService.startKeys)
Expand Down Expand Up @@ -219,7 +322,6 @@ class ServiceRiverTest : FunSpec({
mockService.onError(
withArg {
it shouldBe beriketMelding
it shouldNotContainKey Key.PERSONER
it shouldNotContainValue validJson
},
Mock.fail
Expand Down Expand Up @@ -257,6 +359,34 @@ class ServiceRiverTest : FunSpec({
}
}

test("datamelding (med nested data) trigger ikke service ved manglende startdata (inaktiv service)") {
every {
mockRedis.store.getAll(any())
} returns Mock.values(setOf(Key.PERSONER)).mapKeys { it.key.toString() }

val transaksjonId = UUID.randomUUID()
val virksomhetNavn = "Terkels Sabeltannisbutikk"

val innkommendeMelding = mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to transaksjonId.toJson(),
Key.DATA to mapOf(
Key.VIRKSOMHETER to virksomhetNavn.toJson()
).toJson()
)

testRapid.sendJson(innkommendeMelding)

verifyOrder {
mockRedis.store.set(RedisKey.of(transaksjonId, Key.VIRKSOMHETER), virksomhetNavn.toJson())
mockRedis.store.getAll(any())
}
verify(exactly = 0) {
mockService.onData(any())
mockService.onError(any(), any())
}
}

test("fail-melding trigger ikke service ved manglende startdata (inaktiv service)") {
every {
mockRedis.store.getAll(any())
Expand Down Expand Up @@ -317,17 +447,39 @@ class ServiceRiverTest : FunSpec({
Key.FNR_LISTE to "mock fnr_liste".toJson()
),

"uten alle startdataverdier (nested data)" to mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.DATA to mapOf(
Key.FNR_LISTE to "mock fnr_liste".toJson()
).toJson()
),

"uten noen dataverdier" to mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.DATA to "".toJson()
),

"uten noen dataverdier (nested data)" to mapOf(
Key.EVENT_NAME to mockService.eventName.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.DATA to emptyMap<Key, JsonElement>().toJson()
),

"med uønsket event" to mapOf(
Key.EVENT_NAME to EventName.MANUELL_SLETT_SAK_REQUESTED.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.DATA to "".toJson(),
Key.PERSONER to "mock personer".toJson()
),

"med uønsket event (nested data)" to mapOf(
Key.EVENT_NAME to EventName.MANUELL_SLETT_SAK_REQUESTED.toJson(),
Key.UUID to UUID.randomUUID().toJson(),
Key.DATA to mapOf(
Key.PERSONER to "mock personer".toJson()
).toJson()
)
)
) { innkommendeMelding ->
Expand Down

0 comments on commit f6ae2eb

Please sign in to comment.