Currently, the messages on source queue are sent to dead-letter-queue on every exception. My goal is to add custom attributes to the failed message so that engineers have more information about failure when they monitor the dead-letter-queue.
When I tried to add attributes to existing message, I receive an java.lang.UnsupportedOperationException exception.
Here is the aspect code where I add message attributes to existing message. I am using custom aspect which is triggered before sending the message with AmazonSQSClient.
@Before(value = "execution(* com.amazonaws.services.sqs.AmazonSQS*Client.sendMessage*(com.amazonaws.services.sqs.model.SendMessageRequest,..)) && args(request,..)",
argNames = "request")
public void before(SendMessageRequest request) {
Map<String, MessageAttributeValue> messageAttributes = request.getMessageAttributes();
if (messageAttributes == null) return;
messageAttributes.put("MoveToDlqFlag", createMessageAttribute("true"));
}
This is the code where exception happens.
@SqsListener(value = {"${sqs.queue.source-queue}"}, deletionPolicy = ON_SUCCESS)
public void handleMessageReceived(String rawMessage, @Header("SenderId") String senderId, @Headers Map<String, Object> header) {
var orderMessageWrapper = messageWrapperUtil.create(rawMessage, Order.class);
var order = orderMessageWrapper.getMessage();
var receiveCount = (Integer) header.get("ApproximateReceiveCount");
...
}
Is there a way to add message attributes to existing message before sending to dead-letter-queue? Maybe spring provides a configuration where it is possible.
If messageAttributes
map throws java.lang.UnsupportedOperationException
, then maybe you could try to create a new mutable map, which is a copy of immutable map:
Map<String, MessageAttributeValue> messageAttributes = new HashMap<>(request.getMessageAttributes());
and then you can use setMessageAttributes()
of SendMessageRequest
So I hope that this solution would work (unless setMessageAttributes
doesn't throw UnsupportedOperationException
too)
Map<String, MessageAttributeValue> messageAttributes = request.getMessageAttributes() == null ? new HashMap<>() : new HashMap<>(request.getMessageAttributes());
messageAttributes.put("MoveToDlqFlag", createMessageAttribute("true"));
request.setMessageAttributes(messageAttributes);