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 2002-2011 the original author or authors
* Copyright 2002-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.
@@ -18,8 +18,10 @@ package org.springframework.integration.store;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.springframework.beans.DirectFieldAccessor;
@@ -31,7 +33,7 @@ import org.springframework.util.Assert;
/**
* Base class for implementations of Key/Value style {@link MessageGroupStore} and {@link MessageStore}
*
*
* @author Oleg Zhurakousky
* @since 2.1
*/
@@ -40,11 +42,11 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
protected static final String MESSAGE_KEY_PREFIX = "MESSAGE_";
protected static final String MESSAGE_GROUP_KEY_PREFIX = "MESSAGE_GROUP_";
protected static final String CREATED_DATE = "CREATED_DATE";
// MessageStore methods
public Message<?> getMessage(UUID id) {
Message<?> message = this.getRawMessage(id);
if (message != null){
@@ -56,7 +58,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
@SuppressWarnings("unchecked")
public <T> Message<T> addMessage(Message<T> message) {
Assert.notNull(message, "'message' must not be null");
UUID messageId = message.getHeaders().getId();
UUID messageId = message.getHeaders().getId();
this.doStore(MESSAGE_KEY_PREFIX + messageId, message);
return (Message<T>) this.getRawMessage(messageId);
}
@@ -88,50 +90,50 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
public MessageGroup getMessageGroup(Object groupId) {
return this.buildMessageGroup(groupId, false);
}
/**
* Add a Message to the group with the provided group ID.
* Add a Message to the group with the provided group ID.
*/
public MessageGroup addMessageToGroup(Object groupId, Message<?> message) {
Assert.notNull(groupId, "'groupId' must not be null");
Assert.notNull(message, "'message' must not be null");
// add message as is to the MG accessible by the caller
SimpleMessageGroup messageGroup = this.getSimpleMessageGroup(this.getMessageGroup(groupId));
messageGroup.add(message);
SimpleMessageGroup messageGroup = this.getSimpleMessageGroup(this.getMessageGroup(groupId));
messageGroup.add(message);
// enrich Message with additional headers and add it to MS
Message<?> enrichedMessage = this.enrichMessage(message);
this.addMessage(enrichedMessage);
// build raw MessageGroup and add enriched Message to it
SimpleMessageGroup rawGroup = this.buildMessageGroup(groupId, true);
rawGroup.setLastModified(System.currentTimeMillis());
rawGroup.add(enrichedMessage);
// store MessageGroupMetadata built from enriched MG
this.doStore(MESSAGE_GROUP_KEY_PREFIX + groupId, new MessageGroupMetadata(rawGroup));
this.doStore(MESSAGE_GROUP_KEY_PREFIX + groupId, new MessageGroupMetadata(rawGroup));
// return clean MG
return this.getMessageGroup(groupId);
}
/**
* Remove a Message from the group with the provided group ID.
* Remove a Message from the group with the provided group ID.
*/
public MessageGroup removeMessageFromGroup(Object groupId, Message<?> messageToRemove) {
Assert.notNull(groupId, "'groupId' must not be null");
Assert.notNull(messageToRemove, "'messageToRemove' must not be null");
// build raw MG
SimpleMessageGroup rawGroup = this.buildMessageGroup(groupId, true);
// create a clean instance of
// create a clean instance of
SimpleMessageGroup messageGroup = this.normalizeSimpleMessageGroup(rawGroup);
for (Message<?> message : rawGroup.getMessages()) {
if (message.getHeaders().getId().equals(messageToRemove.getHeaders().getId())){
rawGroup.remove(message);
@@ -139,13 +141,13 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
}
this.removeMessage(messageToRemove.getHeaders().getId());
rawGroup.setLastModified(System.currentTimeMillis());
this.doStore(MESSAGE_GROUP_KEY_PREFIX + groupId, new MessageGroupMetadata(rawGroup));
messageGroup = this.getSimpleMessageGroup(this.getMessageGroup(groupId));
return messageGroup;
}
public void completeGroup(Object groupId) {
Assert.notNull(groupId, "'groupId' must not be null");
@@ -156,7 +158,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
}
/**
* Remove the MessageGroup with the provided group ID.
* Remove the MessageGroup with the provided group ID.
*/
public void removeMessageGroup(Object groupId) {
Assert.notNull(groupId, "'groupId' must not be null");
@@ -164,7 +166,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
if (mgm != null) {
Assert.isInstanceOf(MessageGroupMetadata.class, mgm);
MessageGroupMetadata messageGroupMetadata = (MessageGroupMetadata) mgm;
Iterator<UUID> messageIds = messageGroupMetadata.messageIdIterator();
while (messageIds.hasNext()){
this.removeMessage(messageIds.next());
@@ -179,14 +181,14 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
messageGroup.setLastModified(System.currentTimeMillis());
this.doStore(MESSAGE_GROUP_KEY_PREFIX + groupId, new MessageGroupMetadata(messageGroup));
}
public Message<?> pollMessageFromGroup(Object groupId) {
Assert.notNull(groupId, "'groupId' must not be null");
Object mgm = this.doRetrieve(MESSAGE_GROUP_KEY_PREFIX + groupId);
if (mgm != null) {
Assert.isInstanceOf(MessageGroupMetadata.class, mgm);
MessageGroupMetadata messageGroupMetadata = (MessageGroupMetadata) mgm;
UUID firstId = messageGroupMetadata.firstId();
if (firstId != null){
messageGroupMetadata.remove(firstId);
@@ -198,11 +200,29 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
return null;
}
@SuppressWarnings("unchecked")
public Iterator<MessageGroup> iterator() {
final Iterator<?> idIterator = this.doListKeys(MESSAGE_GROUP_KEY_PREFIX + "*").iterator();
final Iterator<?> idIterator = this.normalizeKeys(
(Collection<String>) this.doListKeys(MESSAGE_GROUP_KEY_PREFIX + "*"))
.iterator();
return new MessageGroupIterator(idIterator);
}
private Collection<String> normalizeKeys(Collection<String> keys){
Set<String> normalizedKeys = new HashSet<String>();
for (Object key : keys) {
String strKey = (String) key;
if (strKey.startsWith(MESSAGE_GROUP_KEY_PREFIX)){
strKey = strKey.replace(MESSAGE_GROUP_KEY_PREFIX, "");
}
else if (strKey.startsWith(MESSAGE_KEY_PREFIX)){
strKey = strKey.replace(MESSAGE_KEY_PREFIX, "");
}
normalizedKeys.add(strKey);
}
return normalizedKeys;
}
public int messageGroupSize(Object groupId) {
Object mgm = this.doRetrieve(MESSAGE_GROUP_KEY_PREFIX + groupId);
if (mgm != null) {
@@ -212,15 +232,15 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
}
return 0;
}
protected abstract Object doRetrieve(Object id);
protected abstract void doStore(Object id, Object objectToStore);
protected abstract Object doRemove(Object id);
protected abstract Object doRemove(Object id);
protected abstract Collection<?> doListKeys(String keyPattern);
@SuppressWarnings({ "rawtypes", "unchecked" })
private Message<?> normalizeMessage(Message<?> message){
Message<?> normalizedMessage = MessageBuilder.fromMessage(message).removeHeader("CREATED_DATE").build();
@@ -229,7 +249,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
innerMap.put(MessageHeaders.TIMESTAMP, message.getHeaders().getTimestamp());
return normalizedMessage;
}
/**
* Will enrich Message with additional meta headers
* @param message
@@ -243,7 +263,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
innerMap.put(MessageHeaders.TIMESTAMP, message.getHeaders().getTimestamp());
return enrichedMessage;
}
private SimpleMessageGroup buildMessageGroup(Object groupId, boolean raw){
Assert.notNull(groupId, "'groupId' must not be null");
Object mgm = this.doRetrieve(MESSAGE_GROUP_KEY_PREFIX + groupId);
@@ -251,7 +271,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
Assert.isInstanceOf(MessageGroupMetadata.class, mgm);
MessageGroupMetadata messageGroupMetadata = (MessageGroupMetadata) mgm;
ArrayList<Message<?>> messages = new ArrayList<Message<?>>();
Iterator<UUID> messageIds = messageGroupMetadata.messageIdIterator();
while (messageIds.hasNext()){
if (raw){
@@ -261,8 +281,8 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
messages.add(this.getMessage(messageIds.next()));
}
}
SimpleMessageGroup messageGroup = new SimpleMessageGroup(messages,
SimpleMessageGroup messageGroup = new SimpleMessageGroup(messages,
groupId, messageGroupMetadata.getTimestamp(), messageGroupMetadata.isComplete());
messageGroup.setLastModified(messageGroupMetadata.getLastModified());
messageGroup.setLastReleasedMessageSequenceNumber(messageGroupMetadata.getLastReleasedMessageSequenceNumber());
@@ -281,7 +301,7 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
return new SimpleMessageGroup(messageGroup);
}
}
private SimpleMessageGroup normalizeSimpleMessageGroup(SimpleMessageGroup messageGroup){
SimpleMessageGroup normalizedGroup = new SimpleMessageGroup(messageGroup.getGroupId());
for (Message<?> message : messageGroup.getMessages()) {
@@ -290,10 +310,10 @@ public abstract class AbstractKeyValueMessageStore extends AbstractMessageGroupS
}
return normalizedGroup;
}
private Message<?> getRawMessage(UUID id) {
Assert.notNull(id, "'id' must not be null");
Object message = this.doRetrieve(MESSAGE_KEY_PREFIX + id);
Object message = this.doRetrieve(MESSAGE_KEY_PREFIX + id);
return (Message<?>) message;
}