@Override public Object resolveParameterValue(Message message) { if (!CurrentUnitOfWork.isStarted()) { return null; } return CurrentUnitOfWork.get(); }
/** * Check if the Unit of Work is the 'currently' active Unit of Work returned by {@link CurrentUnitOfWork#get()}. * * @return {@code true} if the Unit of Work is the currently active Unit of Work */ default boolean isCurrent() { return CurrentUnitOfWork.isStarted() && CurrentUnitOfWork.get() == this; }
/** * Commits the current UnitOfWork. If no UnitOfWork was started, an {@link IllegalStateException} is thrown. * * @throws IllegalStateException if no UnitOfWork is currently started. * @see UnitOfWork#commit() */ public static void commit() { get().commit(); }
@Override public Aggregate<T> newInstance(Callable<T> factoryMethod) throws Exception { CurrentUnitOfWork.get().onRollback(u -> this.rolledBack = true); aggregate = delegate.newInstance(factoryMethod); return aggregate; }
/** * Initializes current unit of work with interceptor chain. * * @param interceptorChain the interceptor chain */ public static void initialize(InterceptorChain interceptorChain) { Assert.state(CurrentUnitOfWork.isStarted(), () -> "An active Unit of Work is required for injecting interceptor chain"); CurrentUnitOfWork.get().resources().put(INTERCEPTOR_CHAIN_EMITTER_KEY, interceptorChain); }
@Override public Aggregate<T> load(String aggregateIdentifier, Long expectedVersion) { CurrentUnitOfWork.get().onRollback(u -> this.rolledBack = true); aggregate = delegate.load(aggregateIdentifier, expectedVersion); validateIdentifier(aggregateIdentifier, aggregate); return aggregate; }
/** * Return {@code true} if the {@link CurrentUnitOfWork#isStarted()} returns {@code true} and in if the phase is * {@link UnitOfWork.Phase#STARTED}, otherwise {@code false}. * * @return {@code true} if the {@link CurrentUnitOfWork#isStarted()} returns {@code true} and in if the phase is * {@link UnitOfWork.Phase#STARTED}, otherwise {@code false}. */ private boolean inStartedPhaseOfUnitOfWork() { return CurrentUnitOfWork.isStarted() && UnitOfWork.Phase.STARTED.equals(CurrentUnitOfWork.get().phase()); }
/** * 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 Aggregate<T> load(String aggregateIdentifier) { CurrentUnitOfWork.get().onRollback(u -> this.rolledBack = true); aggregate = delegate.load(aggregateIdentifier, null); validateIdentifier(aggregateIdentifier, aggregate); return aggregate; }
@Override public void storeToken(TrackingToken token, String processorName, int segment) { if (CurrentUnitOfWork.isStarted()) { CurrentUnitOfWork.get().afterCommit(uow -> tokens.put(new ProcessAndSegment(processorName, segment), getOrDefault(token, NULL_TOKEN))); } else { tokens.put(new ProcessAndSegment(processorName, segment), getOrDefault(token, NULL_TOKEN)); } }
@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 protected void validateOnLoad(Aggregate<T> aggregate, Long expectedVersion) { CurrentUnitOfWork.get().onRollback(u -> cache.remove(aggregate.identifierAsString())); super.validateOnLoad(aggregate, expectedVersion); }
private void lockSagaAccess(String sagaIdentifier) { UnitOfWork<?> unitOfWork = CurrentUnitOfWork.get(); Lock lock = lockFactory.obtainLock(sagaIdentifier); unitOfWork.root().onCleanup(u -> lock.release()); }
@Override public void eventHandled(EventMessage<?> msg) { if (++counter >= threshold && msg instanceof DomainEventMessage) { if (CurrentUnitOfWork.isStarted()) { CurrentUnitOfWork.get().onPrepareCommit( u -> scheduleSnapshot((DomainEventMessage) msg)); } else { scheduleSnapshot((DomainEventMessage) msg); } counter = 0; } }
@Override public Aggregate<T> load(String aggregateIdentifier, Long expectedVersion) { ((CommandHandlingEntry) CurrentUnitOfWork.get()).registerAggregateIdentifier(aggregateIdentifier); Aggregate<T> aggregate = load(aggregateIdentifier); if (expectedVersion != null && aggregate.version() > expectedVersion) { throw new ConflictingAggregateVersionException(aggregateIdentifier, expectedVersion, aggregate.version()); } return aggregate; }
@After public void tearDown() { scheduledThreadPool.shutdownNow(); while (CurrentUnitOfWork.isStarted()) { CurrentUnitOfWork.get().rollback(); } }
@Override protected EventSourcedAggregate<T> doCreateNewForLock(Callable<T> factoryMethod) throws Exception { EventSourcedAggregate<T> aggregate = super.doCreateNewForLock(factoryMethod); CurrentUnitOfWork.get().onRollback(u -> cache.remove(aggregate.identifierAsString())); cache.put(aggregate.identifierAsString(), new AggregateCacheEntry<>(aggregate)); return aggregate; }
@Override protected void validateOnLoad(Aggregate<T> aggregate, Long expectedVersion) { if (expectedVersion != null && expectedVersion < aggregate.version()) { DefaultConflictResolver conflictResolver = new DefaultConflictResolver(eventStore, aggregate.identifierAsString(), expectedVersion, aggregate.version()); ConflictResolution.initialize(conflictResolver); CurrentUnitOfWork.get().onPrepareCommit(uow -> conflictResolver.ensureConflictsResolved()); } else { super.validateOnLoad(aggregate, expectedVersion); } }
@After public void tearDown() { eventProcessor.shutDown(); while (CurrentUnitOfWork.isStarted()) { CurrentUnitOfWork.get().rollback(); } }
@Override protected void storeEvents(EventMessage<?>... events) { UnitOfWork<?> unitOfWork = CurrentUnitOfWork.get(); Transaction transaction = transactionManager.startTransaction(); unitOfWork.onCommit(u -> transaction.commit()); unitOfWork.onRollback(u -> transaction.rollback()); super.storeEvents(events); } }