All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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