Class PostgresqlEventStorageEngine

java.lang.Object
io.axoniq.framework.postgresql.PostgresqlEventStorageEngine
All Implemented Interfaces:
DescribableComponent, EventStorageEngine, SnapshotStore

public final class PostgresqlEventStorageEngine extends Object implements EventStorageEngine, SnapshotStore
A EventStorageEngine and SnapshotStore implementation backed by PostgreSQL, providing reliable event persistence and streaming with support for tagging.
Since:
5.0.0
Author:
John Hendrikx
  • Constructor Details

    • PostgresqlEventStorageEngine

      public PostgresqlEventStorageEngine(DataSource dataSource, EventConverter converter)
      Constructs a new instance.
      Parameters:
      dataSource - a data source to connect to PostgreSQL, cannot be null
      converter - an event converter for converting the payload to bytes, cannot be null
  • Method Details

    • store

      public CompletableFuture<Void> store(QualifiedName qualifiedName, Object identifier, Snapshot snapshot)
      Description copied from interface: SnapshotStore
      Persists a snapshot under the given name and identifier. This replaces any previous snapshot(s) with the same name and identifier.

      This method is asynchronous and returns a CompletableFuture that completes when the snapshot has been durably stored.

      Specified by:
      store in interface SnapshotStore
      Parameters:
      qualifiedName - the name of the snapshot to persist, cannot be null
      identifier - the identifier of the snapshot to persist, cannot be null
      snapshot - the snapshot to persist, cannot be null
      Returns:
      a CompletableFuture that completes when the snapshot has been stored
    • load

      public CompletableFuture<@Nullable Snapshot> load(QualifiedName qualifiedName, Object identifier)
      Description copied from interface: SnapshotStore
      Loads the latest snapshot for a given name and identifier.

      The returned snapshot may have an older or newer version relative to what is expected. The caller is responsible for handling version compatibility or ignoring unusable snapshots.

      This method is asynchronous and returns a CompletableFuture that completes with the snapshot if one exists, or null if no snapshot is available.

      Specified by:
      load in interface SnapshotStore
      Parameters:
      qualifiedName - the name of the snapshot, cannot be null
      identifier - the identifier of the snapshot, cannot be null
      Returns:
      a CompletableFuture containing the snapshot, or containing null if no matching snapshot exists
    • describeTo

      public void describeTo(ComponentDescriptor descriptor)
      Description copied from interface: DescribableComponent
      Describe the properties of this DescribableComponent with the given descriptor.

      Components should call the appropriate describeProperty methods on the descriptor to register their properties. The descriptor is responsible for determining how these properties are formatted and structured in the final output.

      Best Practices: As a general rule, all relevant fields of a DescribableComponent implementation should be described in this method. However, developers have discretion to include only the fields that make sense in the context. Not every field may be meaningful for description purposes, especially internal implementation details. Furthermore, components might want to expose different information based on their current state. The final decision on what properties to include lies with the person implementing the describeTo method, who should focus on providing information that is useful for understanding the component's configuration and state.

      Example implementation:

       public void describeTo(ComponentDescriptor descriptor) {
           descriptor.describeProperty("name", this.name);
           descriptor.describeProperty("enabled", this.enabled);
           descriptor.describeProperty("configuration", this.configuration); // A nested component
           descriptor.describeProperty("handlers", this.eventHandlers);      // A collection
       }
       
      Specified by:
      describeTo in interface DescribableComponent
      Parameters:
      descriptor - The component descriptor to describe this DescribableComponentn its properties in.
    • appendEvents

      Description copied from interface: EventStorageEngine
      Appends a List of events to the underlying storage solution.

      Events will be appended in the order that they are offered in, validating the given condition before being stored. Note that all events should have a unique event identifier. Tags paired with the events will be stored as well.

      Implementations may be able to detect conflicts during the append stage. In such case, the returned completable future will complete exceptionally, indicating such conflict. Other implementations may delay such checks until the EventStorageEngine.AppendTransaction.commit() is called.

      Called during the PREPARE_COMMIT phase.

      Specified by:
      appendEvents in interface EventStorageEngine
      Parameters:
      condition - The condition describing the transactional requirements for the append transaction
      context - The current ProcessingContext, if any.
      events - The List of events to append to the underlying storage solution.
      Returns:
      A transaction instance that can be committed or rolled back.
    • source

      public MessageStream<EventMessage> source(SourcingCondition condition)
      Description copied from interface: EventStorageEngine
      Creates a finite MessageStream of events matching the given condition.

      The final entry of the stream always contains a ConsistencyMarker in the MessageStream.Entry's resources, paired with a TerminalEventMessage. This ConsistencyMarker should be used to construct the AppendCondition when appending events.

      The condition dictates the sequence to load based on the EventsCondition.criteria(). Additionally, an optional SourcingCondition.strategy() may be provided.

      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.

      Specified by:
      source in interface EventStorageEngine
      Parameters:
      condition - The SourcingCondition dictating the stream of events to source.
      Returns:
      A finite MessageStream of events matching the given condition.
    • stream

      public MessageStream<EventMessage> stream(StreamingCondition condition)
      Description copied from interface: EventStorageEngine
      Creates an infinite MessageStream of events matching the given condition.

      The condition may dictate the StreamingCondition.position() to start streaming from, as well as define filter criteria for the returned MessageStream.

      Specified by:
      stream in interface EventStorageEngine
      Parameters:
      condition - The StreamingCondition dictating the StreamingCondition.position() to start streaming from, as well as the filter criteria used for the returned MessageStream.
      Returns:
      An infinite MessageStream of events matching the given condition.
    • firstToken

      public CompletableFuture<TrackingToken> firstToken()
      Description copied from interface: EventStorageEngine
      Creates a TrackingToken that is at the first position of an event stream.

      In other words, a token that tracks events from the beginning of time.

      Specified by:
      firstToken in interface EventStorageEngine
      Returns:
      A CompletableFuture of a TrackingToken at the first position of an event stream.
    • latestToken

      public CompletableFuture<TrackingToken> latestToken()
      Description copied from interface: EventStorageEngine
      Creates a TrackingToken that is at the latest position of an event stream.

      In other words, a token that tracks all new events from this point forward.

      Specified by:
      latestToken in interface EventStorageEngine
      Returns:
      A CompletableFuture of a TrackingToken at the latest position of an event stream.
    • tokenAt

      public CompletableFuture<TrackingToken> tokenAt(Instant at)
      Description copied from interface: EventStorageEngine
      Creates a TrackingToken that tracks all events after the given at.

      If there is an event exactly at the given at, it will be tracked too.

      Specified by:
      tokenAt in interface EventStorageEngine
      Parameters:
      at - The Instant determining how the TrackingToken should be created. A tracking token should point to very first event before this Instant.
      Returns:
      A CompletableFuture of a TrackingToken at the given at, if there aren't events matching this criteria null is returned