feat: use rabbit to projection bus

This commit is contained in:
2025-04-14 22:59:55 +02:00
parent 9d4cc84c4e
commit 2a798646c2
32 changed files with 75 additions and 56 deletions

View File

@@ -3,11 +3,11 @@ package eventDemo.adapter.infrastructureLayer.event.projection
import eventDemo.business.entity.GameId
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.projection.GameList
import eventDemo.business.event.projection.GameListRepository
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameList.GameList
import eventDemo.business.event.projection.gameList.GameListRepository
import eventDemo.business.event.projection.gameList.apply
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.GameState
import eventDemo.business.event.projection.apply
import eventDemo.libs.event.projection.ProjectionSnapshotRepositoryInMemory
import eventDemo.libs.event.projection.SnapshotConfig
import io.github.oshai.kotlinlogging.withLoggingContext

View File

@@ -3,11 +3,11 @@ package eventDemo.adapter.infrastructureLayer.event.projection
import eventDemo.business.entity.GameId
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.projection.GameList
import eventDemo.business.event.projection.GameListRepository
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameList.GameList
import eventDemo.business.event.projection.gameList.GameListRepository
import eventDemo.business.event.projection.gameList.apply
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.GameState
import eventDemo.business.event.projection.apply
import eventDemo.libs.event.projection.ProjectionSnapshotRepositoryInRedis
import eventDemo.libs.event.projection.SnapshotConfig
import io.github.oshai.kotlinlogging.withLoggingContext

View File

@@ -1,15 +1,14 @@
package eventDemo.adapter.infrastructureLayer.event.projection
import eventDemo.business.entity.GameId
import eventDemo.business.event.projection.GameProjection
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.libs.bus.Bus
import eventDemo.libs.bus.BusInMemory
import eventDemo.libs.event.projection.Projection
import java.util.UUID
class GameProjectionBusInMemory :
GameProjectionBus,
Bus<Projection<GameId>> by BusInMemory(GameProjectionBusInMemory::class),
Bus<GameProjection> by BusInMemory(GameProjectionBusInMemory::class),
Comparable<GameProjectionBusInMemory> {
private val instanceId: UUID = UUID.randomUUID()

View File

@@ -0,0 +1,25 @@
package eventDemo.adapter.infrastructureLayer.event.projection
import com.rabbitmq.client.ConnectionFactory
import eventDemo.business.event.projection.GameProjection
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.libs.bus.Bus
import eventDemo.libs.bus.BusInRabbitMQ
import kotlinx.serialization.json.Json
import java.util.UUID
class GameProjectionBusInRabbitMQ(
private val connectionFactory: ConnectionFactory,
) : GameProjectionBus,
Bus<GameProjection> by BusInRabbitMQ(
connectionFactory,
"GameProjection",
{ Json.encodeToString(it) },
{ Json.decodeFromString<GameProjection>(it) },
),
Comparable<GameProjectionBusInRabbitMQ> {
private val instanceId: UUID = UUID.randomUUID()
override fun compareTo(other: GameProjectionBusInRabbitMQ): Int =
compareValues(instanceId, other.instanceId)
}

View File

@@ -5,9 +5,9 @@ import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.event.GameEvent
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.gameState.apply
import eventDemo.business.event.projection.GameState
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.business.event.projection.apply
import eventDemo.libs.event.projection.ProjectionSnapshotRepositoryInMemory
import eventDemo.libs.event.projection.SnapshotConfig
import io.github.oshai.kotlinlogging.withLoggingContext

View File

@@ -5,9 +5,9 @@ import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.event.GameEvent
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.gameState.apply
import eventDemo.business.event.projection.GameState
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.business.event.projection.apply
import eventDemo.libs.event.projection.ProjectionSnapshotRepositoryInRedis
import eventDemo.libs.event.projection.SnapshotConfig
import io.github.oshai.kotlinlogging.withLoggingContext

View File

@@ -1,8 +1,7 @@
package eventDemo.adapter.interfaceLayer.query
import eventDemo.business.event.projection.gameList.GameListRepository
import eventDemo.business.event.projection.GameListRepository
import io.ktor.resources.Resource
import io.ktor.server.application.call
import io.ktor.server.auth.authenticate
import io.ktor.server.resources.get
import io.ktor.server.response.respond

View File

@@ -1,11 +1,10 @@
package eventDemo.adapter.interfaceLayer.query
import eventDemo.business.entity.GameId
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.configuration.serializer.GameIdSerializer
import io.ktor.http.HttpStatusCode
import io.ktor.resources.Resource
import io.ktor.server.application.call
import io.ktor.server.auth.authenticate
import io.ktor.server.resources.get
import io.ktor.server.response.respond

View File

@@ -3,7 +3,7 @@ package eventDemo.business.command.action
import eventDemo.business.command.CommandException
import eventDemo.business.command.command.ICantPlayCommand
import eventDemo.business.event.event.PlayerHavePassEvent
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.GameStateRepository
/**
* A command to perform an action to play a new card

View File

@@ -3,7 +3,7 @@ package eventDemo.business.command.action
import eventDemo.business.command.CommandException
import eventDemo.business.command.command.IWantToJoinTheGameCommand
import eventDemo.business.event.event.NewPlayerEvent
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.GameStateRepository
/**
* A command to perform an action to play a new card

View File

@@ -3,7 +3,7 @@ package eventDemo.business.command.action
import eventDemo.business.command.CommandException
import eventDemo.business.command.command.IWantToPlayCardCommand
import eventDemo.business.event.event.CardIsPlayedEvent
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.GameStateRepository
/**
* A command to perform an action to play a new card

View File

@@ -3,7 +3,7 @@ package eventDemo.business.command.action
import eventDemo.business.command.CommandException
import eventDemo.business.command.command.IamReadyToPlayCommand
import eventDemo.business.event.event.PlayerReadyEvent
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.GameStateRepository
/**
* A command to set as ready to play

View File

@@ -0,0 +1,8 @@
package eventDemo.business.event.projection
import eventDemo.business.entity.GameId
import eventDemo.libs.event.projection.Projection
import kotlinx.serialization.Serializable
@Serializable
sealed interface GameProjection : Projection<GameId>

View File

@@ -1,7 +1,5 @@
package eventDemo.business.event.projection
import eventDemo.business.entity.GameId
import eventDemo.libs.bus.Bus
import eventDemo.libs.event.projection.Projection
interface GameProjectionBus : Bus<Projection<GameId>>
interface GameProjectionBus : Bus<GameProjection>

View File

@@ -1,4 +1,4 @@
package eventDemo.business.event.projection.gameList
package eventDemo.business.event.projection
import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
@@ -15,7 +15,7 @@ data class GameList(
val status: Status = Status.OPENING,
val players: Set<Player> = emptySet(),
val winners: Set<Player> = emptySet(),
) : Projection<GameId> {
) : GameProjection {
enum class Status {
OPENING,
IS_STARTED,

View File

@@ -1,4 +1,4 @@
package eventDemo.business.event.projection.gameList
package eventDemo.business.event.projection
import eventDemo.business.event.event.CardIsPlayedEvent
import eventDemo.business.event.event.GameEvent

View File

@@ -1,4 +1,4 @@
package eventDemo.business.event.projection.gameList
package eventDemo.business.event.projection
interface GameListRepository {
fun getList(): List<GameList>

View File

@@ -1,4 +1,4 @@
package eventDemo.business.event.projection.gameState
package eventDemo.business.event.projection
import eventDemo.business.entity.Card
import eventDemo.business.entity.Deck
@@ -25,7 +25,7 @@ data class GameState(
val isStarted: Boolean = false,
val playerWins: Set<Player> = emptySet(),
val lastEvent: GameEvent? = null,
) : Projection<GameId> {
) : GameProjection {
enum class Direction {
CLOCKWISE,
COUNTER_CLOCKWISE,

View File

@@ -1,4 +1,4 @@
package eventDemo.business.event.projection.gameState
package eventDemo.business.event.projection
import eventDemo.business.entity.Card
import eventDemo.business.event.event.CardIsPlayedEvent

View File

@@ -1,4 +1,4 @@
package eventDemo.business.event.projection.gameState
package eventDemo.business.event.projection
import eventDemo.business.entity.GameId
import eventDemo.business.event.event.GameEvent

View File

@@ -11,7 +11,7 @@ import eventDemo.business.event.event.PlayerHavePassEvent
import eventDemo.business.event.event.PlayerReadyEvent
import eventDemo.business.event.event.PlayerWinEvent
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.GameState
import eventDemo.business.notification.ItsTheTurnOfNotification
import eventDemo.business.notification.Notification
import eventDemo.business.notification.PlayerAsJoinTheGameNotification

View File

@@ -5,7 +5,7 @@ import eventDemo.business.event.GameEventHandler
import eventDemo.business.event.event.GameStartedEvent
import eventDemo.business.event.event.PlayerWinEvent
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.GameState
import eventDemo.libs.event.projection.Projection
import io.github.oshai.kotlinlogging.KotlinLogging
import io.github.oshai.kotlinlogging.withLoggingContext

View File

@@ -6,13 +6,13 @@ import com.zaxxer.hikari.HikariDataSource
import eventDemo.adapter.infrastructureLayer.event.GameEventBusInRabbinMQ
import eventDemo.adapter.infrastructureLayer.event.GameEventStoreInPostgresql
import eventDemo.adapter.infrastructureLayer.event.projection.GameListRepositoryInRedis
import eventDemo.adapter.infrastructureLayer.event.projection.GameProjectionBusInMemory
import eventDemo.adapter.infrastructureLayer.event.projection.GameProjectionBusInRabbitMQ
import eventDemo.adapter.infrastructureLayer.event.projection.GameStateRepositoryInRedis
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.projection.GameListRepository
import eventDemo.business.event.projection.GameProjectionBus
import eventDemo.business.event.projection.gameList.GameListRepository
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.libs.event.projection.SnapshotConfig
import org.koin.core.module.Module
import org.koin.core.module.dsl.singleOf
@@ -62,7 +62,7 @@ fun Module.configureDIInfrastructure(config: Configuration) {
singleOf(::GameEventBusInRabbinMQ) bind GameEventBus::class
singleOf(::GameEventStoreInPostgresql) bind GameEventStore::class
singleOf(::GameProjectionBusInMemory) bind GameProjectionBus::class
singleOf(::GameProjectionBusInRabbitMQ) bind GameProjectionBus::class
single {
GameStateRepositoryInRedis(get(), get(), snapshotConfig = SnapshotConfig())

View File

@@ -5,7 +5,6 @@ import com.auth0.jwt.algorithms.Algorithm
import eventDemo.business.entity.Player
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.Application
import io.ktor.server.application.call
import io.ktor.server.auth.authentication
import io.ktor.server.auth.jwt.JWTPrincipal
import io.ktor.server.auth.jwt.jwt

View File

@@ -6,7 +6,7 @@ import eventDemo.business.event.GameEventHandler
import eventDemo.business.event.event.GameStartedEvent
import eventDemo.business.event.event.NewPlayerEvent
import eventDemo.business.event.event.PlayerReadyEvent
import eventDemo.business.event.projection.gameList.GameList
import eventDemo.business.event.projection.GameList
import eventDemo.testApplicationWithConfig
import io.kotest.assertions.nondeterministic.eventually
import io.kotest.core.spec.style.FunSpec

View File

@@ -12,7 +12,7 @@ import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.event.disableShuffleDeck
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.GameState
import eventDemo.business.event.projection.projectionListener.PlayerNotificationListener
import eventDemo.business.notification.CommandSuccessNotification
import eventDemo.business.notification.ItsTheTurnOfNotification

View File

@@ -8,8 +8,8 @@ import eventDemo.business.event.event.CardIsPlayedEvent
import eventDemo.business.event.event.NewPlayerEvent
import eventDemo.business.event.event.PlayerReadyEvent
import eventDemo.business.event.event.disableShuffleDeck
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.business.event.projection.GameState
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.testApplicationWithConfig
import io.kotest.assertions.nondeterministic.eventually
import io.kotest.core.spec.style.FunSpec

View File

@@ -1,8 +1,5 @@
package eventDemo.business.entity
import eventDemo.business.entity.Card
import eventDemo.business.entity.Player
import eventDemo.business.entity.PlayersHands
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.ints.shouldBeExactly
import kotlin.test.assertNotNull

View File

@@ -8,8 +8,6 @@ import eventDemo.business.event.event.GameStartedEvent
import eventDemo.business.event.event.NewPlayerEvent
import eventDemo.business.event.event.PlayerReadyEvent
import eventDemo.business.event.event.disableShuffleDeck
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.gameState.apply
import eventDemo.libs.event.VersionBuilderLocal
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.equals.shouldBeEqual

View File

@@ -9,8 +9,6 @@ import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.business.event.GameEventHandler
import eventDemo.business.event.event.NewPlayerEvent
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.gameState.GameStateRepository
import eventDemo.testKoinApplicationWithConfig
import eventDemo.withLogLevel
import io.kotest.assertions.nondeterministic.eventually

View File

@@ -6,7 +6,6 @@ import eventDemo.business.entity.Discard
import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.business.entity.PlayersHands
import eventDemo.business.event.projection.gameState.GameState
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.equals.shouldBeEqual

View File

@@ -4,7 +4,7 @@ import eventDemo.adapter.infrastructureLayer.event.projection.GameProjectionBusI
import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.business.event.event.NewPlayerEvent
import eventDemo.business.event.projection.gameState.GameState
import eventDemo.business.event.projection.GameState
import eventDemo.business.notification.WelcomeToTheGameNotification
import io.kotest.core.spec.style.FunSpec
import io.mockk.mockk