Skip to content

Commit 2b6cafd

Browse files
nathankurtykaartembilan
authored andcommitted
INT-4440: Support serialized UUID in headers
JIRA: https://jira.spring.io/browse/INT-4440 The previous fix eliminated an extra `generateId()` call, but at the same introduced regression do not populate `id` and `timestamp` from the serialized state, e.g. after JSON transferring over the network * Introduce a couple utility methods in the `MutableMessageHeaders` to extract and parse `id` and `timestamp` from the provided headers **Cherry-pick to 5.0.x** (cherry picked from commit ae2aa8b)
1 parent a5c16fa commit 2b6cafd

File tree

2 files changed

+73
-13
lines changed

2 files changed

+73
-13
lines changed

spring-integration-core/src/main/java/org/springframework/integration/support/MutableMessageHeaders.java

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2017 the original author or authors.
2+
* Copyright 2015-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.integration.support;
1818

19+
import java.nio.ByteBuffer;
1920
import java.util.Map;
2021
import java.util.UUID;
2122

@@ -30,6 +31,7 @@
3031
* @author Stuart Williams
3132
* @author David Turanski
3233
* @author Artem Bilan
34+
* @author Nathan Kurtyka
3335
*
3436
* @since 4.2
3537
*/
@@ -38,16 +40,12 @@ public class MutableMessageHeaders extends MessageHeaders {
3840
private static final long serialVersionUID = 3084692953798643018L;
3941

4042
public MutableMessageHeaders(@Nullable Map<String, Object> headers) {
41-
this(headers,
42-
(headers != null ?
43-
(UUID) headers.get(MessageHeaders.ID)
44-
: null),
45-
(headers != null ?
46-
(Long) headers.get(MessageHeaders.TIMESTAMP)
47-
: null));
43+
super(headers, extractId(headers), extractTimestamp(headers));
4844
}
4945

50-
protected MutableMessageHeaders(@Nullable Map<String, Object> headers, @Nullable UUID id, @Nullable Long timestamp) {
46+
protected MutableMessageHeaders(@Nullable Map<String, Object> headers, @Nullable UUID id,
47+
@Nullable Long timestamp) {
48+
5149
super(headers, id, timestamp);
5250
}
5351

@@ -76,4 +74,31 @@ public Object remove(Object key) {
7674
return super.getRawHeaders().remove(key);
7775
}
7876

77+
private static UUID extractId(@Nullable Map<String, Object> headers) {
78+
if (headers != null && headers.containsKey(MessageHeaders.ID)) {
79+
Object id = headers.get(MessageHeaders.ID);
80+
if (id instanceof String) {
81+
return UUID.fromString((String) id);
82+
}
83+
else if (id instanceof byte[]) {
84+
ByteBuffer bb = ByteBuffer.wrap((byte[]) id);
85+
return new UUID(bb.getLong(), bb.getLong());
86+
}
87+
else {
88+
return (UUID) id;
89+
}
90+
}
91+
92+
return null;
93+
}
94+
95+
private static Long extractTimestamp(@Nullable Map<String, Object> headers) {
96+
if (headers != null && headers.containsKey(MessageHeaders.TIMESTAMP)) {
97+
Object timestamp = headers.get(MessageHeaders.TIMESTAMP);
98+
return (timestamp instanceof String) ? Long.parseLong((String) timestamp) : (Long) timestamp;
99+
}
100+
101+
return null;
102+
}
103+
79104
}

spring-integration-core/src/test/java/org/springframework/integration/support/MutableMessageTests.java

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2016 the original author or authors.
2+
* Copyright 2015-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,8 +17,10 @@
1717
package org.springframework.integration.support;
1818

1919
import static org.hamcrest.Matchers.hasEntry;
20+
import static org.junit.Assert.assertEquals;
2021
import static org.junit.Assert.assertThat;
2122

23+
import java.nio.ByteBuffer;
2224
import java.util.HashMap;
2325
import java.util.Map;
2426
import java.util.UUID;
@@ -30,6 +32,8 @@
3032

3133
/**
3234
* @author Stuart Williams
35+
* @author Nathan Kurtyka
36+
*
3337
* @since 4.2
3438
*/
3539
public class MutableMessageTests {
@@ -49,8 +53,8 @@ public void testMessageIdTimestampRemains() {
4953
MutableMessage<Object> mutableMessage = new MutableMessage<>(payload, headerMap);
5054
MutableMessageHeaders headers = mutableMessage.getHeaders();
5155

52-
assertThat(headers.getRawHeaders(), hasEntry(MessageHeaders.ID, (Object) uuid));
53-
assertThat(headers.getRawHeaders(), hasEntry(MessageHeaders.TIMESTAMP, (Object) timestamp));
56+
assertThat(headers.getRawHeaders(), hasEntry(MessageHeaders.ID, uuid));
57+
assertThat(headers.getRawHeaders(), hasEntry(MessageHeaders.TIMESTAMP, timestamp));
5458
}
5559

5660
@Test
@@ -69,7 +73,38 @@ public void testMessageHeaderIsSettable() {
6973
headers.remove("eep");
7074
headers.putAll(additional);
7175

72-
assertThat(headers.getRawHeaders(), hasEntry("foo", (Object) "bar"));
76+
assertThat(headers.getRawHeaders(), hasEntry("foo", "bar"));
77+
}
78+
79+
@Test
80+
public void testMessageHeaderIsSerializable() {
81+
82+
Object payload = new Object();
83+
84+
UUID uuid = UUID.nameUUIDFromBytes(((System.currentTimeMillis() - System.nanoTime()) + "").getBytes());
85+
Long timestamp = System.currentTimeMillis();
86+
87+
// UUID as String; timestamp as String
88+
Map<String, Object> headerMapStrings = new HashMap<>();
89+
headerMapStrings.put(MessageHeaders.ID, uuid.toString());
90+
headerMapStrings.put(MessageHeaders.TIMESTAMP, timestamp.toString());
91+
MutableMessage<Object> mutableMessageStrings = new MutableMessage<>(payload, headerMapStrings);
92+
assertEquals(uuid, mutableMessageStrings.getHeaders().getId());
93+
assertEquals(timestamp, mutableMessageStrings.getHeaders().getTimestamp());
94+
95+
// UUID as byte[]; timestamp as Long
96+
Map<String, Object> headerMapByte = new HashMap<>();
97+
byte[] uuidAsBytes =
98+
ByteBuffer.allocate(16)
99+
.putLong(uuid.getMostSignificantBits())
100+
.putLong(uuid.getLeastSignificantBits())
101+
.array();
102+
103+
headerMapByte.put(MessageHeaders.ID, uuidAsBytes);
104+
headerMapByte.put(MessageHeaders.TIMESTAMP, timestamp);
105+
MutableMessage<Object> mutableMessageBytes = new MutableMessage<>(payload, headerMapByte);
106+
assertEquals(uuid, mutableMessageBytes.getHeaders().getId());
107+
assertEquals(timestamp, mutableMessageBytes.getHeaders().getTimestamp());
73108
}
74109

75110
}

0 commit comments

Comments
 (0)