Skip to content

Commit 1741803

Browse files
GH-3006: Read x-death count in a safer way
Fixes: #3006 We had an issue in our system trying to consume a message from RabbitMQ that contained an `x-death` header, with count value typed as `Integer`. This caused a `ClassCastException`. The reason the count value was an int and not a long is that we were storing headers in an internal database as part of a recovery process, and the typing was slightly changed during serialisation / deserialisation. * Use `target.setRetryCount(numberValue.longValue());` in the `DefaultMessagePropertiesConverter` instead of cast to `long` Signed-off-by: Raul Avila <[email protected]> [[email protected] Improve commit message] **Auto-cherry-pick to `3.2.x`** Signed-off-by: Artem Bilan <[email protected]>
1 parent 3ecb055 commit 1741803

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/support/DefaultMessagePropertiesConverter.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
* @author Artem Bilan
4545
* @author Ngoc Nhan
4646
* @author Johan Kaving
47+
* @author Raul Avila
4748
*
4849
* @since 1.0
4950
*/
@@ -147,7 +148,11 @@ else if (MessageProperties.RETRY_COUNT.equals(key)) {
147148
if (target.getRetryCount() == 0) {
148149
List<Map<String, ?>> xDeathHeader = target.getXDeathHeader();
149150
if (!CollectionUtils.isEmpty(xDeathHeader)) {
150-
target.setRetryCount((long) xDeathHeader.get(0).get("count"));
151+
Object value = xDeathHeader.get(0).get("count");
152+
153+
if (value instanceof Number numberValue) {
154+
target.setRetryCount(numberValue.longValue());
155+
}
151156
}
152157
}
153158

spring-rabbit/src/test/java/org/springframework/amqp/rabbit/support/DefaultMessagePropertiesConverterTests.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,21 @@ public void testToMessagePropertiesLongStringInMap() {
104104
assertThat(((Map<String, Object>) messageProperties.getHeaders().get("map")).get("longString")).as("LongString nested in Map not converted to String").isEqualTo(longStringString);
105105
}
106106

107+
@Test
108+
public void testToMessagePropertiesXDeathCount() {
109+
Map<String, Object> headers = new HashMap<String, Object>();
110+
111+
headers.put("x-death", List.of(Map.of("count", Integer.valueOf(2))));
112+
113+
BasicProperties source = new BasicProperties.Builder()
114+
.headers(headers)
115+
.build();
116+
117+
MessageProperties messageProperties = messagePropertiesConverter.toMessageProperties(source, envelope, "UTF-8");
118+
119+
assertThat(messageProperties.getRetryCount()).isEqualTo(2);
120+
}
121+
107122
@Test
108123
public void testLongLongString() {
109124
Map<String, Object> headers = new HashMap<String, Object>();

0 commit comments

Comments
 (0)