/** * Returns a set of identifiers of sagas that may have changed in the context of the given {@code unitOfWork} and * have not been saved yet. * * @param unitOfWork the unit of work to inspect for unsaved sagas * @return set of saga identifiers of unsaved sagas */ protected Set<String> unsavedSagaResource(UnitOfWork<?> unitOfWork) { return unitOfWork.getOrComputeResource(unsavedSagasResourceKey, i -> new HashSet<>()); }
/** * Returns the map of aggregates currently managed by this repository under the given unit of work. Note that the * repository keeps the managed aggregates in the root unit of work, to guarantee each Unit of Work works with the * state left by the parent unit of work. * <p> * The returns map is mutable and reflects any changes made during processing. * * @param uow The unit of work to find the managed aggregates for * @return a map with the aggregates managed by this repository in the given unit of work */ protected Map<String, A> managedAggregates(UnitOfWork<?> uow) { return uow.root().getOrComputeResource(aggregatesKey, s -> new HashMap<>()); }
/** * Initialize conflict resolution in the context of the current Unit of Work dealing with a command on an event * sourced aggregate. * * @param conflictResolver conflict resolver able to detect conflicts */ public static void initialize(ConflictResolver conflictResolver) { Assert.state(CurrentUnitOfWork.isStarted(), () -> "An active Unit of Work is required for conflict resolution"); CurrentUnitOfWork.get().getOrComputeResource(CONFLICT_RESOLUTION_KEY, key -> conflictResolver); }
/** * Either runs the provided {@link Runnable} immediately or adds it to a {@link List} as a resource to the current * {@link UnitOfWork} if {@link SimpleQueryUpdateEmitter#inStartedPhaseOfUnitOfWork} returns {@code true}. This is * done to * ensure any emitter calls made from a message handling function are executed in the * {@link UnitOfWork.Phase#AFTER_COMMIT} phase. * <p> * The latter check requires the current UnitOfWork's phase to be {@link UnitOfWork.Phase#STARTED}. This is done * to allow users to circumvent their {@code queryUpdateTask} being handled in the AFTER_COMMIT phase. They can do * this by retrieving the current UnitOfWork and performing any of the {@link QueryUpdateEmitter} calls in a * different phase. * * @param queryUpdateTask a {@link Runnable} to be ran immediately or as a resource if {@link * SimpleQueryUpdateEmitter#inStartedPhaseOfUnitOfWork} returns {@code true} */ private void runOnAfterCommitOrNow(Runnable queryUpdateTask) { if (inStartedPhaseOfUnitOfWork()) { UnitOfWork<?> unitOfWork = CurrentUnitOfWork.get(); unitOfWork.getOrComputeResource( this.toString() + QUERY_UPDATE_TASKS_RESOURCE_KEY, resourceKey -> { List<Runnable> queryUpdateTasks = new ArrayList<>(); unitOfWork.afterCommit(uow -> queryUpdateTasks.forEach(Runnable::run)); return queryUpdateTasks; } ).add(queryUpdateTask); } else { queryUpdateTask.run(); } }
@Override public void handle(List<? extends EventMessage<?>> events, Consumer<List<? extends EventMessage<?>>> processor) { if (CurrentUnitOfWork.isStarted()) { UnitOfWork<?> unitOfWorkRoot = CurrentUnitOfWork.get().root(); unitOfWorkRoot.getOrComputeResource(scheduledEventsKey, key -> { List<EventMessage<?>> allEvents = new ArrayList<>(); unitOfWorkRoot.afterCommit(uow -> schedule(allEvents, processor)); return allEvents; }).addAll(events); } else { schedule(events, processor); } }
private List<EventMessage<?>> eventsQueue(UnitOfWork<?> unitOfWork) { return unitOfWork.getOrComputeResource(eventsKey, r -> {
@Override protected void appendEvents(List<? extends EventMessage<?>> events, Serializer serializer) { AppendEventTransaction sender; if (CurrentUnitOfWork.isStarted()) { sender = CurrentUnitOfWork.get().root().getOrComputeResource(APPEND_EVENT_TRANSACTION, k -> { AppendEventTransaction appendEventTransaction = eventStoreClient.createAppendEventConnection(); CurrentUnitOfWork.get().root().onRollback( u -> appendEventTransaction.rollback(u.getExecutionResult().getExceptionResult()) ); CurrentUnitOfWork.get().root().onCommit(u -> commit(appendEventTransaction)); return appendEventTransaction; }); } else { sender = eventStoreClient.createAppendEventConnection(); } for (EventMessage<?> eventMessage : events) { sender.append(map(eventMessage, serializer)); } if (!CurrentUnitOfWork.isStarted()) { commit(sender); } }
/** * Returns a set of identifiers of sagas that may have changed in the context of the given {@code unitOfWork} and * have not been saved yet. * * @param unitOfWork the unit of work to inspect for unsaved sagas * @return set of saga identifiers of unsaved sagas */ protected Set<String> unsavedSagaResource(UnitOfWork<?> unitOfWork) { return unitOfWork.getOrComputeResource(unsavedSagasResourceKey, i -> new HashSet<>()); }
/** * Returns a set of identifiers of sagas that may have changed in the context of the given {@code unitOfWork} and * have not been saved yet. * * @param unitOfWork the unit of work to inspect for unsaved sagas * @return set of saga identifiers of unsaved sagas */ protected Set<String> unsavedSagaResource(UnitOfWork<?> unitOfWork) { return unitOfWork.getOrComputeResource(unsavedSagasResourceKey, i -> new HashSet<>()); }
/** * Returns the map of aggregates currently managed by this repository under the given unit of work. Note that the * repository keeps the managed aggregates in the root unit of work, to guarantee each Unit of Work works with the * state left by the parent unit of work. * <p> * The returns map is mutable and reflects any changes made during processing. * * @param uow The unit of work to find the managed aggregates for * @return a map with the aggregates managed by this repository in the given unit of work */ protected Map<String, A> managedAggregates(UnitOfWork<?> uow) { return uow.root().getOrComputeResource(aggregatesKey, s -> new HashMap<>()); }
/** * Returns the map of aggregates currently managed by this repository under the given unit of work. Note that the * repository keeps the managed aggregates in the root unit of work, to guarantee each Unit of Work works with the * state left by the parent unit of work. * <p> * The returns map is mutable and reflects any changes made during processing. * * @param uow The unit of work to find the managed aggregates for * @return a map with the aggregates managed by this repository in the given unit of work */ protected Map<String, A> managedAggregates(UnitOfWork<?> uow) { return uow.root().getOrComputeResource(aggregatesKey, s -> new HashMap<>()); }
/** * Either runs the provided {@link Runnable} immediately or adds it to a {@link List} as a resource to the current * {@link UnitOfWork} if {@link SimpleQueryBus#inStartedPhaseOfUnitOfWork} returns {@code true}. This is done to * ensure any emitter calls made from a message handling function are executed in the * {@link UnitOfWork.Phase#AFTER_COMMIT} phase. * <p> * The latter check requires the current UnitOfWork's phase to be {@link UnitOfWork.Phase#STARTED}. This is done * to allow users to circumvent their {@code queryUpdateTask} being handled in the AFTER_COMMIT phase. They can do * this by retrieving the current UnitOfWork and performing any of the {@link QueryUpdateEmitter} calls in a * different phase. * * @param queryUpdateTask a {@link Runnable} to be ran immediately or as a resource if {@link * SimpleQueryBus#inStartedPhaseOfUnitOfWork} returns {@code true} */ private void runOnAfterCommitOrNow(Runnable queryUpdateTask) { if (inStartedPhaseOfUnitOfWork()) { UnitOfWork<?> unitOfWork = CurrentUnitOfWork.get(); unitOfWork.getOrComputeResource( this.toString() + QUERY_UPDATE_TASKS_RESOURCE_KEY, resourceKey -> { List<Runnable> queryUpdateTasks = new ArrayList<>(); unitOfWork.afterCommit(uow -> queryUpdateTasks.forEach(Runnable::run)); return queryUpdateTasks; } ).add(queryUpdateTask); } else { queryUpdateTask.run(); } }
/** * Initialize conflict resolution in the context of the current Unit of Work dealing with a command on an event * sourced aggregate. * * @param conflictResolver conflict resolver able to detect conflicts */ public static void initialize(ConflictResolver conflictResolver) { Assert.state(CurrentUnitOfWork.isStarted(), () -> "An active Unit of Work is required for conflict resolution"); CurrentUnitOfWork.get().getOrComputeResource(CONFLICT_RESOLUTION_KEY, key -> conflictResolver); }
/** * Either runs the provided {@link Runnable} immediately or adds it to a {@link List} as a resource to the current * {@link UnitOfWork} if {@link SimpleQueryUpdateEmitter#inStartedPhaseOfUnitOfWork} returns {@code true}. This is * done to * ensure any emitter calls made from a message handling function are executed in the * {@link UnitOfWork.Phase#AFTER_COMMIT} phase. * <p> * The latter check requires the current UnitOfWork's phase to be {@link UnitOfWork.Phase#STARTED}. This is done * to allow users to circumvent their {@code queryUpdateTask} being handled in the AFTER_COMMIT phase. They can do * this by retrieving the current UnitOfWork and performing any of the {@link QueryUpdateEmitter} calls in a * different phase. * * @param queryUpdateTask a {@link Runnable} to be ran immediately or as a resource if {@link * SimpleQueryUpdateEmitter#inStartedPhaseOfUnitOfWork} returns {@code true} */ private void runOnAfterCommitOrNow(Runnable queryUpdateTask) { if (inStartedPhaseOfUnitOfWork()) { UnitOfWork<?> unitOfWork = CurrentUnitOfWork.get(); unitOfWork.getOrComputeResource( this.toString() + QUERY_UPDATE_TASKS_RESOURCE_KEY, resourceKey -> { List<Runnable> queryUpdateTasks = new ArrayList<>(); unitOfWork.afterCommit(uow -> queryUpdateTasks.forEach(Runnable::run)); return queryUpdateTasks; } ).add(queryUpdateTask); } else { queryUpdateTask.run(); } }
/** * Initialize conflict resolution in the context of the current Unit of Work dealing with a command on an event * sourced aggregate. * * @param conflictResolver conflict resolver able to detect conflicts */ public static void initialize(ConflictResolver conflictResolver) { Assert.state(CurrentUnitOfWork.isStarted(), () -> "An active Unit of Work is required for conflict resolution"); CurrentUnitOfWork.get().getOrComputeResource(CONFLICT_RESOLUTION_KEY, key -> conflictResolver); }
@Override public void handle(List<? extends EventMessage<?>> events, Consumer<List<? extends EventMessage<?>>> processor) { if (CurrentUnitOfWork.isStarted()) { UnitOfWork<?> unitOfWorkRoot = CurrentUnitOfWork.get().root(); unitOfWorkRoot.getOrComputeResource(scheduledEventsKey, key -> { List<EventMessage<?>> allEvents = new ArrayList<>(); unitOfWorkRoot.afterCommit(uow -> schedule(allEvents, processor)); return allEvents; }).addAll(events); } else { schedule(events, processor); } }
@Override public void handle(List<? extends EventMessage<?>> events, Consumer<List<? extends EventMessage<?>>> processor) { if (CurrentUnitOfWork.isStarted()) { UnitOfWork<?> unitOfWorkRoot = CurrentUnitOfWork.get().root(); unitOfWorkRoot.getOrComputeResource(scheduledEventsKey, key -> { List<EventMessage<?>> allEvents = new ArrayList<>(); unitOfWorkRoot.afterCommit(uow -> schedule(allEvents, processor)); return allEvents; }).addAll(events); } else { schedule(events, processor); } }
private List<EventMessage<?>> eventsQueue(UnitOfWork<?> unitOfWork) { return unitOfWork.getOrComputeResource(eventsKey, r -> {
private List<EventMessage<?>> eventsQueue(UnitOfWork<?> unitOfWork) { return unitOfWork.getOrComputeResource(eventsKey, r -> {
@Override protected void appendEvents(List<? extends EventMessage<?>> events, Serializer serializer) { AppendEventTransaction sender; if (CurrentUnitOfWork.isStarted()) { sender = CurrentUnitOfWork.get().root().getOrComputeResource(APPEND_EVENT_TRANSACTION, k -> { AppendEventTransaction appendEventTransaction = eventStoreClient.createAppendEventConnection(); CurrentUnitOfWork.get().root().onRollback( u -> appendEventTransaction.rollback(u.getExecutionResult().getExceptionResult()) ); CurrentUnitOfWork.get().root().onCommit(u -> commit(appendEventTransaction)); return appendEventTransaction; }); } else { sender = eventStoreClient.createAppendEventConnection(); } for (EventMessage<?> eventMessage : events) { sender.append(map(eventMessage, serializer)); } if (!CurrentUnitOfWork.isStarted()) { commit(sender); } }