RESOLVED - issue INT-1058, INT-1098: message ID is unique to an immutable instance

This commit is contained in:
David Syer
2010-04-27 11:58:37 +00:00
parent c9c3da0fe7
commit 42113a497c
27 changed files with 435 additions and 189 deletions

View File

@@ -47,9 +47,10 @@ public final class MessageHeaders implements Map<String, Object>, Serializable {
public static final String PREFIX = "$";
/**
* The key for the Message ID. This is an automatically generated UUID and should
* never be explicitly set in the header map <b>except</b> in the case of Message
* deserialization where the serialized Message's generated UUID is being restored.
* The key for the Message ID. This is an automatically generated UUID and
* should never be explicitly set in the header map <b>except</b> in the
* case of Message deserialization where the serialized Message's generated
* UUID is being restored.
*/
public static final String ID = PREFIX + "id";
@@ -71,26 +72,17 @@ public final class MessageHeaders implements Map<String, Object>, Serializable {
public static final String SEQUENCE_SIZE = PREFIX + "sequenceSize";
private final Map<String, Object> headers;
public MessageHeaders(Map<String, Object> headers) {
this.headers = (headers != null)
? new HashMap<String, Object>(headers)
: new HashMap<String, Object>();
if (this.headers.get(ID) == null) {
this.headers.put(ID, UUID.randomUUID());
}
if (this.headers.get(TIMESTAMP) == null) {
this.headers.put(TIMESTAMP, new Long(System.currentTimeMillis()));
}
this.headers = (headers != null) ? new HashMap<String, Object>(headers) : new HashMap<String, Object>();
this.headers.put(ID, UUID.randomUUID());
this.headers.put(TIMESTAMP, new Long(System.currentTimeMillis()));
if (this.headers.get(HISTORY) == null) {
this.headers.put(HISTORY, new MessageHistory());
}
}
public UUID getId() {
return this.get(ID, UUID.class);
}
@@ -140,8 +132,8 @@ public final class MessageHeaders implements Map<String, Object>, Serializable {
return null;
}
if (!type.isAssignableFrom(value.getClass())) {
throw new IllegalArgumentException("Incorrect type specified for header '" + key
+ "'. Expected [" + type + "] but actual type is [" + value.getClass() + "]");
throw new IllegalArgumentException("Incorrect type specified for header '" + key + "'. Expected [" + type
+ "] but actual type is [" + value.getClass() + "]");
}
return (T) value;
}

View File

@@ -87,7 +87,7 @@ public final class MessageBuilder<T> {
* <code>null</code>, the header will be removed.
*/
public MessageBuilder<T> setHeader(String headerName, Object headerValue) {
if (StringUtils.hasLength(headerName)) {
if (StringUtils.hasLength(headerName) && !headerName.equals(MessageHeaders.ID) && !headerName.equals(MessageHeaders.TIMESTAMP)) {
this.verifyType(headerName, headerValue);
this.modified = true;
if (headerValue == null) {
@@ -115,7 +115,7 @@ public final class MessageBuilder<T> {
* Remove the value for the given header name.
*/
public MessageBuilder<T> removeHeader(String headerName) {
if (StringUtils.hasLength(headerName)) {
if (StringUtils.hasLength(headerName) && !headerName.equals(MessageHeaders.ID) && !headerName.equals(MessageHeaders.TIMESTAMP)) {
this.modified = true;
this.headers.remove(headerName);
}

View File

@@ -34,30 +34,33 @@ import org.springframework.integration.core.Message;
public interface MessageStore {
/**
* Return the Message with the given id, or <i>null</i> if no
* Message with that id exists in the MessageStore.
* Return the Message with the given id, or <i>null</i> if no Message with
* that id exists in the MessageStore.
*/
Message<?> get(UUID id);
/**
* Put the provided Message into the MessageStore. Its id will
* be used as an index so that the {@link #get(UUID)} and
* {@link #delete(Object)} behave properly. If available, its
* correlationId header will also be stored so that the
* {@link #list(Object)} method behaves properly.
* Put the provided Message into the MessageStore. The store may need to
* mutate the message internally, and if it does then the return value can
* be different than the input. The id of the return value will be used as
* an index so that the {@link #get(UUID)} and {@link #delete(Object)}
* behave properly. Since messages are immutable, putting the same message
* more than once is a no-op.
*
* @return the message that was stored
*/
<T> Message<T> put(Message<T> message);
/**
* Remove the Message with the given id from the MessageStore,
* if present, and return it. If no Message with that id is
* present in the store, this will return <i>null</i>.
* Remove the Message with the given id from the MessageStore, if present,
* and return it. If no Message with that id is present in the store, this
* will return <i>null</i>.
*/
Message<?> delete(UUID id);
/**
* Return all Messages currently in the MessageStore that
* contain the provided correlationId header value.
* Return all Messages currently in the MessageStore that contain the
* provided correlationId header value.
* @see org.springframework.integration.core.MessageHeaders#getCorrelationId()
*/
List<Message<?>> list(Object correlationId);