From 96c627d0b60da3faee9d8319ecb334eccd141a05 Mon Sep 17 00:00:00 2001 From: anjeongkyun Date: Sun, 13 Sep 2026 15:57:51 +0900 Subject: [PATCH] Do not put a null message attribute when contentType is unsupported getContentTypeMessageAttribute returns null for a contentType header that is neither a MimeType nor a String, and the caller put that null straight into the attribute map. The SDK then fails marshalling the whole publish request. Fall back to the same warn-and-skip the loop already uses for header types SNS cannot carry. --- .../sns/core/SnsHeaderConverterUtil.java | 20 ++++++++++++++----- .../sns/core/TopicMessageChannelTest.java | 16 +++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/spring-cloud-aws-sns/src/main/java/io/awspring/cloud/sns/core/SnsHeaderConverterUtil.java b/spring-cloud-aws-sns/src/main/java/io/awspring/cloud/sns/core/SnsHeaderConverterUtil.java index 388c70029c..f6783e29c6 100644 --- a/spring-cloud-aws-sns/src/main/java/io/awspring/cloud/sns/core/SnsHeaderConverterUtil.java +++ b/spring-cloud-aws-sns/src/main/java/io/awspring/cloud/sns/core/SnsHeaderConverterUtil.java @@ -60,7 +60,13 @@ public static Map toSnsMessageAttributes(Message< } if (MessageHeaders.CONTENT_TYPE.equals(messageHeaderName) && messageHeaderValue != null) { - messageAttributes.put(messageHeaderName, getContentTypeMessageAttribute(messageHeaderValue)); + MessageAttributeValue contentType = getContentTypeMessageAttribute(messageHeaderValue); + if (contentType != null) { + messageAttributes.put(messageHeaderName, contentType); + } + else { + logUnsupportedHeader(messageHeaderName, messageHeaderValue); + } } else if (MessageHeaders.ID.equals(messageHeaderName) && messageHeaderValue != null) { messageAttributes.put(messageHeaderName, getStringMessageAttribute(messageHeaderValue.toString())); @@ -81,16 +87,20 @@ else if (messageHeaderValue instanceof List) { messageAttributes.put(messageHeaderName, getStringArrayMessageAttribute((List) messageHeaderValue)); } else { - logger.warn(String.format( - "Message header with name '%s' and type '%s' cannot be sent as" - + " message attribute because it is not supported by SNS.", - messageHeaderName, messageHeaderValue != null ? messageHeaderValue.getClass().getName() : "")); + logUnsupportedHeader(messageHeaderName, messageHeaderValue); } } return messageAttributes; } + private static void logUnsupportedHeader(String messageHeaderName, @Nullable Object messageHeaderValue) { + logger.warn(String.format( + "Message header with name '%s' and type '%s' cannot be sent as" + + " message attribute because it is not supported by SNS.", + messageHeaderName, messageHeaderValue != null ? messageHeaderValue.getClass().getName() : "")); + } + private static boolean isSkipHeader(String headerName) { return NOTIFICATION_SUBJECT_HEADER.equals(headerName) || MESSAGE_GROUP_ID_HEADER.equals(headerName) || MESSAGE_DEDUPLICATION_ID_HEADER.equals(headerName); diff --git a/spring-cloud-aws-sns/src/test/java/io/awspring/cloud/sns/core/TopicMessageChannelTest.java b/spring-cloud-aws-sns/src/test/java/io/awspring/cloud/sns/core/TopicMessageChannelTest.java index e587a8b100..00251ba4b3 100644 --- a/spring-cloud-aws-sns/src/test/java/io/awspring/cloud/sns/core/TopicMessageChannelTest.java +++ b/spring-cloud-aws-sns/src/test/java/io/awspring/cloud/sns/core/TopicMessageChannelTest.java @@ -211,6 +211,22 @@ void sendMessage_withStringArrayMessageHeader_shouldBeSentAsTopicMessageAttribut })); } + @Test + void sendMessage_withUnsupportedContentTypeHeader_shouldNotSetItAsMessageAttribute() { + // Arrange + // a contentType that is neither a MimeType nor a String + Message message = MessageBuilder.withPayload("Hello") + .setHeader(MessageHeaders.CONTENT_TYPE, new Object()).build(); + + // Act + boolean sent = messageChannel.send(message); + + // Assert + assertThat(sent).isTrue(); + verify(snsClient).publish(requestMatches( + it -> assertThat(it.messageAttributes()).doesNotContainKey(MessageHeaders.CONTENT_TYPE))); + } + @Test void sendMessage_withMessageGroupIdHeader_shouldSetMessageGroupIdOnPublishRequestAndNotSetItAsMessageAttribute() { // Arrange