Add AggregateID for the PlayerNotificationEventListener and CommandHandler

This commit is contained in:
2025-03-17 19:41:47 +01:00
parent 0374712824
commit 1a96c68521
11 changed files with 96 additions and 42 deletions

View File

@@ -1,6 +1,7 @@
package eventDemo.business.command
import eventDemo.business.command.command.GameCommand
import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventHandler
@@ -55,27 +56,35 @@ class GameCommandHandler(
*/
suspend fun handle(
player: Player,
gameId: GameId,
incomingCommandChannel: ReceiveChannel<GameCommand>,
channelNotification: SendChannel<Notification>,
) {
commandStreamChannel.process(incomingCommandChannel) { command ->
withLoggingContext("command" to command.toString()) {
if (command.payload.aggregateId.id != gameId.id) {
logger.warn { "Handle command Refuse, the gameId of the command is not the same" }
channelNotification.sendError(command)("The gameId in the command does not match with your game")
return@process
}
if (command.payload.player.id != player.id) {
logger.warn { "Handle command Refuse, the player of the command is not the same" }
channelNotification.sendError(command)("You are not the author of this command")
} else {
logger.info { "Handle command" }
try {
val eventBuilder = runner.run(command)
return@process
}
eventHandler.handle(command.payload.aggregateId) { version ->
eventBuilder(version)
.also { eventCommandMap.set(it.eventId, channelNotification, command.id) }
}
} catch (e: CommandException) {
logger.warn(e) { e.message }
channelNotification.sendError(command)(e.message)
logger.info { "Handle command" }
try {
val eventBuilder = runner.run(command)
eventHandler.handle(command.payload.aggregateId) { version ->
eventBuilder(version)
.also { eventCommandMap.set(it.eventId, channelNotification, command.id) }
}
} catch (e: CommandException) {
logger.warn(e) { e.message }
channelNotification.sendError(command)(e.message)
}
}
}

View File

@@ -3,5 +3,13 @@ package eventDemo.business.event
import eventDemo.business.entity.GameId
import eventDemo.business.event.event.GameEvent
import eventDemo.libs.event.EventBus
import java.util.UUID
interface GameEventBus : EventBus<GameEvent, GameId>
abstract class GameEventBus :
EventBus<GameEvent, GameId>,
Comparable<GameEventBus> {
private val instanceId: UUID = UUID.randomUUID()
override fun compareTo(other: GameEventBus): Int =
compareValues(instanceId, other.instanceId)
}

View File

@@ -24,8 +24,8 @@ data class GameStartedEvent(
fun new(
id: GameId,
players: Set<Player>,
shuffleIsDisabled: Boolean = isDisabled,
version: Int,
shuffleIsDisabled: Boolean = isDisabled,
): GameStartedEvent =
GameStartedEvent(
aggregateId = id,

View File

@@ -1,6 +1,7 @@
package eventDemo.business.event.eventListener
import eventDemo.business.entity.Card
import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.event.CardIsPlayedEvent
@@ -35,9 +36,14 @@ class PlayerNotificationEventListener(
fun startListening(
outgoingNotification: (Notification) -> Unit,
currentPlayer: Player,
gameId: GameId,
) {
eventBus.subscribe { event: GameEvent ->
withLoggingContext("event" to event.toString()) {
if (event.aggregateId != gameId) {
return@subscribe
}
val currentState = gameStateRepository.getUntil(event)
fun Notification.send() {

View File

@@ -10,6 +10,7 @@ import eventDemo.business.event.projection.GameState
import eventDemo.business.event.projection.GameStateRepository
import io.github.oshai.kotlinlogging.KotlinLogging
import io.github.oshai.kotlinlogging.withLoggingContext
import java.util.concurrent.ConcurrentSkipListSet
class ReactionEventListener(
private val eventBus: GameEventBus,
@@ -19,17 +20,22 @@ class ReactionEventListener(
) {
companion object Config {
const val DEFAULT_PRIORITY = -1000
val registeredListeners = ConcurrentSkipListSet<GameEventBus>()
}
private val logger = KotlinLogging.logger { }
fun init() {
eventBus.subscribe(priority) { event: GameEvent ->
withLoggingContext("event" to event.toString()) {
val state = gameStateRepository.getUntil(event)
sendStartGameEvent(state, event)
sendWinnerEvent(state)
if (registeredListeners.add(eventBus)) {
eventBus.subscribe(priority) { event: GameEvent ->
withLoggingContext("event" to event.toString()) {
val state = gameStateRepository.getUntil(event)
sendStartGameEvent(state, event)
sendWinnerEvent(state)
}
}
} else {
logger.error { "${this::class.java.simpleName} is already init for this bus" }
}
}