com.cultureamp.eventsourcing.EventProcessor.kt Maven / Gradle / Ivy
package com.cultureamp.eventsourcing
import com.cultureamp.common.asNestedSealedConcreteClasses
import java.util.UUID
import kotlin.reflect.KClass
interface SequencedEventProcessor {
fun process(sequencedEvent: SequencedEvent)
fun domainEventClasses(): List> = emptyList()
companion object {
fun from(eventProcessor: EventProcessor) = object : SequencedEventProcessor {
override fun process(sequencedEvent: SequencedEvent) = eventProcessor.process(sequencedEvent.event)
override fun domainEventClasses() = eventProcessor.domainEventClasses()
}
}
}
interface EventProcessor {
companion object {
inline fun from(noinline process: (E, UUID) -> Any?) = CompositeDomainEventProcessor.from(process)
inline fun from(noinline process: (E, UUID, M, UUID) -> Any?) = CompositeDomainEventProcessor.from(process)
inline fun from(domainEventProcessor: DomainEventProcessor) = CompositeDomainEventProcessor.from(domainEventProcessor)
inline fun from(domainEventProcessor: DomainEventProcessorWithMetadata) = CompositeDomainEventProcessor.from(domainEventProcessor)
fun compose(first: CompositeDomainEventProcessor, vararg remainder: CompositeDomainEventProcessor) = CompositeDomainEventProcessor.compose(first, *remainder)
}
fun process(event: Event)
fun domainEventClasses(): List> = emptyList()
}
class CompositeDomainEventProcessor (private val domainEventProcessors: List, (DomainEvent, UUID, M, UUID) -> Any?>>) : EventProcessor {
val eventClasses = domainEventProcessors.flatMap { it.first.asNestedSealedConcreteClasses() }
override fun domainEventClasses() = eventClasses
override fun process(event: Event) {
domainEventProcessors.filter { it.first.isInstance(event.domainEvent) }.forEach { it.second(event.domainEvent, event.aggregateId, event.metadata, event.id) }
}
@Suppress("UNCHECKED_CAST")
companion object {
inline fun from(noinline process: (E, UUID) -> Any?): CompositeDomainEventProcessor {
return from(DomainEventProcessor.from(process))
}
inline fun from(noinline process: (E, UUID, M, UUID) -> Any?): CompositeDomainEventProcessor {
return from(DomainEventProcessorWithMetadata.from(process))
}
inline fun from(domainEventProcessor: DomainEventProcessor): CompositeDomainEventProcessor {
val ignoreMetadataHandle = { domainEvent: E, aggregateId: UUID, _: EventMetadata, _: UUID -> domainEventProcessor.process(domainEvent, aggregateId) }
val handler = (E::class to ignoreMetadataHandle) as Pair, (DomainEvent, UUID, EventMetadata, UUID) -> Any?>
return CompositeDomainEventProcessor(listOf(handler))
}
inline fun from(domainEventProcessor: DomainEventProcessorWithMetadata): CompositeDomainEventProcessor {
val handle = { domainEvent: E, aggregateId: UUID, metadata: M, eventId: UUID -> domainEventProcessor.process(domainEvent, aggregateId, metadata, eventId) }
val handler = (E::class to handle) as Pair, (DomainEvent, UUID, EventMetadata, UUID) -> Any?>
return CompositeDomainEventProcessor(listOf(handler))
}
fun compose(first: CompositeDomainEventProcessor, vararg remainder: CompositeDomainEventProcessor): CompositeDomainEventProcessor {
return CompositeDomainEventProcessor(first.domainEventProcessors + remainder.flatMap { it.domainEventProcessors })
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy