/* * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.cloud.aws.messaging.core; import com.amazonaws.services.sqs.model.MessageAttributeValue; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.MessagingException; import org.springframework.messaging.support.GenericMessage; import org.springframework.util.MimeType; import org.springframework.util.NumberUtils; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @author Alain Sahli * @since 1.0 */ public final class QueueMessageUtils { private static final String RECEIPT_HANDLE_MESSAGE_ATTRIBUTE_NAME = "ReceiptHandle"; private static final String MESSAGE_ID_MESSAGE_ATTRIBUTE_NAME = "MessageId"; private QueueMessageUtils() { // Avoid instantiation } public static Message<String> createMessage(com.amazonaws.services.sqs.model.Message message) { return createMessage(message, Collections.<String, Object>emptyMap()); } public static Message<String> createMessage(com.amazonaws.services.sqs.model.Message message, Map<String, Object> additionalHeaders) { HashMap<String, Object> messageHeaders = new HashMap<>(); messageHeaders.put(MESSAGE_ID_MESSAGE_ATTRIBUTE_NAME, message.getMessageId()); messageHeaders.put(RECEIPT_HANDLE_MESSAGE_ATTRIBUTE_NAME, message.getReceiptHandle()); messageHeaders.putAll(additionalHeaders); messageHeaders.putAll(getAttributesAsMessageHeaders(message)); messageHeaders.putAll(getMessageAttributesAsMessageHeaders(message)); return new GenericMessage<>(message.getBody(), new SqsMessageHeaders(messageHeaders)); } private static Map<String, Object> getAttributesAsMessageHeaders(com.amazonaws.services.sqs.model.Message message) { Map<String, Object> messageHeaders = new HashMap<>(); for (Map.Entry<String, String> attributeKeyValuePair : message.getAttributes().entrySet()) { messageHeaders.put(attributeKeyValuePair.getKey(), attributeKeyValuePair.getValue()); } return messageHeaders; } private static Map<String, Object> getMessageAttributesAsMessageHeaders(com.amazonaws.services.sqs.model.Message message) { Map<String, Object> messageHeaders = new HashMap<>(); for (Map.Entry<String, MessageAttributeValue> messageAttribute : message.getMessageAttributes().entrySet()) { if (MessageHeaders.CONTENT_TYPE.equals(messageAttribute.getKey())) { messageHeaders.put(MessageHeaders.CONTENT_TYPE, MimeType.valueOf(messageAttribute.getValue().getStringValue())); } else if (MessageHeaders.ID.equals(messageAttribute.getKey())) { messageHeaders.put(MessageHeaders.ID, UUID.fromString(messageAttribute.getValue().getStringValue())); } else if (MessageAttributeDataTypes.STRING.equals(messageAttribute.getValue().getDataType())) { messageHeaders.put(messageAttribute.getKey(), messageAttribute.getValue().getStringValue()); } else if (messageAttribute.getValue().getDataType().startsWith(MessageAttributeDataTypes.NUMBER)) { Object numberValue = getNumberValue(messageAttribute.getValue()); if (numberValue != null) { messageHeaders.put(messageAttribute.getKey(), numberValue); } } else if (MessageAttributeDataTypes.BINARY.equals(messageAttribute.getValue().getDataType())) { messageHeaders.put(messageAttribute.getKey(), messageAttribute.getValue().getBinaryValue()); } } return messageHeaders; } private static Object getNumberValue(MessageAttributeValue value) { String numberType = value.getDataType().substring(MessageAttributeDataTypes.NUMBER.length() + 1); try { Class<? extends Number> numberTypeClass = Class.forName(numberType).asSubclass(Number.class); return NumberUtils.parseNumber(value.getStringValue(), numberTypeClass); } catch (ClassNotFoundException e) { throw new MessagingException(String.format("Message attribute with value '%s' and data type '%s' could not be converted " + "into a Number because target class was not found.", value.getStringValue(), value.getDataType()), e); } } }