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

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