diff --git a/spring-data-keyvalue-parent/pom.xml b/spring-data-keyvalue-parent/pom.xml
index f4de10948..e0b82b8d7 100644
--- a/spring-data-keyvalue-parent/pom.xml
+++ b/spring-data-keyvalue-parent/pom.xml
@@ -16,7 +16,7 @@
4.8.1
1.2.15
1.6.1
- 1.8.4
+ 1.8.5
1.5.8
0.5-groovy-1.7-SNAPSHOT
3.0.5.RELEASE
diff --git a/src/docbkx/reference/introduction.xml b/src/docbkx/reference/introduction.xml
index 7ef643d5a..1bba3527a 100644
--- a/src/docbkx/reference/introduction.xml
+++ b/src/docbkx/reference/introduction.xml
@@ -5,5 +5,6 @@
offered by Spring Data Key Value.
introduces the Redis module feature set.
+ introduces the Riak module feature set.
\ No newline at end of file
diff --git a/src/docbkx/reference/redis-messaging.xml b/src/docbkx/reference/redis-messaging.xml
new file mode 100644
index 000000000..bd0fd44a7
--- /dev/null
+++ b/src/docbkx/reference/redis-messaging.xml
@@ -0,0 +1,182 @@
+
+
+
+
+ Introduction
+
+ Spring Data provides dedicated messaging integration for Redis,
+ very similar in functionality and naming to the JMS integration in
+ Spring Framework; in fact, users familiar with the JMS support in Spring, should
+ feel right at home.
+
+ Redis messaging can be roughly divided into two areas of functionality, namely
+ the production or publication and consumption or subscription of messages, hence the shortcut
+ pubsub (Publish/Subscribe). The
+ RedisTemplate class is used for message production.
+ For asynchronous reception similar to
+ Java EE's message-driven bean style, Spring Data provides a dedicated message
+ listener containers that is used to create Message-Driven POJOs
+ (MDPs) and for synchronous reception, the RedisConnection contract.
+
+ The package org.springframework.data.keyvalue.redis.connection and
+ org.springframework.data.keyvalue.redis.listener provide
+ the core functionality for using Redis messaging.
+
+
+
+ Sending/Publishing messages
+
+ To publish a message, one can use, as with the other operations, either the low-level
+ RedisConnection or the high-level RedisTemplate.
+ Both entities offer the publish method that accepts as argument the message
+ that needs to be sent as well as the destination channel. While RedisConnection
+ requires raw-data (array of bytes), the RedisTemplate allow arbitrary objects to be passed
+ in as messages:
+
+
+
+
+
+ Receiving/Subscribing for messages
+
+ On the receiving side, one can subscribe to one or multiple channels either by naming them directly or by using
+ pattern matching. The latter approach is quite useful as it not only allows multiple subscriptions to be created with
+ one command but to also listen on channels not yet created at subscription time (as long as match the pattern).
+
+
+ At the low-level, RedisConnection offers subscribe and
+ pSubscribe methods that map the Redis commands for subscribing by channel respectively by pattern.
+ Note that multiple channels or patterns can be used as arguments. To change the subscription of a connection or simply query
+ whether it is listening or not, RedisConnection
+ provides getSubscription and isSubscribed method.
+
+ Subscribing commands are synchronized and thus blocking. That is, calling subscribe on a connection will cause
+ the current thread to block as it will start waiting for messages - the thread will be released only if the subscription
+ is canceled, that is an additional thread invokes unsubscribe respectively pUnsubscribe
+ on the same connection.
+
+ As mentioned above, one subscribed a connection starts waiting for messages - no other commands can be invoked on it except
+ for adding new subscriptions or modifying/canceling the existing ones, that is invoking anything else then subscribe,
+ pSubscribe, unsubscribe, pUnsubscribe or is illegal and will
+ through an exception.
+
+ In order to subscribe for messages, one needs to implement the MessageListener callback: each time
+ a new message arrives, the callback gets invoked and the user code executed through onMessage method.
+ The interface gives access not only to the actual message but to the channel it has been received through and the pattern (if any) used
+ by the subscription to match the channel. This information allows the callee to differentiate between various messages not just by content but
+ also through data.
+
+
+
+ Message Listener Containers
+
+ Due to its blocking nature, low-level subscription is not attractive as it requires connection and thread management for every single
+ listener. To alleviate this problem, Spring Data offers RedisListenerContainer which does all the heavy lifting
+ on behalf of the user - users familiar with EJB and JMS should find the concepts familiar as it is designed as close as possible to the
+ support in Spring Framework and its message-driven POJOs (MDPs)
+
+ RedisListenerContainer acts as a message listener container; it is used to receive messages from a
+ Redis channel and drive the MessageListener that are injected into
+ it. The listener container is responsible for all threading of message
+ reception and dispatches into the listener for processing. A message
+ listener container is the intermediary between an MDP and a messaging
+ provider, and takes care of registering to receive messages, resource acquisition and release,
+ exception conversion and suchlike. This allows you as an application
+ developer to write the (possibly complex) business logic associated with
+ receiving a message (and reacting to it), and delegates
+ boilerplate Redis infrastructure concerns to the framework.
+
+
+ Further more, to minimize the application footprint, RedisListenerContainer performs allows one connection and one thread
+ to be shared by multiple listeners even though they do not share a subscription. Thus no matter how many listeners or channels an application tracks,
+ the runtime cost will remain the same through out its lifetime. Moreover, the container allows runtime configuration changes so one can add or remove
+ listeners while an application is running without the need for restart. Additionally, the container uses a lazy subscription approach, using a
+ RedisConnection only when needed - if all the listeners are unsubscribed, cleanup is automatically performed and the used
+ thread released.
+
+ To help with the asynch manner of messages, the container requires a java.util.concurrent.Executor (
+ or Spring's TaskExecutor) for dispatching the messages. Depending on the load, the number of listeners or the runtime
+ environment, one should change or tweak the executor to better serve her needs - in particular in managed environments (such as app servers), it is
+ highly recommended to pick a a proper TaskExecutor to take advantage of its runtime.
+
+
+
+ The MessageListenerAdapter
+
+ The MessageListenerAdapter class is the
+ final component in Spring's asynchronous messaging support: in a
+ nutshell, it allows you to expose almost any class
+ as a MDP (there are of course some constraints).
+
+ Consider the following interface definition. Notice that although
+ the interface extends the
+ MessageListener interface,
+ it can still be used as a MDP via the use of the
+ MessageListenerAdapter class. Notice also how the
+ various message handling methods are strongly typed according to the
+ contents of the various
+ Message types that they can receive and
+ handle.
+
+ public interface MessageDelegate {
+
+ void handleMessage(String message);
+
+ void handleMessage(Map message);
+
+ void handleMessage(byte[] message);
+
+ void handleMessage(Serializable message);
+}
+
+ public class DefaultMessageDelegate implements MessageDelegate {
+ // implementation elided for clarity...
+}
+
+ In particular, note how the above implementation of the
+ MessageDelegate interface (the above
+ DefaultMessageDelegate class) has
+ no Redis dependencies at all. It truly is a POJO that
+ we will make into an MDP via the following configuration.
+
+ <!-- this is the Message Driven POJO (MDP) -->
+<bean id="messageListener" class="org.springframework.data.keyvalue.redis.listener.adapter.MessageListenerAdapter">
+ <constructor-arg>
+ <bean class="redisexample.DefaultMessageDelegate"/>
+ </constructor-arg>
+</bean>
+
+<!-- and this is the message listener container... -->
+<bean id="redisContainer" class="org.springframework.data.keyvalue.redis.listener.RedisMessageListenerContainer">
+ <property name="connectionFactory" ref="connectionFactory"/>
+ <property name="messageListeners">
+ <!-- map of listeners and their associated topics (channels or topics) -->
+ <map>
+ <entry key-ref="messageListener">
+ <bean class="org.springframework.data.keyvalue.redis.listener.ChannelTopic">
+ <constructor-arg value="chatroom">
+ </bean>
+ </entry>
+ </map>
+ </property>
+</bean>
+
+ Each time a message is received, the adapter automatically performs
+ translation (using the configured RedisSerializer)
+ between the low-level format and the required object type transparently. Any exception caused by the method invocation
+ is caught and handled by the container (by default, being logged).
+
+
+
+
+
\ No newline at end of file