INT-2737 RedisMessageStore Fix

Fix RedisMessageStore to ensure that it
strips prefix from keys wheh they are returned
via iterator().

INT-2737 polishing

INT-2737 polishing
This commit is contained in:
Oleg Zhurakousky
2012-09-06 12:24:08 -04:00
committed by Gary Russell
parent 5df766b93d
commit 108baedd53
3 changed files with 154 additions and 124 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2007-2011 the original author or authors
* Copyright 2007-2012 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.
@@ -33,7 +33,7 @@ import org.springframework.util.Assert;
/**
* Redis implementation of the key/value style {@link MessageStore} and {@link MessageGroupStore}
*
*
* @author Oleg Zhurakousky
* @since 2.1
*/
@@ -52,7 +52,7 @@ public class RedisMessageStore extends AbstractKeyValueMessageStore {
Assert.notNull(valueSerializer, "'valueSerializer' must not be null");
this.redisTemplate.setValueSerializer(valueSerializer);
}
@Override
protected Object doRetrieve(Object id){
Assert.notNull(id, "'id' must not be null");
@@ -83,7 +83,7 @@ public class RedisMessageStore extends AbstractKeyValueMessageStore {
Object removedObject = this.doRetrieve(id);
if (removedObject != null){
redisTemplate.delete(id);
}
}
return removedObject;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2007-2011 the original author or authors
* Copyright 2007-2012 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,6 +15,12 @@
*/
package org.springframework.integration.redis.store;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -42,12 +48,6 @@ import org.springframework.integration.store.MessageGroup;
import org.springframework.integration.store.SimpleMessageGroup;
import org.springframework.integration.support.MessageBuilder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* @author Oleg Zhurakousky
*
@@ -56,19 +56,19 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
@Test
@RedisAvailable
public void testNonExistingEmptyMessageGroup() throws Exception{
public void testNonExistingEmptyMessageGroup() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
MessageGroup messageGroup = store.getMessageGroup(1);
assertNotNull(messageGroup);
assertTrue(messageGroup instanceof SimpleMessageGroup);
assertEquals(0, messageGroup.size());
}
@Test
@RedisAvailable
public void testMessageGroupUpdatedDateChangesWithEachAddedMessage() throws Exception{
@RedisAvailable
public void testMessageGroupUpdatedDateChangesWithEachAddedMessage() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
@@ -85,17 +85,17 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
createdTimestamp = messageGroup.getTimestamp();
updatedTimestamp = messageGroup.getLastModified();
assertTrue(updatedTimestamp > createdTimestamp);
// make sure the store is properly rebuild from Redis
store = new RedisMessageStore(jcf);
messageGroup = store.getMessageGroup(1);
assertEquals(2, messageGroup.size());
}
@Test
@RedisAvailable
public void testMessageGroupWithAddedMessage() throws Exception{
public void testMessageGroupWithAddedMessage() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
@@ -103,17 +103,17 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
Message<?> message = new GenericMessage<String>("Hello");
messageGroup = store.addMessageToGroup(1, message);
assertEquals(1, messageGroup.size());
// make sure the store is properly rebuild from Redis
store = new RedisMessageStore(jcf);
messageGroup = store.getMessageGroup(1);
assertEquals(1, messageGroup.size());
}
@Test
@RedisAvailable
public void testRemoveMessageGroup() throws Exception{
public void testRemoveMessageGroup() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
@@ -121,26 +121,26 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
Message<?> message = new GenericMessage<String>("Hello");
messageGroup = store.addMessageToGroup(messageGroup.getGroupId(), message);
assertEquals(1, messageGroup.size());
store.removeMessageGroup(1);
MessageGroup messageGroupA = store.getMessageGroup(1);
assertNotSame(messageGroup, messageGroupA);
// assertEquals(0, messageGroupA.getMarked().size());
assertEquals(0, messageGroupA.getMessages().size());
assertEquals(0, messageGroupA.size());
// make sure the store is properly rebuild from Redis
store = new RedisMessageStore(jcf);
messageGroup = store.getMessageGroup(1);
assertEquals(0, messageGroup.getMessages().size());
assertEquals(0, messageGroup.size());
}
@Test
@RedisAvailable
public void testCompleteMessageGroup() throws Exception{
public void testCompleteMessageGroup() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
@@ -151,10 +151,10 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
messageGroup = store.getMessageGroup(1);
assertTrue(messageGroup.isComplete());
}
@Test
@RedisAvailable
public void testLastReleasedSequenceNumber() throws Exception{
public void testLastReleasedSequenceNumber() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
@@ -165,10 +165,10 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
messageGroup = store.getMessageGroup(1);
assertEquals(5, messageGroup.getLastReleasedMessageSequenceNumber());
}
@Test
@RedisAvailable
public void testRemoveMessageFromTheGroup() throws Exception{
public void testRemoveMessageFromTheGroup() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
@@ -178,37 +178,37 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
store.addMessageToGroup(messageGroup.getGroupId(), message);
messageGroup = store.addMessageToGroup(messageGroup.getGroupId(), new GenericMessage<String>("3"));
assertEquals(3, messageGroup.size());
messageGroup = store.removeMessageFromGroup(1, message);
assertEquals(2, messageGroup.size());
// make sure the store is properly rebuild from Redis
store = new RedisMessageStore(jcf);
messageGroup = store.getMessageGroup(1);
assertEquals(2, messageGroup.size());
}
@Test
@RedisAvailable
public void testWithMessageHistory() throws Exception{
public void testWithMessageHistory() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
store.getMessageGroup(1);
Message<?> message = new GenericMessage<String>("Hello");
DirectChannel fooChannel = new DirectChannel();
fooChannel.setBeanName("fooChannel");
DirectChannel barChannel = new DirectChannel();
barChannel.setBeanName("barChannel");
message = MessageHistory.write(message, fooChannel);
message = MessageHistory.write(message, barChannel);
store.addMessageToGroup(1, message);
message = store.getMessageGroup(1).getMessages().iterator().next();
MessageHistory messageHistory = MessageHistory.read(message);
assertNotNull(messageHistory);
assertEquals(2, messageHistory.size());
@@ -218,7 +218,7 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
}
@Test
@RedisAvailable
public void testRemoveNonExistingMessageFromTheGroup() throws Exception{
public void testRemoveNonExistingMessageFromTheGroup() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
@@ -226,61 +226,71 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
store.addMessageToGroup(messageGroup.getGroupId(), new GenericMessage<String>("1"));
store.removeMessageFromGroup(1, new GenericMessage<String>("2"));
}
@Test
@RedisAvailable
public void testRemoveNonExistingMessageFromNonExistingTheGroup() throws Exception{
public void testRemoveNonExistingMessageFromNonExistingTheGroup() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store = new RedisMessageStore(jcf);
store.removeMessageFromGroup(1, new GenericMessage<String>("2"));
}
@Test
@RedisAvailable
public void testMultipleInstancesOfGroupStore() throws Exception{
public void testMultipleInstancesOfGroupStore() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store1 = new RedisMessageStore(jcf);
RedisMessageStore store2 = new RedisMessageStore(jcf);
Message<?> message = new GenericMessage<String>("1");
store1.addMessageToGroup(1, message);
MessageGroup messageGroup = store2.addMessageToGroup(1, new GenericMessage<String>("2"));
assertEquals(2, messageGroup.getMessages().size());
RedisMessageStore store3 = new RedisMessageStore(jcf);
messageGroup = store3.removeMessageFromGroup(1, message);
assertEquals(1, messageGroup.getMessages().size());
}
@Test
@RedisAvailable
public void testIteratorOfMessageGroups() throws Exception{
public void testIteratorOfMessageGroups() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
RedisMessageStore store1 = new RedisMessageStore(jcf);
RedisMessageStore store2 = new RedisMessageStore(jcf);
store1.addMessageToGroup(1, new GenericMessage<String>("1"));
store2.addMessageToGroup(2, new GenericMessage<String>("2"));
store1.addMessageToGroup(3, new GenericMessage<String>("3"));
store2.addMessageToGroup(3, new GenericMessage<String>("3A"));
Iterator<MessageGroup> messageGroups = store1.iterator();
int counter = 0;
while (messageGroups.hasNext()) {
messageGroups.next();
MessageGroup group = messageGroups.next();
String groupId = (String) group.getGroupId();
if (groupId.equals("1")){
assertEquals(1, group.getMessages().size());
}
else if (groupId.equals("2")) {
assertEquals(1, group.getMessages().size());
}
else if (groupId.equals("3")) {
assertEquals(2, group.getMessages().size());
}
counter++;
}
assertEquals(3, counter);
store2.removeMessageGroup(3);
messageGroups = store1.iterator();
counter = 0;
while (messageGroups.hasNext()) {
@@ -289,58 +299,58 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
}
assertEquals(2, counter);
}
@Test
@RedisAvailable @Ignore
public void testConcurrentModifications() throws Exception{
public void testConcurrentModifications() throws Exception{
JedisConnectionFactory jcf = this.getConnectionFactoryForTest();
final RedisMessageStore store1 = new RedisMessageStore(jcf);
final RedisMessageStore store2 = new RedisMessageStore(jcf);
final Message<?> message = new GenericMessage<String>("1");
final Message<?> message = new GenericMessage<String>("1");
ExecutorService executor = null;
final List<Object> failures = new ArrayList<Object>();
for (int i = 0; i < 100; i++) {
executor = Executors.newCachedThreadPool();
executor.execute(new Runnable() {
public void run() {
executor.execute(new Runnable() {
public void run() {
MessageGroup group = store1.addMessageToGroup(1, message);
if (group.getMessages().size() != 1){
failures.add("ADD");
throw new AssertionFailedError("Failed on ADD");
}
}
}
});
executor.execute(new Runnable() {
executor.execute(new Runnable() {
public void run() {
MessageGroup group = store2.removeMessageFromGroup(1, message);
if (group.getMessages().size() != 0){
failures.add("REMOVE");
throw new AssertionFailedError("Failed on Remove");
}
}
}
});
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
store2.removeMessageFromGroup(1, message); // ensures that if ADD thread executed after REMOVE, the store is empty for the next cycle
}
assertTrue(failures.size() == 0);
}
@Test
@RedisAvailable
public void testWithAggregatorWithShutdown(){
public void testWithAggregatorWithShutdown(){
this.getConnectionFactoryForTest(); // for this test it only ensures that DB was flushed before test
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("redis-aggregator-config.xml", this.getClass());
MessageChannel input = context.getBean("inputChannel", MessageChannel.class);
QueueChannel output = context.getBean("outputChannel", QueueChannel.class);
Message<?> m1 = MessageBuilder.withPayload("1").setSequenceNumber(1).setSequenceSize(3).setCorrelationId(1).build();
Message<?> m2 = MessageBuilder.withPayload("2").setSequenceNumber(2).setSequenceSize(3).setCorrelationId(1).build();
input.send(m1);
@@ -348,14 +358,14 @@ public class RedisMessageGroupStoreTests extends RedisAvailableTests {
input.send(m2);
assertNull(output.receive(1000));
context.close();
context = new ClassPathXmlApplicationContext("redis-aggregator-config.xml", this.getClass());
input = context.getBean("inputChannel", MessageChannel.class);
output = context.getBean("outputChannel", QueueChannel.class);
Message<?> m3 = MessageBuilder.withPayload("3").setSequenceNumber(3).setSequenceSize(3).setCorrelationId(1).build();
input.send(m3);
assertNotNull(output.receive(1000));
}
}