/* * Copyright (c) 2010-2016. Axon Framework * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.axonframework.eventsourcing.eventstore; import org.axonframework.eventhandling.EventMessage; import org.axonframework.eventhandling.TrackedEventMessage; import org.axonframework.eventsourcing.DomainEventMessage; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import static java.util.Arrays.asList; /** * Provides a mechanism to append as well as retrieve events from an underlying storage like a database. An event * storage engine can also be used to store and fetch aggregate snapshot events. * * @author Rene de Waele */ public interface EventStorageEngine { /** * Append one or more events to the event storage. Events will be appended in the order that they are offered in. * <p> * Note that all events should have a unique event identifier. When storing {@link DomainEventMessage domain events} * events should also have a unique combination of aggregate id and sequence number. * <p> * By default this method creates a list of the offered events and then invokes {@link #appendEvents(List)}. * * @param events Events to append to the event storage */ default void appendEvents(EventMessage<?>... events) { appendEvents(asList(events)); } /** * Append a list of events to the event storage. Events will be appended in the order that they are offered in. * <p> * Note that all events should have a unique event identifier. When storing {@link DomainEventMessage domain events} * events should also have a unique combination of aggregate id and sequence number. * * @param events Events to append to the event storage */ void appendEvents(List<? extends EventMessage<?>> events); /** * Store an event that contains a snapshot of an aggregate. If the event storage already contains a snapshot for the * same aggregate, then it will be replaced with the given snapshot. * * @param snapshot The snapshot event of the aggregate that is to be stored */ void storeSnapshot(DomainEventMessage<?> snapshot); /** * Open an event stream containing all events stored since given tracking token. The returned stream is comprised of * events from aggregates as well as other application events. Pass a {@code trackingToken} of {@code null} to open * a stream containing all available events. * <p> * If the value of the given {@code mayBlock} is {@code true} the returned stream is allowed to block while waiting * for new event messages if the end of the stream is reached. * * @param trackingToken Object describing the global index of the last processed event or {@code null} to create a * stream of all events in the store * @param mayBlock If {@code true} the storage engine may optionally choose to block to wait for new event * messages if the end of the stream is reached. * @return A stream containing all tracked event messages stored since the given tracking token */ Stream<? extends TrackedEventMessage<?>> readEvents(TrackingToken trackingToken, boolean mayBlock); /** * Get a {@link DomainEventStream} containing all events published by the aggregate with given {@code * aggregateIdentifier}. By default calling this method is shorthand for an invocation of * {@link #readEvents(String, long)} with a sequence number of 0. * <p> * The returned stream is finite, i.e. it should not block to wait for further events if the end of the event stream * of the aggregate is reached. * * @param aggregateIdentifier The identifier of the aggregate to return an event stream for * @return A non-blocking DomainEventStream of the given aggregate */ default DomainEventStream readEvents(String aggregateIdentifier) { return readEvents(aggregateIdentifier, 0L); } /** * Get a {@link DomainEventStream} containing all events published by the aggregate with given {@code * aggregateIdentifier} starting with the first event having a sequence number that is equal or larger than the * given {@code firstSequenceNumber}. * <p> * The returned stream is finite, i.e. it should not block to wait for further * events if the end of the event stream of the aggregate is reached. * * @param aggregateIdentifier The identifier of the aggregate * @param firstSequenceNumber The expected sequence number of the first event in the returned stream * @return A non-blocking DomainEventStream of the given aggregate */ DomainEventStream readEvents(String aggregateIdentifier, long firstSequenceNumber); /** * Try to load a snapshot event of the aggregate with given {@code aggregateIdentifier}. If the storage engine has * no snapshot event of the aggregate, an empty Optional is returned. * * @param aggregateIdentifier The identifier of the aggregate * @return An optional with a snapshot of the aggregate */ Optional<DomainEventMessage<?>> readSnapshot(String aggregateIdentifier); }