package com.spring.akka.eventsourcing.persistance.eventsourcing; import java.util.Map; import java.util.concurrent.CompletionStage; import java.util.function.BiConsumer; import java.util.function.BiFunction; import com.spring.akka.eventsourcing.persistance.AsyncResult; import com.spring.akka.eventsourcing.persistance.eventsourcing.actions.Persist; import lombok.Builder; import lombok.Data; import lombok.Singular; /** * @param <C> root command class type * @param <E> root event class * @param <S> root state class * <p> * builder class for the execution flow of the aggregate entity */ @Builder @Data public class ExecutionFlow<C, E, S> { private S state; @Singular("onCommand") private Map<Class<? extends C>, TriFunction<C, FlowContext, S, Persist<E>>> onCommand; @Singular("asyncOnCommand") private Map<Class<? extends C>, TriFunction<C, FlowContext, S, CompletionStage<AsyncResult<E>>>> asyncOnCommand; @Singular("onEvent") private Map<Class<? extends E>, BiFunction<E, S, S>> onEvent; public static class ExecutionFlowBuilder<C, E, S> { /* * Register a read-only command handler for a given command class. A read-only command * handler does not persist events (i.e. it does not change state) but it may perform side * effects, such as replying to the request. Replies are sent with the `reply` method of the * context that is passed to the command handler function. */ public ExecutionFlowBuilder<C, E, S> onReadOnlyCommand(Class<? extends C> command, BiConsumer<C, ReadOnlyFlowContext> handler) { onCommand(command, (cmd, flowContext, state) -> { handler.accept(cmd, flowContext); return flowContext.done(); }); return this; } } }