Split configs

This commit is contained in:
2025-03-16 03:11:42 +01:00
parent 769d104040
commit 4adfc6467c
43 changed files with 254 additions and 191 deletions

View File

@@ -2,7 +2,7 @@ package eventDemo.adapter.interfaceLayer
import eventDemo.business.entity.GameId
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.configuration.GameIdSerializer
import eventDemo.configuration.serializer.GameIdSerializer
import io.ktor.http.HttpStatusCode
import io.ktor.resources.Resource
import io.ktor.server.application.call

View File

@@ -1,6 +1,6 @@
package eventDemo.business.entity
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,6 +1,6 @@
package eventDemo.business.entity
import eventDemo.configuration.GameIdSerializer
import eventDemo.configuration.serializer.GameIdSerializer
import eventDemo.libs.event.AggregateId
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.entity
import eventDemo.configuration.PlayerIdSerializer
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.PlayerIdSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import eventDemo.libs.event.AggregateId
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,6 +1,6 @@
package eventDemo.business.notification
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import eventDemo.libs.command.Command
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,6 +1,6 @@
package eventDemo.business.notification
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import eventDemo.libs.command.CommandId
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.notification
import eventDemo.business.entity.Player
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,6 +1,6 @@
package eventDemo.business.notification
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.notification
import eventDemo.business.entity.Player
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -2,7 +2,7 @@ package eventDemo.business.notification
import eventDemo.business.entity.Card
import eventDemo.business.entity.Player
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.notification
import eventDemo.business.entity.Player
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -2,7 +2,7 @@ package eventDemo.business.notification
import eventDemo.business.entity.Card
import eventDemo.business.entity.Player
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.notification
import eventDemo.business.entity.Player
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.notification
import eventDemo.business.entity.Player
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.notification
import eventDemo.business.entity.Card
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.notification
import eventDemo.business.entity.Player
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,7 +1,7 @@
package eventDemo.business.notification
import eventDemo.business.entity.Card
import eventDemo.configuration.UUIDSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -1,5 +1,13 @@
package eventDemo.configuration
import eventDemo.configuration.business.configureGameListener
import eventDemo.configuration.ktor.configureHttpRouting
import eventDemo.configuration.ktor.configureKoin
import eventDemo.configuration.ktor.configureSecurity
import eventDemo.configuration.ktor.configureSerialization
import eventDemo.configuration.ktor.configureWebSockets
import eventDemo.configuration.route.declareHttpGameRoute
import eventDemo.configuration.route.declareWebSocketsGameRoute
import io.ktor.server.application.Application
import org.koin.ktor.ext.get

View File

@@ -1,65 +0,0 @@
package eventDemo.configuration
import eventDemo.adapter.infrastructureLayer.event.GameEventBusInMemory
import eventDemo.adapter.infrastructureLayer.event.GameEventStoreInMemory
import eventDemo.adapter.infrastructureLayer.event.projection.GameStateRepositoryInMemory
import eventDemo.business.command.GameCommandActionRunner
import eventDemo.business.command.GameCommandHandler
import eventDemo.business.command.command.GameCommand
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventHandler
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.eventListener.PlayerNotificationEventListener
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.libs.command.CommandRunnerController
import eventDemo.libs.command.CommandStreamChannel
import eventDemo.libs.event.VersionBuilder
import eventDemo.libs.event.VersionBuilderLocal
import eventDemo.libs.event.projection.SnapshotConfig
import io.ktor.server.application.Application
import io.ktor.server.application.install
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.bind
import org.koin.dsl.module
import org.koin.ktor.plugin.Koin
import org.koin.logger.slf4jLogger
fun Application.configureKoin() {
install(Koin) {
slf4jLogger()
modules(appKoinModule)
}
}
val appKoinModule =
module {
single {
GameEventBusInMemory()
} bind GameEventBus::class
single {
GameEventStoreInMemory()
} bind GameEventStore::class
single {
GameStateRepositoryInMemory(get(), get(), snapshotConfig = SnapshotConfig())
} bind GameStateRepository::class
single {
CommandStreamChannel<GameCommand>(get())
}
single {
CommandRunnerController<GameCommand>()
}
single {
GameCommandHandler(get(), get(), get(), get())
}
singleOf(::VersionBuilderLocal) bind VersionBuilder::class
singleOf(::GameEventHandler)
singleOf(::GameCommandActionRunner)
singleOf(::PlayerNotificationEventListener)
// Actions
configureActions()
}

View File

@@ -1,93 +0,0 @@
package eventDemo.configuration
import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.libs.command.CommandId
import io.ktor.serialization.kotlinx.json.json
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import java.util.UUID
fun Application.configureSerialization() {
install(ContentNegotiation) {
json(
defaultJsonSerializer(),
)
}
}
fun defaultJsonSerializer(): Json =
Json {
serializersModule =
SerializersModule {
contextual(UUID::class) { UUIDSerializer }
contextual(GameId::class) { GameIdSerializer }
contextual(CommandId::class) { CommandIdSerializer }
contextual(Player.PlayerId::class) { PlayerIdSerializer }
}
}
object CommandIdSerializer : KSerializer<CommandId> {
override fun deserialize(decoder: Decoder): CommandId =
CommandId(decoder.decodeString())
override fun serialize(
encoder: Encoder,
value: CommandId,
) {
encoder.encodeString(value.toString())
}
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("CommandId", PrimitiveKind.STRING)
}
object PlayerIdSerializer : KSerializer<Player.PlayerId> {
override fun deserialize(decoder: Decoder): Player.PlayerId =
Player.PlayerId(UUID.fromString(decoder.decodeString()))
override fun serialize(
encoder: Encoder,
value: Player.PlayerId,
) {
encoder.encodeString(value.id.toString())
}
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("PlayerId", PrimitiveKind.STRING)
}
object GameIdSerializer : KSerializer<GameId> {
override fun deserialize(decoder: Decoder): GameId =
GameId(UUID.fromString(decoder.decodeString()))
override fun serialize(
encoder: Encoder,
value: GameId,
) {
encoder.encodeString(value.id.toString())
}
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("GameId", PrimitiveKind.STRING)
}
object UUIDSerializer : KSerializer<UUID> {
override fun deserialize(decoder: Decoder): UUID =
UUID.fromString(decoder.decodeString())
override fun serialize(
encoder: Encoder,
value: UUID,
) {
encoder.encodeString(value.toString())
}
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
}

View File

@@ -1,4 +1,4 @@
package eventDemo.configuration
package eventDemo.configuration.business
import eventDemo.business.event.eventListener.ReactionEventListener
import io.ktor.server.application.Application

View File

@@ -0,0 +1,11 @@
package eventDemo.configuration.injection
import org.koin.dsl.module
val appKoinModule =
module {
configureDIBusiness()
configureDIInfrastructure()
configureDILibs()
configureDICommandActions()
}

View File

@@ -1,4 +1,4 @@
package eventDemo.configuration
package eventDemo.configuration.injection
import eventDemo.business.command.action.ICantPlay
import eventDemo.business.command.action.IWantToJoinTheGame
@@ -10,7 +10,7 @@ import org.koin.core.module.dsl.singleOf
/**
* Configure all actions
*/
fun Module.configureActions() {
fun Module.configureDICommandActions() {
singleOf(::IWantToPlayCard)
singleOf(::IamReadyToPlay)
singleOf(::IWantToJoinTheGame)

View File

@@ -0,0 +1,17 @@
package eventDemo.configuration.injection
import eventDemo.business.command.GameCommandActionRunner
import eventDemo.business.command.GameCommandHandler
import eventDemo.business.event.GameEventHandler
import eventDemo.business.event.eventListener.PlayerNotificationEventListener
import org.koin.core.module.Module
import org.koin.core.module.dsl.singleOf
fun Module.configureDIBusiness() {
single {
GameCommandHandler(get(), get(), get(), get())
}
singleOf(::GameEventHandler)
singleOf(::GameCommandActionRunner)
singleOf(::PlayerNotificationEventListener)
}

View File

@@ -0,0 +1,25 @@
package eventDemo.configuration.injection
import eventDemo.adapter.infrastructureLayer.event.GameEventBusInMemory
import eventDemo.adapter.infrastructureLayer.event.GameEventStoreInMemory
import eventDemo.adapter.infrastructureLayer.event.projection.GameStateRepositoryInMemory
import eventDemo.business.event.GameEventBus
import eventDemo.business.event.GameEventStore
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.libs.event.projection.SnapshotConfig
import org.koin.core.module.Module
import org.koin.dsl.bind
fun Module.configureDIInfrastructure() {
single {
GameEventBusInMemory()
} bind GameEventBus::class
single {
GameEventStoreInMemory()
} bind GameEventStore::class
single {
GameStateRepositoryInMemory(get(), get(), snapshotConfig = SnapshotConfig())
} bind GameStateRepository::class
}

View File

@@ -0,0 +1,17 @@
package eventDemo.configuration.injection
import eventDemo.business.command.command.GameCommand
import eventDemo.libs.command.CommandRunnerController
import eventDemo.libs.command.CommandStreamChannel
import eventDemo.libs.event.VersionBuilder
import eventDemo.libs.event.VersionBuilderLocal
import org.koin.core.module.Module
import org.koin.core.module.dsl.singleOf
import org.koin.dsl.bind
fun Module.configureDILibs() {
single {
CommandStreamChannel<GameCommand>(CommandRunnerController())
}
singleOf(::VersionBuilderLocal) bind VersionBuilder::class
}

View File

@@ -1,4 +1,4 @@
package eventDemo.configuration
package eventDemo.configuration.ktor
import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
@@ -37,7 +37,7 @@ fun Application.configureSecurity() {
null
}
}
challenge { defaultScheme, realm ->
challenge { _, _ ->
call.respond(HttpStatusCode.Unauthorized, "Token is not valid or has expired")
}
}

View File

@@ -1,4 +1,4 @@
package eventDemo.configuration
package eventDemo.configuration.ktor
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpMethod

View File

@@ -0,0 +1,14 @@
package eventDemo.configuration.ktor
import eventDemo.configuration.injection.appKoinModule
import io.ktor.server.application.Application
import io.ktor.server.application.install
import org.koin.ktor.plugin.Koin
import org.koin.logger.slf4jLogger
fun Application.configureKoin() {
install(Koin) {
slf4jLogger()
modules(appKoinModule)
}
}

View File

@@ -0,0 +1,35 @@
package eventDemo.configuration.ktor
import eventDemo.business.entity.GameId
import eventDemo.business.entity.Player
import eventDemo.configuration.serializer.CommandIdSerializer
import eventDemo.configuration.serializer.GameIdSerializer
import eventDemo.configuration.serializer.PlayerIdSerializer
import eventDemo.configuration.serializer.UUIDSerializer
import eventDemo.libs.command.CommandId
import io.ktor.serialization.kotlinx.json.json
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import java.util.UUID
fun Application.configureSerialization() {
install(ContentNegotiation) {
json(
defaultJsonSerializer(),
)
}
}
fun defaultJsonSerializer(): Json =
Json {
serializersModule =
SerializersModule {
contextual(UUID::class) { UUIDSerializer }
contextual(GameId::class) { GameIdSerializer }
contextual(CommandId::class) { CommandIdSerializer }
contextual(Player.PlayerId::class) { PlayerIdSerializer }
}
}

View File

@@ -1,4 +1,4 @@
package eventDemo.configuration
package eventDemo.configuration.ktor
import io.ktor.server.application.Application
import io.ktor.server.application.install

View File

@@ -1,4 +1,4 @@
package eventDemo.configuration
package eventDemo.configuration.route
import eventDemo.adapter.interfaceLayer.readTheGameState
import io.ktor.server.application.Application

View File

@@ -1,4 +1,4 @@
package eventDemo.configuration
package eventDemo.configuration.route
import eventDemo.adapter.interfaceLayer.gameWebSocket
import eventDemo.business.command.GameCommandHandler

View File

@@ -0,0 +1,23 @@
package eventDemo.configuration.serializer
import eventDemo.libs.command.CommandId
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
object CommandIdSerializer : KSerializer<CommandId> {
override fun deserialize(decoder: Decoder): CommandId =
CommandId(decoder.decodeString())
override fun serialize(
encoder: Encoder,
value: CommandId,
) {
encoder.encodeString(value.toString())
}
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("CommandId", PrimitiveKind.STRING)
}

View File

@@ -0,0 +1,24 @@
package eventDemo.configuration.serializer
import eventDemo.business.entity.GameId
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.util.UUID
object GameIdSerializer : KSerializer<GameId> {
override fun deserialize(decoder: Decoder): GameId =
GameId(UUID.fromString(decoder.decodeString()))
override fun serialize(
encoder: Encoder,
value: GameId,
) {
encoder.encodeString(value.id.toString())
}
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("GameId", PrimitiveKind.STRING)
}

View File

@@ -0,0 +1,24 @@
package eventDemo.configuration.serializer
import eventDemo.business.entity.Player
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.util.UUID
object PlayerIdSerializer : KSerializer<Player.PlayerId> {
override fun deserialize(decoder: Decoder): Player.PlayerId =
Player.PlayerId(UUID.fromString(decoder.decodeString()))
override fun serialize(
encoder: Encoder,
value: Player.PlayerId,
) {
encoder.encodeString(value.id.toString())
}
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("PlayerId", PrimitiveKind.STRING)
}

View File

@@ -0,0 +1,23 @@
package eventDemo.configuration.serializer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.util.UUID
object UUIDSerializer : KSerializer<UUID> {
override fun deserialize(decoder: Decoder): UUID =
UUID.fromString(decoder.decodeString())
override fun serialize(
encoder: Encoder,
value: UUID,
) {
encoder.encodeString(value.toString())
}
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
}

View File

@@ -1,6 +1,6 @@
package eventDemo.libs.command
import eventDemo.configuration.CommandIdSerializer
import eventDemo.configuration.serializer.CommandIdSerializer
import kotlinx.serialization.Serializable
import java.util.UUID

View File

@@ -10,7 +10,7 @@ import eventDemo.business.event.eventListener.ReactionEventListener
import eventDemo.business.notification.CommandSuccessNotification
import eventDemo.business.notification.Notification
import eventDemo.business.notification.WelcomeToTheGameNotification
import eventDemo.configuration.appKoinModule
import eventDemo.configuration.injection.appKoinModule
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldContain
import io.kotest.matchers.equals.shouldBeEqual

View File

@@ -5,7 +5,7 @@ import eventDemo.business.entity.Player
import eventDemo.business.event.GameEventHandler
import eventDemo.business.event.event.NewPlayerEvent
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.configuration.appKoinModule
import eventDemo.configuration.injection.appKoinModule
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.equals.shouldBeEqual

View File

@@ -11,7 +11,7 @@ import eventDemo.business.event.event.PlayerReadyEvent
import eventDemo.business.event.projection.GameState
import eventDemo.business.event.projection.GameStateRepository
import eventDemo.configuration.configure
import eventDemo.configuration.makeJwt
import eventDemo.configuration.ktor.makeJwt
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.equals.shouldBeEqual

View File

@@ -22,7 +22,7 @@ import eventDemo.business.notification.PlayerAsPlayACardNotification
import eventDemo.business.notification.PlayerWasReadyNotification
import eventDemo.business.notification.TheGameWasStartedNotification
import eventDemo.business.notification.WelcomeToTheGameNotification
import eventDemo.configuration.appKoinModule
import eventDemo.configuration.injection.appKoinModule
import eventDemo.libs.event.projection.ProjectionSnapshotRepositoryInMemory
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldHaveSize

View File

@@ -1,5 +1,5 @@
package eventDemo.app.query
import eventDemo.configuration.defaultJsonSerializer
import eventDemo.configuration.ktor.defaultJsonSerializer
import io.ktor.client.HttpClient
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.serialization.kotlinx.json.json