refactor: replace Redis references with Valkey in tests and cache modules
Updated test cases in `ValkeyEventStoreTest` and cache implementation in `ValkeyDistributedCache` to fully transition from Redis to Valkey. Adjusted configurations, templates, connection handling, and exception management to reflect Valkey-specific behavior and APIs.
This commit is contained in:
@@ -28,6 +28,13 @@ dependencies {
|
|||||||
// OPTIMIERUNG: Verwendung des `valkey-cache`-Bundles aus libs.versions.toml.
|
// OPTIMIERUNG: Verwendung des `valkey-cache`-Bundles aus libs.versions.toml.
|
||||||
// Dieses Bundle enthält Spring Data Valkey, Lettuce und Jackson-Module.
|
// Dieses Bundle enthält Spring Data Valkey, Lettuce und Jackson-Module.
|
||||||
implementation(libs.bundles.valkey.cache)
|
implementation(libs.bundles.valkey.cache)
|
||||||
|
// Benötigt für Lettuce-basierten Valkey-Client (LettuceConnectionFactory)
|
||||||
|
implementation(libs.lettuce.core)
|
||||||
|
// Für Boot-Autoconfiguration-Annotations wie @ConfigurationProperties,
|
||||||
|
// @EnableConfigurationProperties und @ConditionalOnMissingBean
|
||||||
|
implementation("org.springframework.boot:spring-boot-autoconfigure")
|
||||||
|
// Optional, generiert Metadata f. @ConfigurationProperties (zur IDE-Unterstützung)
|
||||||
|
compileOnly("org.springframework.boot:spring-boot-configuration-processor")
|
||||||
// Stellt alle Test-Abhängigkeiten gebündelt bereit.
|
// Stellt alle Test-Abhängigkeiten gebündelt bereit.
|
||||||
testImplementation(projects.platform.platformTesting)
|
testImplementation(projects.platform.platformTesting)
|
||||||
testImplementation(libs.bundles.testing.jvm)
|
testImplementation(libs.bundles.testing.jvm)
|
||||||
|
|||||||
+14
-14
@@ -3,18 +3,18 @@ package at.mocode.infrastructure.cache.valkey
|
|||||||
import at.mocode.infrastructure.cache.api.CacheConfiguration
|
import at.mocode.infrastructure.cache.api.CacheConfiguration
|
||||||
import at.mocode.infrastructure.cache.api.CacheSerializer
|
import at.mocode.infrastructure.cache.api.CacheSerializer
|
||||||
import at.mocode.infrastructure.cache.api.DefaultCacheConfiguration
|
import at.mocode.infrastructure.cache.api.DefaultCacheConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyPassword
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
|
import io.valkey.springframework.data.valkey.serializer.StringValkeySerializer
|
||||||
import org.springframework.beans.factory.annotation.Qualifier
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory
|
|
||||||
import org.springframework.data.redis.connection.RedisPassword
|
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Valkey connection properties.
|
* Valkey connection properties.
|
||||||
@@ -46,11 +46,11 @@ class ValkeyConfiguration {
|
|||||||
* @return Valkey connection factory
|
* @return Valkey connection factory
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
fun valkeyConnectionFactory(properties: ValkeyProperties): RedisConnectionFactory {
|
fun valkeyConnectionFactory(properties: ValkeyProperties): ValkeyConnectionFactory {
|
||||||
val config = RedisStandaloneConfiguration().apply {
|
val config = ValkeyStandaloneConfiguration().apply {
|
||||||
hostName = properties.host
|
hostName = properties.host
|
||||||
port = properties.port
|
port = properties.port
|
||||||
properties.password?.let { password = RedisPassword.of(it) }
|
properties.password?.let { password = ValkeyPassword.of(it) }
|
||||||
database = properties.database
|
database = properties.database
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,11 +68,11 @@ class ValkeyConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
fun valkeyTemplate(
|
fun valkeyTemplate(
|
||||||
@Qualifier("valkeyConnectionFactory") connectionFactory: RedisConnectionFactory
|
@Qualifier("valkeyConnectionFactory") connectionFactory: ValkeyConnectionFactory
|
||||||
): RedisTemplate<String, ByteArray> {
|
): ValkeyTemplate<String, ByteArray> {
|
||||||
return RedisTemplate<String, ByteArray>().apply {
|
return ValkeyTemplate<String, ByteArray>().apply {
|
||||||
setConnectionFactory(connectionFactory)
|
setConnectionFactory(connectionFactory)
|
||||||
keySerializer = StringRedisSerializer()
|
keySerializer = StringValkeySerializer()
|
||||||
// Use default serializer for values (byte arrays)
|
// Use default serializer for values (byte arrays)
|
||||||
afterPropertiesSet()
|
afterPropertiesSet()
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-13
@@ -7,9 +7,9 @@ import at.mocode.infrastructure.cache.api.ConnectionState
|
|||||||
import at.mocode.infrastructure.cache.api.ConnectionStateListener
|
import at.mocode.infrastructure.cache.api.ConnectionStateListener
|
||||||
import at.mocode.infrastructure.cache.api.ConnectionStatusTracker
|
import at.mocode.infrastructure.cache.api.ConnectionStatusTracker
|
||||||
import at.mocode.infrastructure.cache.api.DistributedCache
|
import at.mocode.infrastructure.cache.api.DistributedCache
|
||||||
|
import io.valkey.springframework.data.valkey.ValkeyConnectionFailureException
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.data.redis.RedisConnectionFailureException
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled
|
import org.springframework.scheduling.annotation.Scheduled
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.CopyOnWriteArrayList
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
@@ -21,7 +21,7 @@ import kotlin.time.ExperimentalTime
|
|||||||
|
|
||||||
@OptIn(ExperimentalTime::class)
|
@OptIn(ExperimentalTime::class)
|
||||||
class ValkeyDistributedCache(
|
class ValkeyDistributedCache(
|
||||||
private val valkeyTemplate: RedisTemplate<String, ByteArray>,
|
private val valkeyTemplate: ValkeyTemplate<String, ByteArray>,
|
||||||
private val serializer: CacheSerializer,
|
private val serializer: CacheSerializer,
|
||||||
private val config: CacheConfiguration
|
private val config: CacheConfiguration
|
||||||
) : DistributedCache, ConnectionStatusTracker {
|
) : DistributedCache, ConnectionStatusTracker {
|
||||||
@@ -86,7 +86,7 @@ class ValkeyDistributedCache(
|
|||||||
|
|
||||||
trackOperation(true)
|
trackOperation(true)
|
||||||
return entry.value
|
return entry.value
|
||||||
} catch (e: RedisConnectionFailureException) {
|
} catch (e: ValkeyConnectionFailureException) {
|
||||||
handleConnectionFailure(e)
|
handleConnectionFailure(e)
|
||||||
trackOperation(false)
|
trackOperation(false)
|
||||||
return null
|
return null
|
||||||
@@ -121,13 +121,13 @@ class ValkeyDistributedCache(
|
|||||||
val bytes = serializer.serializeEntry(entry)
|
val bytes = serializer.serializeEntry(entry)
|
||||||
val effectiveTtl = ttl ?: config.defaultTtl
|
val effectiveTtl = ttl ?: config.defaultTtl
|
||||||
if (effectiveTtl != null) {
|
if (effectiveTtl != null) {
|
||||||
// KORREKTUR: Konvertierung zu java.time.Duration für RedisTemplate
|
// KORREKTUR: Konvertierung zu java.time.Duration für ValkeyTemplate
|
||||||
valkeyTemplate.opsForValue().set(prefixedKey, bytes, effectiveTtl.toJavaDuration())
|
valkeyTemplate.opsForValue().set(prefixedKey, bytes, effectiveTtl.toJavaDuration())
|
||||||
} else {
|
} else {
|
||||||
valkeyTemplate.opsForValue().set(prefixedKey, bytes)
|
valkeyTemplate.opsForValue().set(prefixedKey, bytes)
|
||||||
}
|
}
|
||||||
trackOperation(true)
|
trackOperation(true)
|
||||||
} catch (e: RedisConnectionFailureException) {
|
} catch (e: ValkeyConnectionFailureException) {
|
||||||
handleConnectionFailure(e)
|
handleConnectionFailure(e)
|
||||||
markDirty(key)
|
markDirty(key)
|
||||||
trackOperation(false)
|
trackOperation(false)
|
||||||
@@ -153,7 +153,7 @@ class ValkeyDistributedCache(
|
|||||||
// Try to delete from Valkey
|
// Try to delete from Valkey
|
||||||
try {
|
try {
|
||||||
valkeyTemplate.delete(prefixedKey)
|
valkeyTemplate.delete(prefixedKey)
|
||||||
} catch (e: RedisConnectionFailureException) {
|
} catch (e: ValkeyConnectionFailureException) {
|
||||||
handleConnectionFailure(e)
|
handleConnectionFailure(e)
|
||||||
markDirty(key)
|
markDirty(key)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -183,7 +183,7 @@ class ValkeyDistributedCache(
|
|||||||
// Check Valkey
|
// Check Valkey
|
||||||
try {
|
try {
|
||||||
return valkeyTemplate.hasKey(prefixedKey) ?: false
|
return valkeyTemplate.hasKey(prefixedKey) ?: false
|
||||||
} catch (e: RedisConnectionFailureException) {
|
} catch (e: ValkeyConnectionFailureException) {
|
||||||
handleConnectionFailure(e)
|
handleConnectionFailure(e)
|
||||||
return false
|
return false
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -243,7 +243,7 @@ class ValkeyDistributedCache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: RedisConnectionFailureException) {
|
} catch (e: ValkeyConnectionFailureException) {
|
||||||
handleConnectionFailure(e)
|
handleConnectionFailure(e)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logger.error("Error getting multiple values from Valkey", e)
|
logger.error("Error getting multiple values from Valkey", e)
|
||||||
@@ -286,7 +286,7 @@ class ValkeyDistributedCache(
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: RedisConnectionFailureException) {
|
} catch (e: ValkeyConnectionFailureException) {
|
||||||
handleConnectionFailure(e)
|
handleConnectionFailure(e)
|
||||||
entries.keys.forEach { markDirty(it) }
|
entries.keys.forEach { markDirty(it) }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -310,7 +310,7 @@ class ValkeyDistributedCache(
|
|||||||
// Try to delete from Valkey
|
// Try to delete from Valkey
|
||||||
try {
|
try {
|
||||||
valkeyTemplate.delete(prefixedKeys)
|
valkeyTemplate.delete(prefixedKeys)
|
||||||
} catch (e: RedisConnectionFailureException) {
|
} catch (e: ValkeyConnectionFailureException) {
|
||||||
handleConnectionFailure(e)
|
handleConnectionFailure(e)
|
||||||
keys.forEach { markDirty(it) }
|
keys.forEach { markDirty(it) }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -402,7 +402,7 @@ class ValkeyDistributedCache(
|
|||||||
if (keys != null && keys.isNotEmpty()) {
|
if (keys != null && keys.isNotEmpty()) {
|
||||||
valkeyTemplate.delete(keys)
|
valkeyTemplate.delete(keys)
|
||||||
}
|
}
|
||||||
} catch (e: RedisConnectionFailureException) {
|
} catch (e: ValkeyConnectionFailureException) {
|
||||||
handleConnectionFailure(e)
|
handleConnectionFailure(e)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logger.error("Error clearing Valkey cache", e)
|
logger.error("Error clearing Valkey cache", e)
|
||||||
@@ -565,7 +565,7 @@ class ValkeyDistributedCache(
|
|||||||
/**
|
/**
|
||||||
* Loggt Performance-Metriken (periodisch aufgerufen).
|
* Loggt Performance-Metriken (periodisch aufgerufen).
|
||||||
*/
|
*/
|
||||||
@Scheduled(fixedDelayString = "\${valkey.metrics-log-interval:300000}")
|
@Scheduled(fixedDelayString = $$"${valkey.metrics-log-interval:300000}")
|
||||||
fun logPerformanceMetrics() {
|
fun logPerformanceMetrics() {
|
||||||
val metrics = getPerformanceMetrics()
|
val metrics = getPerformanceMetrics()
|
||||||
logger.info("Cache performance metrics: $metrics")
|
logger.info("Cache performance metrics: $metrics")
|
||||||
|
|||||||
+10
-10
@@ -5,12 +5,12 @@ import at.mocode.infrastructure.cache.api.DefaultCacheConfiguration
|
|||||||
import at.mocode.infrastructure.cache.api.get
|
import at.mocode.infrastructure.cache.api.get
|
||||||
import at.mocode.infrastructure.cache.api.multiGet
|
import at.mocode.infrastructure.cache.api.multiGet
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
|
import io.valkey.springframework.data.valkey.serializer.StringValkeySerializer
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -37,14 +37,14 @@ class ValkeyDistributedCacheConfigurationTest {
|
|||||||
|
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer = GenericContainer<Nothing>(
|
val valkeyContainer = GenericContainer<Nothing>(
|
||||||
DockerImageName.parse("valkey/valkey:9-alpine")
|
DockerImageName.parse("valkey/valkey:8.0.2-alpine")
|
||||||
.asCompatibleSubstituteFor("valkey")
|
.asCompatibleSubstituteFor("redis")
|
||||||
).apply {
|
).apply {
|
||||||
withExposedPorts(6379)
|
withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: RedisTemplate<String, ByteArray>
|
private lateinit var valkeyTemplate: ValkeyTemplate<String, ByteArray>
|
||||||
private lateinit var serializer: CacheSerializer
|
private lateinit var serializer: CacheSerializer
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@@ -52,13 +52,13 @@ class ValkeyDistributedCacheConfigurationTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = RedisTemplate<String, ByteArray>().apply {
|
valkeyTemplate = ValkeyTemplate<String, ByteArray>().apply {
|
||||||
setConnectionFactory(connectionFactory)
|
setConnectionFactory(connectionFactory)
|
||||||
keySerializer = StringRedisSerializer()
|
keySerializer = StringValkeySerializer()
|
||||||
afterPropertiesSet()
|
afterPropertiesSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -2,12 +2,12 @@ package at.mocode.infrastructure.cache.valkey
|
|||||||
|
|
||||||
import at.mocode.infrastructure.cache.api.*
|
import at.mocode.infrastructure.cache.api.*
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
|
import io.valkey.springframework.data.valkey.serializer.StringValkeySerializer
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -29,14 +29,14 @@ class ValkeyDistributedCacheEdgeCasesTest {
|
|||||||
|
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer = GenericContainer<Nothing>(
|
val valkeyContainer = GenericContainer<Nothing>(
|
||||||
DockerImageName.parse("valkey/valkey:9-alpine")
|
DockerImageName.parse("valkey/valkey:8.0.2-alpine")
|
||||||
.asCompatibleSubstituteFor("valkey")
|
.asCompatibleSubstituteFor("redis")
|
||||||
).apply {
|
).apply {
|
||||||
withExposedPorts(6379)
|
withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: RedisTemplate<String, ByteArray>
|
private lateinit var valkeyTemplate: ValkeyTemplate<String, ByteArray>
|
||||||
private lateinit var serializer: CacheSerializer
|
private lateinit var serializer: CacheSerializer
|
||||||
private lateinit var config: CacheConfiguration
|
private lateinit var config: CacheConfiguration
|
||||||
private lateinit var cache: ValkeyDistributedCache
|
private lateinit var cache: ValkeyDistributedCache
|
||||||
@@ -46,13 +46,13 @@ class ValkeyDistributedCacheEdgeCasesTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = RedisTemplate<String, ByteArray>().apply {
|
valkeyTemplate = ValkeyTemplate<String, ByteArray>().apply {
|
||||||
setConnectionFactory(connectionFactory)
|
setConnectionFactory(connectionFactory)
|
||||||
keySerializer = StringRedisSerializer()
|
keySerializer = StringValkeySerializer()
|
||||||
afterPropertiesSet()
|
afterPropertiesSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -2,14 +2,14 @@ package at.mocode.infrastructure.cache.valkey
|
|||||||
|
|
||||||
import at.mocode.infrastructure.cache.api.*
|
import at.mocode.infrastructure.cache.api.*
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
|
import io.valkey.springframework.data.valkey.serializer.StringValkeySerializer
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -36,14 +36,14 @@ class ValkeyDistributedCacheIntegrationTest {
|
|||||||
|
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer = GenericContainer<Nothing>(
|
val valkeyContainer = GenericContainer<Nothing>(
|
||||||
DockerImageName.parse("valkey/valkey:9-alpine")
|
DockerImageName.parse("valkey/valkey:8.0.2-alpine")
|
||||||
.asCompatibleSubstituteFor("valkey")
|
.asCompatibleSubstituteFor("redis")
|
||||||
).apply {
|
).apply {
|
||||||
withExposedPorts(6379)
|
withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: RedisTemplate<String, ByteArray>
|
private lateinit var valkeyTemplate: ValkeyTemplate<String, ByteArray>
|
||||||
private lateinit var serializer: CacheSerializer
|
private lateinit var serializer: CacheSerializer
|
||||||
private lateinit var config: CacheConfiguration
|
private lateinit var config: CacheConfiguration
|
||||||
|
|
||||||
@@ -52,13 +52,13 @@ class ValkeyDistributedCacheIntegrationTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = RedisTemplate<String, ByteArray>().apply {
|
valkeyTemplate = ValkeyTemplate<String, ByteArray>().apply {
|
||||||
setConnectionFactory(connectionFactory)
|
setConnectionFactory(connectionFactory)
|
||||||
keySerializer = StringRedisSerializer()
|
keySerializer = StringValkeySerializer()
|
||||||
afterPropertiesSet()
|
afterPropertiesSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -2,15 +2,15 @@ package at.mocode.infrastructure.cache.valkey
|
|||||||
|
|
||||||
import at.mocode.infrastructure.cache.api.*
|
import at.mocode.infrastructure.cache.api.*
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
|
import io.valkey.springframework.data.valkey.serializer.StringValkeySerializer
|
||||||
import kotlinx.coroutines.joinAll
|
import kotlinx.coroutines.joinAll
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -32,14 +32,14 @@ class ValkeyDistributedCachePerformanceTest {
|
|||||||
|
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer = GenericContainer<Nothing>(
|
val valkeyContainer = GenericContainer<Nothing>(
|
||||||
DockerImageName.parse("valkey/valkey:9-alpine")
|
DockerImageName.parse("valkey/valkey:8.0.2-alpine")
|
||||||
.asCompatibleSubstituteFor("valkey")
|
.asCompatibleSubstituteFor("redis")
|
||||||
).apply {
|
).apply {
|
||||||
withExposedPorts(6379)
|
withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: RedisTemplate<String, ByteArray>
|
private lateinit var valkeyTemplate: ValkeyTemplate<String, ByteArray>
|
||||||
private lateinit var serializer: CacheSerializer
|
private lateinit var serializer: CacheSerializer
|
||||||
private lateinit var config: CacheConfiguration
|
private lateinit var config: CacheConfiguration
|
||||||
private lateinit var cache: ValkeyDistributedCache
|
private lateinit var cache: ValkeyDistributedCache
|
||||||
@@ -49,13 +49,13 @@ class ValkeyDistributedCachePerformanceTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = RedisTemplate<String, ByteArray>().apply {
|
valkeyTemplate = ValkeyTemplate<String, ByteArray>().apply {
|
||||||
setConnectionFactory(connectionFactory)
|
setConnectionFactory(connectionFactory)
|
||||||
keySerializer = StringRedisSerializer()
|
keySerializer = StringValkeySerializer()
|
||||||
afterPropertiesSet()
|
afterPropertiesSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-25
@@ -4,16 +4,16 @@ import at.mocode.infrastructure.cache.api.*
|
|||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
import io.valkey.springframework.data.valkey.ValkeyConnectionFailureException
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValueOperations
|
||||||
|
import io.valkey.springframework.data.valkey.serializer.StringValkeySerializer
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.springframework.data.redis.RedisConnectionFailureException
|
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.data.redis.core.ValueOperations
|
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -38,14 +38,14 @@ class ValkeyDistributedCacheResilienceTest {
|
|||||||
|
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer = GenericContainer<Nothing>(
|
val valkeyContainer = GenericContainer<Nothing>(
|
||||||
DockerImageName.parse("valkey/valkey:9-alpine")
|
DockerImageName.parse("valkey/valkey:8.0.2-alpine")
|
||||||
.asCompatibleSubstituteFor("valkey")
|
.asCompatibleSubstituteFor("redis")
|
||||||
).apply {
|
).apply {
|
||||||
withExposedPorts(6379)
|
withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: RedisTemplate<String, ByteArray>
|
private lateinit var valkeyTemplate: ValkeyTemplate<String, ByteArray>
|
||||||
private lateinit var serializer: CacheSerializer
|
private lateinit var serializer: CacheSerializer
|
||||||
private lateinit var config: CacheConfiguration
|
private lateinit var config: CacheConfiguration
|
||||||
|
|
||||||
@@ -54,13 +54,13 @@ class ValkeyDistributedCacheResilienceTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = RedisTemplate<String, ByteArray>().apply {
|
valkeyTemplate = ValkeyTemplate<String, ByteArray>().apply {
|
||||||
setConnectionFactory(connectionFactory)
|
setConnectionFactory(connectionFactory)
|
||||||
keySerializer = StringRedisSerializer()
|
keySerializer = StringValkeySerializer()
|
||||||
afterPropertiesSet()
|
afterPropertiesSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ class ValkeyDistributedCacheResilienceTest {
|
|||||||
fun `test connection timeout scenarios`() = runBlocking {
|
fun `test connection timeout scenarios`() = runBlocking {
|
||||||
logger.info { "Testing connection timeout scenarios" }
|
logger.info { "Testing connection timeout scenarios" }
|
||||||
|
|
||||||
val mockTemplate = mockk<RedisTemplate<String, ByteArray>>()
|
val mockTemplate = mockk<ValkeyTemplate<String, ByteArray>>()
|
||||||
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
||||||
|
|
||||||
every { mockTemplate.opsForValue() } returns mockValueOps
|
every { mockTemplate.opsForValue() } returns mockValueOps
|
||||||
@@ -117,7 +117,7 @@ class ValkeyDistributedCacheResilienceTest {
|
|||||||
fun `test partial valkey failures`() {
|
fun `test partial valkey failures`() {
|
||||||
logger.info { "Testing partial Valkey failures" }
|
logger.info { "Testing partial Valkey failures" }
|
||||||
|
|
||||||
val mockTemplate = mockk<RedisTemplate<String, ByteArray>>()
|
val mockTemplate = mockk<ValkeyTemplate<String, ByteArray>>()
|
||||||
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
||||||
|
|
||||||
every { mockTemplate.opsForValue() } returns mockValueOps
|
every { mockTemplate.opsForValue() } returns mockValueOps
|
||||||
@@ -128,14 +128,14 @@ class ValkeyDistributedCacheResilienceTest {
|
|||||||
// Simulate intermittent connection failures (fail every 3rd operation)
|
// Simulate intermittent connection failures (fail every 3rd operation)
|
||||||
every { mockValueOps.get(any()) } answers {
|
every { mockValueOps.get(any()) } answers {
|
||||||
if (failureCounter.incrementAndGet() % 3 == 0) {
|
if (failureCounter.incrementAndGet() % 3 == 0) {
|
||||||
throw RedisConnectionFailureException("Intermittent failure")
|
throw ValkeyConnectionFailureException("Intermittent failure") as Throwable
|
||||||
}
|
}
|
||||||
serializer.serializeEntry(CacheEntry("test", "value"))
|
serializer.serializeEntry(CacheEntry("test", "value"))
|
||||||
}
|
}
|
||||||
|
|
||||||
every { mockValueOps.set(any<String>(), any<ByteArray>(), any<JavaDuration>()) } answers {
|
every { mockValueOps.set(any<String>(), any<ByteArray>(), any<JavaDuration>()) } answers {
|
||||||
if (failureCounter.incrementAndGet() % 3 == 0) {
|
if (failureCounter.incrementAndGet() % 3 == 0) {
|
||||||
throw RedisConnectionFailureException("Intermittent failure")
|
throw ValkeyConnectionFailureException("Intermittent failure")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,20 +197,20 @@ class ValkeyDistributedCacheResilienceTest {
|
|||||||
|
|
||||||
// Phase 2: Simulate network partition by creating a new cache with a broken connection
|
// Phase 2: Simulate network partition by creating a new cache with a broken connection
|
||||||
logger.info { "Phase 2: Simulating network partition" }
|
logger.info { "Phase 2: Simulating network partition" }
|
||||||
val mockTemplate = mockk<RedisTemplate<String, ByteArray>>()
|
val mockTemplate = mockk<ValkeyTemplate<String, ByteArray>>()
|
||||||
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
||||||
|
|
||||||
every { mockTemplate.opsForValue() } returns mockValueOps
|
every { mockTemplate.opsForValue() } returns mockValueOps
|
||||||
every { mockValueOps.get(any()) } throws RedisConnectionFailureException("Network partition")
|
every { mockValueOps.get(any()) } throws ValkeyConnectionFailureException("Network partition")
|
||||||
every {
|
every {
|
||||||
mockValueOps.set(
|
mockValueOps.set(
|
||||||
any<String>(),
|
any<String>(),
|
||||||
any<ByteArray>(),
|
any<ByteArray>(),
|
||||||
any<JavaDuration>()
|
any<JavaDuration>()
|
||||||
)
|
)
|
||||||
} throws RedisConnectionFailureException("Network partition")
|
} throws ValkeyConnectionFailureException("Network partition")
|
||||||
every { mockTemplate.delete(any<String>()) } throws RedisConnectionFailureException("Network partition")
|
every { mockTemplate.delete(any<String>()) } throws ValkeyConnectionFailureException("Network partition")
|
||||||
every { mockTemplate.hasKey(any()) } throws RedisConnectionFailureException("Network partition")
|
every { mockTemplate.hasKey(any()) } throws ValkeyConnectionFailureException("Network partition")
|
||||||
|
|
||||||
val partitionedCache = ValkeyDistributedCache(mockTemplate, serializer, config)
|
val partitionedCache = ValkeyDistributedCache(mockTemplate, serializer, config)
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ class ValkeyDistributedCacheResilienceTest {
|
|||||||
fun `test reconnection and synchronization after network issues`() {
|
fun `test reconnection and synchronization after network issues`() {
|
||||||
logger.info { "Testing reconnection and synchronization" }
|
logger.info { "Testing reconnection and synchronization" }
|
||||||
|
|
||||||
val mockTemplate = mockk<RedisTemplate<String, ByteArray>>()
|
val mockTemplate = mockk<ValkeyTemplate<String, ByteArray>>()
|
||||||
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
||||||
|
|
||||||
every { mockTemplate.opsForValue() } returns mockValueOps
|
every { mockTemplate.opsForValue() } returns mockValueOps
|
||||||
@@ -243,15 +243,15 @@ class ValkeyDistributedCacheResilienceTest {
|
|||||||
val reconnectingCache = ValkeyDistributedCache(mockTemplate, serializer, config)
|
val reconnectingCache = ValkeyDistributedCache(mockTemplate, serializer, config)
|
||||||
|
|
||||||
// Phase 1: Simulate disconnection
|
// Phase 1: Simulate disconnection
|
||||||
every { mockValueOps.get(any()) } throws RedisConnectionFailureException("Disconnected")
|
every { mockValueOps.get(any()) } throws ValkeyConnectionFailureException("Disconnected")
|
||||||
every {
|
every {
|
||||||
mockValueOps.set(
|
mockValueOps.set(
|
||||||
any<String>(),
|
any<String>(),
|
||||||
any<ByteArray>(),
|
any<ByteArray>(),
|
||||||
any<JavaDuration>()
|
any<JavaDuration>()
|
||||||
)
|
)
|
||||||
} throws RedisConnectionFailureException("Disconnected")
|
} throws ValkeyConnectionFailureException("Disconnected")
|
||||||
every { mockTemplate.hasKey(any()) } throws RedisConnectionFailureException("Disconnected")
|
every { mockTemplate.hasKey(any()) } throws ValkeyConnectionFailureException("Disconnected")
|
||||||
|
|
||||||
reconnectingCache.set("reconnect-test-1", "value-1")
|
reconnectingCache.set("reconnect-test-1", "value-1")
|
||||||
reconnectingCache.set("reconnect-test-2", "value-2")
|
reconnectingCache.set("reconnect-test-2", "value-2")
|
||||||
|
|||||||
+24
-19
@@ -5,15 +5,15 @@ import io.github.oshai.kotlinlogging.KotlinLogging
|
|||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
|
import io.valkey.springframework.data.valkey.ValkeyConnectionFailureException
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValueOperations
|
||||||
|
import io.valkey.springframework.data.valkey.serializer.StringValkeySerializer
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.springframework.data.redis.RedisConnectionFailureException
|
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.data.redis.core.ValueOperations
|
|
||||||
import org.springframework.data.redis.serializer.StringRedisSerializer
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -31,14 +31,14 @@ class ValkeyDistributedCacheTest {
|
|||||||
|
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer = GenericContainer<Nothing>(
|
val valkeyContainer = GenericContainer<Nothing>(
|
||||||
DockerImageName.parse("valkey/valkey:9-alpine")
|
DockerImageName.parse("valkey/valkey:8.0.2-alpine")
|
||||||
.asCompatibleSubstituteFor("valkey")
|
.asCompatibleSubstituteFor("redis")
|
||||||
).apply {
|
).apply {
|
||||||
withExposedPorts(6379)
|
withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: RedisTemplate<String, ByteArray>
|
private lateinit var valkeyTemplate: ValkeyTemplate<String, ByteArray>
|
||||||
private lateinit var serializer: CacheSerializer
|
private lateinit var serializer: CacheSerializer
|
||||||
private lateinit var config: CacheConfiguration
|
private lateinit var config: CacheConfiguration
|
||||||
private lateinit var cache: ValkeyDistributedCache
|
private lateinit var cache: ValkeyDistributedCache
|
||||||
@@ -48,13 +48,13 @@ class ValkeyDistributedCacheTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = RedisTemplate<String, ByteArray>().apply {
|
valkeyTemplate = ValkeyTemplate<String, ByteArray>().apply {
|
||||||
setConnectionFactory(connectionFactory)
|
setConnectionFactory(connectionFactory)
|
||||||
keySerializer = StringRedisSerializer()
|
keySerializer = StringValkeySerializer()
|
||||||
afterPropertiesSet()
|
afterPropertiesSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ class ValkeyDistributedCacheTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `should handle offline mode and synchronize correctly`() {
|
fun `should handle offline mode and synchronize correctly`() {
|
||||||
// Arrange
|
// Arrange
|
||||||
val mockTemplate = mockk<RedisTemplate<String, ByteArray>>(relaxed = true)
|
val mockTemplate = mockk<ValkeyTemplate<String, ByteArray>>(relaxed = true)
|
||||||
val mockValueOps = mockk<ValueOperations<String, ByteArray>>(relaxed = true)
|
val mockValueOps = mockk<ValueOperations<String, ByteArray>>(relaxed = true)
|
||||||
every { mockTemplate.opsForValue() } returns mockValueOps
|
every { mockTemplate.opsForValue() } returns mockValueOps
|
||||||
|
|
||||||
@@ -157,10 +157,15 @@ class ValkeyDistributedCacheTest {
|
|||||||
any<ByteArray>(),
|
any<ByteArray>(),
|
||||||
any<JavaDuration>()
|
any<JavaDuration>()
|
||||||
)
|
)
|
||||||
} throws RedisConnectionFailureException("Valkey is down")
|
} throws ValkeyConnectionFailureException("Valkey is down")
|
||||||
every { mockValueOps.set(any<String>(), any<ByteArray>()) } throws RedisConnectionFailureException("Valkey is down")
|
every {
|
||||||
|
mockValueOps.set(
|
||||||
|
any<String>(),
|
||||||
|
any<ByteArray>()
|
||||||
|
)
|
||||||
|
} throws ValkeyConnectionFailureException("Valkey is down")
|
||||||
|
|
||||||
every { mockTemplate.delete(any<String>()) } throws RedisConnectionFailureException("Valkey is down")
|
every { mockTemplate.delete(any<String>()) } throws ValkeyConnectionFailureException("Valkey is down")
|
||||||
|
|
||||||
offlineCache.set("key2", "offline-value")
|
offlineCache.set("key2", "offline-value")
|
||||||
offlineCache.delete("key1")
|
offlineCache.delete("key1")
|
||||||
@@ -246,13 +251,13 @@ class ValkeyDistributedCacheTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `test handling valkey connection failures`() {
|
fun `test handling valkey connection failures`() {
|
||||||
// Create a mock ValkeyTemplate and ValueOperations
|
// Create a mock ValkeyTemplate and ValueOperations
|
||||||
val mockTemplate = mockk<RedisTemplate<String, ByteArray>>()
|
val mockTemplate = mockk<ValkeyTemplate<String, ByteArray>>()
|
||||||
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
val mockValueOps = mockk<ValueOperations<String, ByteArray>>()
|
||||||
|
|
||||||
// Configure the mock to throw connection failure
|
// Configure the mock to throw connection failure
|
||||||
every { mockTemplate.opsForValue() } returns mockValueOps
|
every { mockTemplate.opsForValue() } returns mockValueOps
|
||||||
every { mockValueOps.get(any()) } throws RedisConnectionFailureException("Test connection failure")
|
every { mockValueOps.get(any()) } throws ValkeyConnectionFailureException("Test connection failure")
|
||||||
every { mockTemplate.hasKey(any()) } throws RedisConnectionFailureException("Test connection failure")
|
every { mockTemplate.hasKey(any()) } throws ValkeyConnectionFailureException("Test connection failure")
|
||||||
|
|
||||||
// Create a cache with the mock
|
// Create a cache with the mock
|
||||||
val mockCache = ValkeyDistributedCache(mockTemplate, serializer, config)
|
val mockCache = ValkeyDistributedCache(mockTemplate, serializer, config)
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
<!-- Valkey/Lettuce Logger (reduziert Verbosity) -->
|
<!-- Valkey/Lettuce Logger (reduziert Verbosity) -->
|
||||||
<logger name="io.lettuce" level="WARN"/>
|
<logger name="io.lettuce" level="WARN"/>
|
||||||
<logger name="org.springframework.data.redis" level="WARN" />
|
<logger name="io.valkey.springframework.data" level="WARN"/>
|
||||||
|
|
||||||
<!-- Root Logger -->
|
<!-- Root Logger -->
|
||||||
<root level="INFO">
|
<root level="INFO">
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ dependencies {
|
|||||||
// OPTIMIERUNG: Wiederverwendung des `valkey-cache`-Bundles, da es die
|
// OPTIMIERUNG: Wiederverwendung des `valkey-cache`-Bundles, da es die
|
||||||
// gleichen Technologien (Spring Data Valkey, Lettuce, Jackson) verwendet
|
// gleichen Technologien (Spring Data Valkey, Lettuce, Jackson) verwendet
|
||||||
implementation(libs.bundles.valkey.cache)
|
implementation(libs.bundles.valkey.cache)
|
||||||
|
// Benötigt für Lettuce-basierten Valkey-Client (LettuceConnectionFactory)
|
||||||
|
implementation(libs.lettuce.core)
|
||||||
|
// Für Boot-Autoconfiguration-Annotations (z. B. @ConditionalOnMissingBean,
|
||||||
|
// @ConfigurationProperties, @EnableConfigurationProperties)
|
||||||
|
implementation("org.springframework.boot:spring-boot-autoconfigure")
|
||||||
// Stellt Jakarta Annotations bereit (z. B. @PostConstruct), die von Spring verwendet werden
|
// Stellt Jakarta Annotations bereit (z. B. @PostConstruct), die von Spring verwendet werden
|
||||||
implementation(libs.jakarta.annotation.api)
|
implementation(libs.jakarta.annotation.api)
|
||||||
// Für Kotlin-spezifische Coroutines-Integration mit Spring
|
// Für Kotlin-spezifische Coroutines-Integration mit Spring
|
||||||
|
|||||||
+8
-4
@@ -2,12 +2,16 @@ package at.mocode.infrastructure.eventstore.valkey
|
|||||||
|
|
||||||
import at.mocode.core.domain.event.DomainEvent
|
import at.mocode.core.domain.event.DomainEvent
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
|
import io.valkey.springframework.data.valkey.connection.stream.Consumer
|
||||||
|
import io.valkey.springframework.data.valkey.connection.stream.MapRecord
|
||||||
|
import io.valkey.springframework.data.valkey.connection.stream.ReadOffset
|
||||||
|
import io.valkey.springframework.data.valkey.connection.stream.StreamOffset
|
||||||
|
import io.valkey.springframework.data.valkey.connection.stream.StreamReadOptions
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
import jakarta.annotation.PostConstruct
|
import jakarta.annotation.PostConstruct
|
||||||
import jakarta.annotation.PreDestroy
|
import jakarta.annotation.PreDestroy
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.data.domain.Range
|
import org.springframework.data.domain.Range
|
||||||
import org.springframework.data.redis.connection.stream.*
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled
|
import org.springframework.scheduling.annotation.Scheduled
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.CopyOnWriteArrayList
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
@@ -16,7 +20,7 @@ import java.util.concurrent.CopyOnWriteArrayList
|
|||||||
* Consumer for Valkey Streams that processes events using consumer groups.
|
* Consumer for Valkey Streams that processes events using consumer groups.
|
||||||
*/
|
*/
|
||||||
class ValkeyEventConsumer(
|
class ValkeyEventConsumer(
|
||||||
private val valkeyTemplate: StringRedisTemplate,
|
private val valkeyTemplate: StringValkeyTemplate,
|
||||||
private val serializer: EventSerializer,
|
private val serializer: EventSerializer,
|
||||||
private val properties: ValkeyEventStoreProperties
|
private val properties: ValkeyEventStoreProperties
|
||||||
) {
|
) {
|
||||||
@@ -143,7 +147,7 @@ class ValkeyEventConsumer(
|
|||||||
/**
|
/**
|
||||||
* Periodic polls for new events from all streams.
|
* Periodic polls for new events from all streams.
|
||||||
*/
|
*/
|
||||||
@Scheduled(fixedDelayString = $$"${valkey.event-store.poll-interval:100}")
|
@Scheduled(fixedDelayString = "\${valkey.event-store.poll-interval:100}")
|
||||||
fun pollEvents() {
|
fun pollEvents() {
|
||||||
if (!running) {
|
if (!running) {
|
||||||
running = true
|
running = true
|
||||||
|
|||||||
+8
-7
@@ -8,16 +8,17 @@ import at.mocode.infrastructure.eventstore.api.ConcurrencyException
|
|||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
import at.mocode.infrastructure.eventstore.api.EventStore
|
import at.mocode.infrastructure.eventstore.api.EventStore
|
||||||
import at.mocode.infrastructure.eventstore.api.Subscription
|
import at.mocode.infrastructure.eventstore.api.Subscription
|
||||||
|
import io.valkey.springframework.data.valkey.core.SessionCallback
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyOperations
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.dao.DataAccessException
|
import org.springframework.dao.DataAccessException
|
||||||
import org.springframework.data.domain.Range
|
import org.springframework.data.domain.Range
|
||||||
import org.springframework.data.redis.core.SessionCallback
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import kotlin.uuid.Uuid
|
import kotlin.uuid.Uuid
|
||||||
|
|
||||||
class ValkeyEventStore(
|
class ValkeyEventStore(
|
||||||
private val valkeyTemplate: StringRedisTemplate,
|
private val valkeyTemplate: StringValkeyTemplate,
|
||||||
private val serializer: EventSerializer,
|
private val serializer: EventSerializer,
|
||||||
private val properties: ValkeyEventStoreProperties
|
private val properties: ValkeyEventStoreProperties
|
||||||
) : EventStore {
|
) : EventStore {
|
||||||
@@ -131,8 +132,8 @@ class ValkeyEventStore(
|
|||||||
try {
|
try {
|
||||||
valkeyTemplate.execute(object : SessionCallback<List<Any>> {
|
valkeyTemplate.execute(object : SessionCallback<List<Any>> {
|
||||||
@Throws(DataAccessException::class)
|
@Throws(DataAccessException::class)
|
||||||
override fun <K, V> execute(operations: org.springframework.data.redis.core.RedisOperations<K, V>): List<Any> {
|
override fun <K, V> execute(operations: ValkeyOperations<K, V>): List<Any> {
|
||||||
val streamOps = (operations as StringRedisTemplate).opsForStream<String, String>()
|
val streamOps = (operations as StringValkeyTemplate).opsForStream<String, String>()
|
||||||
|
|
||||||
operations.multi()
|
operations.multi()
|
||||||
|
|
||||||
@@ -178,8 +179,8 @@ class ValkeyEventStore(
|
|||||||
try {
|
try {
|
||||||
valkeyTemplate.execute(object : SessionCallback<List<Any>> {
|
valkeyTemplate.execute(object : SessionCallback<List<Any>> {
|
||||||
@Throws(DataAccessException::class)
|
@Throws(DataAccessException::class)
|
||||||
override fun <K, V> execute(operations: org.springframework.data.redis.core.RedisOperations<K, V>): List<Any> {
|
override fun <K, V> execute(operations: ValkeyOperations<K, V>): List<Any> {
|
||||||
val streamOps = (operations as StringRedisTemplate).opsForStream<String, String>()
|
val streamOps = (operations as StringValkeyTemplate).opsForStream<String, String>()
|
||||||
|
|
||||||
operations.multi()
|
operations.multi()
|
||||||
streamOps.add(streamKey, eventData)
|
streamOps.add(streamKey, eventData)
|
||||||
|
|||||||
+18
-17
@@ -2,16 +2,17 @@ package at.mocode.infrastructure.eventstore.valkey
|
|||||||
|
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
import at.mocode.infrastructure.eventstore.api.EventStore
|
import at.mocode.infrastructure.eventstore.api.EventStore
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
import io.valkey.springframework.data.valkey.connection.ValkeyConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyPassword
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory
|
|
||||||
import org.springframework.data.redis.connection.RedisPassword
|
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,11 +54,11 @@ class ValkeyEventStoreConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(name = ["eventStoreValkeyConnectionFactory"])
|
@ConditionalOnMissingBean(name = ["eventStoreValkeyConnectionFactory"])
|
||||||
fun eventStoreValkeyConnectionFactory(properties: ValkeyEventStoreProperties): RedisConnectionFactory {
|
fun eventStoreValkeyConnectionFactory(properties: ValkeyEventStoreProperties): ValkeyConnectionFactory {
|
||||||
val config = RedisStandaloneConfiguration().apply {
|
val config = ValkeyStandaloneConfiguration().apply {
|
||||||
hostName = properties.host
|
hostName = properties.host
|
||||||
port = properties.port
|
port = properties.port
|
||||||
properties.password?.let { password = RedisPassword.of(it) }
|
properties.password?.let { password = ValkeyPassword.of(it) }
|
||||||
database = properties.database
|
database = properties.database
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,10 +77,10 @@ class ValkeyEventStoreConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(name = ["eventStoreValkeyTemplate"])
|
@ConditionalOnMissingBean(name = ["eventStoreValkeyTemplate"])
|
||||||
fun eventStoreValkeyTemplate(
|
fun eventStoreValkeyTemplate(
|
||||||
@org.springframework.beans.factory.annotation.Qualifier("eventStoreValkeyConnectionFactory")
|
@Qualifier("eventStoreValkeyConnectionFactory")
|
||||||
connectionFactory: RedisConnectionFactory
|
connectionFactory: ValkeyConnectionFactory
|
||||||
): StringRedisTemplate {
|
): StringValkeyTemplate {
|
||||||
return StringRedisTemplate().apply {
|
return StringValkeyTemplate().apply {
|
||||||
setConnectionFactory(connectionFactory)
|
setConnectionFactory(connectionFactory)
|
||||||
afterPropertiesSet()
|
afterPropertiesSet()
|
||||||
}
|
}
|
||||||
@@ -107,8 +108,8 @@ class ValkeyEventStoreConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
fun eventStore(
|
fun eventStore(
|
||||||
@org.springframework.beans.factory.annotation.Qualifier("eventStoreValkeyTemplate")
|
@Qualifier("eventStoreValkeyTemplate")
|
||||||
valkeyTemplate: StringRedisTemplate,
|
valkeyTemplate: StringValkeyTemplate,
|
||||||
eventSerializer: EventSerializer,
|
eventSerializer: EventSerializer,
|
||||||
properties: ValkeyEventStoreProperties
|
properties: ValkeyEventStoreProperties
|
||||||
): EventStore {
|
): EventStore {
|
||||||
@@ -126,8 +127,8 @@ class ValkeyEventStoreConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
fun eventConsumer(
|
fun eventConsumer(
|
||||||
@org.springframework.beans.factory.annotation.Qualifier("eventStoreValkeyTemplate")
|
@Qualifier("eventStoreValkeyTemplate")
|
||||||
valkeyTemplate: StringRedisTemplate,
|
valkeyTemplate: StringValkeyTemplate,
|
||||||
eventSerializer: EventSerializer,
|
eventSerializer: EventSerializer,
|
||||||
properties: ValkeyEventStoreProperties
|
properties: ValkeyEventStoreProperties
|
||||||
): ValkeyEventConsumer {
|
): ValkeyEventConsumer {
|
||||||
|
|||||||
+5
-5
@@ -8,6 +8,8 @@ import at.mocode.infrastructure.cache.valkey.JacksonCacheSerializer
|
|||||||
import at.mocode.infrastructure.cache.valkey.ValkeyConfiguration
|
import at.mocode.infrastructure.cache.valkey.ValkeyConfiguration
|
||||||
import at.mocode.infrastructure.cache.valkey.ValkeyDistributedCache
|
import at.mocode.infrastructure.cache.valkey.ValkeyDistributedCache
|
||||||
import at.mocode.infrastructure.eventstore.api.EventStore
|
import at.mocode.infrastructure.eventstore.api.EventStore
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.ValkeyTemplate
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.jupiter.api.AfterAll
|
import org.junit.jupiter.api.AfterAll
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
@@ -20,8 +22,6 @@ import org.springframework.boot.test.context.SpringBootTest
|
|||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.context.annotation.Import
|
import org.springframework.context.annotation.Import
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate
|
|
||||||
import org.springframework.test.context.DynamicPropertyRegistry
|
import org.springframework.test.context.DynamicPropertyRegistry
|
||||||
import org.springframework.test.context.DynamicPropertySource
|
import org.springframework.test.context.DynamicPropertySource
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
@@ -96,7 +96,7 @@ class ValkeyCacheAndEventStoreIntegrationTest {
|
|||||||
class TestConfig {
|
class TestConfig {
|
||||||
@Bean
|
@Bean
|
||||||
fun distributedCache(
|
fun distributedCache(
|
||||||
@Qualifier("valkeyTemplate") valkeyTemplate: RedisTemplate<String, ByteArray>,
|
@Qualifier("valkeyTemplate") valkeyTemplate: ValkeyTemplate<String, ByteArray>,
|
||||||
cacheConfiguration: CacheConfiguration
|
cacheConfiguration: CacheConfiguration
|
||||||
): DistributedCache {
|
): DistributedCache {
|
||||||
return ValkeyDistributedCache(
|
return ValkeyDistributedCache(
|
||||||
@@ -116,11 +116,11 @@ class ValkeyCacheAndEventStoreIntegrationTest {
|
|||||||
// Verify separate ConnectionFactories
|
// Verify separate ConnectionFactories
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("valkeyConnectionFactory")
|
@Qualifier("valkeyConnectionFactory")
|
||||||
private lateinit var cacheConnectionFactory: RedisConnectionFactory
|
private lateinit var cacheConnectionFactory: ValkeyConnectionFactory
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("eventStoreValkeyConnectionFactory")
|
@Qualifier("eventStoreValkeyConnectionFactory")
|
||||||
private lateinit var eventStoreConnectionFactory: RedisConnectionFactory
|
private lateinit var eventStoreConnectionFactory: ValkeyConnectionFactory
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test both modules can be used simultaneously without conflicts`(): Unit = runBlocking {
|
fun `test both modules can be used simultaneously without conflicts`(): Unit = runBlocking {
|
||||||
|
|||||||
+7
-7
@@ -6,6 +6,9 @@ import at.mocode.core.domain.model.AggregateId
|
|||||||
import at.mocode.core.domain.model.EventType
|
import at.mocode.core.domain.model.EventType
|
||||||
import at.mocode.core.domain.model.EventVersion
|
import at.mocode.core.domain.model.EventVersion
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
@@ -14,9 +17,6 @@ import org.junit.jupiter.api.Assertions.assertTrue
|
|||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -35,11 +35,11 @@ class ValkeyEventConsumerResilienceTest {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:9-alpine"))
|
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:8.0.2-alpine"))
|
||||||
.withExposedPorts(6379)
|
.withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: StringRedisTemplate
|
private lateinit var valkeyTemplate: StringValkeyTemplate
|
||||||
private lateinit var serializer: EventSerializer
|
private lateinit var serializer: EventSerializer
|
||||||
private lateinit var properties: ValkeyEventStoreProperties
|
private lateinit var properties: ValkeyEventStoreProperties
|
||||||
private lateinit var eventStore: ValkeyEventStore
|
private lateinit var eventStore: ValkeyEventStore
|
||||||
@@ -51,11 +51,11 @@ class ValkeyEventConsumerResilienceTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = StringRedisTemplate(connectionFactory)
|
valkeyTemplate = StringValkeyTemplate(connectionFactory)
|
||||||
|
|
||||||
serializer = JacksonEventSerializer().apply {
|
serializer = JacksonEventSerializer().apply {
|
||||||
registerEventType(ResilienceTestEvent::class.java, "ResilienceTestEvent")
|
registerEventType(ResilienceTestEvent::class.java, "ResilienceTestEvent")
|
||||||
|
|||||||
+8
-8
@@ -2,6 +2,8 @@ package at.mocode.infrastructure.eventstore.valkey
|
|||||||
|
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
import at.mocode.infrastructure.eventstore.api.EventStore
|
import at.mocode.infrastructure.eventstore.api.EventStore
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
import org.junit.jupiter.api.Assertions.*
|
import org.junit.jupiter.api.Assertions.*
|
||||||
import org.junit.jupiter.api.DisplayName
|
import org.junit.jupiter.api.DisplayName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@@ -11,8 +13,6 @@ import org.springframework.boot.autoconfigure.AutoConfigurations
|
|||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,8 +71,8 @@ class ValkeyEventStoreConfigurationTest {
|
|||||||
assertTrue(context.containsBean("eventConsumer"))
|
assertTrue(context.containsBean("eventConsumer"))
|
||||||
|
|
||||||
// Verify bean types
|
// Verify bean types
|
||||||
assertNotNull(context.getBean<RedisConnectionFactory>("eventStoreValkeyConnectionFactory"))
|
assertNotNull(context.getBean<ValkeyConnectionFactory>("eventStoreValkeyConnectionFactory"))
|
||||||
assertNotNull(context.getBean<StringRedisTemplate>("eventStoreValkeyTemplate"))
|
assertNotNull(context.getBean<StringValkeyTemplate>("eventStoreValkeyTemplate"))
|
||||||
assertNotNull(context.getBean<EventSerializer>("eventSerializer"))
|
assertNotNull(context.getBean<EventSerializer>("eventSerializer"))
|
||||||
assertNotNull(context.getBean<EventStore>("eventStore"))
|
assertNotNull(context.getBean<EventStore>("eventStore"))
|
||||||
assertNotNull(context.getBean<ValkeyEventConsumer>("eventConsumer"))
|
assertNotNull(context.getBean<ValkeyEventConsumer>("eventConsumer"))
|
||||||
@@ -160,7 +160,7 @@ class ValkeyEventStoreConfigurationTest {
|
|||||||
"valkey.event-store.database=1"
|
"valkey.event-store.database=1"
|
||||||
)
|
)
|
||||||
.run { context ->
|
.run { context ->
|
||||||
val connectionFactory = context.getBean<RedisConnectionFactory>("eventStoreValkeyConnectionFactory")
|
val connectionFactory = context.getBean<ValkeyConnectionFactory>("eventStoreValkeyConnectionFactory")
|
||||||
assertNotNull(connectionFactory)
|
assertNotNull(connectionFactory)
|
||||||
|
|
||||||
// Verify the connection factory is properly configured
|
// Verify the connection factory is properly configured
|
||||||
@@ -176,7 +176,7 @@ class ValkeyEventStoreConfigurationTest {
|
|||||||
fun `should handle Valkey template creation correctly`() {
|
fun `should handle Valkey template creation correctly`() {
|
||||||
contextRunner
|
contextRunner
|
||||||
.run { context ->
|
.run { context ->
|
||||||
val valkeyTemplate = context.getBean<StringRedisTemplate>("eventStoreValkeyTemplate")
|
val valkeyTemplate = context.getBean<StringValkeyTemplate>("eventStoreValkeyTemplate")
|
||||||
assertNotNull(valkeyTemplate)
|
assertNotNull(valkeyTemplate)
|
||||||
|
|
||||||
// Verify the template is properly set up
|
// Verify the template is properly set up
|
||||||
@@ -211,7 +211,7 @@ class ValkeyEventStoreConfigurationTest {
|
|||||||
assertTrue(eventStore is ValkeyEventStore)
|
assertTrue(eventStore is ValkeyEventStore)
|
||||||
|
|
||||||
// Verify dependencies are wired correctly
|
// Verify dependencies are wired correctly
|
||||||
val valkeyTemplate = context.getBean<StringRedisTemplate>("eventStoreValkeyTemplate")
|
val valkeyTemplate = context.getBean<StringValkeyTemplate>("eventStoreValkeyTemplate")
|
||||||
val eventSerializer = context.getBean<EventSerializer>("eventSerializer")
|
val eventSerializer = context.getBean<EventSerializer>("eventSerializer")
|
||||||
val properties = context.getBean<ValkeyEventStoreProperties>()
|
val properties = context.getBean<ValkeyEventStoreProperties>()
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ class ValkeyEventStoreConfigurationTest {
|
|||||||
assertNotNull(eventConsumer)
|
assertNotNull(eventConsumer)
|
||||||
|
|
||||||
// Verify dependencies are available
|
// Verify dependencies are available
|
||||||
val valkeyTemplate = context.getBean<StringRedisTemplate>("eventStoreValkeyTemplate")
|
val valkeyTemplate = context.getBean<StringValkeyTemplate>("eventStoreValkeyTemplate")
|
||||||
val eventSerializer = context.getBean<EventSerializer>("eventSerializer")
|
val eventSerializer = context.getBean<EventSerializer>("eventSerializer")
|
||||||
val properties = context.getBean<ValkeyEventStoreProperties>()
|
val properties = context.getBean<ValkeyEventStoreProperties>()
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -6,6 +6,9 @@ import at.mocode.core.domain.model.EventType
|
|||||||
import at.mocode.core.domain.model.EventVersion
|
import at.mocode.core.domain.model.EventVersion
|
||||||
import at.mocode.infrastructure.eventstore.api.ConcurrencyException
|
import at.mocode.infrastructure.eventstore.api.ConcurrencyException
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
@@ -13,9 +16,6 @@ import org.junit.jupiter.api.Assertions.*
|
|||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -32,11 +32,11 @@ class ValkeyEventStoreErrorHandlingTest {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:9-alpine"))
|
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:8.0.2-alpine"))
|
||||||
.withExposedPorts(6379)
|
.withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: StringRedisTemplate
|
private lateinit var valkeyTemplate: StringValkeyTemplate
|
||||||
private lateinit var serializer: EventSerializer
|
private lateinit var serializer: EventSerializer
|
||||||
private lateinit var properties: ValkeyEventStoreProperties
|
private lateinit var properties: ValkeyEventStoreProperties
|
||||||
private lateinit var eventStore: ValkeyEventStore
|
private lateinit var eventStore: ValkeyEventStore
|
||||||
@@ -46,11 +46,11 @@ class ValkeyEventStoreErrorHandlingTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = StringRedisTemplate(connectionFactory)
|
valkeyTemplate = StringValkeyTemplate(connectionFactory)
|
||||||
|
|
||||||
serializer = JacksonEventSerializer().apply {
|
serializer = JacksonEventSerializer().apply {
|
||||||
registerEventType(TestErrorEvent::class.java, "TestErrorEvent")
|
registerEventType(TestErrorEvent::class.java, "TestErrorEvent")
|
||||||
|
|||||||
+7
-7
@@ -7,14 +7,14 @@ import at.mocode.core.domain.event.DomainEvent
|
|||||||
import at.mocode.core.domain.model.*
|
import at.mocode.core.domain.model.*
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
import at.mocode.infrastructure.eventstore.api.EventStore
|
import at.mocode.infrastructure.eventstore.api.EventStore
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -30,11 +30,11 @@ class ValkeyEventStoreIntegrationTest {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:9-alpine"))
|
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:8.0.2-alpine"))
|
||||||
.withExposedPorts(6379)
|
.withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: StringRedisTemplate
|
private lateinit var valkeyTemplate: StringValkeyTemplate
|
||||||
private lateinit var serializer: EventSerializer
|
private lateinit var serializer: EventSerializer
|
||||||
private lateinit var properties: ValkeyEventStoreProperties
|
private lateinit var properties: ValkeyEventStoreProperties
|
||||||
private lateinit var eventStore: EventStore
|
private lateinit var eventStore: EventStore
|
||||||
@@ -45,11 +45,11 @@ class ValkeyEventStoreIntegrationTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = StringRedisTemplate(connectionFactory)
|
valkeyTemplate = StringValkeyTemplate(connectionFactory)
|
||||||
|
|
||||||
serializer = JacksonEventSerializer().apply {
|
serializer = JacksonEventSerializer().apply {
|
||||||
registerEventType(TestCreatedEvent::class.java, "TestCreated")
|
registerEventType(TestCreatedEvent::class.java, "TestCreated")
|
||||||
|
|||||||
+7
-7
@@ -5,6 +5,9 @@ import at.mocode.core.domain.model.AggregateId
|
|||||||
import at.mocode.core.domain.model.EventType
|
import at.mocode.core.domain.model.EventType
|
||||||
import at.mocode.core.domain.model.EventVersion
|
import at.mocode.core.domain.model.EventVersion
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
@@ -12,9 +15,6 @@ import org.junit.jupiter.api.Assertions.*
|
|||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -31,11 +31,11 @@ class ValkeyEventStoreStreamTest {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:9-alpine"))
|
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:8.0.2-alpine"))
|
||||||
.withExposedPorts(6379)
|
.withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: StringRedisTemplate
|
private lateinit var valkeyTemplate: StringValkeyTemplate
|
||||||
private lateinit var serializer: EventSerializer
|
private lateinit var serializer: EventSerializer
|
||||||
private lateinit var properties: ValkeyEventStoreProperties
|
private lateinit var properties: ValkeyEventStoreProperties
|
||||||
private lateinit var eventStore: ValkeyEventStore
|
private lateinit var eventStore: ValkeyEventStore
|
||||||
@@ -45,11 +45,11 @@ class ValkeyEventStoreStreamTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = StringRedisTemplate(connectionFactory)
|
valkeyTemplate = StringValkeyTemplate(connectionFactory)
|
||||||
|
|
||||||
serializer = JacksonEventSerializer().apply {
|
serializer = JacksonEventSerializer().apply {
|
||||||
registerEventType(StreamTestEvent::class.java, "StreamTestEvent")
|
registerEventType(StreamTestEvent::class.java, "StreamTestEvent")
|
||||||
|
|||||||
+7
-7
@@ -6,6 +6,9 @@ import at.mocode.core.domain.model.EventType
|
|||||||
import at.mocode.core.domain.model.EventVersion
|
import at.mocode.core.domain.model.EventVersion
|
||||||
import at.mocode.infrastructure.eventstore.api.ConcurrencyException
|
import at.mocode.infrastructure.eventstore.api.ConcurrencyException
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
@@ -13,9 +16,6 @@ import org.junit.jupiter.api.Assertions.assertEquals
|
|||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -27,11 +27,11 @@ class ValkeyEventStoreTest {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:9-alpine"))
|
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:8.0.2-alpine"))
|
||||||
.withExposedPorts(6379)
|
.withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: StringRedisTemplate
|
private lateinit var valkeyTemplate: StringValkeyTemplate
|
||||||
private lateinit var serializer: EventSerializer
|
private lateinit var serializer: EventSerializer
|
||||||
private lateinit var properties: ValkeyEventStoreProperties
|
private lateinit var properties: ValkeyEventStoreProperties
|
||||||
private lateinit var eventStore: ValkeyEventStore
|
private lateinit var eventStore: ValkeyEventStore
|
||||||
@@ -41,11 +41,11 @@ class ValkeyEventStoreTest {
|
|||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
|
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
|
|
||||||
valkeyTemplate = StringRedisTemplate(connectionFactory)
|
valkeyTemplate = StringValkeyTemplate(connectionFactory)
|
||||||
|
|
||||||
serializer = JacksonEventSerializer().apply {
|
serializer = JacksonEventSerializer().apply {
|
||||||
registerEventType(TestCreatedEvent::class.java, "TestCreated")
|
registerEventType(TestCreatedEvent::class.java, "TestCreated")
|
||||||
|
|||||||
+7
-7
@@ -9,15 +9,15 @@ import at.mocode.core.domain.model.EventType
|
|||||||
import at.mocode.core.domain.model.EventVersion
|
import at.mocode.core.domain.model.EventVersion
|
||||||
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
import at.mocode.infrastructure.eventstore.api.EventSerializer
|
||||||
import at.mocode.infrastructure.eventstore.api.EventStore
|
import at.mocode.infrastructure.eventstore.api.EventStore
|
||||||
|
import io.valkey.springframework.data.valkey.connection.ValkeyStandaloneConfiguration
|
||||||
|
import io.valkey.springframework.data.valkey.connection.lettuce.LettuceConnectionFactory
|
||||||
|
import io.valkey.springframework.data.valkey.core.StringValkeyTemplate
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration
|
|
||||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory
|
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate
|
|
||||||
import org.testcontainers.containers.GenericContainer
|
import org.testcontainers.containers.GenericContainer
|
||||||
import org.testcontainers.junit.jupiter.Container
|
import org.testcontainers.junit.jupiter.Container
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers
|
import org.testcontainers.junit.jupiter.Testcontainers
|
||||||
@@ -29,11 +29,11 @@ class ValkeyIntegrationTest {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Container
|
@Container
|
||||||
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:9-alpine"))
|
val valkeyContainer: GenericContainer<*> = GenericContainer(DockerImageName.parse("valkey/valkey:8.0.2-alpine"))
|
||||||
.withExposedPorts(6379)
|
.withExposedPorts(6379)
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var valkeyTemplate: StringRedisTemplate
|
private lateinit var valkeyTemplate: StringValkeyTemplate
|
||||||
private lateinit var serializer: EventSerializer
|
private lateinit var serializer: EventSerializer
|
||||||
private lateinit var properties: ValkeyEventStoreProperties
|
private lateinit var properties: ValkeyEventStoreProperties
|
||||||
private lateinit var eventStore: EventStore
|
private lateinit var eventStore: EventStore
|
||||||
@@ -43,10 +43,10 @@ class ValkeyIntegrationTest {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
val valkeyPort = valkeyContainer.getMappedPort(6379)
|
||||||
val valkeyHost = valkeyContainer.host
|
val valkeyHost = valkeyContainer.host
|
||||||
val valkeyConfig = RedisStandaloneConfiguration(valkeyHost, valkeyPort)
|
val valkeyConfig = ValkeyStandaloneConfiguration(valkeyHost, valkeyPort)
|
||||||
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
val connectionFactory = LettuceConnectionFactory(valkeyConfig)
|
||||||
connectionFactory.afterPropertiesSet()
|
connectionFactory.afterPropertiesSet()
|
||||||
valkeyTemplate = StringRedisTemplate(connectionFactory)
|
valkeyTemplate = StringValkeyTemplate(connectionFactory)
|
||||||
serializer = JacksonEventSerializer().apply {
|
serializer = JacksonEventSerializer().apply {
|
||||||
registerEventType(TestCreatedEvent::class.java, "TestCreated")
|
registerEventType(TestCreatedEvent::class.java, "TestCreated")
|
||||||
registerEventType(TestUpdatedEvent::class.java, "TestUpdated")
|
registerEventType(TestUpdatedEvent::class.java, "TestUpdated")
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ dependencies {
|
|||||||
// Resilience (Reactive) - WICHTIG: Reactor-Variante für WebFlux!
|
// Resilience (Reactive) - WICHTIG: Reactor-Variante für WebFlux!
|
||||||
implementation(libs.spring.cloud.starter.circuitbreaker.reactor.resilience4j)
|
implementation(libs.spring.cloud.starter.circuitbreaker.reactor.resilience4j)
|
||||||
|
|
||||||
implementation(libs.spring.boot.starter.data.redis)
|
implementation(libs.spring.data.valkey)
|
||||||
implementation(libs.micrometer.tracing.bridge.brave)
|
implementation(libs.micrometer.tracing.bridge.brave)
|
||||||
|
|
||||||
testImplementation(projects.platform.platformTesting)
|
testImplementation(projects.platform.platformTesting)
|
||||||
|
|||||||
@@ -41,3 +41,9 @@ dependencies {
|
|||||||
// Stellt alle Test-Abhängigkeiten gebündelt bereit.
|
// Stellt alle Test-Abhängigkeiten gebündelt bereit.
|
||||||
testImplementation(projects.platform.platformTesting)
|
testImplementation(projects.platform.platformTesting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JVM Native Access (JDK 22+): Unterdrückt Warnung/Blockade für Snappy (org.xerial.snappy)
|
||||||
|
tasks.withType<Test>().configureEach {
|
||||||
|
// Erfordert JDK 21+; ab zukünftigen Versionen sonst Fehler statt Warnung
|
||||||
|
jvmArgs("--enable-native-access=ALL-UNNAMED")
|
||||||
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ flyway = "11.19.1"
|
|||||||
redisson = "4.0.0"
|
redisson = "4.0.0"
|
||||||
# Spring Boot 3.5.x manages Lettuce 6.6.x; keep aligned to avoid binary/API mismatches.
|
# Spring Boot 3.5.x manages Lettuce 6.6.x; keep aligned to avoid binary/API mismatches.
|
||||||
lettuce = "6.6.0.RELEASE"
|
lettuce = "6.6.0.RELEASE"
|
||||||
|
springDataValkey = "0.2.0"
|
||||||
|
|
||||||
# Observability
|
# Observability
|
||||||
micrometer = "1.16.1"
|
micrometer = "1.16.1"
|
||||||
@@ -229,6 +230,7 @@ flyway-postgresql = { module = "org.flywaydb:flyway-database-postgresql", versio
|
|||||||
|
|
||||||
redisson = { module = "org.redisson:redisson", version.ref = "redisson" }
|
redisson = { module = "org.redisson:redisson", version.ref = "redisson" }
|
||||||
lettuce-core = { module = "io.lettuce:lettuce-core", version.ref = "lettuce" }
|
lettuce-core = { module = "io.lettuce:lettuce-core", version.ref = "lettuce" }
|
||||||
|
spring-data-valkey = { module = "io.valkey.springframework.data:spring-data-valkey", version.ref = "springDataValkey" }
|
||||||
|
|
||||||
micrometer-prometheus = { module = "io.micrometer:micrometer-registry-prometheus", version.ref = "micrometer" }
|
micrometer-prometheus = { module = "io.micrometer:micrometer-registry-prometheus", version.ref = "micrometer" }
|
||||||
micrometer-tracing-bridge-brave = { module = "io.micrometer:micrometer-tracing-bridge-brave", version.ref = "micrometerTracing" }
|
micrometer-tracing-bridge-brave = { module = "io.micrometer:micrometer-tracing-bridge-brave", version.ref = "micrometerTracing" }
|
||||||
@@ -342,8 +344,7 @@ database-complete = [
|
|||||||
"flyway-postgresql"
|
"flyway-postgresql"
|
||||||
]
|
]
|
||||||
valkey-cache = [
|
valkey-cache = [
|
||||||
"spring-boot-starter-data-redis",
|
"spring-data-valkey",
|
||||||
"lettuce-core",
|
|
||||||
"jackson-module-kotlin",
|
"jackson-module-kotlin",
|
||||||
"jackson-datatype-jsr310"
|
"jackson-datatype-jsr310"
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user