Skip to content

Commit

Permalink
IS-3066: Use valkey-cache (#578)
Browse files Browse the repository at this point in the history
  • Loading branch information
geir-waagboe authored Feb 10, 2025
1 parent b4f35af commit 776e93e
Show file tree
Hide file tree
Showing 24 changed files with 93 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .nais/naiserator-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ spec:
claims:
extra:
- "NAVident"
redis:
valkey:
- instance: cache
access: readwrite
tokenx:
Expand Down
2 changes: 1 addition & 1 deletion .nais/naiserator-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ spec:
claims:
extra:
- "NAVident"
redis:
valkey:
- instance: cache
access: readwrite
tokenx:
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ Creating a docker image should be as simple as `docker build -t isdialogmote .`

### Cache

This application uses Redis for caching. Redis is deployed automatically on changes to workflow or config on master
branch. For manual deploy, run: `kubectl apply -f .nais/redis-config.yaml`
or `kubectl apply -f .nais/redisexporter.yaml`.
This application uses Aiven Valkey for caching.

### Kafka

Expand Down
20 changes: 10 additions & 10 deletions src/main/kotlin/no/nav/syfo/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import no.nav.syfo.application.ApplicationState
import no.nav.syfo.application.Environment
import no.nav.syfo.application.api.apiModule
import no.nav.syfo.application.api.authentication.getWellKnown
import no.nav.syfo.application.cache.RedisStore
import no.nav.syfo.application.cache.ValkeyStore
import no.nav.syfo.application.database.applicationDatabase
import no.nav.syfo.application.database.databaseModule
import no.nav.syfo.application.isDevGcp
Expand Down Expand Up @@ -76,16 +76,16 @@ fun main() {
kafkaEsyfovarselConfig(environment.kafka)
),
)
val redisConfig = environment.redisConfig
val cache = RedisStore(
val valkeyConfig = environment.valkeyConfig
val cache = ValkeyStore(
JedisPool(
JedisPoolConfig(),
HostAndPort(redisConfig.host, redisConfig.port),
HostAndPort(valkeyConfig.host, valkeyConfig.port),
DefaultJedisClientConfig.builder()
.ssl(redisConfig.ssl)
.user(redisConfig.redisUsername)
.password(redisConfig.redisPassword)
.database(redisConfig.redisDB)
.ssl(valkeyConfig.ssl)
.user(valkeyConfig.valkeyUsername)
.password(valkeyConfig.valkeyPassword)
.database(valkeyConfig.valkeyDB)
.build()
)
)
Expand All @@ -95,7 +95,7 @@ fun main() {
aadAppClient = environment.aadAppClient,
aadAppSecret = environment.aadAppSecret,
aadTokenEndpoint = environment.aadTokenEndpoint,
redisStore = cache,
valkeyStore = cache,
)
val tokendingsClient = TokendingsClient(
tokenxClientId = environment.tokenxClientId,
Expand All @@ -113,7 +113,7 @@ fun main() {
azureAdV2Client = azureAdV2Client,
pdlClientId = environment.pdlClientId,
pdlUrl = environment.pdlUrl,
redisStore = cache,
valkeyStore = cache,
)
val behandlendeEnhetClient = BehandlendeEnhetClient(
azureAdV2Client = azureAdV2Client,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package no.nav.syfo.application

import io.ktor.server.application.*
import no.nav.syfo.application.cache.RedisConfig
import no.nav.syfo.application.cache.ValkeyConfig
import java.net.URI
import java.time.LocalDate

Expand Down Expand Up @@ -29,11 +29,11 @@ data class Environment(
aivenTruststoreLocation = getEnvVar("KAFKA_TRUSTSTORE_PATH"),
aivenKeystoreLocation = getEnvVar("KAFKA_KEYSTORE_PATH"),
),
val redisConfig: RedisConfig = RedisConfig(
redisUri = URI(getEnvVar("REDIS_URI_CACHE")),
redisDB = 7, // se https://github.com/navikt/istilgangskontroll/blob/master/README.md
redisUsername = getEnvVar("REDIS_USERNAME_CACHE"),
redisPassword = getEnvVar("REDIS_PASSWORD_CACHE"),
val valkeyConfig: ValkeyConfig = ValkeyConfig(
valkeyUri = URI(getEnvVar("VALKEY_URI_CACHE")),
valkeyDB = 7, // se https://github.com/navikt/istilgangskontroll/blob/master/README.md
valkeyUsername = getEnvVar("VALKEY_USERNAME_CACHE"),
valkeyPassword = getEnvVar("VALKEY_PASSWORD_CACHE"),
),
val isdialogmoteDbHost: String = getEnvVar("NAIS_DATABASE_ISDIALOGMOTE_ISDIALOGMOTE_DB_HOST"),
val isdialogmoteDbPort: String = getEnvVar("NAIS_DATABASE_ISDIALOGMOTE_ISDIALOGMOTE_DB_PORT"),
Expand Down
14 changes: 0 additions & 14 deletions src/main/kotlin/no/nav/syfo/application/cache/RedisConfig.kt

This file was deleted.

14 changes: 14 additions & 0 deletions src/main/kotlin/no/nav/syfo/application/cache/ValkeyConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package no.nav.syfo.application.cache

import java.net.URI

class ValkeyConfig(
val valkeyUri: URI,
val valkeyDB: Int,
val valkeyUsername: String,
val valkeyPassword: String,
val ssl: Boolean = true
) {
val host: String = valkeyUri.host
val port: Int = valkeyUri.port
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory
import redis.clients.jedis.JedisPool
import redis.clients.jedis.exceptions.JedisConnectionException

class RedisStore(private val jedisPool: JedisPool) {
class ValkeyStore(private val jedisPool: JedisPool) {

private val log: Logger = LoggerFactory.getLogger("no.nav.syfo.application.cache")
val mapper = configuredJacksonMapper()
Expand Down Expand Up @@ -34,7 +34,7 @@ class RedisStore(private val jedisPool: JedisPool) {
try {
jedisPool.resource.use { jedis -> return jedis.get(key) }
} catch (e: JedisConnectionException) {
log.warn("Got connection error when fetching from redis! Continuing without cached value", e)
log.warn("Got connection error when fetching from valkey! Continuing without cached value", e)
return null
}
}
Expand All @@ -53,7 +53,7 @@ class RedisStore(private val jedisPool: JedisPool) {
)
}
} catch (e: JedisConnectionException) {
log.warn("Got connection error when storing in redis! Continue without caching", e)
log.warn("Got connection error when storing in valkey! Continue without caching", e)
}
}
}
12 changes: 6 additions & 6 deletions src/main/kotlin/no/nav/syfo/client/azuread/AzureAdV2Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import io.ktor.client.statement.*
import io.ktor.http.*
import no.nav.syfo.application.api.authentication.getConsumerClientId
import no.nav.syfo.application.api.authentication.getNAVIdentFromToken
import no.nav.syfo.application.cache.RedisStore
import no.nav.syfo.application.cache.ValkeyStore
import no.nav.syfo.client.httpClientProxy
import org.slf4j.LoggerFactory

class AzureAdV2Client(
private val aadAppClient: String,
private val aadAppSecret: String,
private val aadTokenEndpoint: String,
private val redisStore: RedisStore,
private val valkeyStore: ValkeyStore,
private val httpClient: HttpClient = httpClientProxy(),
) {

Expand All @@ -29,7 +29,7 @@ class AzureAdV2Client(
val veilederIdent = getNAVIdentFromToken(token)

val cacheKey = "$veilederIdent-$azp-$scopeClientId"
val cachedToken: AzureAdV2Token? = redisStore.getObject(key = cacheKey)
val cachedToken: AzureAdV2Token? = valkeyStore.getObject(key = cacheKey)
return if (cachedToken?.isExpired() == false) {
COUNT_CALL_AZUREAD_TOKEN_OBO_CACHE_HIT.increment()
cachedToken
Expand All @@ -48,7 +48,7 @@ class AzureAdV2Client(
azureAdTokenResponse?.let { tokenResponse ->
val azureAdToken = tokenResponse.toAzureAdV2Token()
COUNT_CALL_AZUREAD_TOKEN_OBO_CACHE_MISS.increment()
redisStore.setObject(
valkeyStore.setObject(
expireSeconds = 3600,
key = cacheKey,
value = azureAdToken,
Expand All @@ -60,7 +60,7 @@ class AzureAdV2Client(

suspend fun getSystemToken(scopeClientId: String): AzureAdV2Token? {
val cacheKey = "${CACHE_AZUREAD_TOKEN_SYSTEM_KEY_PREFIX}$scopeClientId"
val cachedToken = redisStore.getObject<AzureAdV2Token>(key = cacheKey)
val cachedToken = valkeyStore.getObject<AzureAdV2Token>(key = cacheKey)
return if (cachedToken?.isExpired() == false) {
COUNT_CALL_AZUREAD_TOKEN_SYSTEM_CACHE_HIT.increment()
cachedToken
Expand All @@ -76,7 +76,7 @@ class AzureAdV2Client(
azureAdTokenResponse?.let { token ->
val azureAdToken = token.toAzureAdV2Token()
COUNT_CALL_AZUREAD_TOKEN_SYSTEM_CACHE_MISS.increment()
redisStore.setObject(
valkeyStore.setObject(
expireSeconds = 3600,
key = cacheKey,
value = azureAdToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import net.logstash.logback.argument.StructuredArguments
import no.nav.syfo.application.cache.RedisStore
import no.nav.syfo.application.cache.ValkeyStore
import no.nav.syfo.client.azuread.AzureAdV2Client
import no.nav.syfo.client.httpClientDefault
import no.nav.syfo.client.tokendings.TokendingsClient
Expand All @@ -21,7 +21,7 @@ class NarmesteLederClient(
private val narmestelederClientId: String,
private val azureAdV2Client: AzureAdV2Client,
private val tokendingsClient: TokendingsClient,
private val cache: RedisStore,
private val cache: ValkeyStore,
private val httpClient: HttpClient = httpClientDefault(),
) {
private val narmesteLederPath = "$narmesteLederBaseUrl$CURRENT_NARMESTELEDER_PATH"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import net.logstash.logback.argument.StructuredArguments
import no.nav.syfo.application.cache.RedisStore
import no.nav.syfo.application.cache.ValkeyStore
import no.nav.syfo.client.azuread.AzureAdV2Client
import no.nav.syfo.client.httpClientDefault
import no.nav.syfo.domain.PersonIdent
Expand All @@ -22,7 +22,7 @@ class OppfolgingstilfelleClient(
private val tokendingsClient: TokendingsClient,
private val isoppfolgingstilfelleClientId: String,
isoppfolgingstilfelleBaseUrl: String,
private val cache: RedisStore,
private val cache: ValkeyStore,
private val httpClient: HttpClient = httpClientDefault()
) {
private val personOppfolgingstilfelleUrl: String =
Expand Down
12 changes: 6 additions & 6 deletions src/main/kotlin/no/nav/syfo/client/pdl/PdlClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import no.nav.syfo.application.cache.RedisStore
import no.nav.syfo.application.cache.ValkeyStore
import no.nav.syfo.client.azuread.AzureAdV2Client
import no.nav.syfo.client.azuread.AzureAdV2Token
import no.nav.syfo.client.httpClientDefault
Expand All @@ -20,23 +20,23 @@ class PdlClient(
private val azureAdV2Client: AzureAdV2Client,
private val pdlClientId: String,
private val pdlUrl: String,
private val redisStore: RedisStore,
private val valkeyStore: ValkeyStore,
private val httpClient: HttpClient = httpClientDefault(),
) {

suspend fun navn(
personIdent: PersonIdent,
): String {
val cacheKey = "$NAVN_CACHE_KEY_PREFIX${personIdent.value}"
val cachedNavn: String? = redisStore.get(key = cacheKey)
val cachedNavn: String? = valkeyStore.get(key = cacheKey)
return if (cachedNavn != null) {
cachedNavn
} else {
val token = azureAdV2Client.getSystemToken(pdlClientId)
?: throw RuntimeException("Failed to send request to PDL: No token was found")
val navn = person(personIdent, token)?.fullName()
?: throw RuntimeException("PDL returned empty navn for given fnr")
redisStore.set(cacheKey, navn, CACHE_EXPIRE_SECONDS)
valkeyStore.set(cacheKey, navn, CACHE_EXPIRE_SECONDS)
navn
}
}
Expand All @@ -46,7 +46,7 @@ class PdlClient(
callId: String,
): Set<PersonIdent> {
val cacheKey = "$FOLKEREG_IDENTER_CACHE_KEY_PREFIX${personIdent.value}"
val cachedIdenter: Set<PersonIdent>? = redisStore.getSetObject(key = cacheKey)
val cachedIdenter: Set<PersonIdent>? = valkeyStore.getSetObject(key = cacheKey)
return if (cachedIdenter != null) {
cachedIdenter
} else {
Expand All @@ -62,7 +62,7 @@ class PdlClient(
} ?: emptySet()
)
}.toSet().also {
redisStore.setObject(cacheKey, it, CACHE_EXPIRE_SECONDS)
valkeyStore.setObject(cacheKey, it, CACHE_EXPIRE_SECONDS)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import net.logstash.logback.argument.StructuredArguments
import no.nav.syfo.application.cache.RedisStore
import no.nav.syfo.application.cache.ValkeyStore
import no.nav.syfo.client.azuread.AzureAdV2Client
import no.nav.syfo.client.httpClientDefault
import no.nav.syfo.client.person.COUNT_CALL_PERSON_KONTAKTINFORMASJON_FAIL
Expand All @@ -18,7 +18,7 @@ import org.slf4j.LoggerFactory

class KontaktinformasjonClient(
private val azureAdV2Client: AzureAdV2Client,
private val cache: RedisStore,
private val cache: ValkeyStore,
private val clientId: String,
baseUrl: String,
private val httpClient: HttpClient = httpClientDefault()
Expand Down
8 changes: 4 additions & 4 deletions src/main/kotlin/no/nav/syfo/cronjob/CronjobModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package no.nav.syfo.cronjob
import io.ktor.server.application.Application
import no.nav.syfo.application.ApplicationState
import no.nav.syfo.application.Environment
import no.nav.syfo.application.cache.RedisStore
import no.nav.syfo.application.cache.ValkeyStore
import no.nav.syfo.application.database.DatabaseInterface
import no.nav.syfo.application.launchBackgroundTask
import no.nav.syfo.brev.arbeidstaker.ArbeidstakerVarselService
Expand Down Expand Up @@ -33,7 +33,7 @@ fun Application.cronjobModule(
applicationState: ApplicationState,
database: DatabaseInterface,
environment: Environment,
cache: RedisStore,
cache: ValkeyStore,
dialogmotestatusService: DialogmotestatusService,
dialogmoterelasjonService: DialogmoterelasjonService,
arbeidstakerVarselService: ArbeidstakerVarselService,
Expand All @@ -43,7 +43,7 @@ fun Application.cronjobModule(
aadAppClient = environment.aadAppClient,
aadAppSecret = environment.aadAppSecret,
aadTokenEndpoint = environment.aadTokenEndpoint,
redisStore = cache,
valkeyStore = cache,
)
val dokarkivClient = DokarkivClient(
azureAdV2Client = azureAdV2Client,
Expand All @@ -54,7 +54,7 @@ fun Application.cronjobModule(
azureAdV2Client = azureAdV2Client,
pdlClientId = environment.pdlClientId,
pdlUrl = environment.pdlUrl,
redisStore = cache,
valkeyStore = cache,
)
val eregClient = EregClient(
baseUrl = environment.eregUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.mockk.mockk
import io.mockk.verify
import java.time.LocalDateTime
import kotlinx.coroutines.runBlocking
import no.nav.syfo.application.cache.RedisStore
import no.nav.syfo.application.cache.ValkeyStore
import no.nav.syfo.testhelper.ExternalMockEnvironment
import no.nav.syfo.testhelper.UserConstants.AZUREAD_TOKEN
import no.nav.syfo.testhelper.UserConstants.JWT_AZP
Expand All @@ -25,13 +25,13 @@ class AzureAdClientSpek : Spek({

describe(AzureAdClientSpek::class.java.simpleName) {
val externalMockEnvironment = ExternalMockEnvironment.getInstance()
val cacheMock = mockk<RedisStore>()
val cacheMock = mockk<ValkeyStore>()

val azureAdClient = AzureAdV2Client(
aadAppClient = externalMockEnvironment.environment.aadAppClient,
aadAppSecret = externalMockEnvironment.environment.aadAppSecret,
aadTokenEndpoint = externalMockEnvironment.environment.aadTokenEndpoint,
redisStore = cacheMock,
valkeyStore = cacheMock,
httpClient = externalMockEnvironment.mockHttpClient,
)
val systemTokenCacheKey =
Expand Down
Loading

0 comments on commit 776e93e

Please sign in to comment.