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 <raul.avila@pagonxt.com> [artem.bilan@broadcom.com Improve commit message] **Auto-cherry-pick to `3.2.x`** Signed-off-by: Artem Bilan <artem.bilan@broadcom.com>
This commit is contained in:
@@ -44,6 +44,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Artem Bilan
|
||||
* @author Ngoc Nhan
|
||||
* @author Johan Kaving
|
||||
* @author Raul Avila
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@@ -147,7 +148,11 @@ public class DefaultMessagePropertiesConverter implements MessagePropertiesConve
|
||||
if (target.getRetryCount() == 0) {
|
||||
List<Map<String, ?>> xDeathHeader = target.getXDeathHeader();
|
||||
if (!CollectionUtils.isEmpty(xDeathHeader)) {
|
||||
target.setRetryCount((long) xDeathHeader.get(0).get("count"));
|
||||
Object value = xDeathHeader.get(0).get("count");
|
||||
|
||||
if (value instanceof Number numberValue) {
|
||||
target.setRetryCount(numberValue.longValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,21 @@ public class DefaultMessagePropertiesConverterTests {
|
||||
assertThat(((Map<String, Object>) messageProperties.getHeaders().get("map")).get("longString")).as("LongString nested in Map not converted to String").isEqualTo(longStringString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToMessagePropertiesXDeathCount() {
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
|
||||
headers.put("x-death", List.of(Map.of("count", Integer.valueOf(2))));
|
||||
|
||||
BasicProperties source = new BasicProperties.Builder()
|
||||
.headers(headers)
|
||||
.build();
|
||||
|
||||
MessageProperties messageProperties = messagePropertiesConverter.toMessageProperties(source, envelope, "UTF-8");
|
||||
|
||||
assertThat(messageProperties.getRetryCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongLongString() {
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
|
||||
Reference in New Issue
Block a user