Repository: qpid-broker-j Updated Branches: refs/heads/master 47c64a075 -> 2e809efcc
QPID-7434: [Java Broker] Improve AMQP 1.0 to Internal content conversion and add unit tests Project: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/commit/2e809efc Tree: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/tree/2e809efc Diff: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/diff/2e809efc Branch: refs/heads/master Commit: 2e809efccb6d431a413c9497b6785a16cfb4d668 Parents: 47c64a0 Author: Lorenz Quack <lqu...@apache.org> Authored: Thu Aug 10 13:45:09 2017 +0100 Committer: Lorenz Quack <lqu...@apache.org> Committed: Thu Aug 10 17:18:19 2017 +0100 ---------------------------------------------------------------------- .../message/internal/InternalMessage.java | 11 +- .../internal/InternalMessageMetaData.java | 44 +- .../qpid/server/protocol/v0_8/FieldTable.java | 5 + .../v1_0/MessageConverter_from_1_0.java | 21 +- .../v1_0/MessageConverter_v1_0_to_Internal.java | 188 ++++- .../MessageConverter_v1_0_to_InternalTest.java | 744 +++++++++++++++++++ .../MessageConverter_1_0_to_v0_10.java | 4 +- .../PropertyConverter_0_10_to_0_8Test.java | 18 - .../v0_8_v1_0/MessageConverter_1_0_to_v0_8.java | 4 +- .../PropertyConverter_1_0_to_0_8Test.java | 34 + 10 files changed, 1011 insertions(+), 62 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessage.java ---------------------------------------------------------------------- diff --git a/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessage.java b/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessage.java index 21c55bf..3382109 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessage.java +++ b/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessage.java @@ -40,9 +40,9 @@ import org.apache.qpid.server.store.MessageHandle; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoredMessage; import org.apache.qpid.server.store.TransactionLogResource; -import org.apache.qpid.server.util.ConnectionScopedRuntimeException; import org.apache.qpid.server.util.ByteBufferInputStream; import org.apache.qpid.server.util.ByteBufferUtils; +import org.apache.qpid.server.util.ConnectionScopedRuntimeException; public class InternalMessage extends AbstractServerMessageImpl<InternalMessage, InternalMessageMetaData> { @@ -53,10 +53,10 @@ public class InternalMessage extends AbstractServerMessageImpl<InternalMessage, private final String _destinationName; - InternalMessage(final StoredMessage<InternalMessageMetaData> handle, - final InternalMessageHeader header, - final Object messageBody, - final String destinationName) + public InternalMessage(final StoredMessage<InternalMessageMetaData> handle, + final InternalMessageHeader header, + final Object messageBody, + final String destinationName) { super(handle, null); _header = header; @@ -64,6 +64,7 @@ public class InternalMessage extends AbstractServerMessageImpl<InternalMessage, _destinationName = destinationName; } + // used by recovery path InternalMessage(final StoredMessage<InternalMessageMetaData> msg, final String destinationName) { http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessageMetaData.java ---------------------------------------------------------------------- diff --git a/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessageMetaData.java b/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessageMetaData.java index 0d8728b..feb9992 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessageMetaData.java +++ b/broker-core/src/main/java/org/apache/qpid/server/message/internal/InternalMessageMetaData.java @@ -30,31 +30,16 @@ import org.apache.qpid.server.util.ConnectionScopedRuntimeException; public class InternalMessageMetaData implements StorableMessageMetaData { - - - private boolean _isPersistent; - private InternalMessageHeader _header; - private int _contentSize; - private byte[] _headerBytes; + private final boolean _isPersistent; + private final InternalMessageHeader _header; + private final int _contentSize; + private volatile byte[] _headerBytes; public InternalMessageMetaData(final boolean isPersistent, final InternalMessageHeader header, final int contentSize) { _isPersistent = isPersistent; _header = header; _contentSize = contentSize; - - try(ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - ObjectOutputStream os = new ObjectOutputStream(bytesOut)) - { - os.writeInt(contentSize); - os.writeObject(header); - os.close(); - _headerBytes = bytesOut.toByteArray(); - } - catch (IOException e) - { - throw new ConnectionScopedRuntimeException("Unexpected IO Exception on in memory operation", e); - } } @Override @@ -66,12 +51,14 @@ public class InternalMessageMetaData implements StorableMessageMetaData @Override public int getStorableSize() { + ensureHeaderIsEncoded(); return _headerBytes.length; } @Override public void writeToBuffer(final QpidByteBuffer dest) { + ensureHeaderIsEncoded(); dest.put(_headerBytes); } @@ -115,5 +102,22 @@ public class InternalMessageMetaData implements StorableMessageMetaData return new InternalMessageMetaData(persistent, header, contentSize); } - + private void ensureHeaderIsEncoded() + { + if (_headerBytes == null) + { + try(ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + ObjectOutputStream os = new ObjectOutputStream(bytesOut)) + { + os.writeInt(_contentSize); + os.writeObject(_header); + os.close(); + _headerBytes = bytesOut.toByteArray(); + } + catch (IOException e) + { + throw new ConnectionScopedRuntimeException("Unexpected IO Exception on in memory operation", e); + } + } + } } http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java ---------------------------------------------------------------------- diff --git a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java index c344bb8..3fd8408 100644 --- a/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java +++ b/broker-core/src/main/java/org/apache/qpid/server/protocol/v0_8/FieldTable.java @@ -31,6 +31,7 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; +import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -722,6 +723,10 @@ public class FieldTable { return setBytes(string, (byte[]) object); } + else if (object instanceof UUID) + { + return setString(string, object.toString()); + } throw new AMQPInvalidClassException(AMQPInvalidClassException.INVALID_OBJECT_MSG + (object == null ? "null" : object.getClass())); } http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_from_1_0.java ---------------------------------------------------------------------- diff --git a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_from_1_0.java b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_from_1_0.java index 62230d8..d5581fa 100644 --- a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_from_1_0.java +++ b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_from_1_0.java @@ -74,7 +74,8 @@ public class MessageConverter_from_1_0 Character.class, String.class, byte[].class, - UUID.class)); + UUID.class, + Date.class)); public static final Pattern TEXT_CONTENT_TYPES = Pattern.compile("^(text/.*)|(application/(xml|xml-dtd|.*\\+xml|json|.*\\+json|javascript|ecmascript))$"); public static final Pattern MAP_MESSAGE_CONTENT_TYPES = Pattern.compile("^amqp/map|jms/map-message$"); @@ -206,10 +207,6 @@ public class MessageConverter_from_1_0 { return value.toString(); } - else if(value instanceof Date) - { - return ((Date)value).getTime(); - } else if(value instanceof Binary) { return ((Binary)value).getArray(); @@ -237,7 +234,7 @@ public class MessageConverter_from_1_0 return result; } - private static ContentHint getTypeHint(final Message_1_0 serverMsg) + private static ContentHint getAmqp0xTypeHint(final Message_1_0 serverMsg) { Symbol contentType = getContentType(serverMsg); @@ -502,12 +499,12 @@ public class MessageConverter_from_1_0 return messageId; } - public static ConvertedContentAndMimeType getConvertedContentAndMimeType(final Message_1_0 serverMsg) + public static ConvertedContentAndMimeType getAmqp0xConvertedContentAndMimeType(final Message_1_0 serverMsg) { Object bodyObject = convertBodyToObject(serverMsg); ObjectToMimeContentConverter converter = getBestFitObjectToMimeContentConverter(bodyObject); - ContentHint contentHint = getTypeHint(serverMsg); + ContentHint contentHint = getAmqp0xTypeHint(serverMsg); Class<?> typeHint = contentHint.getContentClass(); if (typeHint == null && bodyObject == null) { @@ -548,23 +545,23 @@ public class MessageConverter_from_1_0 return new ConvertedContentAndMimeType(messageContent, mimeType); } - private static class ContentHint + public static class ContentHint { private final Class<?> _contentClass; private final String _contentType; - private ContentHint(final Class<?> contentClass, final String contentType) + public ContentHint(final Class<?> contentClass, final String contentType) { _contentClass = contentClass; _contentType = contentType; } - private Class<?> getContentClass() + public Class<?> getContentClass() { return _contentClass; } - private String getContentType() + public String getContentType() { return _contentType; } http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_Internal.java ---------------------------------------------------------------------- diff --git a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_Internal.java b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_Internal.java index 35fc420..749c1a6 100644 --- a/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_Internal.java +++ b/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_Internal.java @@ -20,11 +20,20 @@ */ package org.apache.qpid.server.protocol.v1_0; -import org.apache.qpid.server.model.NamedAddressSpace; -import org.apache.qpid.server.protocol.v1_0.type.codec.AMQPDescribedTypeRegistry; +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.internal.InternalMessage; +import org.apache.qpid.server.message.internal.InternalMessageHeader; +import org.apache.qpid.server.model.NamedAddressSpace; import org.apache.qpid.server.plugin.MessageConverter; import org.apache.qpid.server.plugin.PluggableService; +import org.apache.qpid.server.protocol.v1_0.type.Symbol; +import org.apache.qpid.server.protocol.v1_0.type.codec.AMQPDescribedTypeRegistry; +import org.apache.qpid.server.protocol.v1_0.type.messaging.MessageAnnotationsSection; +import org.apache.qpid.server.util.ServerScopedRuntimeException; @PluggableService public class MessageConverter_v1_0_to_Internal implements MessageConverter<Message_1_0, InternalMessage> @@ -55,8 +64,31 @@ public class MessageConverter_v1_0_to_Internal implements MessageConverter<Messa public InternalMessage convert(Message_1_0 serverMessage, NamedAddressSpace addressSpace) { Object bodyObject = MessageConverter_from_1_0.convertBodyToObject(serverMessage); + final AMQMessageHeader convertHeader = convertHeader(serverMessage, addressSpace, bodyObject); + return InternalMessage.convert(serverMessage, convertHeader, bodyObject); + } - return InternalMessage.convert(serverMessage, serverMessage.getMessageHeader(), bodyObject); + private AMQMessageHeader convertHeader(final Message_1_0 serverMessage, + final NamedAddressSpace addressSpace, + final Object convertedBodyObject) + { + final String convertedMimeType = getInternalConvertedContentAndMimeType(serverMessage, convertedBodyObject); + final MessageMetaData_1_0.MessageHeader_1_0 messageHeader = serverMessage.getMessageHeader(); + final InternalMessageHeader header = new InternalMessageHeader(messageHeader.getHeadersAsMap(), + messageHeader.getCorrelationId(), + messageHeader.getExpiration(), + messageHeader.getUserId(), + messageHeader.getAppId(), + messageHeader.getMessageId(), + convertedMimeType, + messageHeader.getEncoding(), + messageHeader.getPriority(), + messageHeader.getTimestamp(), + messageHeader.getNotValidBefore(), + messageHeader.getType(), + messageHeader.getReplyTo(), + serverMessage.getArrivalTime()); + return header; } @Override @@ -70,4 +102,154 @@ public class MessageConverter_v1_0_to_Internal implements MessageConverter<Messa { return "v1-0 to Internal"; } + + private static String getInternalConvertedContentAndMimeType(final Message_1_0 serverMsg, + final Object convertedBodyObject) + { + MessageConverter_from_1_0.ContentHint contentHint = getInternalTypeHint(serverMsg); + + final Class<?> contentClassHint = contentHint.getContentClass(); + final String originalContentType = contentHint.getContentType(); + String mimeType = originalContentType; + if (convertedBodyObject == null) + { + if (contentClassHint == Void.class + || contentClassHint == Map.class + || contentClassHint == List.class) + { + mimeType = null; + } + else if (contentClassHint == Serializable.class) + { + mimeType = "application/x-java-serialized-object"; + } + else if (contentClassHint == byte[].class) + { + mimeType = "application/octet-stream"; + } + else if (contentClassHint == String.class + && (originalContentType == null + || !MessageConverter_from_1_0.TEXT_CONTENT_TYPES.matcher(originalContentType).matches())) + { + mimeType = "text/plain"; + } + } + else if (convertedBodyObject instanceof byte[] + && originalContentType == null) + { + if (contentClassHint == Serializable.class) + { + mimeType = "application/x-java-serialized-object"; + } + else + { + mimeType = "application/octet-stream"; + } + } + else if (convertedBodyObject instanceof List + || convertedBodyObject instanceof Map) + { + mimeType = null; + } + else if (convertedBodyObject instanceof String + && (originalContentType == null + || !MessageConverter_from_1_0.TEXT_CONTENT_TYPES.matcher(originalContentType).matches())) + { + mimeType = "text/plain"; + } + + return mimeType; + } + + private static MessageConverter_from_1_0.ContentHint getInternalTypeHint(final Message_1_0 serverMsg) + { + Symbol contentType = MessageConverter_from_1_0.getContentType(serverMsg); + + JmsMessageTypeAnnotation jmsMessageTypeAnnotation = null; + MessageAnnotationsSection section = serverMsg.getMessageAnnotationsSection(); + if (section != null) + { + Map<Symbol, Object> annotations = section.getValue(); + if (annotations != null && annotations.containsKey(JmsMessageTypeAnnotation.ANNOTATION_KEY)) + { + Object object = annotations.get(JmsMessageTypeAnnotation.ANNOTATION_KEY); + if (object instanceof Byte) + { + try + { + jmsMessageTypeAnnotation = JmsMessageTypeAnnotation.valueOf(((Byte) object)); + } + catch (IllegalArgumentException e) + { + // ignore + } + } + } + } + + Class<?> classHint = null; + String mimeTypeHint = null; + + if (jmsMessageTypeAnnotation != null) + { + switch (jmsMessageTypeAnnotation) + { + case MESSAGE: + classHint = Void.class; + break; + case MAP_MESSAGE: + classHint = Map.class; + break; + case BYTES_MESSAGE: + classHint = byte[].class; + break; + case OBJECT_MESSAGE: + classHint = Serializable.class; + break; + case TEXT_MESSAGE: + classHint = String.class; + break; + case STREAM_MESSAGE: + classHint = List.class; + break; + default: + throw new ServerScopedRuntimeException(String.format( + "Unexpected jms message type annotation %s", jmsMessageTypeAnnotation)); + } + } + + if (contentType != null) + { + Class<?> contentTypeClassHint = null; + String type = contentType.toString(); + if (MessageConverter_from_1_0.TEXT_CONTENT_TYPES.matcher(type).matches()) + { + contentTypeClassHint = String.class; + } + else if (MessageConverter_from_1_0.MAP_MESSAGE_CONTENT_TYPES.matcher(type).matches()) + { + contentTypeClassHint = Map.class; + } + else if (MessageConverter_from_1_0.LIST_MESSAGE_CONTENT_TYPES.matcher(type).matches()) + { + contentTypeClassHint = List.class; + } + else if (MessageConverter_from_1_0.OBJECT_MESSAGE_CONTENT_TYPES.matcher(type).matches()) + { + contentTypeClassHint = Serializable.class; + } + else if (MessageConverter_from_1_0.BYTES_MESSAGE_CONTENT_TYPES.matcher(type).matches()) + { + contentTypeClassHint = byte[].class; + } + + if (classHint == null || classHint == contentTypeClassHint) + { + classHint = contentTypeClassHint; + } + mimeTypeHint = contentType.toString(); + } + + return new MessageConverter_from_1_0.ContentHint(classHint, mimeTypeHint); + } } http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_InternalTest.java ---------------------------------------------------------------------- diff --git a/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_InternalTest.java b/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_InternalTest.java new file mode 100644 index 0000000..6c68154 --- /dev/null +++ b/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/MessageConverter_v1_0_to_InternalTest.java @@ -0,0 +1,744 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.qpid.server.protocol.v1_0; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertArrayEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.google.common.io.ByteStreams; +import org.mockito.ArgumentCaptor; + +import org.apache.qpid.server.bytebuffer.QpidByteBuffer; +import org.apache.qpid.server.message.internal.InternalMessage; +import org.apache.qpid.server.model.NamedAddressSpace; +import org.apache.qpid.server.protocol.v1_0.type.Binary; +import org.apache.qpid.server.protocol.v1_0.type.Symbol; +import org.apache.qpid.server.protocol.v1_0.type.messaging.AmqpSequence; +import org.apache.qpid.server.protocol.v1_0.type.messaging.AmqpValue; +import org.apache.qpid.server.protocol.v1_0.type.messaging.ApplicationProperties; +import org.apache.qpid.server.protocol.v1_0.type.messaging.Data; +import org.apache.qpid.server.protocol.v1_0.type.messaging.DeliveryAnnotations; +import org.apache.qpid.server.protocol.v1_0.type.messaging.EncodingRetainingSection; +import org.apache.qpid.server.protocol.v1_0.type.messaging.Footer; +import org.apache.qpid.server.protocol.v1_0.type.messaging.Header; +import org.apache.qpid.server.protocol.v1_0.type.messaging.MessageAnnotations; +import org.apache.qpid.server.protocol.v1_0.type.messaging.Properties; +import org.apache.qpid.server.protocol.v1_0.type.messaging.Source; +import org.apache.qpid.server.store.StoredMessage; +import org.apache.qpid.server.util.ByteBufferUtils; +import org.apache.qpid.test.utils.QpidTestCase; + +public class MessageConverter_v1_0_to_InternalTest extends QpidTestCase +{ + private static final MessageAnnotations MESSAGE_MESSAGE_ANNOTATION = + new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), (byte) 0)); + private static final MessageAnnotations OBJECT_MESSAGE_MESSAGE_ANNOTATION = + new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), (byte) 1)); + private static final MessageAnnotations MAP_MESSAGE_MESSAGE_ANNOTATION = + new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), (byte) 2)); + private static final MessageAnnotations BYTE_MESSAGE_MESSAGE_ANNOTATION = + new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), (byte) 3)); + private static final MessageAnnotations STREAM_MESSAGE_MESSAGE_ANNOTATION = + new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), (byte) 4)); + private static final MessageAnnotations TEXT_MESSAGE_MESSAGE_ANNOTATION = + new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), (byte) 5)); + private MessageConverter_v1_0_to_Internal _converter; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _converter = new MessageConverter_v1_0_to_Internal(); + } + + public void testAmqpValueWithNullWithTextMessageAnnotation() throws Exception + { + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = + createTestMessage(TEXT_MESSAGE_MESSAGE_ANNOTATION, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertNull("Unexpected content", convertedMessage.getMessageBody()); + assertEquals("Unexpected mime type", "text/plain", convertedMessage.getMessageHeader().getMimeType()); + } + + public void testAmqpValueWithNullWithMessageAnnotation() throws Exception + { + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = + createTestMessage(MESSAGE_MESSAGE_ANNOTATION, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertNull("Unexpected content", convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithNullWithObjectMessageAnnotation() throws Exception + { + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(OBJECT_MESSAGE_MESSAGE_ANNOTATION, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + final Collection<QpidByteBuffer> content = convertedMessage.getContent(0, (int) convertedMessage.getSize()); + + assertEquals("Unexpected mime type", + "application/x-java-serialized-object", + convertedMessage.getMessageHeader().getMimeType()); + assertNull("Unexpected content", convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithNullWithMapMessageAnnotation() throws Exception + { + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(MAP_MESSAGE_MESSAGE_ANNOTATION, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + final Collection<QpidByteBuffer> content = convertedMessage.getContent(0, (int) convertedMessage.getSize()); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertNull("Unexpected content", convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithNullWithBytesMessageAnnotation() throws Exception + { + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(BYTE_MESSAGE_MESSAGE_ANNOTATION, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + "application/octet-stream", + convertedMessage.getMessageHeader().getMimeType()); + assertNull("Unexpected content", convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithNullWithStreamMessageAnnotation() throws Exception + { + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(STREAM_MESSAGE_MESSAGE_ANNOTATION, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertNull("Unexpected content", convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithNullWithUnknownMessageAnnotation() throws Exception + { + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = + createTestMessage(new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), + (byte) 11)), + amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertNull("Unexpected content", convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithNullWithContentType() throws Exception + { + Properties properties = new Properties(); + final String mimeType = "foo/bar"; + properties.setContentType(Symbol.valueOf(mimeType)); + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(properties, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + mimeType, convertedMessage.getMessageHeader().getMimeType()); + assertNull("Unexpected content", convertedMessage.getMessageBody()); + } + + + public void testAmqpValueWithNull() throws Exception + { + final Object expected = null; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertNull("Unexpected content", convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithString() throws Exception + { + final String expected = "testContent"; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", "text/plain", convertedMessage.getMessageHeader().getMimeType()); + final Collection<QpidByteBuffer> content = convertedMessage.getContent(0, (int) convertedMessage.getSize()); + assertEquals("Unexpected content", expected, convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithStringWithKnownTextualContentType() throws Exception + { + Properties properties = new Properties(); + final String mimeType = "text/foo"; + properties.setContentType(Symbol.valueOf(mimeType)); + final Object expected = "content"; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(properties, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + mimeType, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", expected, convertedMessage.getMessageBody()); + } + + public void testAmqpValueWithStringWithUnknownTextualContentType() throws Exception + { + Properties properties = new Properties(); + final String mimeType = "foo/bar"; + properties.setContentType(Symbol.valueOf(mimeType)); + final Object expected = "content"; + final AmqpValue amqpValue = new AmqpValue(expected); + Message_1_0 sourceMessage = createTestMessage(properties, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + "text/plain", convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", expected, convertedMessage.getMessageBody()); + } + + + public void testAmqpValueWithMap() throws Exception + { + final Map<Object, Object> originalMap = new LinkedHashMap<>(); + originalMap.put("binaryEntry", new Binary(new byte[]{0x00, (byte) 0xFF})); + originalMap.put("intEntry", 42); + originalMap.put("uuidEntry", UUID.randomUUID()); + originalMap.put("nullEntry", null); + originalMap.put(43, "nonstringkey"); + originalMap.put("mapEntry", Collections.singletonMap("foo", "bar")); + final AmqpValue amqpValue = new AmqpValue(originalMap); + Message_1_0 sourceMessage = createTestMessage(amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + + Map<Object, Object> convertedMap = (Map<Object, Object>) convertedMessage.getMessageBody(); + + assertEquals("Unexpected size", originalMap.size(), convertedMap.size()); + assertArrayEquals("Unexpected binary entry", ((Binary) originalMap.get("binaryEntry")).getArray(), + (byte[]) convertedMap.get("binaryEntry")); + assertEquals("Unexpected int entry", originalMap.get("intEntry"), convertedMap.get("intEntry")); + assertEquals("Unexpected null entry", originalMap.get("nullEntry"), convertedMap.get("nullEntry")); + assertEquals("Unexpected uuid entry", originalMap.get("uuidEntry"), convertedMap.get("uuidEntry")); + assertEquals("Unexpected nonstringkey entry", originalMap.get(43), convertedMap.get(43)); + assertEquals("Unexpected map entry", new HashMap((Map) originalMap.get("mapEntry")), new HashMap((Map) convertedMap.get("mapEntry"))); + } + + public void testAmqpValueWithList() throws Exception + { + final List<Object> originalList = new ArrayList<>(); + originalList.add(new Binary(new byte[]{0x00, (byte) 0xFF})); + originalList.add(42); + originalList.add(null); + originalList.add(Collections.singletonMap("foo", "bar")); + final AmqpValue amqpValue = new AmqpValue(originalList); + Message_1_0 sourceMessage = createTestMessage(amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + + List<Object> convertedList = ((List<Object>) convertedMessage.getMessageBody()); + assertEquals("Unexpected size", originalList.size(), convertedList.size()); + assertArrayEquals("Unexpected binary item", ((Binary) originalList.get(0)).getArray(), + (byte[]) convertedList.get(0)); + assertEquals("Unexpected int item", originalList.get(1), convertedList.get(1)); + assertEquals("Unexpected null item", originalList.get(2), convertedList.get(2)); + assertEquals("Unexpected map item", new HashMap((Map) originalList.get(3)), new HashMap((Map) convertedList.get(3))); + } + + + public void testAmqpValueWithAmqpType() throws Exception + { + final Date originalValue = new Date(); + final AmqpValue amqpValue = new AmqpValue(originalValue); + Properties properties = new Properties(); + final String mimeType = "foo/bar"; + properties.setContentType(Symbol.valueOf(mimeType)); + Message_1_0 sourceMessage = createTestMessage(properties, amqpValue.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", mimeType, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", originalValue, convertedMessage.getMessageBody()); + } + + public void testAmqpSequenceWithSimpleTypes() throws Exception + { + final List<Object> originalList = new ArrayList<>(); + originalList.add(37); + originalList.add(42F); + final AmqpSequence amqpSequence = new AmqpSequence(originalList); + Message_1_0 sourceMessage = createTestMessage(amqpSequence.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + List<Object> convertedList = ((List<Object>) convertedMessage.getMessageBody()); + assertEquals("Unexpected size", originalList.size(), convertedList.size()); + assertEquals("Unexpected first item", originalList.get(0), convertedList.get(0)); + assertEquals("Unexpected second item", originalList.get(1), convertedList.get(1)); + } + + public void testDataWithMessageAnnotation() throws Exception + { + final byte[] data = "helloworld".getBytes(UTF_8); + doTestDataWithAnnotation(data, MESSAGE_MESSAGE_ANNOTATION, null, "application/octet-stream"); + + } + + public void testDataWithMessageAnnotationWithContentType() throws Exception + { + final byte[] data = "helloworld".getBytes(UTF_8); + final String mimeType = "foo/bar"; + doTestDataWithAnnotation(data, MESSAGE_MESSAGE_ANNOTATION, mimeType, mimeType); + } + + public void testDataWithObjectMessageAnnotation() throws Exception + { + byte[] bytes = "helloworld".getBytes(UTF_8); + final byte[] expected = getObjectBytes(bytes); + doTestDataWithAnnotation(expected, OBJECT_MESSAGE_MESSAGE_ANNOTATION, + null, + "application/x-java-serialized-object"); + } + + public void testDataWithObjectMessageAnnotationWithContentType() throws Exception + { + byte[] bytes = "helloworld".getBytes(UTF_8); + final byte[] expected = getObjectBytes(bytes); + final String mimeType = "foo/bar"; + doTestDataWithAnnotation(expected, OBJECT_MESSAGE_MESSAGE_ANNOTATION, mimeType, mimeType); + } + + public void testDataWithMapMessageAnnotation() throws Exception + { + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), + MAP_MESSAGE_MESSAGE_ANNOTATION, + null, "application/octet-stream"); + } + + public void testDataWithMapMessageAnnotationWithContentType() throws Exception + { + final String mimeType = "foor/bar"; + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), + MAP_MESSAGE_MESSAGE_ANNOTATION, + mimeType, mimeType); + } + + public void testDataWithBytesMessageAnnotation() throws Exception + { + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), + BYTE_MESSAGE_MESSAGE_ANNOTATION, + null, "application/octet-stream"); + } + + public void testDataWithBytesMessageAnnotationWithContentType() throws Exception + { + final String mimeType = "foo/bar"; + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), + BYTE_MESSAGE_MESSAGE_ANNOTATION, + mimeType, mimeType); + } + + public void testDataWithStreamMessageAnnotation() throws Exception + { + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), STREAM_MESSAGE_MESSAGE_ANNOTATION, + null, "application/octet-stream"); + } + + public void testDataWithStreamMessageAnnotationWithContentType() throws Exception + { + final String mimeType = "foo/bar"; + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), STREAM_MESSAGE_MESSAGE_ANNOTATION, + mimeType, mimeType); + } + + public void testDataWithTextMessageAnnotation() throws Exception + { + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), TEXT_MESSAGE_MESSAGE_ANNOTATION, null, "application/octet-stream"); + } + + public void testDataWithTextMessageAnnotationWithContentType() throws Exception + { + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), TEXT_MESSAGE_MESSAGE_ANNOTATION, "foo/bar", "foo/bar"); + } + + public void testDataWithUnsupportedMessageAnnotation() throws Exception + { + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), + new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), + (byte) 11)), + null, "application/octet-stream"); + } + + public void testDataWithUnsupportedMessageAnnotationWithContentType() throws Exception + { + final String mimeType = "foo/bar"; + doTestDataWithAnnotation("helloworld".getBytes(UTF_8), + new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), + (byte) 11)), + mimeType, mimeType); + } + + public void testData() throws Exception + { + final byte[] expected = getObjectBytes("helloworld".getBytes(UTF_8)); + final Data value = new Data(new Binary(expected)); + final Message_1_0 sourceMessage = createTestMessage(value.createEncodingRetainingSection()); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + "application/octet-stream", + convertedMessage.getMessageHeader().getMimeType()); + assertArrayEquals("Unexpected content", expected, ((byte[]) convertedMessage.getMessageBody())); + } + + public void testNoBodyWithMessageAnnotation() throws Exception + { + Message_1_0 sourceMessage = createTestMessage(MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithObjectMessageAnnotation() throws Exception + { + Message_1_0 sourceMessage = createTestMessage(OBJECT_MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + "application/x-java-serialized-object", + convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithMapMessageAnnotation() throws Exception + { + Message_1_0 sourceMessage = createTestMessage(MAP_MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithBytesMessageAnnotation() throws Exception + { + Message_1_0 sourceMessage = createTestMessage(BYTE_MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + "application/octet-stream", + convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithStreamMessageAnnotation() throws Exception + { + Message_1_0 sourceMessage = createTestMessage(STREAM_MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithTextMessageAnnotation() throws Exception + { + Message_1_0 sourceMessage = createTestMessage(TEXT_MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", "text/plain", convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithTextMessageAnnotationWithKnownTextualContentType() throws Exception + { + final String mimeType = "text/foo"; + Properties properties = new Properties(); + properties.setContentType(Symbol.valueOf(mimeType)); + + Message_1_0 sourceMessage = createTestMessage(properties, TEXT_MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", mimeType, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithTextMessageAnnotationWithUnknownTextualContentType() throws Exception + { + final String mimeType = "foo/bar"; + Properties properties = new Properties(); + properties.setContentType(Symbol.valueOf(mimeType)); + Message_1_0 sourceMessage = createTestMessage(properties, TEXT_MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", "text/plain", convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + + public void testNoBodyWithUnknownMessageAnnotation() throws Exception + { + Message_1_0 sourceMessage = + createTestMessage(new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), + (byte) 11)), null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithUnknownMessageAnnotationWithContentType() throws Exception + { + + final String mimeType = "foo/bar"; + Properties properties = new Properties(); + properties.setContentType(Symbol.valueOf(mimeType)); + Message_1_0 sourceMessage = + createTestMessage(properties, new MessageAnnotations(Collections.singletonMap(Symbol.valueOf("x-opt-jms-msg-type"), + (byte) 11)), null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", mimeType, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBody() throws Exception + { + final Message_1_0 sourceMessage = createTestMessage(null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", null, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testNoBodyWithContentTypeApplicationOctetStream() throws Exception + { + final String mimeType = "foo/bar"; + Properties properties = new Properties(); + properties.setContentType(Symbol.valueOf(mimeType)); + final Message_1_0 sourceMessage = createTestMessage(properties, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", mimeType, convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + public void testMessageAnnotationTakesPrecedenceOverContentType() throws Exception + { + final Properties properties = new Properties(); + properties.setContentType(Symbol.valueOf("application/octet-stream")); + final Message_1_0 sourceMessage = createTestMessage(OBJECT_MESSAGE_MESSAGE_ANNOTATION, null); + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + "application/x-java-serialized-object", + convertedMessage.getMessageHeader().getMimeType()); + assertEquals("Unexpected content", null, convertedMessage.getMessageBody()); + } + + private byte[] getBytes(final Collection<QpidByteBuffer> content) throws Exception + { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + for (QpidByteBuffer buf : content) + { + ByteStreams.copy(buf.asInputStream(), bos); + buf.dispose(); + } + return bos.toByteArray(); + } + + private Message_1_0 createTestMessage(final EncodingRetainingSection encodingRetainingSection) + { + return createTestMessage(new Properties(), encodingRetainingSection); + } + + private Message_1_0 createTestMessage(final Properties properties, final EncodingRetainingSection section) + { + return createTestMessage(new Header(), + new DeliveryAnnotations(Collections.emptyMap()), + new MessageAnnotations(Collections.emptyMap()), + properties, + new ApplicationProperties(Collections.emptyMap()), + 0, + section); + } + + private Message_1_0 createTestMessage(final Properties properties, + final MessageAnnotations messageAnnotations, + final EncodingRetainingSection section) + { + return createTestMessage(new Header(), + new DeliveryAnnotations(Collections.emptyMap()), + messageAnnotations, + properties, + new ApplicationProperties(Collections.emptyMap()), + 0, + section); + } + + private Message_1_0 createTestMessage(final MessageAnnotations messageAnnotations, + final EncodingRetainingSection section) + { + return createTestMessage(new Header(), + new DeliveryAnnotations(Collections.emptyMap()), + messageAnnotations, + new Properties(), + new ApplicationProperties(Collections.emptyMap()), + 0, + section); + } + + private Message_1_0 createTestMessage(final Header header, + final DeliveryAnnotations deliveryAnnotations, + final MessageAnnotations messageAnnotations, + final Properties properties, + final ApplicationProperties applicationProperties, + final long arrivalTime, + final EncodingRetainingSection section) + { + final StoredMessage<MessageMetaData_1_0> storedMessage = mock(StoredMessage.class); + MessageMetaData_1_0 metaData = new MessageMetaData_1_0(header.createEncodingRetainingSection(), + deliveryAnnotations.createEncodingRetainingSection(), + messageAnnotations.createEncodingRetainingSection(), + properties.createEncodingRetainingSection(), + applicationProperties.createEncodingRetainingSection(), + new Footer(Collections.emptyMap()).createEncodingRetainingSection(), + arrivalTime, + 0); + when(storedMessage.getMetaData()).thenReturn(metaData); + + if (section != null) + { + final QpidByteBuffer combined = QpidByteBuffer.wrap(ByteBufferUtils.combine(section.getEncodedForm())); + when(storedMessage.getContentSize()).thenReturn((int) section.getEncodedSize()); + final ArgumentCaptor<Integer> offsetCaptor = ArgumentCaptor.forClass(Integer.class); + final ArgumentCaptor<Integer> sizeCaptor = ArgumentCaptor.forClass(Integer.class); + + when(storedMessage.getContent(offsetCaptor.capture(), + sizeCaptor.capture())).then(invocation -> + { + final QpidByteBuffer view = combined.view( + offsetCaptor.getValue(), + sizeCaptor.getValue()); + return Collections.singleton(view); + }); + } + return new Message_1_0(storedMessage); + } + + private byte[] getObjectBytes(final Object object) throws IOException + { + final byte[] expected; + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos)) + { + oos.writeObject(object); + expected = baos.toByteArray(); + } + return expected; + } + + private void doTestDataWithAnnotation(final byte[] data, + final MessageAnnotations messageAnnotations, + final String mimeType, final String expectedMimeType) throws Exception + { + + final Data value = new Data(new Binary(data)); + + Message_1_0 sourceMessage; + if (mimeType != null) + { + Properties properties = new Properties(); + properties.setContentType(Symbol.valueOf(mimeType)); + sourceMessage = createTestMessage(properties, messageAnnotations, value.createEncodingRetainingSection()); + } + else + { + sourceMessage = createTestMessage(messageAnnotations, value.createEncodingRetainingSection()); + } + + final InternalMessage convertedMessage = _converter.convert(sourceMessage, mock(NamedAddressSpace.class)); + + assertEquals("Unexpected mime type", + expectedMimeType, convertedMessage.getMessageHeader().getMimeType()); + assertArrayEquals("Unexpected content", data, ((byte[]) convertedMessage.getMessageBody())); + + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-plugins/amqp-msg-conv-0-10-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_10_v1_0/MessageConverter_1_0_to_v0_10.java ---------------------------------------------------------------------- diff --git a/broker-plugins/amqp-msg-conv-0-10-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_10_v1_0/MessageConverter_1_0_to_v0_10.java b/broker-plugins/amqp-msg-conv-0-10-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_10_v1_0/MessageConverter_1_0_to_v0_10.java index ad94f42..c10a232 100644 --- a/broker-plugins/amqp-msg-conv-0-10-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_10_v1_0/MessageConverter_1_0_to_v0_10.java +++ b/broker-plugins/amqp-msg-conv-0-10-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_10_v1_0/MessageConverter_1_0_to_v0_10.java @@ -23,7 +23,7 @@ package org.apache.qpid.server.protocol.converter.v0_10_v1_0; import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.convertValue; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getAbsoluteExpiryTime; -import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getConvertedContentAndMimeType; +import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getAmqp0xConvertedContentAndMimeType; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getCorrelationId; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getCreationTime; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getGroupId; @@ -103,7 +103,7 @@ public class MessageConverter_1_0_to_v0_10 implements MessageConverter<Message_1 private StoredMessage<MessageMetaData_0_10> convertToStoredMessage(final Message_1_0 serverMsg, final NamedAddressSpace addressSpace) { - final ConvertedContentAndMimeType convertedContentAndMimeType = getConvertedContentAndMimeType(serverMsg); + final ConvertedContentAndMimeType convertedContentAndMimeType = getAmqp0xConvertedContentAndMimeType(serverMsg); final byte[] convertedContent = convertedContentAndMimeType.getContent(); final MessageMetaData_0_10 messageMetaData_0_10 = convertMetaData(serverMsg, addressSpace, http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/PropertyConverter_0_10_to_0_8Test.java ---------------------------------------------------------------------- diff --git a/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/PropertyConverter_0_10_to_0_8Test.java b/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/PropertyConverter_0_10_to_0_8Test.java index 1c2f2a1..e46d732 100644 --- a/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/PropertyConverter_0_10_to_0_8Test.java +++ b/broker-plugins/amqp-msg-conv-0-8-to-0-10/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v0_10/PropertyConverter_0_10_to_0_8Test.java @@ -120,24 +120,6 @@ public class PropertyConverter_0_10_to_0_8Test extends QpidTestCase assertEquals("Unexpected subject in application properties", testSubject, applicationProperties.get("qpid.subject")); } - public void testApplicationHeadersConversionContainingInconvertibleValues() - { - Map<String, Object> headers = Collections.singletonMap("testUUID", UUID.randomUUID()); - final MessageProperties messageProperties = new MessageProperties(); - messageProperties.setApplicationHeaders(headers); - MessageTransferMessage message = createTestMessage(messageProperties); - - try - { - _messageConverter.convert(message, _namedAddressSpace); - fail("Exception is not thrown"); - } - catch (MessageConversionException e) - { - // pass - } - } - public void testPersistentDeliveryModeConversion() { MessageDeliveryMode deliveryMode = MessageDeliveryMode.PERSISTENT; http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/MessageConverter_1_0_to_v0_8.java ---------------------------------------------------------------------- diff --git a/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/MessageConverter_1_0_to_v0_8.java b/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/MessageConverter_1_0_to_v0_8.java index 30f4235..73e6b65 100644 --- a/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/MessageConverter_1_0_to_v0_8.java +++ b/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/main/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/MessageConverter_1_0_to_v0_8.java @@ -23,7 +23,7 @@ package org.apache.qpid.server.protocol.converter.v0_8_v1_0; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.convertValue; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getAbsoluteExpiryTime; -import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getConvertedContentAndMimeType; +import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getAmqp0xConvertedContentAndMimeType; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getCorrelationId; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getCreationTime; import static org.apache.qpid.server.protocol.v1_0.MessageConverter_from_1_0.getGroupId; @@ -90,7 +90,7 @@ public class MessageConverter_1_0_to_v0_8 implements MessageConverter<Message_1_ private StoredMessage<MessageMetaData> convertToStoredMessage(final Message_1_0 serverMsg, final NamedAddressSpace addressSpace) { - final ConvertedContentAndMimeType convertedContentAndMimeType = getConvertedContentAndMimeType(serverMsg); + final ConvertedContentAndMimeType convertedContentAndMimeType = getAmqp0xConvertedContentAndMimeType(serverMsg); final byte[] convertedContent = convertedContentAndMimeType.getContent(); final MessageMetaData messageMetaData_0_8 = convertMetaData(serverMsg, http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/2e809efc/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/PropertyConverter_1_0_to_0_8Test.java ---------------------------------------------------------------------- diff --git a/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/PropertyConverter_1_0_to_0_8Test.java b/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/PropertyConverter_1_0_to_0_8Test.java index 067fe35..efd35fd 100644 --- a/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/PropertyConverter_1_0_to_0_8Test.java +++ b/broker-plugins/amqp-msg-conv-0-8-to-1-0/src/test/java/org/apache/qpid/server/protocol/converter/v0_8_v1_0/PropertyConverter_1_0_to_0_8Test.java @@ -116,6 +116,40 @@ public class PropertyConverter_1_0_to_0_8Test extends QpidTestCase assertEquals("Unexpected headers", properties, new HashMap<>(headers)); } + public void testApplicationPropertiesConversionWithUuid() + { + Map<String, Object> properties = new HashMap<>(); + final String key = "uuidProperty"; + properties.put(key, UUID.randomUUID()); + ApplicationProperties applicationProperties = new ApplicationProperties(properties); + Message_1_0 message = createTestMessage(applicationProperties); + + final AMQMessage convertedMessage = _messageConverter.convert(message, _namedAddressSpace); + + BasicContentHeaderProperties convertedProperties = convertedMessage.getContentHeaderBody().getProperties(); + final Map<String, Object> headers = FieldTable.convertToMap(convertedProperties.getHeaders()); + assertEquals("Unexpected headers size", properties.size(), headers.size()); + assertEquals("Unexpected headers", properties.get(key), UUID.fromString((String) headers.get(key))); + + } + + public void testApplicationPropertiesConversionWithDate() + { + Map<String, Object> properties = new HashMap<>(); + final String key = "dateProperty"; + properties.put(key, new Date()); + ApplicationProperties applicationProperties = new ApplicationProperties(properties); + Message_1_0 message = createTestMessage(applicationProperties); + + final AMQMessage convertedMessage = _messageConverter.convert(message, _namedAddressSpace); + + BasicContentHeaderProperties convertedProperties = convertedMessage.getContentHeaderBody().getProperties(); + final Map<String, Object> headers = FieldTable.convertToMap(convertedProperties.getHeaders()); + assertEquals("Unexpected headers size", properties.size(), headers.size()); + assertEquals("Unexpected headers", properties.get(key), new Date((Long) headers.get(key))); + + } + public void testSubjectConversion() { final String subject = "testSubject"; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org