/** * Copyright (c) 2016, All Contributors (see CONTRIBUTORS file) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.eventsourcing; import com.eventsourcing.hlc.HybridTimestamp; import com.eventsourcing.hlc.PhysicalTimeProvider; import com.eventsourcing.index.IndexEngine; import com.google.common.util.concurrent.Service; import com.googlecode.cqengine.IndexedCollection; import com.googlecode.cqengine.query.Query; import com.googlecode.cqengine.query.QueryFactory; import com.googlecode.cqengine.query.option.QueryOptions; import com.googlecode.cqengine.resultset.ResultSet; import java.util.Set; import java.util.concurrent.CompletableFuture; import static com.googlecode.cqengine.query.QueryFactory.noQueryOptions; /** * Repository is holder of resources necessary to * facilitate Eventsourcing operations. */ public interface Repository extends Service { /** * Gets journal as previously configured. * * @return null if journal was not configured yet. */ Journal getJournal(); /** * Sets journal to be used in this repository * <p> * Should be done before invoking {@link #startAsync()} * * @param journal * @throws IllegalStateException if called after the service is started */ void setJournal(Journal journal) throws IllegalStateException; /** * Gets index engine as previously configured. Useful for querying. * * @return null if index engine was not configured yet. */ IndexEngine getIndexEngine(); /** * Sets index engine to be used in this repository * <p> * Should be done before invoking {@link #startAsync()} * * @param indexEngine * @throws IllegalStateException if called after the service is started */ void setIndexEngine(IndexEngine indexEngine) throws IllegalStateException; /** * Gets physical time provider as previously configured * * @return null if physical time provider was not configured yet. */ PhysicalTimeProvider getPhysicalTimeProvider(); /** * Sets physical time provider * * @param timeProvider */ void setPhysicalTimeProvider(PhysicalTimeProvider timeProvider) throws IllegalStateException; /** * Gets lock provider as previously configured * * @return null if lock provider was not configured yet. */ LockProvider getLockProvider(); /** * Sets lock provider * * @param lockProvider */ void setLockProvider(LockProvider lockProvider) throws IllegalStateException; /** * @return Repository's current timestamp */ HybridTimestamp getTimestamp(); /** * Returns a set of commands discovered or configured * with this repository * * @return */ Set<Class<? extends Command>> getCommands(); /** * Returns a set of events discovered or configured * with this repository * * @return */ Set<Class<? extends Event>> getEvents(); /** * Adds a command set provider. Will fetch a command set upon initialization * * @param provider */ void addCommandSetProvider(CommandSetProvider provider); /** * Removes a command set provider * * @param provider */ void removeCommandSetProvider(CommandSetProvider provider); /** * Adds an event set provider. Will fetch an event set upon initialization * * @param provider */ void addEventSetProvider(EventSetProvider provider); /** * Removes an event set provider * * @param provider */ void removeEventSetProvider(EventSetProvider provider); /** * Adds an entity subscriber * @param subscriber */ void addEntitySubscriber(EntitySubscriber subscriber); /** * Removes an entity subscriber * @param subscriber */ void removeEntitySubscriber(EntitySubscriber subscriber); /** * Publishes command asynchronously * * @param command * @param <T> Command class * @param <C> Result class * @return {@link CompletableFuture} with command's result */ <T extends Command<S, C>, S, C> CompletableFuture<C> publish(T command); /** * Shortcut method for accessing index retrieval (see {@link #query(Class, Query, QueryOptions)} with * {@link QueryFactory#noQueryOptions()} specified as {@link QueryOptions} * * @param klass * @param query * @param <E> * @return */ default <E extends Entity> ResultSet<EntityHandle<E>> query(Class<E> klass, Query<EntityHandle<E>> query) { return query(klass, query, noQueryOptions()); } /** * Shortcut method for accessing index querying. * <p> * <p>Example:</p> * <p> * {@code * repository.query(UserCreated.class, equal(UserCreated.EMAIL, email), noQueryOptions()) * } * * @param klass * @param query * @param queryOptions * @param <E> * @return */ default <E extends Entity> ResultSet<EntityHandle<E>> query(Class<E> klass, Query<EntityHandle<E>> query, QueryOptions queryOptions) { IndexedCollection<EntityHandle<E>> collection = getIndexEngine().getIndexedCollection(klass); queryOptions.put(Iterable.class, collection); queryOptions.put(IndexedCollection.class, collection); return collection.retrieve(query, queryOptions); } }