diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/adapter/ListenerExecutionFailedException.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/adapter/ListenerExecutionFailedException.java
new file mode 100644
index 000000000..cb47028bf
--- /dev/null
+++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/adapter/ListenerExecutionFailedException.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.keyvalue.redis.listener.adapter;
+
+import org.springframework.dao.InvalidDataAccessApiUsageException;
+
+/**
+ * Exception thrown when the execution of a listener method failed.
+ *
+ * @author Costin Leau
+ * @see MessageListenerAdapter
+ */
+public class ListenerExecutionFailedException extends InvalidDataAccessApiUsageException {
+
+ /**
+ * Constructs a new ListenerExecutionFailedException instance.
+ *
+ * @param msg
+ * @param cause
+ */
+ public ListenerExecutionFailedException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ /**
+ * Constructs a new ListenerExecutionFailedException instance.
+ *
+ * @param msg
+ */
+ public ListenerExecutionFailedException(String msg) {
+ super(msg);
+ }
+}
diff --git a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/adapter/MessageListenerAdapter.java b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/adapter/MessageListenerAdapter.java
index 4763a33f4..ba3dfe171 100644
--- a/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/adapter/MessageListenerAdapter.java
+++ b/spring-data-redis/src/main/java/org/springframework/data/keyvalue/redis/listener/adapter/MessageListenerAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 the original author or authors.
+ * Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,12 +15,17 @@
*/
package org.springframework.data.keyvalue.redis.listener.adapter;
+import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.keyvalue.redis.connection.Message;
import org.springframework.data.keyvalue.redis.connection.MessageListener;
+import org.springframework.data.keyvalue.redis.serializer.JdkSerializationRedisSerializer;
+import org.springframework.data.keyvalue.redis.serializer.RedisSerializer;
import org.springframework.util.Assert;
import org.springframework.util.MethodInvoker;
import org.springframework.util.ObjectUtils;
@@ -34,87 +39,33 @@ import org.springframework.util.ObjectUtils;
*
By default, the content of incoming JMS messages gets extracted before + *
By default, the content of incoming Redis messages gets extracted before
* being passed into the target listener method, to let the target method
* operate on message content types such as String or byte array instead of
* the raw {@link Message}. Message type conversion is delegated to a Spring
- * JMS {@link MessageConverter}. By default, a {@link SimpleMessageConverter}
+ * Data {@link RedisSerializer}. By default, the {@link JdkSerializationRedisSerializer}
* will be used. (If you do not want such automatic message conversion taking
- * place, then be sure to set the {@link #setMessageConverter MessageConverter}
+ * place, then be sure to set the {@link #setSerializer Serializer}
* to null.)
*
- *
If a target listener method returns a non-null object (typically of a
- * message content type such as String or byte array), it will get
- * wrapped in a JMS Message and sent to the response destination
- * (either the JMS "reply-to" destination or a
- * {@link #setDefaultResponseDestination(javax.jms.Destination) specified default
- * destination}).
- *
- *
Note: The sending of response messages is only available when - * using the {@link SessionAwareMessageListener} entry point (typically through a - * Spring message listener container). Usage as standard JMS {@link MessageListener} - * does not support the generation of response messages. - * *
Find below some examples of method signatures compliant with this
* adapter class. This first example handles all Message types
* and gets passed the contents of each Message type as an
- * argument. No Message will be sent back as all of these
- * methods return void.
+ * argument.
*
*
public interface MessageContentsDelegate {
* void handleMessage(String text);
- * void handleMessage(Map map);
* void handleMessage(byte[] bytes);
- * void handleMessage(Serializable obj);
+ * void handleMessage(Person obj);
* }
*
- * This next example handles all Message types and gets
- * passed the actual (raw) Message as an argument. Again, no
- * Message will be sent back as all of these methods return
- * void.
- *
- * public interface RawMessageDelegate {
- * void handleMessage(TextMessage message);
- * void handleMessage(MapMessage message);
- * void handleMessage(BytesMessage message);
- * void handleMessage(ObjectMessage message);
- * }
- *
- * This next example illustrates a Message delegate
- * that just consumes the String contents of
- * {@link javax.jms.TextMessage TextMessages}. Notice also how the
- * name of the Message handling method is different from the
- * {@link #ORIGINAL_DEFAULT_LISTENER_METHOD original} (this will have to
- * be configured in the attandant bean definition). Again, no Message
- * will be sent back as the method returns void.
- *
- * public interface TextMessageContentDelegate {
- * void onMessage(String text);
- * }
- *
- * This final example illustrates a Message delegate
- * that just consumes the String contents of
- * {@link javax.jms.TextMessage TextMessages}. Notice how the return type
- * of this method is String: This will result in the configured
- * {@link MessageListenerAdapter} sending a {@link javax.jms.TextMessage} in response.
- *
- * public interface ResponsiveTextMessageContentDelegate {
- * String handleMessage(String text);
- * }
- *
- * For further examples and discussion please do refer to the Spring
+ * For further examples and discussion please do refer to the Spring Data
* reference documentation which describes this class (and it's attendant
* XML configuration) in detail.
*
* @author Juergen Hoeller
- * @since 2.0
- * @see #setDelegate
- * @see #setDefaultListenerMethod
- * @see #setDefaultResponseDestination
- * @see #setMessageConverter
- * @see org.springframework.jms.support.converter.SimpleMessageConverter
- * @see org.springframework.jms.listener.SessionAwareMessageListener
- * @see org.springframework.jms.listener.AbstractMessageListenerContainer#setMessageListener
+ * @author Costin Leau
+ * @see org.springframework.jms.listener.adapter.MessageListenerAdapter
*/
public class MessageListenerAdapter implements MessageListener {
@@ -131,7 +82,7 @@ public class MessageListenerAdapter implements MessageListener {
private String defaultListenerMethod = ORIGINAL_DEFAULT_LISTENER_METHOD;
- private MessageConverter messageConverter;
+ private RedisSerializer> serializer;
/**
@@ -144,6 +95,7 @@ public class MessageListenerAdapter implements MessageListener {
/**
* Create a new {@link MessageListenerAdapter} for the given delegate.
+ *
* @param delegate the delegate object
*/
public MessageListenerAdapter(Object delegate) {
@@ -158,6 +110,8 @@ public class MessageListenerAdapter implements MessageListener {
* If no explicit delegate object has been specified, listener * methods are expected to present on this adapter instance, that is, * on a custom subclass of this adapter, defining listener methods. + * + * @param delegate delegate object */ public void setDelegate(Object delegate) { Assert.notNull(delegate, "Delegate must not be null"); @@ -165,9 +119,11 @@ public class MessageListenerAdapter implements MessageListener { } /** - * Return the target object to delegate message listening to. + * Returns the target object to delegate message listening to. + * + * @return message listening delegation */ - protected Object getDelegate() { + public Object getDelegate() { return this.delegate; } @@ -189,77 +145,32 @@ public class MessageListenerAdapter implements MessageListener { } /** - * Set the converter that will convert incoming JMS messages to - * listener method arguments, and objects returned from listener - * methods back to JMS messages. - *
The default converter is a {@link SimpleMessageConverter}, which is able - * to handle {@link javax.jms.BytesMessage BytesMessages}, - * {@link javax.jms.TextMessage TextMessages} and - * {@link javax.jms.ObjectMessage ObjectMessages}. + * Set the serializer that will convert incoming raw Redis messages to + * listener method arguments. + *
The default converter is a {@link JdkSerializationRedisSerializer}, which is able + * to handle {@link Serializable} objects. */ - public void setMessageConverter(MessageConverter messageConverter) { - this.messageConverter = messageConverter; + public void setSerializer(RedisSerializer> serializer) { + this.serializer = serializer; } /** - * Return the converter that will convert incoming JMS messages to - * listener method arguments, and objects returned from listener - * methods back to JMS messages. - */ - protected MessageConverter getMessageConverter() { - return this.messageConverter; - } - - - /** - * Standard JMS {@link MessageListener} entry point. + * Standard Redis {@link MessageListener} entry point. *
Delegates the message to the target listener method, with appropriate * conversion of the message argument. In case of an exception, the * {@link #handleListenerException(Throwable)} method will be invoked. - *
Note: Does not support sending response messages based on - * result objects returned from listener methods. Use the - * {@link SessionAwareMessageListener} entry point (typically through a Spring - * message listener container) for handling result objects as well. - * @param message the incoming JMS message + * + * @param message the incoming Redis message * @see #handleListenerException - * @see #onMessage(javax.jms.Message, javax.jms.Session) - */ - public void onMessage(Message message) { - try { - onMessage(message, null); - } catch (Throwable ex) { - handleListenerException(ex); - } - } - - /** - * Spring {@link SessionAwareMessageListener} entry point. - *
Delegates the message to the target listener method, with appropriate
- * conversion of the message argument. If the target method returns a
- * non-null object, wrap in a JMS message and send it back.
- * @param message the incoming JMS message
- * @param session the JMS session to operate on
- * @throws JMSException if thrown by JMS API methods
*/
+ @Override
@SuppressWarnings("unchecked")
- public void onMessage(Message message, Session session) throws JMSException {
+ public void onMessage(Message message, byte[] pattern) {
// Check whether the delegate is a MessageListener impl itself.
// In that case, the adapter will simply act as a pass-through.
- Object delegate = getDelegate();
if (delegate != this) {
- if (delegate instanceof SessionAwareMessageListener) {
- if (session != null) {
- ((SessionAwareMessageListener) delegate).onMessage(message, session);
- return;
- }
- else if (!(delegate instanceof MessageListener)) {
- throw new javax.jms.IllegalStateException("MessageListenerAdapter cannot handle a "
- + "SessionAwareMessageListener delegate if it hasn't been invoked with a Session itself");
- }
- }
if (delegate instanceof MessageListener) {
- ((MessageListener) delegate).onMessage(message);
- return;
+ ((MessageListener) delegate).onMessage(message, pattern);
}
}
@@ -267,40 +178,24 @@ public class MessageListenerAdapter implements MessageListener {
Object convertedMessage = extractMessage(message);
String methodName = getListenerMethodName(message, convertedMessage);
if (methodName == null) {
- throw new javax.jms.IllegalStateException("No default listener method specified: "
+ throw new InvalidDataAccessApiUsageException("No default listener method specified: "
+ "Either specify a non-null value for the 'defaultListenerMethod' property or "
+ "override the 'getListenerMethodName' method.");
}
// Invoke the handler method with appropriate arguments.
Object[] listenerArguments = buildListenerArguments(convertedMessage);
- Object result = invokeListenerMethod(methodName, listenerArguments);
- if (result != null) {
- handleResult(result, message, session);
- }
- else {
- logger.trace("No result object given - no result to handle");
- }
+ invokeListenerMethod(methodName, listenerArguments);
}
- public String getSubscriptionName() {
- Object delegate = getDelegate();
- if (delegate != this && delegate instanceof SubscriptionNameProvider) {
- return ((SubscriptionNameProvider) delegate).getSubscriptionName();
- }
- else {
- return delegate.getClass().getName();
- }
- }
-
-
/**
* Initialize the default implementations for the adapter's strategies.
- * @see #setMessageConverter
- * @see org.springframework.jms.support.converter.SimpleMessageConverter
+ *
+ * @see #setSerializer(RedisSerializer)
+ * @see JdkSerializationRedisSerializer
*/
protected void initDefaultStrategies() {
- setMessageConverter(new SimpleMessageConverter());
+ setSerializer(new JdkSerializationRedisSerializer());
}
/**
@@ -321,12 +216,10 @@ public class MessageListenerAdapter implements MessageListener {
* @param message the JMS Message
* @return the content of the message, to be passed into the
* listener method as argument
- * @throws JMSException if thrown by JMS API methods
*/
- protected Object extractMessage(Message message) throws JMSException {
- MessageConverter converter = getMessageConverter();
- if (converter != null) {
- return converter.fromMessage(message);
+ protected Object extractMessage(Message message) {
+ if (serializer != null) {
+ return serializer.deserialize(message.getPayload());
}
return message;
}
@@ -336,14 +229,13 @@ public class MessageListenerAdapter implements MessageListener {
* handle the given message.
*
The default implementation simply returns the configured
* default listener method, if any.
- * @param originalMessage the JMS request message
- * @param extractedMessage the converted JMS request message,
+ * @param originalMessage the Redis request message
+ * @param extractedMessage the converted Redis request message,
* to be passed into the listener method as argument
* @return the name of the listener method (never null)
- * @throws JMSException if thrown by JMS API methods
* @see #setDefaultListenerMethod
*/
- protected String getListenerMethodName(Message originalMessage, Object extractedMessage) throws JMSException {
+ protected String getListenerMethodName(Message originalMessage, Object extractedMessage) {
return getDefaultListenerMethod();
}
@@ -371,11 +263,10 @@ public class MessageListenerAdapter implements MessageListener {
* @param methodName the name of the listener method
* @param arguments the message arguments to be passed in
* @return the result returned from the listener method
- * @throws JMSException if thrown by JMS API methods
* @see #getListenerMethodName
* @see #buildListenerArguments
*/
- protected Object invokeListenerMethod(String methodName, Object[] arguments) throws JMSException {
+ protected Object invokeListenerMethod(String methodName, Object[] arguments) {
try {
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.setTargetObject(getDelegate());
@@ -385,8 +276,8 @@ public class MessageListenerAdapter implements MessageListener {
return methodInvoker.invoke();
} catch (InvocationTargetException ex) {
Throwable targetEx = ex.getTargetException();
- if (targetEx instanceof JMSException) {
- throw (JMSException) targetEx;
+ if (targetEx instanceof DataAccessException) {
+ throw (DataAccessException) targetEx;
}
else {
throw new ListenerExecutionFailedException("Listener method '" + methodName + "' threw exception",
@@ -397,27 +288,4 @@ public class MessageListenerAdapter implements MessageListener {
+ "' with arguments " + ObjectUtils.nullSafeToString(arguments), ex);
}
}
-
-
- /**
- * Build a JMS message to be sent as response based on the given result object.
- * @param session the JMS Session to operate on
- * @param result the content of the message, as returned from the listener method
- * @return the JMS Message (never null)
- * @throws JMSException if thrown by JMS API methods
- * @see #setMessageConverter
- */
- protected Message buildMessage(Session session, Object result) throws JMSException {
- MessageConverter converter = getMessageConverter();
- if (converter != null) {
- return converter.toMessage(result, session);
- }
- else {
- if (!(result instanceof Message)) {
- throw new MessageConversionException("No MessageConverter specified - cannot handle message [" + result
- + "]");
- }
- return (Message) result;
- }
- }
}
\ No newline at end of file