Configure redis for ktor/koin

This commit is contained in:
2025-03-19 00:30:35 +01:00
parent 6d2043d9fe
commit 8e732b0f9e
7 changed files with 30 additions and 10 deletions

View File

@@ -2,10 +2,14 @@ package eventDemo.configuration.injection
import org.koin.dsl.module import org.koin.dsl.module
val appKoinModule = fun appKoinModule(config: Configuration) =
module { module {
configureDIBusiness() configureDIBusiness()
configureDIInfrastructure() configureDIInfrastructure(config.redisUrl)
configureDILibs() configureDILibs()
configureDICommandActions() configureDICommandActions()
} }
data class Configuration(
val redisUrl: String,
)

View File

@@ -14,8 +14,13 @@ import eventDemo.libs.event.projection.SnapshotConfig
import org.koin.core.module.Module import org.koin.core.module.Module
import org.koin.core.module.dsl.singleOf import org.koin.core.module.dsl.singleOf
import org.koin.dsl.bind import org.koin.dsl.bind
import redis.clients.jedis.JedisPool
fun Module.configureDIInfrastructure(redisUrl: String) {
single {
JedisPool(redisUrl)
}
fun Module.configureDIInfrastructure() {
singleOf(::GameEventBusInMemory) bind GameEventBus::class singleOf(::GameEventBusInMemory) bind GameEventBus::class
singleOf(::GameEventStoreInMemory) bind GameEventStore::class singleOf(::GameEventStoreInMemory) bind GameEventStore::class
singleOf(::GameProjectionBusInMemory) bind GameProjectionBus::class singleOf(::GameProjectionBusInMemory) bind GameProjectionBus::class

View File

@@ -1,5 +1,6 @@
package eventDemo.configuration.ktor package eventDemo.configuration.ktor
import eventDemo.configuration.injection.Configuration
import eventDemo.configuration.injection.appKoinModule import eventDemo.configuration.injection.appKoinModule
import io.ktor.server.application.Application import io.ktor.server.application.Application
import io.ktor.server.application.install import io.ktor.server.application.install
@@ -9,6 +10,8 @@ import org.koin.logger.slf4jLogger
fun Application.configureKoin() { fun Application.configureKoin() {
install(Koin) { install(Koin) {
slf4jLogger() slf4jLogger()
modules(appKoinModule)
val redisUrl = environment.config.propertyOrNull("redis.url")?.getString() ?: error("You must set the redis.url")
modules(appKoinModule(Configuration(redisUrl)))
} }
} }

View File

@@ -2,3 +2,8 @@ jwt {
secret = "secret" secret = "secret"
secret = ${?JWT_SECRET} secret = ${?JWT_SECRET}
} }
redis {
url = "redis://localhost:6379"
url = ${?REDIS_URL}
}

View File

@@ -27,6 +27,7 @@ import eventDemo.libs.event.projection.ProjectionSnapshotRepositoryInMemory
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.equals.shouldBeEqual import io.kotest.matchers.equals.shouldBeEqual
import io.mockk.mockk
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@@ -170,7 +171,7 @@ class GameSimulationTest :
} }
} }
koinApplication { modules(appKoinModule) }.koin.apply { koinApplication { modules(appKoinModule(mockk(relaxed = true))) }.koin.apply {
val commandHandler by inject<GameCommandHandler>() val commandHandler by inject<GameCommandHandler>()
val eventStore by inject<GameEventStore>() val eventStore by inject<GameEventStore>()
val playerNotificationListener by inject<PlayerNotificationListener>() val playerNotificationListener by inject<PlayerNotificationListener>()

View File

@@ -13,6 +13,7 @@ import eventDemo.configuration.injection.appKoinModule
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldContain import io.kotest.matchers.collections.shouldContain
import io.kotest.matchers.equals.shouldBeEqual import io.kotest.matchers.equals.shouldBeEqual
import io.mockk.mockk
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
@@ -25,7 +26,7 @@ import kotlin.test.assertIs
class GameCommandHandlerTest : class GameCommandHandlerTest :
FunSpec({ FunSpec({
test("handle a command should execute the command") { test("handle a command should execute the command") {
koinApplication { modules(appKoinModule) }.koin.apply { koinApplication { modules(appKoinModule(mockk(relaxed = true))) }.koin.apply {
val commandHandler by inject<GameCommandHandler>() val commandHandler by inject<GameCommandHandler>()
val notificationListener by inject<PlayerNotificationListener>() val notificationListener by inject<PlayerNotificationListener>()
val gameId = GameId() val gameId = GameId()

View File

@@ -9,6 +9,7 @@ import eventDemo.configuration.injection.appKoinModule
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.equals.shouldBeEqual import io.kotest.matchers.equals.shouldBeEqual
import io.mockk.mockk
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.joinAll import kotlinx.coroutines.joinAll
@@ -25,7 +26,7 @@ class GameStateRepositoryTest :
test("GameStateRepository should build the projection when a new event occurs") { test("GameStateRepository should build the projection when a new event occurs") {
val aggregateId = GameId() val aggregateId = GameId()
koinApplication { modules(appKoinModule) }.koin.apply { koinApplication { modules(appKoinModule(mockk(relaxed = true))) }.koin.apply {
val repo = get<GameStateRepository>() val repo = get<GameStateRepository>()
val eventHandler = get<GameEventHandler>() val eventHandler = get<GameEventHandler>()
eventHandler eventHandler
@@ -44,7 +45,7 @@ class GameStateRepositoryTest :
test("get should build the last version of the state") { test("get should build the last version of the state") {
val aggregateId = GameId() val aggregateId = GameId()
koinApplication { modules(appKoinModule) }.koin.apply { koinApplication { modules(appKoinModule(mockk(relaxed = true))) }.koin.apply {
val repo = get<GameStateRepository>() val repo = get<GameStateRepository>()
val eventHandler = get<GameEventHandler>() val eventHandler = get<GameEventHandler>()
@@ -69,7 +70,7 @@ class GameStateRepositoryTest :
test("getUntil should build the state until the event") { test("getUntil should build the state until the event") {
repeat(10) { repeat(10) {
val aggregateId = GameId() val aggregateId = GameId()
koinApplication { modules(appKoinModule) }.koin.apply { koinApplication { modules(appKoinModule(mockk(relaxed = true))) }.koin.apply {
val repo = get<GameStateRepository>() val repo = get<GameStateRepository>()
val eventHandler = get<GameEventHandler>() val eventHandler = get<GameEventHandler>()
@@ -98,7 +99,7 @@ class GameStateRepositoryTest :
test("getUntil should be concurrently secure") { test("getUntil should be concurrently secure") {
val aggregateId = GameId() val aggregateId = GameId()
koinApplication { modules(appKoinModule) }.koin.apply { koinApplication { modules(appKoinModule(mockk(relaxed = true))) }.koin.apply {
val repo = get<GameStateRepository>() val repo = get<GameStateRepository>()
val eventHandler = get<GameEventHandler>() val eventHandler = get<GameEventHandler>()