| /* |
| * 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. |
| */ |
| |
| using System; |
| using System.Collections.Generic; |
| using System.IO; |
| using System.Runtime.Serialization.Formatters.Binary; |
| using Amqp.Framing; |
| using Amqp.Types; |
| using Apache.NMS; |
| using Apache.NMS.AMQP.Provider.Amqp.Message; |
| using Apache.NMS.AMQP.Util; |
| using NUnit.Framework; |
| |
| namespace NMS.AMQP.Test.Provider.Amqp |
| { |
| [TestFixture] |
| public class AmqpNmsObjectMessageFacadeTest : AmqpNmsMessageTypesTestCase |
| { |
| // ---------- Test initial state of newly created message -----------------// |
| |
| [Test] |
| public void TestNewMessageToSendDoesNotContainMessageTypeAnnotation() |
| { |
| AmqpNmsObjectMessageFacade amqpObjectMessageFacade = CreateNewObjectMessageFacade(false); |
| Assert.Null(amqpObjectMessageFacade.MessageAnnotations); |
| |
| Assert.IsNull(amqpObjectMessageFacade.JmsMsgType); |
| } |
| |
| [Test] |
| public void TestNewMessageToSendReturnsNullObject() |
| { |
| DoNewMessageToSendReturnsNullObjectTestImpl(false); |
| } |
| |
| [Test] |
| public void TestNewAmqpTypedMessageToSendReturnsNullObject() |
| { |
| DoNewMessageToSendReturnsNullObjectTestImpl(true); |
| } |
| |
| private void DoNewMessageToSendReturnsNullObjectTestImpl(bool amqpTyped) |
| { |
| AmqpNmsObjectMessageFacade amqpObjectMessageFacade = CreateNewObjectMessageFacade(amqpTyped); |
| Assert.Null(amqpObjectMessageFacade.Body); |
| } |
| |
| [Test] |
| public void TestNewMessageToSendHasBodySectionRepresentingNull() |
| { |
| DoNewMessageToSendHasBodySectionRepresentingNull(false); |
| } |
| |
| [Test] |
| public void TestNewAmqpTypedMessageToSendHasBodySectionRepresentingNull() |
| { |
| DoNewMessageToSendHasBodySectionRepresentingNull(true); |
| } |
| |
| private void DoNewMessageToSendHasBodySectionRepresentingNull(bool amqpTyped) |
| { |
| AmqpNmsObjectMessageFacade amqpObjectMessageFacade = CreateNewObjectMessageFacade(amqpTyped); |
| amqpObjectMessageFacade.OnSend(TimeSpan.Zero); |
| |
| Assert.NotNull(amqpObjectMessageFacade.Message.BodySection, "Message body should be presents"); |
| if (amqpTyped) |
| Assert.AreSame(AmqpTypedObjectDelegate.NULL_OBJECT_BODY, amqpObjectMessageFacade.Message.BodySection, "Expected existing body section to be replaced"); |
| else |
| Assert.AreSame(AmqpSerializedObjectDelegate.NULL_OBJECT_BODY, amqpObjectMessageFacade.Message.BodySection, "Expected existing body section to be replaced"); |
| } |
| |
| // ---------- test for normal message operations -------------------------// |
| |
| /* |
| * Test that Bytes setting an object on a new message results in the expected |
| * content in the body section of the underlying message. |
| */ |
| [Test] |
| public void TestSetObjectOnNewMessage() |
| { |
| String content = "myStringContent"; |
| |
| AmqpNmsObjectMessageFacade amqpObjectMessageFacade = CreateNewObjectMessageFacade(); |
| amqpObjectMessageFacade.Body = content; |
| |
| var bytes = GetSerializedBytes(content); |
| |
| // retrieve the bytes from the underlying message, check they match expectation |
| RestrictedDescribed messageBodySection = amqpObjectMessageFacade.Message.BodySection; |
| Assert.NotNull(messageBodySection); |
| |
| Assert.IsInstanceOf<Data>(messageBodySection); |
| CollectionAssert.AreEqual(bytes, ((Data) messageBodySection).Binary, "Underlying message data section did not contain the expected bytes"); |
| } |
| |
| /* |
| * Test that setting an object on a new message results in the expected |
| * content in the body section of the underlying message. |
| */ |
| [Test] |
| public void TestSetObjectOnNewAmqpTypedMessage() |
| { |
| String content = "myStringContent"; |
| |
| AmqpNmsObjectMessageFacade amqpObjectMessageFacade = CreateNewObjectMessageFacade(true); |
| amqpObjectMessageFacade.Body = content; |
| |
| // retrieve the body from the underlying message, check it matches expectation |
| RestrictedDescribed section = amqpObjectMessageFacade.Message.BodySection; |
| Assert.NotNull(section); |
| Assert.IsInstanceOf<AmqpValue>(section); |
| Assert.AreEqual(content, ((AmqpValue) section).Value); |
| } |
| |
| /* |
| * Test that setting a null object on a message results in the underlying body |
| * section being set with the null object body, ensuring getObject returns null. |
| */ |
| [Test] |
| public void TestSetObjectWithNullClearsExistingBodySection() |
| { |
| global::Amqp.Message message = new global::Amqp.Message |
| { |
| Properties = new Properties |
| { |
| ContentType = MessageSupport.SERIALIZED_DOTNET_OBJECT_CONTENT_TYPE |
| }, |
| BodySection = new Data |
| { |
| Binary = new byte[0] |
| } |
| }; |
| |
| AmqpNmsObjectMessageFacade facade = CreateReceivedObjectMessageFacade(message); |
| |
| Assert.NotNull(facade.Message.BodySection, "Expected existing body section to be found"); |
| facade.Body = null; |
| Assert.AreSame(AmqpSerializedObjectDelegate.NULL_OBJECT_BODY, facade.Message.BodySection, "Expected existing body section to be replaced"); |
| Assert.Null(facade.Body); |
| } |
| |
| /* |
| * Test that clearing the body on a message results in the underlying body |
| * section being set with the null object body, ensuring getObject returns null. |
| */ |
| [Test] |
| public void TestClearBodyWithExistingSerializedBodySection() |
| { |
| global::Amqp.Message message = new global::Amqp.Message |
| { |
| Properties = new Properties |
| { |
| ContentType = MessageSupport.SERIALIZED_DOTNET_OBJECT_CONTENT_TYPE |
| }, |
| BodySection = new Data |
| { |
| Binary = new byte[0] |
| } |
| }; |
| |
| AmqpNmsObjectMessageFacade facade = CreateReceivedObjectMessageFacade(message); |
| |
| Assert.NotNull(facade.Message.BodySection, "Expected existing body section to be found"); |
| facade.ClearBody(); |
| |
| Assert.AreSame(AmqpSerializedObjectDelegate.NULL_OBJECT_BODY, facade.Message.BodySection, "Expected existing body section to be replaced"); |
| Assert.Null(facade.Body); |
| } |
| |
| /* |
| * Test that setting an object on a new message and later getting the value, returns an |
| * equal but different object that does not pick up intermediate changes to the set object. |
| */ |
| [Test] |
| public void TestSetThenGetObjectOnSerializedMessageReturnsSnapshot() |
| { |
| Dictionary<string, string> origMap = new Dictionary<string, string> |
| { |
| {"key1", "value1"} |
| }; |
| |
| AmqpNmsObjectMessageFacade facade = CreateNewObjectMessageFacade(false); |
| facade.Body = origMap; |
| |
| Dictionary<string, string> d = new Dictionary<string, string>(); |
| |
| // verify we get a different-but-equal object back |
| object body = facade.Body; |
| Assert.IsInstanceOf<Dictionary<string, string>>(body); |
| Dictionary<string, string> returnedObject1 = (Dictionary<string, string>) body; |
| Assert.AreNotSame(origMap, returnedObject1, "Expected different objects, due to snapshot being taken"); |
| Assert.AreEqual(origMap, returnedObject1, "Expected equal objects, due to snapshot being taken"); |
| |
| // mutate the original object |
| origMap.Add("key2", "value2"); |
| |
| // verify we get a different-but-equal object back when compared to the previously retrieved object |
| object body2 = facade.Body; |
| Assert.IsInstanceOf<Dictionary<string, string>>(body2); |
| Dictionary<string, string> returnedObject2 = (Dictionary<string, string>) body2; |
| Assert.AreNotSame(origMap, returnedObject2, "Expected different objects, due to snapshot being taken"); |
| Assert.AreEqual(returnedObject1, returnedObject2); |
| |
| // verify the mutated map is a different and not equal object |
| Assert.AreNotSame(returnedObject1, returnedObject2, "Expected different objects, due to snapshot being taken"); |
| Assert.AreNotEqual(origMap, returnedObject2, "Expected objects to differ, due to snapshot being taken"); |
| } |
| |
| // ---------- test handling of received messages -------------------------// |
| |
| [Test] |
| public void TestGetObjectUsingReceivedMessageWithNoBodySectionNoContentTypeReturnsNull() |
| { |
| DoGetObjectUsingReceivedMessageWithNoBodySectionReturnsNullTestImpl(true); |
| } |
| |
| [Test] |
| public void TestGetObjectUsingReceivedMessageWithNoBodySectionReturnsNull() |
| { |
| DoGetObjectUsingReceivedMessageWithNoBodySectionReturnsNullTestImpl(false); |
| } |
| |
| private void DoGetObjectUsingReceivedMessageWithNoBodySectionReturnsNullTestImpl(bool amqpTyped) |
| { |
| global::Amqp.Message message = new global::Amqp.Message(); |
| |
| if (!amqpTyped) |
| { |
| message.Properties = new Properties {ContentType = MessageSupport.SERIALIZED_DOTNET_OBJECT_CONTENT_TYPE}; |
| } |
| |
| AmqpNmsObjectMessageFacade facade = CreateReceivedObjectMessageFacade(message); |
| |
| Assert.Null(facade.Body, "Expected null object"); |
| } |
| |
| [Test] |
| public void TestGetObjectUsingReceivedMessageWithDataSectionContainingNothingReturnsNull() |
| { |
| global::Amqp.Message message = new global::Amqp.Message |
| { |
| Properties = new Properties |
| { |
| ContentType = MessageSupport.SERIALIZED_DOTNET_OBJECT_CONTENT_TYPE |
| }, |
| BodySection = new AmqpValue {Value = "nonBinarySectionContent"} |
| }; |
| |
| AmqpNmsObjectMessageFacade facade = CreateReceivedObjectMessageFacade(message); |
| |
| Assert.Catch<IllegalStateException>(() => |
| { |
| object body = facade.Body; |
| }); |
| } |
| |
| /* |
| * Test that setting an object on a received message and later getting the value, returns an |
| * equal but different object that does not pick up intermediate changes to the set object. |
| */ |
| [Test] |
| public void TestSetThenGetObjectOnSerializedReceivedMessageNoContentTypeReturnsSnapshot() |
| { |
| Dictionary<string, string> origMap = new Dictionary<string, string> |
| { |
| {"key1", "value1"} |
| }; |
| global::Amqp.Message message = new global::Amqp.Message() |
| { |
| Properties = new Properties {ContentType = MessageSupport.SERIALIZED_DOTNET_OBJECT_CONTENT_TYPE}, |
| BodySection = new Data {Binary = GetSerializedBytes(origMap)} |
| }; |
| |
| AmqpNmsObjectMessageFacade facade = CreateReceivedObjectMessageFacade(message); |
| |
| // verify we get a different-but-equal object back |
| object body = facade.Body; |
| Assert.IsInstanceOf<Dictionary<string, string>>(body); |
| Dictionary<string, string> returnedObject1 = (Dictionary<string, string>) body; |
| Assert.AreNotSame(origMap, returnedObject1, "Expected different objects, due to snapshot being taken"); |
| Assert.AreEqual(origMap, returnedObject1, "Expected equal objects, due to snapshot being taken"); |
| |
| |
| // verify we get a different-but-equal object back when compared to the previously retrieved object |
| object body2 = facade.Body; |
| Assert.IsInstanceOf<Dictionary<string, string>>(body2); |
| Dictionary<string, string> returnedObject2 = (Dictionary<string, string>) body2; |
| Assert.AreNotSame(origMap, returnedObject2, "Expected different objects, due to snapshot being taken"); |
| Assert.AreEqual(returnedObject1, returnedObject2); |
| |
| // mutate the original object |
| origMap.Add("key2", "value2"); |
| |
| // verify the mutated map is a different and not equal object |
| Assert.AreNotSame(returnedObject1, returnedObject2, "Expected different objects, due to snapshot being taken"); |
| Assert.AreNotEqual(origMap, returnedObject2, "Expected objects to differ, due to snapshot being taken"); |
| } |
| |
| [Test] |
| public void TestSetThenGetObjectOnSerializedReceivedMessageReturnsSnapshot() |
| { |
| Map origMap = new Map |
| { |
| {"key1", "value1"} |
| }; |
| global::Amqp.Message message = new global::Amqp.Message {BodySection = new AmqpValue {Value = origMap}}; |
| |
| AmqpNmsObjectMessageFacade facade = CreateReceivedObjectMessageFacade(message); |
| |
| // verify we get a different-but-equal object back |
| object body = facade.Body; |
| Assert.IsInstanceOf<Map>(body); |
| Map returnedObject1 = (Map) body; |
| Assert.AreNotSame(origMap, returnedObject1, "Expected different objects, due to snapshot being taken"); |
| Assert.AreEqual(origMap, returnedObject1, "Expected equal objects, due to snapshot being taken"); |
| |
| |
| // verify we get a different-but-equal object back when compared to the previously retrieved object |
| object body2 = facade.Body; |
| Assert.IsInstanceOf<Map>(body2); |
| Map returnedObject2 = (Map) body2; |
| Assert.AreNotSame(origMap, returnedObject2, "Expected different objects, due to snapshot being taken"); |
| Assert.AreEqual(returnedObject1, returnedObject2); |
| |
| // mutate the original object |
| origMap.Add("key2", "value2"); |
| |
| // verify the mutated map is a different and not equal object |
| Assert.AreNotSame(returnedObject1, returnedObject2, "Expected different objects, due to snapshot being taken"); |
| Assert.AreNotEqual(origMap, returnedObject2, "Expected objects to differ, due to snapshot being taken"); |
| } |
| |
| [Test] |
| public void TestMessageCopy() |
| { |
| String content = "myStringContent"; |
| |
| AmqpNmsObjectMessageFacade amqpObjectMessageFacade = CreateNewObjectMessageFacade(); |
| amqpObjectMessageFacade.Body = content; |
| |
| AmqpNmsObjectMessageFacade copy = amqpObjectMessageFacade.Copy() as AmqpNmsObjectMessageFacade; |
| Assert.IsNotNull(copy); |
| Assert.AreEqual(amqpObjectMessageFacade.Body, copy.Body); |
| } |
| |
| private static byte[] GetSerializedBytes(object content) |
| { |
| using (MemoryStream stream = new MemoryStream()) |
| { |
| BinaryFormatter formatter = new BinaryFormatter(); |
| formatter.Serialize(stream, content); |
| byte[] bytes = stream.ToArray(); |
| return bytes; |
| } |
| } |
| } |
| } |