com.opencredo.concourse.domain.state.EventSourcingStateRepository Maven / Gradle / Ivy
package com.opencredo.concourse.domain.state;
import com.opencredo.concourse.domain.events.Event;
import com.opencredo.concourse.domain.events.binding.EventTypeBinding;
import com.opencredo.concourse.domain.events.sourcing.CachedEventSource;
import com.opencredo.concourse.domain.events.sourcing.EventReplayer;
import com.opencredo.concourse.domain.events.sourcing.EventSource;
import com.opencredo.concourse.domain.time.TimeRange;
import java.time.Instant;
import java.util.AbstractMap.SimpleEntry;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public final class EventSourcingStateRepository implements StateRepository {
public static EventSourcingStateRepository using(Supplier> stateSupplier, EventSource eventSource, EventTypeBinding typeBinding, Comparator causalOrdering) {
return new EventSourcingStateRepository(stateSupplier, eventSource, typeBinding, causalOrdering);
}
private final Supplier> stateSupplier;
private final EventSource eventSource;
private final EventTypeBinding typeBinding;
private final Comparator causalOrdering;
private EventSourcingStateRepository(Supplier> stateSupplier, EventSource eventSource, EventTypeBinding typeBinding, Comparator causalOrdering) {
this.stateSupplier = stateSupplier;
this.eventSource = eventSource;
this.typeBinding = typeBinding;
this.causalOrdering = causalOrdering;
}
@Override
public Optional getState(UUID aggregateId, Instant upTo) {
return getState(typeBinding.replaying(eventSource, aggregateId, TimeRange.fromUnbounded().toExclusive(upTo)));
}
private Optional getState(EventReplayer eventReplayer) {
StateBuilder state = stateSupplier.get();
eventReplayer.inAscendingOrder(causalOrdering).replayAll(state);
return state.get();
}
@Override
public Map getStates(Collection aggregateIds, Instant upTo) {
final CachedEventSource preloaded = typeBinding.preload(eventSource, aggregateIds, TimeRange.fromUnbounded().toExclusive(upTo));
return aggregateIds.stream().flatMap(id ->
getState(typeBinding.replaying(preloaded, id, TimeRange.unbounded()))
.map(s -> Stream.of(new SimpleEntry<>(id, s))).orElseGet(Stream::empty))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy