de.otto.synapse.messagestore.redis.RedisIndexedMessageStore Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of synapse-redis Show documentation
Show all versions of synapse-redis Show documentation
Support for Redis as a MessageStore.
package de.otto.synapse.messagestore.redis;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import de.otto.synapse.channel.ChannelPosition;
import de.otto.synapse.channel.ShardPosition;
import de.otto.synapse.message.TextMessage;
import de.otto.synapse.messagestore.Index;
import de.otto.synapse.messagestore.Indexer;
import de.otto.synapse.messagestore.MessageStore;
import de.otto.synapse.messagestore.MessageStoreEntry;
import de.otto.synapse.translator.*;
import org.slf4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static de.otto.synapse.channel.ChannelPosition.channelPosition;
import static de.otto.synapse.channel.ShardPosition.fromPosition;
import static de.otto.synapse.message.DefaultHeaderAttr.MSG_ID;
import static java.util.Arrays.asList;
import static java.util.Spliterators.spliteratorUnknownSize;
import static java.util.stream.Collectors.toMap;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Redis-based implementation of a WritableMessageStore.
*
*
* The store can be configured like a ring-buffer to only store the latest N messages.
*
*/
@Beta
public class RedisIndexedMessageStore implements MessageStore {
private static final Logger LOG = getLogger(RedisIndexedMessageStore.class);
private static final int CHARACTERISTICS = Spliterator.ORDERED | Spliterator.NONNULL | Spliterator.IMMUTABLE;
private final String name;
private final Indexer indexer;
private final RedisTemplate redisTemplate;
private final int batchSize;
private final int maxSize;
private final Encoder encoder;
private final Decoder decoder;
private final long maxAge;
/**
* @param name the name of the message store
* @param batchSize the size of the batches used to fetch messages from Redis
* @param maxMessages the maximum number of messages stored in the message store
* @param maxAge maximum number of seconds after that a message will be evicted
* @param indexer the {@code Indexer} used to index entities stored in the message store
* @param stringRedisTemplate the RedisTemplate used to access Redis
*/
public RedisIndexedMessageStore(final String name,
final int batchSize,
final int maxMessages,
final long maxAge,
final Indexer indexer,
final RedisTemplate stringRedisTemplate) {
this(name, batchSize, maxMessages, maxAge, indexer, stringRedisTemplate, new TextEncoder(MessageFormat.V2), new TextDecoder());
}
/**
* @param name the name of the message store
* @param batchSize the size of the batches used to fetch messages from Redis
* @param maxMessages the maximum number of messages stored in the message store
* @param maxAge maximum number of seconds after that a message will be evicted
* @param indexer the {@code Indexer} used to index entities stored in the message store
* @param stringRedisTemplate the RedisTemplate used to access Redis
* @param messageEncoder the encoder used to encode messages into the string-representation stored in Redis
* @param messageDecoder the decoder used to decode messages from the string-representation stored in Redis
*/
public RedisIndexedMessageStore(final String name,
final int batchSize,
final int maxMessages,
final long maxAge,
final Indexer indexer,
final RedisTemplate stringRedisTemplate,
final Encoder messageEncoder,
final Decoder messageDecoder) {
this.name = name;
this.maxAge = maxAge;
this.indexer = indexer;
this.redisTemplate = stringRedisTemplate;
this.batchSize = batchSize;
this.maxSize = maxMessages;
this.encoder = messageEncoder;
this.decoder = messageDecoder;
}
@Override
@SuppressWarnings("unchecked")
public void add(final MessageStoreEntry entry) {
final MessageStoreEntry indexedEntry = indexer.index(entry);
final TextMessage textMessage = indexedEntry.getTextMessage();
final String messageId = messageIdCalculator(textMessage);
// This will contain the results of all ops in the transaction
final List