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

org.enodeframework.commanding.impl.CommandExecuteContext.kt Maven / Gradle / Ivy

There is a newer version: 1.1.10
Show newest version
package org.enodeframework.commanding.impl

import org.enodeframework.commanding.CommandResult
import org.enodeframework.commanding.ICommandExecuteContext
import org.enodeframework.common.exception.AggregateRootAlreadyExistException
import org.enodeframework.common.exception.AggregateRootNotFoundException
import org.enodeframework.common.io.Task
import org.enodeframework.common.utilities.Ensure
import org.enodeframework.domain.IAggregateRoot
import org.enodeframework.domain.IAggregateStorage
import org.enodeframework.domain.IRepository
import org.enodeframework.messaging.IApplicationMessage
import org.enodeframework.queue.IMessageContext
import org.enodeframework.queue.ISendReplyService
import org.enodeframework.queue.QueueMessage
import org.enodeframework.queue.command.CommandMessage
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap

/**
 * @author [email protected]
 */
class CommandExecuteContext(
        repository: IRepository,
        aggregateRootStorage: IAggregateStorage,
        queueMessage: QueueMessage,
        messageContext: IMessageContext,
        commandMessage: CommandMessage,
        sendReplyService: ISendReplyService
) : ICommandExecuteContext {
    private val trackingAggregateRootDict: ConcurrentMap
    private val repository: IRepository
    private val aggregateRootStorage: IAggregateStorage
    private val sendReplyService: ISendReplyService
    private val queueMessage: QueueMessage
    private val messageContext: IMessageContext
    private val commandMessage: CommandMessage
    override var result: String = ""
    override var applicationMessage: IApplicationMessage? = null
    override fun onCommandExecutedAsync(commandResult: CommandResult): CompletableFuture {
        messageContext.onMessageHandled(queueMessage)
        return if (Objects.isNull(commandMessage.replyAddress)) {
            Task.completedTask
        } else sendReplyService.sendCommandReply(commandResult, commandMessage.replyAddress)
    }

    override fun add(aggregateRoot: IAggregateRoot) {
        Ensure.notNull(aggregateRoot, "aggregateRoot")
        if (trackingAggregateRootDict.containsKey(aggregateRoot.uniqueId)) {
            throw AggregateRootAlreadyExistException(aggregateRoot.uniqueId, aggregateRoot.javaClass)
        }
        trackingAggregateRootDict[aggregateRoot.uniqueId] = aggregateRoot
    }

    /**
     * Add a new aggregate into the current command context synchronously, and then return a completed task object.
     */
    override fun addAsync(aggregateRoot: IAggregateRoot): CompletableFuture {
        add(aggregateRoot)
        return Task.completedTask
    }

    /**
     * Get an aggregate from the current command context.
     */
    override fun  getAsync(id: Any, firstFromCache: Boolean, aggregateRootType: Class): CompletableFuture {
        Ensure.notNull(id, "id")
        val aggregateRootId = id.toString()
        val iAggregateRoot = trackingAggregateRootDict[aggregateRootId] as T?
        var future = CompletableFuture()
        if (iAggregateRoot != null) {
            future.complete(iAggregateRoot)
            return future
        }
        future = if (firstFromCache) {
            repository.getAsync(aggregateRootType, id)
        } else {
            aggregateRootStorage.getAsync(aggregateRootType, aggregateRootId)
        }
        return future.thenApply { aggregateRoot: T? ->
            if (aggregateRoot == null) {
                throw AggregateRootNotFoundException(aggregateRootId, aggregateRootType)
            }
            trackingAggregateRootDict[aggregateRoot.uniqueId] = aggregateRoot
            repository.refreshAggregate(aggregateRoot)
            aggregateRoot
        }
    }

    override fun  getAsync(id: Any, aggregateRootType: Class): CompletableFuture {
        return getAsync(id, true, aggregateRootType)
    }

    override fun  get(id: Any, firstFromCache: Boolean, aggregateRootType: Class): T {
        return getAsync(id, firstFromCache, aggregateRootType).join()
    }

    override fun  get(id: Any, aggregateRootType: Class): T {
        return getAsync(id, aggregateRootType).join()
    }

    override val trackedAggregateRoots: List
        get() = ArrayList(trackingAggregateRootDict.values)

    override fun clear() {
        trackingAggregateRootDict.clear()
        result = ""
    }

    init {
        trackingAggregateRootDict = ConcurrentHashMap()
        this.repository = repository
        this.aggregateRootStorage = aggregateRootStorage
        this.sendReplyService = sendReplyService
        this.queueMessage = queueMessage
        this.commandMessage = commandMessage
        this.messageContext = messageContext
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy