blob: 015b64bd1156d8bd6b93d17412aa0f469e630aa3 [file] [log] [blame]
/*
* 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.AreEqual(MessageSupport.JMS_TYPE_OBJ, 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;
}
}
}
}