/** * 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.queries.QueryFactory; import com.eventsourcing.utils.CloseableWrappingIterator; import com.google.common.collect.Iterators; import com.google.common.util.concurrent.Service; import com.googlecode.cqengine.index.support.CloseableIterator; import com.googlecode.cqengine.query.option.QueryOptions; import lombok.SneakyThrows; import java.util.*; import java.util.function.Consumer; import java.util.stream.Stream; import static com.eventsourcing.queries.QueryFactory.noQueryOptions; /** * Journal is the storage of all events and commands registered * through Eventsourcing. */ public interface Journal extends Service { Listener DEFAULT_LISTENER = new Listener() {}; default void onCommandsAdded(Set<Class<? extends Command>> commands) {} default void onEventsAdded(Set<Class<? extends Event>> events) {} /** * Set repository. Should be done before invoking {@link #startAsync()} * * @param repository */ void setRepository(Repository repository); /** * Get repository * @return */ Repository getRepository(); /** * Retrieves a command or event by UUID * * @param uuid * @param <T> * @return Empty {@link Optional} if neither a command nor an event are found by <code>uuid</code> */ <T extends Entity> Optional<T> get(UUID uuid); /** * Iterate over commands of a specific type (through {@code EntityHandler<T>}) * * @param klass * @param <T> * @return iterator */ default <T extends Command<?, ?>> CloseableIterator<EntityHandle<T>> commandIterator(Class<T> klass) { return commandIterator(klass, noQueryOptions()); } /** * Iterate over events of a specific type (through {@code EntityHandler<T>}) * * @param klass * @param <T> * @return iterator */ default <T extends Event> CloseableIterator<EntityHandle<T>> eventIterator(Class<T> klass) { return eventIterator(klass, noQueryOptions()); } /** * Iterate over commands of a specific type (through {@code EntityHandler<T>}) * * @param klass * @param <T> * @return iterator */ <T extends Command<?, ?>> CloseableIterator<EntityHandle<T>> commandIterator(Class<T> klass, QueryOptions queryOptions); /** * Iterate over events of a specific type (through {@code EntityHandler<T>}) * * @param klass * @param <T> * @return iterator */ <T extends Event> CloseableIterator<EntityHandle<T>> eventIterator(Class<T> klass, QueryOptions queryOptions); /** * Removes everything from the journal. * <p> * <b>Use with caution</b>: the data will be lost irrevocably */ void clear(); /** * Returns the count of entities of specified type * * @param klass * @param <T> * @return */ <T extends Entity> long size(Class<T> klass); /** * Returns true if there are no entities of specified type stored * * @param klass * @param <T> * @return */ <T extends Entity> boolean isEmpty(Class<T> klass); /** * Record command within a transaction * @param tx * @param command * @param <S> * @param <T> * @return */ <S, T> Command<S, T> journal(Transaction tx, Command<S, T> command); /** * Record event within a transaction * @param tx * @param event * @return */ Event journal(Transaction tx, Event event); /** * Starts a transaction * @return */ Transaction beginTransaction(); /** * An interface abstracting journal's transaction */ interface Transaction { void commit(); void rollback(); } /** * Journal-stored "system" properties */ interface Properties { Optional<HybridTimestamp> getRepositoryTimestamp(); void setRepositoryTimestamp(HybridTimestamp timestamp); } /** * @return journal {@link Properties} object */ Properties getProperties(); }