All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.otto.synapse.journal.Journal Maven / Gradle / Ivy

Go to download

A library used at otto.de to implement Spring Boot based event-sourcing microservices.

There is a newer version: 0.33.1
Show newest version
package de.otto.synapse.journal;

import com.google.common.collect.ImmutableList;
import de.otto.synapse.message.Key;
import de.otto.synapse.messagestore.Index;
import de.otto.synapse.messagestore.MessageStore;
import de.otto.synapse.messagestore.MessageStoreEntry;
import de.otto.synapse.state.StateRepository;

import java.util.stream.Stream;

/**
 * A Journal contains all the messages that where leading to the current state of a single event-sourced entity
 * stored in a {@link StateRepository} or in some other kind of storage.
 *
 * 

Messages can come from different channels. The Journal will keep track not only of the messages for a single * entity, but also from the originating channel for every message.

* *

The messages of a {@code Journal} will be stored in a {@link MessageStore}. The store must have a * {@link Index#JOURNAL_KEY journal-key index}, so the {@code Journal} is able to return the {@code Stream} * of messages (more precisely {@link MessageStoreEntry}) for every entity stored in the {code StateRepository} * when calling {@link #getJournalFor(String)}.

* *

In order to identify the messages for an entity, {@link #journalKeyOf(String)} must return the key of * the associated messages for a given {@code entityId}, which is the key of the stored entities: the key that * would be used, for example, to {@link StateRepository#get(String) get} the entity from the StateRepository.

* *

A number of default implementations of the {@code Journal} interface can be created using the {@code Journal} * helper {@link Journals}.

* *

Implementation hints:

* *

If you intend to write your own {@code Journal}, you need to make sure, that messages will be added * to the {@link Journal#getMessageStore() journal's MessageStore}, for example by registering * {@link JournalingInterceptor} for every message-log receiver that has to be journaled. The journal's * {@code MessageStore} must have a {@link Index#JOURNAL_KEY}.

* *

In most cases, the journal-key index will be calculated by just using the message's {@link Key#partitionKey()} * as journal key. This is the case, if the {@code partitionKey} is used as primary key of your journaled entities.

* * @see EIP: Message Store */ public interface Journal { /** * The name of the journal. * *

In most cases, this will be equal to the name of the journaled {@link StateRepository}

* * @return journal name */ String getName(); /** * The List of channels that take influence on this Journal. * *

For every channel, a {@link JournalingInterceptor} is auto-configured, if the {@code Journal} is registered * as a Spring Bean. The interceptors will take care of {@link MessageStore#add(MessageStoreEntry) adding} incoming * messages to the {@link #getMessageStore() journal's MessageStore}.

* * @return list of channel names */ ImmutableList getJournaledChannels(); /** * Returns the {@code MessageStore} used to store the messages of the journaled entities. * *

The store must be indexed for {@link Index#JOURNAL_KEY}. For every given entity, the journal-key * must match the key returned by {@link #journalKeyOf(String)}

* * @return MessageStore */ MessageStore getMessageStore(); /** * Calculates the journal key for a given entityId. * *

The returned key will be used to fetch the messages for the entity.

* *

The default implementation will simply return the {@code entityId}, assuming that the message's * {@link Key#partitionKey()} will be used as a primary key for stored entites.

* * @param entityId the key used to get the entity from a {@link StateRepository} or other entity store. * @return key used to identify the messages for the entity */ default String journalKeyOf(final String entityId) { return entityId; } /** * Returns the {@code MessageStoreEntries} containing all messages that where modifying the state of the * entity identified by {@code entityId}. * *

The default implementation assumes, that all stored messages can be found by calling * {@code getMessageStore().stream(Index.JOURNAL_KEY, journalKeyOf(entityId));}.

* * @param entityId the key of the entity. In most cases, this will be the partitionKey of the message. * @return stream of MessageStoreEntry that have influenced the entity, ordered from oldest to youngest * messages. */ default Stream getJournalFor(final String entityId) { return getMessageStore() .stream(Index.JOURNAL_KEY, journalKeyOf(entityId)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy