com.github.rahulsom.grooves.queries.FunctionalVersionedQuery Maven / Gradle / Ivy
package com.github.rahulsom.grooves.queries;
import com.github.rahulsom.grooves.api.AggregateType;
import com.github.rahulsom.grooves.api.EventApplyOutcome;
import com.github.rahulsom.grooves.api.events.BaseEvent;
import com.github.rahulsom.grooves.api.snapshots.VersionedSnapshot;
import com.github.rahulsom.grooves.queries.internal.SimpleExecutor;
import com.github.rahulsom.grooves.queries.internal.SimpleQuery;
import org.jetbrains.annotations.NotNull;
import org.reactivestreams.Publisher;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Util class to build Versioned Queries in a Functional Style.
*
* @param The type of {@link AggregateT}'s id
* @param The aggregate over which the query executes
* @param The type of the {@link EventT}'s id field
* @param The type of the Event
* @param The type of the {@link SnapshotT}'s id field
* @param The type of the Snapshot
* @param A reference to the query type. Typically a self reference.
*
* @author Rahul Somasunderam
*/
public class FunctionalVersionedQuery<
AggregateIdT,
AggregateT extends AggregateType,
EventIdT,
EventT extends BaseEvent,
SnapshotIdT,
SnapshotT extends VersionedSnapshot,
QueryT extends FunctionalVersionedQuery
> implements
VersionedQuerySupport,
SimpleQuery {
private BiFunction> snapshot;
private Supplier emptySnapshot;
private TriFunction> events;
private Predicate applyEvents;
private BiConsumer deprecator;
private TriFunction> exceptionHandler;
private BiFunction> eventHandler;
@NotNull
@Override
public SimpleExecutor getExecutor() {
return new SimpleExecutor();
}
@NotNull
@Override
public Publisher getSnapshot(long version, @NotNull AggregateT aggregate) {
return snapshot.apply(version, aggregate);
}
@NotNull
@Override
public SnapshotT createEmptySnapshot() {
return emptySnapshot.get();
}
@Override
public Publisher getUncomputedEvents(
AggregateT aggregate, SnapshotT lastSnapshot, long version) {
return events.apply(aggregate, lastSnapshot, version);
}
@Override
public boolean shouldEventsBeApplied(@NotNull SnapshotT snapshot) {
return applyEvents.test(snapshot);
}
@Override
public void addToDeprecates(
@NotNull SnapshotT snapshot, @NotNull AggregateT deprecatedAggregate) {
deprecator.accept(snapshot, deprecatedAggregate);
}
@NotNull
@Override
public Publisher onException(
@NotNull Exception e, @NotNull SnapshotT snapshot, @NotNull EventT event) {
return exceptionHandler.apply(e, snapshot, event);
}
@Override
public Publisher applyEvent(EventT event, SnapshotT snapshot) {
return eventHandler.apply(event, snapshot);
}
/**
* Builder for {@link FunctionalVersionedQuery}.
*
* @param The type of {@link AggregateT}'s id
* @param The aggregate over which the query executes
* @param The type of the {@link EventT}'s id field
* @param The type of the Event
* @param The type of the {@link SnapshotT}'s id field
* @param The type of the Snapshot
* @param A reference to the query type. Typically a self reference.
*/
public static final class Builder<
AggregateIdT,
AggregateT extends AggregateType,
EventIdT,
EventT extends BaseEvent,
SnapshotIdT,
SnapshotT extends VersionedSnapshot,
QueryT extends FunctionalVersionedQuery
> {
private BiFunction> snapshot;
private Supplier emptySnapshot;
private TriFunction> events;
private Predicate applyEvents = snapshotT -> true;
private BiConsumer deprecator;
private TriFunction> exceptionHandler;
private BiFunction> eventHandler;
private Builder() {
}
public static <
AggregateIdT,
AggregateT extends AggregateType,
EventIdT,
EventT extends BaseEvent,
SnapshotIdT,
SnapshotT extends VersionedSnapshot,
QueryT extends FunctionalVersionedQuery
> Builder newBuilder() {
return new Builder<>();
}
public Builder withSnapshot(BiFunction> snapshot) {
this.snapshot = snapshot;
return this;
}
public Builder withEmptySnapshot(Supplier emptySnapshot) {
this.emptySnapshot = emptySnapshot;
return this;
}
public Builder withEvents(TriFunction> events) {
this.events = events;
return this;
}
public Builder withApplyEvents(Predicate applyEvents) {
this.applyEvents = applyEvents;
return this;
}
public Builder withDeprecator(BiConsumer deprecator) {
this.deprecator = deprecator;
return this;
}
public Builder withExceptionHandler(
TriFunction> exceptionHandler) {
this.exceptionHandler = exceptionHandler;
return this;
}
public Builder withEventHandler(
BiFunction> eventHandler) {
this.eventHandler = eventHandler;
return this;
}
/**
* Builds the Functional Versioned Query.
*/
public VersionedQuery build() {
FunctionalVersionedQuery functionalVersionedQuery =
new FunctionalVersionedQuery<>();
functionalVersionedQuery.deprecator = this.deprecator;
functionalVersionedQuery.events = this.events;
functionalVersionedQuery.exceptionHandler = this.exceptionHandler;
functionalVersionedQuery.applyEvents = this.applyEvents;
functionalVersionedQuery.snapshot = this.snapshot;
functionalVersionedQuery.emptySnapshot = this.emptySnapshot;
functionalVersionedQuery.eventHandler = this.eventHandler;
return functionalVersionedQuery;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy