# Redis Support
## Redis Support
Spring Integration 2.1 introduced support for [Redis](https://redis.io/): “an open source advanced key-value store”.
This support comes in the form of a Redis-based `MessageStore` as well as publish-subscribe messaging adapters that are supported by Redis through its [`PUBLISH`, `SUBSCRIBE`, and `UNSUBSCRIBE`](https://redis.io/topics/pubsub) commands.
You need to include this dependency into your project:
Maven
```
org.springframework.integrationspring-integration-redis5.5.9
```
Gradle
```
compile "org.springframework.integration:spring-integration-redis:5.5.9"
```
You also need to include Redis client dependency, e.g. Lettuce.
To download, install, and run Redis, see the [Redis documentation](https://redis.io/download).
### Connecting to Redis
To begin interacting with Redis, you first need to connect to it.
Spring Integration uses support provided by another Spring project, [Spring Data Redis](https://github.com/SpringSource/spring-data-redis), which provides typical Spring constructs: `ConnectionFactory` and `Template`.
Those abstractions simplify integration with several Redis client Java APIs.
Currently Spring Data Redis supports [Jedis](https://github.com/xetorthio/jedis) and [Lettuce](https://lettuce.io/).
#### Using `RedisConnectionFactory`
To connect to Redis, you can use one of the implementations of the `RedisConnectionFactory` interface.
The following listing shows the interface definition:
```
public interface RedisConnectionFactory extends PersistenceExceptionTranslator {
/**
* Provides a suitable connection for interacting with Redis.
* @return connection for interacting with Redis.
*/
RedisConnection getConnection();
}
```
The following example shows how to create a `LettuceConnectionFactory` in Java:
```
LettuceConnectionFactory cf = new LettuceConnectionFactory();
cf.afterPropertiesSet();
```
The following example shows how to create a `LettuceConnectionFactory` in Spring’s XML configuration:
```
```
The implementations of `RedisConnectionFactory` provide a set of properties, such as port and host, that you can set if needed.
Once you have an instance of `RedisConnectionFactory`, you can create an instance of `RedisTemplate` and inject it with the `RedisConnectionFactory`.
#### Using `RedisTemplate`
As with other template classes in Spring (such as `JdbcTemplate` and `JmsTemplate`) `RedisTemplate` is a helper class that simplifies Redis data access code.
For more information about `RedisTemplate` and its variations (such as `StringRedisTemplate`) see the [Spring Data Redis documentation](https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/).
The following example shows how to create an instance of `RedisTemplate` in Java:
```
RedisTemplate rt = new RedisTemplate();
rt.setConnectionFactory(redisConnectionFactory);
```
The following example shows how to create an instance of `RedisTemplate` in Spring’s XML configuration:
```
```
### Messaging with Redis
As mentioned in [the introduction](#redis), Redis provides support for publish-subscribe messaging through its `PUBLISH`, `SUBSCRIBE`, and `UNSUBSCRIBE` commands.
As with JMS and AMQP, Spring Integration provides message channels and adapters for sending and receiving messages through Redis.
#### Redis Publish/Subscribe channel
Similarly to JMS, there are cases where both the producer and consumer are intended to be part of the same application, running within the same process.
You can accomplished this by using a pair of inbound and outbound channel adapters.
However, as with Spring Integration’s JMS support, there is a simpler way to address this use case.
You can create a publish-subscribe channel, as the following example shows:
```
```
A `publish-subscribe-channel` behaves much like a normal `` element from the main Spring Integration namespace.
It can be referenced by both the `input-channel` and the `output-channel` attributes of any endpoint.
The difference is that this channel is backed by a Redis topic name: a `String` value specified by the `topic-name` attribute.
However, unlike JMS, this topic does not have to be created in advance or even auto-created by Redis.
In Redis, topics are simple `String` values that play the role of an address.
The producer and consumer can communicate by using the same `String` value as their topic name.
A simple subscription to this channel means that asynchronous publish-subscribe messaging is possible between the producing and consuming endpoints.
However, unlike the asynchronous message channels created by adding a `` element within a simple Spring Integration `` element, the messages are not stored in an in-memory queue.
Instead, those messages are passed through Redis, which lets you rely on its support for persistence and clustering as well as its interoperability with other non-Java platforms.
#### Redis Inbound Channel Adapter
The Redis inbound channel adapter (`RedisInboundChannelAdapter`) adapts incoming Redis messages into Spring messages in the same way as other inbound adapters.
It receives platform-specific messages (Redis in this case) and converts them to Spring messages by using a `MessageConverter` strategy.
The following example shows how to configure a Redis inbound channel adapter:
```
```
The preceding example shows a simple but complete configuration of a Redis inbound channel adapter.
Note that the preceding configuration relies on the familiar Spring paradigm of auto-discovering certain beans.
In this case, the `redisConnectionFactory` is implicitly injected into the adapter.
You can specify it explicitly by using the `connection-factory` attribute instead.
Also, note that the preceding configuration injects the adapter with a custom `MessageConverter`.
The approach is similar to JMS, where `MessageConverter` instances are used to convert between Redis messages and the Spring Integration message payloads.
The default is a `SimpleMessageConverter`.
Inbound adapters can subscribe to multiple topic names, hence the comma-separated set of values in the `topics` attribute.
Since version 3.0, the inbound adapter, in addition to the existing `topics` attribute, now has the `topic-patterns` attribute.
This attribute contains a comma-separated set of Redis topic patterns.
For more information regarding Redis publish-subscribe, see [Redis Pub/Sub](https://redis.io/topics/pubsub).
Inbound adapters can use a `RedisSerializer` to deserialize the body of Redis messages.
The `serializer` attribute of the `` can be set to an empty string, which results in a `null` value for the `RedisSerializer` property.
In this case, the raw `byte[]` bodies of Redis messages are provided as the message payloads.
Since version 5.0, you can provide an `Executor` instance to the inbound adapter by using the `task-executor` attribute of the ``.
Also, the received Spring Integration messages now have the `RedisHeaders.MESSAGE_SOURCE` header to indicate the source of the published message: topic or pattern.
You can use this downstream for routing logic.
#### Redis Outbound Channel Adapter
The Redis outbound channel adapter adapts outgoing Spring Integration messages into Redis messages in the same way as other outbound adapters.
It receives Spring Integration messages and converts them to platform-specific messages (Redis in this case) by using a `MessageConverter` strategy.
The following example shows how to configure a Redis outbound channel adapter:
```
```
The configuration parallels the Redis inbound channel adapter.
The adapter is implicitly injected with a `RedisConnectionFactory`, which is defined with `redisConnectionFactory` as its bean name.
This example also includes the optional (and custom) `MessageConverter` (the `testConverter` bean).
Since Spring Integration 3.0, the `` offers an alternative to the `topic` attribute: You can use the `topic-expression` attribute to determine the Redis topic for the message at runtime.
These attributes are mutually exclusive.
#### Redis Queue Inbound Channel Adapter
Spring Integration 3.0 introduced a queue inbound channel adapter to “pop” messages from a Redis list.
By default, it uses “right pop”, but you can configure it to use “left pop” instead.
The adapter is message-driven.
It uses an internal listener thread and does not use a poller.
The following listing shows all the available attributes for `queue-inbound-channel-adapter`:
```
(13)
```
|**1** | The component bean name. If you do not provide the `channel` attribute, a `DirectChannel` is created and registered in the application context with this `id` attribute as the bean name. In this case, the endpoint itself is registered with the bean name `id` plus `.adapter`. (If the bean name were `thing1`, the endpoint is registered as `thing1.adapter`.) |
|------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|**2** | The `MessageChannel` to which to send `Message` instances from this Endpoint. |
|**3** | A `SmartLifecycle` attribute to specify whether this endpoint should start automatically after the application context start or not. It defaults to `true`. |
|**4** | A `SmartLifecycle` attribute to specify the phase in which this endpoint is started. It defaults to `0`. |
|**5** | A reference to a `RedisConnectionFactory` bean. It defaults to `redisConnectionFactory`. |
|**6** | The name of the Redis list on which the queue-based 'pop' operation is performed to get Redis messages. |
|**7** | The `MessageChannel` to which to send `ErrorMessage` instances when exceptions are received from the listening task of the endpoint. By default, the underlying `MessagePublishingErrorHandler` uses the default `errorChannel` from the application context. |
|**8** | The `RedisSerializer` bean reference. It can be an empty string, which means 'no serializer'. In this case, the raw `byte[]` from the inbound Redis message is sent to the `channel` as the `Message` payload. By default it is a `JdkSerializationRedisSerializer`. |
|**9** | The timeout in milliseconds for 'pop' operation to wait for a Redis message from the queue. The default is 1 second. |
|**10**| The time in milliseconds for which the listener task should sleep after exceptions on the 'pop' operation, before restarting the listener task. |
|**11**| Specifies whether this endpoint expects data from the Redis queue to contain entire `Message` instances. If this attribute is set to `true`, the `serializer` cannot be an empty string, because messages require some form of deserialization (JDK serialization by default). Its default is `false`. |
|**12**| A reference to a Spring `TaskExecutor` (or standard JDK 1.5+ `Executor`) bean. It is used for the underlying listening task. It defaults to a `SimpleAsyncTaskExecutor`. |
|**13**|Specifies whether this endpoint should use “right pop” (when `true`) or “left pop” (when `false`) to read messages from the Redis list. If `true`, the Redis List acts as a `FIFO` queue when used with a default Redis queue outbound channel adapter. Set it to `false` to use with software that writes to the list with “right push” or to achieve a stack-like message order. Its default is `true`. Since version 4.3.|
| |The `task-executor` has to be configured with more than one thread for processing; otherwise there is a possible deadlock when the `RedisQueueMessageDrivenEndpoint` tries to restart the listener task after an error. The `errorChannel` can be used to process those errors, to avoid restarts, but it preferable to not expose your application to the possible deadlock situation. See Spring Framework [Reference Manual](https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling-task-executor-types) for possible `TaskExecutor` implementations.|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### Redis Queue Outbound Channel Adapter
Spring Integration 3.0 introduced a queue outbound channel adapter to “push” to a Redis list from Spring Integration messages.
By default, it uses “left push”, but you can configure it to use “right push” instead.
The following listing shows all the available attributes for a Redis `queue-outbound-channel-adapter`:
```
(8)
```
|**1**| The component bean name. If you do not provide the `channel` attribute, a `DirectChannel` is created and registered in the application context with this `id` attribute as the bean name. In this case, the endpoint is registered with a bean name of `id` plus `.adapter`. (If the bean name were `thing1`, the endpoint is registered as `thing1.adapter`.) |
|-----|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|**2**| The `MessageChannel` from which this endpoint receives `Message` instances. |
|**3**| A reference to a `RedisConnectionFactory` bean. It defaults to `redisConnectionFactory`. |
|**4**| The name of the Redis list on which the queue-based 'push' operation is performed to send Redis messages. This attribute is mutually exclusive with `queue-expression`. |
|**5**| A SpEL `Expression` to determine the name of the Redis list. It uses the incoming `Message` at runtime as the `#root` variable. This attribute is mutually exclusive with `queue`. |
|**6**| A `RedisSerializer` bean reference. It defaults to a `JdkSerializationRedisSerializer`. However, for `String` payloads, a `StringRedisSerializer` is used, if a `serializer` reference is not provided. |
|**7**| Specifies whether this endpoint should send only the payload or the entire `Message` to the Redis queue. It defaults to `true`. |
|**8**|Specifies whether this endpoint should use “left push” (when `true`) or “right push” (when `false`) to write messages to the Redis list. If `true`, the Redis list acts as a `FIFO` queue when used with a default Redis queue inbound channel adapter. Set it to `false` to use with software that reads from the list with “left pop” or to achieve a stack-like message order. It defaults to `true`. Since version 4.3.|
#### Redis Application Events
Since Spring Integration 3.0, the Redis module provides an implementation of `IntegrationEvent`, which, in turn, is a `org.springframework.context.ApplicationEvent`.
The `RedisExceptionEvent` encapsulates exceptions from Redis operations (with the endpoint being the “source” of the event).
For example, the `` emits those events after catching exceptions from the `BoundListOperations.rightPop` operation.
The exception may be any generic `org.springframework.data.redis.RedisSystemException` or a `org.springframework.data.redis.RedisConnectionFailureException`.
Handling these events with an `` can be useful to determine problems with background Redis tasks and to take administrative actions.
### Redis Message Store
As described in the *Enterprise Integration Patterns* (EIP) book, a [message store](https://www.enterpriseintegrationpatterns.com/MessageStore.html) lets you persist messages.
This can be useful when dealing with components that have a capability to buffer messages (aggregator, resequencer, and others) when reliability is a concern.
In Spring Integration, the `MessageStore` strategy also provides the foundation for the [claim check](https://www.enterpriseintegrationpatterns.com/StoreInLibrary.html) pattern, which is described in EIP as well.
Spring Integration’s Redis module provides the `RedisMessageStore`.
The following example shows how to use it with a aggregator:
```
```
The preceding example is a bean configuration, and it expects a `RedisConnectionFactory` as a constructor argument.
By default, the `RedisMessageStore` uses Java serialization to serialize the message.
However, if you want to use a different serialization technique (such as JSON), you can provide your own serializer by setting the `valueSerializer` property of the `RedisMessageStore`.
Starting with version 4.3.10, the Framework provides Jackson serializer and deserializer implementations for `Message` instances and `MessageHeaders` instances — `MessageJacksonDeserializer` and `MessageHeadersJacksonSerializer`, respectively.
They have to be configured with the `SimpleModule` options for the `ObjectMapper`.
In addition, you should set `enableDefaultTyping` on the `ObjectMapper` to add type information for each serialized complex object (if you trust the source).
That type information is then used during deserialization.
The framework provides a utility method called `JacksonJsonUtils.messagingAwareMapper()`, which is already supplied with all the previously mentioned properties and serializers.
This utility method comes with the `trustedPackages` argument to limit Java packages for deserialization to avoid security vulnerabilities.
The default trusted packages: `java.util`, `java.lang`, `org.springframework.messaging.support`, `org.springframework.integration.support`, `org.springframework.integration.message`, `org.springframework.integration.store`.
To manage JSON serialization in the `RedisMessageStore`, you must configure it in a fashion similar to the following example:
```
RedisMessageStore store = new RedisMessageStore(redisConnectionFactory);
ObjectMapper mapper = JacksonJsonUtils.messagingAwareMapper();
RedisSerializer