diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Configuration.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Configuration.cs
index c31d995f3f42..25ada820b9af 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Configuration.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Configuration.cs
@@ -32,7 +32,7 @@ internal static class Configuration
///
/// Gets the namespace used for testing.
///
- private static string ServiceNamespace { get { throw new NotImplementedException(); } }
+ private static string ServiceNamespace { get { throw new NotImplementedException(); } }
///
/// Gets the user name used for testing.
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Microsoft.WindowsAzure.ServiceLayer.UnitTests.csproj b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Microsoft.WindowsAzure.ServiceLayer.UnitTests.csproj
index fb66e2c1df03..36ee264b446b 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Microsoft.WindowsAzure.ServiceLayer.UnitTests.csproj
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/Microsoft.WindowsAzure.ServiceLayer.UnitTests.csproj
@@ -115,10 +115,14 @@
+
+
+
+
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs
new file mode 100644
index 000000000000..cb22569ae4ea
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs
@@ -0,0 +1,273 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.WindowsAzure.ServiceLayer.Http;
+using Windows.Storage.Streams;
+using Xunit;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.UnitTests.ServiceBusTests
+{
+ ///
+ /// Tests for the Content class.
+ ///
+ public sealed class ContentTests
+ {
+ ///
+ /// Creates a memory content from the given text.
+ ///
+ /// Content text.
+ /// Memory-initialized content with the given text.
+ private static HttpContent CreateMemoryContent(string text)
+ {
+ return HttpContent.CreateFromText(text, "text/plain");
+ }
+
+ ///
+ /// Creates a memory content from the given bytes.
+ ///
+ /// Content data.
+ /// Memory-initialized content with the given bytes.
+ private static HttpContent CreateMemoryContent(params byte[] bytes)
+ {
+ return HttpContent.CreateFromByteArray(bytes);
+ }
+
+ ///
+ /// Creates a stream content from the array of bytes.
+ ///
+ /// Content bytes.
+ /// Stream-initialized content with the given bytes.
+ private static HttpContent CreateStreamContent(params byte[] bytes)
+ {
+ MemoryStream stream = new MemoryStream(bytes);
+ return HttpContent.CreateFromStream(stream.AsInputStream());
+ }
+
+ ///
+ /// Creates a stream content from the given string.
+ ///
+ /// Content string.
+ /// Stream-initialized text content.
+ private static HttpContent CreateStreamContent(string text)
+ {
+ byte[] bytes = Encoding.UTF8.GetBytes(text);
+ MemoryStream stream = new MemoryStream(bytes);
+ return HttpContent.CreateFromStream(stream.AsInputStream());
+ }
+
+
+ ///
+ /// Tests passing invalid arguments into content's constructors.
+ ///
+ [Fact]
+ public void InvalidArgs()
+ {
+ Assert.Throws(() => HttpContent.CreateFromText(null, "text/plain"));
+ Assert.Throws(() => HttpContent.CreateFromText("test", null));
+ Assert.Throws(() => HttpContent.CreateFromByteArray(null));
+ Assert.Throws(() => HttpContent.CreateFromStream(null));
+
+ HttpContent content = HttpContent.CreateFromText("this is a test.", "text/plain");
+ Assert.Throws(() => content.CopyToAsync(null));
+ }
+
+ ///
+ /// Tests reading text content as a string.
+ ///
+ [Fact]
+ public void ReadTextAsString()
+ {
+ string originalContent = Guid.NewGuid().ToString();
+ HttpContent content = CreateMemoryContent(originalContent);
+
+ // Must be able to read multiple times
+ for (int i = 0; i < 2; i++)
+ {
+ string readContent = content.ReadAsStringAsync().AsTask().Result;
+ Assert.Equal(originalContent, readContent, StringComparer.Ordinal);
+ }
+ }
+
+ ///
+ /// Tests reading text content as a bytes array.
+ ///
+ [Fact]
+ public void ReadTextAsBytes()
+ {
+ string originalContent = Guid.NewGuid().ToString();
+ HttpContent content = HttpContent.CreateFromText(originalContent, "text/plain");
+
+ // Must be able to read multiple times.
+ for (int i = 0; i < 2; i++)
+ {
+ List bytes = new List(content.ReadAsByteArrayAsync().AsTask().Result);
+
+ string readContent = Encoding.UTF8.GetString(bytes.ToArray(), 0, bytes.Count);
+ Assert.Equal(originalContent, readContent, StringComparer.Ordinal);
+ }
+ }
+
+ ///
+ /// Tests reading text content as a bytes stream.
+ ///
+ [Fact]
+ public void ReadTextAsStream()
+ {
+ string originalContent = Guid.NewGuid().ToString();
+ HttpContent content = HttpContent.CreateFromText(originalContent, "text/plain");
+
+ // Must be able to read multiple times.
+ for (int i = 0; i < 2; i++)
+ {
+ Stream stream = content.ReadAsStreamAsync().AsTask().Result.AsStreamForRead();
+ using (StreamReader reader = new StreamReader(stream))
+ {
+ string readContent = reader.ReadToEnd();
+ Assert.Equal(originalContent, readContent, StringComparer.Ordinal);
+ }
+ }
+ }
+
+ ///
+ /// Tests buffering memory content (which is a no-op operation).
+ ///
+ [Fact]
+ public void BufferMemoryContent()
+ {
+ string originalContent = Guid.NewGuid().ToString();
+ HttpContent content = CreateMemoryContent(originalContent);
+
+ content.CopyToBufferAsync().AsTask().Wait();
+
+ // Must be able to read as many times as we want.
+ for (int i = 0; i < 2; i++)
+ {
+ string readContent = content.ReadAsStringAsync().AsTask().Result;
+ Assert.Equal(originalContent, readContent, StringComparer.Ordinal);
+ }
+ }
+
+ ///
+ /// Tests copying memory content into a stream.
+ ///
+ [Fact]
+ public void CopyMemoryContent()
+ {
+ byte[] originalContent = new byte[] { 1, 2, 3, 4, };
+ HttpContent content = CreateMemoryContent(originalContent);
+
+ // Memory content allows multiple reads.
+ for (int i = 0; i < 2; i++)
+ {
+ using (MemoryStream stream = new MemoryStream())
+ {
+ content.CopyToAsync(stream.AsOutputStream()).AsTask().Wait();
+ stream.Flush();
+ byte[] readContent = stream.ToArray();
+
+ Assert.Equal(originalContent, readContent);
+ }
+ }
+ }
+
+ ///
+ /// Tests reading stream content as a string.
+ ///
+ [Fact]
+ public void ReadStreamAsText()
+ {
+ string originalContent = Guid.NewGuid().ToString();
+ HttpContent content = CreateStreamContent(originalContent);
+
+ // Reading the first time should be OK.
+ string readContent = content.ReadAsStringAsync().AsTask().Result;
+ Assert.Equal(originalContent, readContent, StringComparer.Ordinal);
+
+ // Reading again: there should be nothing left in the stream.
+ readContent = content.ReadAsStringAsync().AsTask().Result;
+ Assert.Equal(readContent, string.Empty, StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests reading stream as a bytes array.
+ ///
+ [Fact]
+ public void ReadStreamAsBytes()
+ {
+ byte[] originalBytes = new byte[] { 1, 2, 3, 4, };
+ HttpContent content = CreateStreamContent(originalBytes);
+ List readBytes = new List(content.ReadAsByteArrayAsync().AsTask().Result);
+
+ Assert.Equal(originalBytes, readBytes);
+
+ // Reading again: there should be nothing left in the stream.
+ readBytes = new List(content.ReadAsByteArrayAsync().AsTask().Result);
+ Assert.Equal(readBytes.Count, 0);
+ }
+
+ ///
+ /// Tests buffering stream content.
+ ///
+ [Fact]
+ public void BufferStreamContent()
+ {
+ byte[] originalBytes = new byte[] { 1, 2, 3, 4, };
+ HttpContent content = CreateStreamContent(originalBytes);
+
+ // Reading multiple times should work after buffering.
+ content.CopyToBufferAsync().AsTask().Wait();
+
+ for (int i = 0; i < 2; i++)
+ {
+ List readBytes = new List(
+ content.ReadAsByteArrayAsync().AsTask().Result);
+ Assert.Equal(originalBytes, readBytes);
+ }
+ }
+
+ ///
+ /// Tests copying stream content into a stream.
+ ///
+ [Fact]
+ public void CopyStreamContent()
+ {
+ byte[] originalContent = new byte[] { 1, 2, 3, 4, };
+ HttpContent content = CreateStreamContent(originalContent);
+
+ using (MemoryStream stream = new MemoryStream())
+ {
+ content.CopyToAsync(stream.AsOutputStream()).AsTask().Wait();
+ stream.Flush();
+ byte[] readContent = stream.ToArray();
+ Assert.Equal(originalContent, readContent);
+ }
+
+ // Reading for the second time should
+ using (MemoryStream stream = new MemoryStream())
+ {
+ content.CopyToAsync(stream.AsOutputStream()).AsTask().Wait();
+ stream.Flush();
+ byte[] readContent = stream.ToArray();
+ Assert.Equal(readContent.Length, 0);
+ }
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs
new file mode 100644
index 000000000000..f3622bc9ab78
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs
@@ -0,0 +1,61 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.WindowsAzure.ServiceLayer.Http;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus
+{
+ ///
+ /// Helper class for dealing with messages.
+ ///
+ internal static class MessageHelper
+ {
+ ///
+ /// Creates a brokered message with the text content.
+ ///
+ /// Message text.
+ /// Brokered message.
+ internal static BrokeredMessageSettings CreateMessage(string messageText, string contentType = "text/plain")
+ {
+ return BrokeredMessageSettings.CreateFromText(messageText, contentType);
+ }
+
+ ///
+ /// Creates a brokered message with the binary content.
+ ///
+ /// Message content.
+ /// Brokered message.
+ internal static BrokeredMessageSettings CreateMessage(byte[] bytes)
+ {
+ return BrokeredMessageSettings.CreateFromByteArray(bytes);
+ }
+
+ ///
+ /// Creates a brokered message with the binary content.
+ ///
+ /// Message content.
+ /// Brokered message.
+ internal static BrokeredMessageSettings CreateMessage(Stream stream)
+ {
+ return BrokeredMessageSettings.CreateFromStream(stream.AsInputStream());
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagePropertiesTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagePropertiesTests.cs
index aa5fa407ce26..4f8c5c45968e 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagePropertiesTests.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagePropertiesTests.cs
@@ -36,8 +36,8 @@ public sealed class MessagePropertiesTests
public void MessageProperties()
{
string queueName = UsesUniqueQueueAttribute.QueueName;
- DateTimeOffset originalDateTime = DateTimeOffset.Now;
- BrokeredMessageSettings messageSettings = BrokeredMessageSettings.CreateFromText("text/plain", "This is a test.");
+ DateTimeOffset originalDateTime = DateTimeOffset.UtcNow;
+ BrokeredMessageSettings messageSettings = MessageHelper.CreateMessage("This is a test.");
messageSettings.Properties.Add("StringProperty", "Test");
messageSettings.Properties.Add("BoolPropertyTrue", true);
@@ -81,7 +81,7 @@ public void MessageProperties()
public void InvalidPropertyType()
{
string queueName = UsesUniqueQueueAttribute.QueueName;
- BrokeredMessageSettings messageSettings = BrokeredMessageSettings.CreateFromText("text/plain", "This is a test.");
+ BrokeredMessageSettings messageSettings = MessageHelper.CreateMessage("This is a test.");
messageSettings.Properties.Add("TestProperty", new int[] { 1, 2, 3});
Assert.Throws(() => Configuration.ServiceBus.SendMessageAsync(queueName, messageSettings));
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageSettingsTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageSettingsTests.cs
index 6a7fd8fcb14c..909c4c7c2ea2 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageSettingsTests.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageSettingsTests.cs
@@ -19,64 +19,13 @@ public sealed class MessageSettingsTests
/// Tests specifying null arguments in constructors.
///
[Fact]
- public void NullArgumentsInConstructors()
+ public void InvalidArgumentsInMethods()
{
- Assert.Throws(() => BrokeredMessageSettings.CreateFromBytes((byte[])null));
- Assert.Throws(() => BrokeredMessageSettings.CreateFromText(null, "This is a test."));
- Assert.Throws(() => BrokeredMessageSettings.CreateFromText("text/plain", (string)null));
- Assert.Throws(() => BrokeredMessageSettings.CreateFromStream((IInputStream)null));
- }
-
- ///
- /// Tests specifying null arguments in methods of a brokered message.
- ///
- [Fact]
- public void NullArgumentsInMethods()
- {
- BrokeredMessageSettings message = BrokeredMessageSettings.CreateFromText("text/plain", "This is a test.");
- Assert.Throws(() => message.CopyContentToAsync(null));
- }
-
- ///
- /// Tests reading a message as a string.
- ///
- [Fact]
- public void ReadAsString()
- {
- string originalBody = "This is only a test!";
- BrokeredMessageSettings message = BrokeredMessageSettings.CreateFromText("text/plain", originalBody);
-
- // Do it twice to make sure the position in the stream is restored after each read.
- for (int i = 0; i < 2; i++)
- {
- string newBody = message.ReadContentAsStringAsync().AsTask().Result;
- Assert.Equal(originalBody, newBody, StringComparer.Ordinal);
- }
- }
-
- ///
- /// Tests reading content of the message into a stream.
- ///
- [Fact]
- public void ReadIntoStream()
- {
- Byte[] bytes = new byte[] { 1, 2, 3 };
- BrokeredMessageSettings message = BrokeredMessageSettings.CreateFromBytes(bytes);
-
- // Do it twice to make sure the position in the stream is restored after each read.
- for (int i = 0; i < 2; i++)
- {
- using (MemoryStream stream = new MemoryStream())
- {
- message.CopyContentToAsync(stream.AsOutputStream()).AsTask().Wait();
- stream.Flush();
- stream.Position = 0;
-
- BinaryReader reader = new BinaryReader(stream);
- byte[] readBytes = reader.ReadBytes(bytes.Length + 1);
- Assert.Equal(bytes, readBytes);
- }
- }
+ Assert.Throws(() => new BrokeredMessageSettings(null));
+ Assert.Throws(() => BrokeredMessageSettings.CreateFromText(null));
+ Assert.Throws(() => BrokeredMessageSettings.CreateFromText("Test", null));
+ Assert.Throws(() => BrokeredMessageSettings.CreateFromByteArray(null));
+ Assert.Throws(() => BrokeredMessageSettings.CreateFromStream(null));
}
}
}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs
new file mode 100644
index 000000000000..9fee31a534c1
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs
@@ -0,0 +1,394 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.WindowsAzure.ServiceLayer;
+using Microsoft.WindowsAzure.ServiceLayer.ServiceBus;
+using Xunit;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.UnitTests.ServiceBusTests
+{
+ ///
+ /// Base class for messaging tests. All tests in this class assume single
+ /// storage with support for the following operations: send, get, peek,
+ /// lock, unock, and delete.
+ ///
+ public abstract class MessagingTestsBase
+ {
+ ///
+ /// Sends a message,
+ ///
+ /// Message to send.
+ protected abstract void SendMessage(BrokeredMessageSettings settings);
+
+ ///
+ /// Gets a message from the queue.
+ ///
+ /// First queued message.
+ protected abstract BrokeredMessageInfo GetMessage(TimeSpan lockSpan);
+
+ ///
+ /// Peeks a message from the queue.
+ ///
+ /// First queued message.
+ protected abstract BrokeredMessageInfo PeekMessage(TimeSpan lockSpan);
+
+ ///
+ /// Unlocks previously locked message.
+ ///
+ /// Sequence number of the locked message.
+ /// Lock token of the locked message.
+ protected abstract void UnlockMessage(long sequenceNumber, string lockToken);
+
+ ///
+ /// Deletes previously locked message.
+ ///
+ /// Sequence number of the locked message.
+ /// Lock token of the locked message.
+ protected abstract void DeleteMessage(long sequenceNumber, string lockToken);
+
+ ///
+ /// Tests setting and reading a property.
+ ///
+ /// Property type.
+ /// Property value.
+ /// Method for setting the value.
+ /// Method for getting the value.
+ /// Comparer for values.
+ protected void TestSetProperty(
+ T value,
+ Action setValue,
+ Func getValue,
+ IEqualityComparer comparer = null)
+ {
+ if (comparer == null)
+ {
+ comparer = EqualityComparer.Default;
+ }
+
+ // Create a message.
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(Guid.NewGuid().ToString());
+
+ // Set the requested property.
+ setValue(settings, value);
+
+ // Send the message to the queue.
+ SendMessage(settings);
+
+ // Get the message and compare properties.
+ BrokeredMessageInfo message = GetMessage(TimeSpan.FromSeconds(10));
+ T newValue = getValue(message);
+ Assert.Equal(value, newValue, comparer);
+ }
+
+ ///
+ /// Verifies preserving content type.
+ ///
+ [Fact]
+ public void PreserveContentType()
+ {
+ string[] contentTypes = new string[] { "text/plain", "text/xml", };
+
+ foreach (string contentType in contentTypes)
+ {
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(Guid.NewGuid().ToString(), contentType);
+ SendMessage(settings);
+
+ BrokeredMessageInfo message = GetMessage(TimeSpan.FromSeconds(10));
+ Assert.Equal(message.ContentType, contentType, StringComparer.Ordinal);
+ }
+ }
+
+ ///
+ /// Tests preserving content text.
+ ///
+ [Fact]
+ public void PreservingContentText()
+ {
+ string originalContent = Guid.NewGuid().ToString();
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(originalContent);
+ SendMessage(settings);
+
+ BrokeredMessageInfo message = GetMessage(TimeSpan.FromSeconds(10));
+ string readContent = message.ReadContentAsStringAsync().AsTask().Result;
+ Assert.Equal(originalContent, readContent, StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests peeking a message.
+ ///
+ [Fact]
+ public void PeekingMessage()
+ {
+ string originalContent = Guid.NewGuid().ToString();
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(originalContent);
+ SendMessage(settings);
+
+ BrokeredMessageInfo message = PeekMessage(TimeSpan.FromSeconds(10));
+ string readContent = message.ReadContentAsStringAsync().AsTask().Result;
+ Assert.Equal(originalContent, readContent, StringComparer.Ordinal);
+
+ // Delete message. This will fail if the message is not there.
+ DeleteMessage(message.SequenceNumber, message.LockToken);
+ }
+
+ ///
+ /// Tests peeking a message from an empty queue.
+ ///
+ [Fact]
+ public void PeekingMessageFromEmptyQueue()
+ {
+ Assert.Throws(() => PeekMessage(TimeSpan.FromSeconds(10)));
+ }
+
+ ///
+ /// Tests getting a message.
+ ///
+ [Fact]
+ public void GettingMessage()
+ {
+ string originalContent = Guid.NewGuid().ToString();
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(originalContent);
+ SendMessage(settings);
+
+ BrokeredMessageInfo message = GetMessage(TimeSpan.FromSeconds(10));
+ string readContent = message.ReadContentAsStringAsync().AsTask().Result;
+ Assert.Equal(originalContent, readContent, StringComparer.Ordinal);
+
+ // Make sure nothing's left.
+ Assert.Throws(() => PeekMessage(TimeSpan.FromSeconds(10)));
+ }
+
+ ///
+ /// Tests getting a message from an empty queue.
+ ///
+ [Fact]
+ public void GettingMessageFromEmptyQueue()
+ {
+ Assert.Throws(() => GetMessage(TimeSpan.FromSeconds(10)));
+ }
+
+ ///
+ /// Tests deleting a message.
+ ///
+ [Fact]
+ public void DeletingMessage()
+ {
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage("This is a test.");
+ SendMessage(settings);
+
+ BrokeredMessageInfo message = PeekMessage(TimeSpan.FromSeconds(10));
+ DeleteMessage(message.SequenceNumber, message.LockToken);
+
+ Assert.Throws(() => PeekMessage(TimeSpan.FromSeconds(10)));
+ }
+
+ ///
+ /// Tests specifying invalid arguments for DeleteMessage call.
+ ///
+ [Fact]
+ public void InvalidArgsInDeleteMessage()
+ {
+ Assert.Throws(() => DeleteMessage(0, null));
+ }
+
+ ///
+ /// Tests unlocking a message.
+ ///
+ [Fact]
+ public void UnlockingMessage()
+ {
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage("This is a test.");
+ SendMessage(settings);
+
+ BrokeredMessageInfo message = PeekMessage(TimeSpan.FromSeconds(10));
+ UnlockMessage(message.SequenceNumber, message.LockToken);
+ message = GetMessage(TimeSpan.FromSeconds(10));
+ Assert.Throws(() => PeekMessage(TimeSpan.FromSeconds(10)));
+ }
+
+ ///
+ /// Tests specifying invalid arguments for UnlockMessage call.
+ ///
+ [Fact]
+ public void InvalidArgsInUnlockMessage()
+ {
+ Assert.Throws(() => UnlockMessage(0, null));
+ }
+
+ ///
+ /// Tests setting/getting message's CorrelationId property.
+ ///
+ [Fact]
+ public void SetCorrelationId()
+ {
+ TestSetProperty(
+ "correlationId",
+ (message, value) => { message.CorrelationId = value; },
+ (message) => message.CorrelationId,
+ StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests setting/getting message's Label property.
+ ///
+ [Fact]
+ public void SetLabel()
+ {
+ TestSetProperty(
+ "TestLabel",
+ (message, value) => { message.Label = value; },
+ (message) => message.Label,
+ StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests setting/getting MessaqgeId property.
+ ///
+ [Fact]
+ public void SetMessageId()
+ {
+ TestSetProperty(
+ "TestMessageId",
+ (message, value) => { message.MessageId = value; },
+ (message) => message.MessageId,
+ StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests setting ReplyTo property.
+ ///
+ [Fact]
+ public void SetReplyTo()
+ {
+ TestSetProperty(
+ "testReplyTo",
+ (message, value) => { message.ReplyTo = value; },
+ (message) => message.ReplyTo,
+ StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests setting ReplyToSessionId property.
+ ///
+ [Fact]
+ public void SetReplyToSessionId()
+ {
+ TestSetProperty(
+ "testReplyToSessionId",
+ (message, value) => { message.ReplyToSessionId = value; },
+ (message) => message.ReplyToSessionId,
+ StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests setting SessionId property.
+ ///
+ [Fact]
+ public void SetSessionId()
+ {
+ TestSetProperty(
+ "testSessionId",
+ (message, value) => { message.SessionId = value; },
+ (message) => message.SessionId,
+ StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests setting TimeToLive property.
+ ///
+ [Fact]
+ public void SetTimeToLive()
+ {
+ TestSetProperty(
+ TimeSpan.FromDays(2),
+ (message, value) => { message.TimeToLive = value; },
+ (message) => message.TimeToLive.Value);
+ }
+
+ ///
+ /// Tests setting To property.
+ ///
+ [Fact]
+ public void SetTo()
+ {
+ TestSetProperty(
+ "testTo",
+ (message, value) => { message.To = value; },
+ (message) => message.To,
+ StringComparer.Ordinal);
+ }
+
+ ///
+ /// Tests sending and receiving an array of bytes.
+ ///
+ [Fact]
+ public void PreserveBytes()
+ {
+ byte[] originalBytes = new byte[] { 1, 2, 3, 4, };
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(originalBytes);
+ SendMessage(settings);
+ BrokeredMessageInfo message = GetMessage(TimeSpan.FromSeconds(10));
+
+ List readBytes = new List(message.ReadContentAsBytesAsync().AsTask().Result);
+ Assert.Equal(originalBytes, readBytes);
+ }
+
+ ///
+ /// Tests sending and receiving a stream.
+ ///
+ [Fact]
+ public void PreserveStream()
+ {
+ byte[] originalBytes = new byte[] { 5, 4, 3, 2, 1, };
+ using (MemoryStream stream = new MemoryStream(originalBytes))
+ {
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(stream);
+ SendMessage(settings);
+ BrokeredMessageInfo message = GetMessage(TimeSpan.FromSeconds(10));
+
+ using (Stream readStream = message.ReadContentAsStreamAsync().AsTask().Result.AsStreamForRead())
+ {
+ byte[] readBytes = new byte[originalBytes.Length];
+ int cnt = readStream.Read(readBytes, 0, originalBytes.Length);
+ Assert.Equal(cnt, readBytes.Length);
+ Assert.Equal(originalBytes, readBytes);
+
+ cnt = readStream.Read(readBytes, 0, 1);
+ Assert.Equal(cnt, 0);
+ }
+ }
+ }
+
+ ///
+ /// Tests sending/receiving an empty string in the message content.
+ ///
+ [Fact]
+ public void EmptyStringContent()
+ {
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(string.Empty);
+ SendMessage(settings);
+
+ BrokeredMessageInfo message = GetMessage(TimeSpan.FromSeconds(10));
+ string readText = message.ReadContentAsStringAsync().AsTask().Result;
+ Assert.Equal(readText.Length, 0);
+ }
+
+ ///
+ /// Tests sending/receiving an empty bytes array.
+ ///
+ [Fact]
+ public void EmptyArrayContent()
+ {
+ byte[] originalBytes = new byte[0];
+ BrokeredMessageSettings settings = MessageHelper.CreateMessage(originalBytes);
+ SendMessage(settings);
+
+ BrokeredMessageInfo message = GetMessage(TimeSpan.FromSeconds(10));
+ List readBytes = new List(message.ReadContentAsBytesAsync().AsTask().Result);
+ Assert.Equal(originalBytes, readBytes);
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/QueueMessagingTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/QueueMessagingTests.cs
index 1a27cad30ee2..f35f62b57006 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/QueueMessagingTests.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/QueueMessagingTests.cs
@@ -27,133 +27,74 @@ namespace Microsoft.WindowsAzure.ServiceLayer.UnitTests.ServiceBusTests
///
/// Runtime tests for queues.
///
- public sealed class QueueMessagingTests
+ public sealed class QueueMessagingTests: MessagingTestsBase, IUseFixture
{
+ private string _queueName; // Shared queue.
+
///
- /// Tests setting and reading a property.
+ /// Sends a message to the queue.
///
- /// Property type.
- /// Property value.
- /// Method for setting the value.
- /// Method for getting the value.
- /// Comparer for values.
- private void TestSetProperty(
- T value,
- Action setValue,
- Func getValue,
- IEqualityComparer comparer = null)
+ /// Message to send.
+ protected override void SendMessage(BrokeredMessageSettings settings)
{
- if (comparer == null)
- {
- comparer = EqualityComparer.Default;
- }
-
- // Create a message.
- string messageText = Guid.NewGuid().ToString();
- BrokeredMessageSettings messageSettings = BrokeredMessageSettings.CreateFromText("text/plain", messageText);
-
- // Set the requested property.
- setValue(messageSettings, value);
-
- // Send the message to the queue.
- string queueName = UsesUniqueQueueAttribute.QueueName;
- Configuration.ServiceBus.SendMessageAsync(queueName, messageSettings).AsTask().Wait();
- BrokeredMessageInfo message = Configuration.ServiceBus.GetQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Result;
- T newValue = getValue(message);
-
- Assert.Equal(value, newValue, comparer);
+ Configuration.ServiceBus.SendMessageAsync(_queueName, settings).AsTask().Wait();
}
-
///
- /// Tests getting a message from the queue.
+ /// Gets the first message in the queue.
///
- [Fact]
- [UsesUniqueQueue]
- public void PeekMessage()
+ /// Lock interval.
+ /// Message.
+ protected override BrokeredMessageInfo GetMessage(TimeSpan lockSpan)
{
- string queueName = UsesUniqueQueueAttribute.QueueName;
- string text = Guid.NewGuid().ToString();
- BrokeredMessageSettings messageSettings = BrokeredMessageSettings.CreateFromText("text/plain", text);
-
- BrokeredMessageInfo message = Configuration.ServiceBus.SendMessageAsync(queueName, messageSettings)
- .AsTask()
- .ContinueWith((t) => Configuration.ServiceBus.PeekQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Result, TaskContinuationOptions.OnlyOnRanToCompletion)
- .Result;
-
- string newText = message.ReadContentAsStringAsync().AsTask().Result;
-
- Assert.Equal(text, newText, StringComparer.Ordinal);
-
- // Make sure the message is still there.
- QueueInfo info = Configuration.ServiceBus.GetQueueAsync(queueName).AsTask().Result;
- Assert.Equal(info.MessageCount, 1);
+ return Configuration.ServiceBus.GetQueueMessageAsync(_queueName, lockSpan).AsTask().Result;
}
///
- /// Tests getting a message from the queue.
+ /// Peeks the first message in the queue.
///
- [Fact]
- [UsesUniqueQueue]
- public void GetMessage()
+ /// Lock interval.
+ /// Message.
+ protected override BrokeredMessageInfo PeekMessage(TimeSpan lockSpan)
{
- string queueName = UsesUniqueQueueAttribute.QueueName;
- string text = Guid.NewGuid().ToString();
- BrokeredMessageSettings messageSettings = BrokeredMessageSettings.CreateFromText("text/html", text);
-
- BrokeredMessageInfo message = Configuration.ServiceBus.SendMessageAsync(queueName, messageSettings)
- .AsTask()
- .ContinueWith((t) => Configuration.ServiceBus.GetQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Result, TaskContinuationOptions.OnlyOnRanToCompletion)
- .Result;
- string newText = message.ReadContentAsStringAsync().AsTask().Result;
-
- Assert.Equal(newText, text, StringComparer.Ordinal);
-
- // Make sure the message disappeared.
- QueueInfo info = Configuration.ServiceBus.GetQueueAsync(queueName).AsTask().Result;
- Assert.Equal(info.MessageCount, 0);
+ return Configuration.ServiceBus.PeekQueueMessageAsync(_queueName, lockSpan).AsTask().Result;
}
///
- /// Tests getting a message from an empty queue.
+ /// Unlocks given message.
///
- [Fact]
- [UsesUniqueQueue]
- public void GetMessageFromEmptyQueue()
+ /// Sequence number of the locked message.
+ /// Lock token of the locked message.
+ protected override void UnlockMessage(long sequenceNumber, string lockToken)
{
- string queueName = UsesUniqueQueueAttribute.QueueName;
-
- Assert.Throws(() => Configuration.ServiceBus.GetQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Wait());
+ Configuration.ServiceBus.UnlockQueueMessageAsync(_queueName, sequenceNumber, lockToken).AsTask().Wait();
}
///
- /// Tests deleting a message from the queue.
+ /// Deletes previously locked message.
///
- [Fact]
- [UsesUniqueQueue]
- public void DeleteMessage()
+ /// Sequence number of the locked message.
+ /// Lock token of the locked message.
+ protected override void DeleteMessage(long sequenceNumber, string lockToken)
{
- string queueName = UsesUniqueQueueAttribute.QueueName;
-
- BrokeredMessageSettings messageSettings = BrokeredMessageSettings.CreateFromText("text/plain", "This is only a test.");
- Configuration.ServiceBus.SendMessageAsync(queueName, messageSettings).AsTask().Wait();
- BrokeredMessageInfo message = Configuration.ServiceBus.PeekQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Result;
- Configuration.ServiceBus.DeleteQueueMessageAsync(queueName, message.SequenceNumber, message.LockToken).AsTask().Wait();
+ Configuration.ServiceBus.DeleteQueueMessageAsync(_queueName, sequenceNumber, lockToken).AsTask().Wait();
+ }
- QueueInfo info = Configuration.ServiceBus.GetQueueAsync(queueName).AsTask().Result;
- Assert.Equal(info.MessageCount, 0);
+ // Assigns a fixture to the class.
+ void IUseFixture.SetFixture(UniqueQueueFixture data)
+ {
+ _queueName = data.QueueName;
}
///
- /// Tests peeking a message from a non-existing queue.
+ /// Tests specifying invalid arguments in SendMessage call.
///
[Fact]
- [UsesUniqueQueue]
- public void PeekMessageFromEmptyQueue()
+ public void InvalidArgsInSendMessage()
{
- string queueName = UsesUniqueQueueAttribute.QueueName;
- BrokeredMessageInfo message = Configuration.ServiceBus.PeekQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Result;
- Assert.Null(message);
+ BrokeredMessageSettings message = MessageHelper.CreateMessage("This is a test.");
+ Assert.Throws(() => Configuration.ServiceBus.SendMessageAsync(null, message));
+ Assert.Throws(() => Configuration.ServiceBus.SendMessageAsync(_queueName, null));
}
///
@@ -177,189 +118,5 @@ public void PeekMessageFromNonExistingQueue()
Assert.Throws(() => Configuration.ServiceBus.PeekQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Wait());
}
-
- ///
- /// Tests null reference exceptions in queue methods.
- ///
- [Fact]
- public void NullArgsInQueueMessages()
- {
- BrokeredMessageSettings validMessageSettings = BrokeredMessageSettings.CreateFromText("test/plain", "This is a test");
- Assert.Throws(() => Configuration.ServiceBus.SendMessageAsync(null, validMessageSettings));
- Assert.Throws(() => Configuration.ServiceBus.SendMessageAsync("somename", null));
- Assert.Throws(() => Configuration.ServiceBus.GetQueueMessageAsync(null, TimeSpan.FromSeconds(10)));
- Assert.Throws(() => Configuration.ServiceBus.PeekQueueMessageAsync(null, TimeSpan.FromSeconds(10)));
- Assert.Throws(() => Configuration.ServiceBus.UnlockQueueMessageAsync(null, 0, "test"));
- Assert.Throws(() => Configuration.ServiceBus.UnlockQueueMessageAsync("test", 0, null));
- Assert.Throws(() => Configuration.ServiceBus.DeleteQueueMessageAsync(null, 0, "test"));
- Assert.Throws(() => Configuration.ServiceBus.DeleteQueueMessageAsync("test", 0, null));
- }
-
- ///
- /// Tests setting/getting message's CorrelationId property.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SetCorrelationId()
- {
- TestSetProperty(
- "correlationId",
- (message, value) => { message.CorrelationId = value; },
- (message) => message.CorrelationId,
- StringComparer.Ordinal);
- }
-
- ///
- /// Tests setting/getting message's Label property.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SetLabel()
- {
- TestSetProperty(
- "TestLabel",
- (message, value) => { message.Label = value; },
- (message) => message.Label,
- StringComparer.Ordinal);
- }
-
- ///
- /// Tests setting/getting MessaqgeId property.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SetMessageId()
- {
- TestSetProperty(
- "TestMessageId",
- (message, value) => { message.MessageId = value; },
- (message) => message.MessageId,
- StringComparer.Ordinal);
- }
-
- ///
- /// Tests setting ReplyTo property.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SetReplyTo()
- {
- TestSetProperty(
- "testReplyTo",
- (message, value) => { message.ReplyTo = value; },
- (message) => message.ReplyTo,
- StringComparer.Ordinal);
- }
-
- ///
- /// Tests setting ReplyToSessionId property.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SetReplyToSessionId()
- {
- TestSetProperty(
- "testReplyToSessionId",
- (message, value) => { message.ReplyToSessionId = value; },
- (message) => message.ReplyToSessionId,
- StringComparer.Ordinal);
- }
-
- ///
- /// Tests setting SessionId property.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SetSessionId()
- {
- TestSetProperty(
- "testSessionId",
- (message, value) => { message.SessionId = value; },
- (message) => message.SessionId,
- StringComparer.Ordinal);
- }
-
- ///
- /// Tests setting TimeToLive property.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SetTimeToLive()
- {
- TestSetProperty(
- TimeSpan.FromDays(2),
- (message, value) => { message.TimeToLive = value; },
- (message) => message.TimeToLive.Value);
- }
-
- ///
- /// Tests setting To property.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SetTo()
- {
- TestSetProperty(
- "testTo",
- (message, value) => { message.To = value; },
- (message) => message.To,
- StringComparer.Ordinal);
- }
-
- ///
- /// Tests sending and receiving an array of bytes.
- ///
- [Fact]
- [UsesUniqueQueue]
- public void SendBytes()
- {
- string queueName = UsesUniqueQueueAttribute.QueueName;
- byte[] bytes = new byte[] { 1, 2, 3, };
- BrokeredMessageSettings settings = BrokeredMessageSettings.CreateFromBytes(bytes);
- Configuration.ServiceBus.SendMessageAsync(queueName, settings).AsTask().Wait();
-
- BrokeredMessageInfo message = Configuration.ServiceBus.GetQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Result;
-
- // Do that twice to make sure stream positions are preserved.
- for (int i = 0; i < 2; i++)
- {
- List newBytes = new List(message.ReadContentAsBytesAsync().AsTask().Result);
- Assert.Equal(bytes, newBytes.ToArray());
- }
- }
-
- ///
- /// Tests sending a stream of bytes.
- ///
- [Fact(Skip="Doesn't work with .Net libraries; disabling for now.")]
- [UsesUniqueQueue]
- public void SendStream()
- {
- string queueName = UsesUniqueQueueAttribute.QueueName;
- byte[] inBytes = new byte[] { 1, 2, 3, 4, };
-
- using (MemoryStream inStream = new MemoryStream())
- {
- inStream.Write(inBytes, 0, inBytes.Length);
- inStream.Flush();
- inStream.Position = 0;
-
- BrokeredMessageSettings settings = BrokeredMessageSettings.CreateFromStream(inStream.AsInputStream());
- Configuration.ServiceBus.SendMessageAsync(queueName, settings).AsTask().Wait();
- }
-
- BrokeredMessageInfo message = Configuration.ServiceBus.GetQueueMessageAsync(queueName, TimeSpan.FromSeconds(10)).AsTask().Result;
-
- for (int i = 0; i < 2; i++)
- {
- using (Stream stream = message.ReadContentAsStreamAsync().AsTask().Result.AsStreamForRead())
- {
- byte[] outBytes = new byte[4];
- int cnt = stream.Read(outBytes, 0, 4);
- Assert.Equal(cnt, 4);
- Assert.Equal(inBytes, outBytes);
- }
- }
- }
}
}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/SubscriptionMessagingTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/SubscriptionMessagingTests.cs
index 7b84af4f6d3d..d04a7a6c67f3 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/SubscriptionMessagingTests.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/SubscriptionMessagingTests.cs
@@ -1,4 +1,19 @@
-using System;
+//
+// Copyright 2012 Microsoft Corporation
+//
+// 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.
+//
+
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -11,7 +26,7 @@ namespace Microsoft.WindowsAzure.ServiceLayer.UnitTests.ServiceBusTests
///
/// Unit tests for topic/subscription messaging.
///
- public sealed class SubscriptionMessagingTests: IUseFixture
+ public sealed class SubscriptionMessagingTests: MessagingTestsBase, IUseFixture
{
UniqueSubscriptionFixture _subscription; // Unique topic/subscription fixture.
@@ -40,24 +55,61 @@ private IServiceBusService ServiceBus
}
///
- /// Assigns fixture to the class.
+ /// Sends a message to the subscription.
///
- /// Fixture.
- void IUseFixture.SetFixture(UniqueSubscriptionFixture data)
+ /// Message settings.
+ protected override void SendMessage(BrokeredMessageSettings settings)
{
- _subscription = data;
+ Configuration.ServiceBus.SendMessageAsync(TopicName, settings).AsTask().Wait();
}
///
- /// Sends a text message with the given text to the topic.
+ /// Gets the first message in the subscription.
///
- /// Message text.
- /// Message settings.
- BrokeredMessageSettings SendTextMessage(string messageText)
+ /// Locking interval.
+ /// Message.
+ protected override BrokeredMessageInfo GetMessage(TimeSpan lockSpan)
{
- BrokeredMessageSettings message = BrokeredMessageSettings.CreateFromText("text/plain", messageText);
- ServiceBus.SendMessageAsync(TopicName, message).AsTask().Wait();
- return message;
+ return Configuration.ServiceBus.GetSubscriptionMessageAsync(TopicName, SubscriptionName, lockSpan).AsTask().Result;
+ }
+
+ ///
+ /// Peeks the first message in the subscription.
+ ///
+ /// Lock interval.
+ /// Message or null, if none.
+ protected override BrokeredMessageInfo PeekMessage(TimeSpan lockSpan)
+ {
+ return Configuration.ServiceBus.PeekSubscriptionMessageAsync(TopicName, SubscriptionName, lockSpan).AsTask().Result;
+ }
+
+ ///
+ /// Unlocks previously locked message in the subscription.
+ ///
+ /// Sequence number of the locked message.
+ /// Lock token of the message.
+ protected override void UnlockMessage(long sequenceNumber, string lockToken)
+ {
+ Configuration.ServiceBus.UnlockSubscriptionMessageAsync(TopicName, SubscriptionName, sequenceNumber, lockToken).AsTask().Wait();
+ }
+
+ ///
+ /// Deletes previously locked subscription message.
+ ///
+ /// Sequence number of the previously locked message.
+ /// Lock token of the message.
+ protected override void DeleteMessage(long sequenceNumber, string lockToken)
+ {
+ Configuration.ServiceBus.DeleteSubscriptionMessageAsync(TopicName, SubscriptionName, sequenceNumber, lockToken).AsTask().Wait();
+ }
+
+ ///
+ /// Assigns fixture to the class.
+ ///
+ /// Fixture.
+ void IUseFixture.SetFixture(UniqueSubscriptionFixture data)
+ {
+ _subscription = data;
}
///
@@ -79,57 +131,23 @@ public void NullArgs()
}
///
- /// Tests getting a message from subscription (destructive reading).
- ///
- [Fact]
- public void GetMessage()
- {
- string messageText = Guid.NewGuid().ToString();
- SendTextMessage(messageText);
-
- BrokeredMessageInfo message = ServiceBus.GetSubscriptionMessageAsync(TopicName, SubscriptionName, TimeSpan.FromSeconds(10)).AsTask().Result;
- Assert.Equal(message.ReadContentAsStringAsync().AsTask().Result, messageText, StringComparer.Ordinal);
-
- // Reading the message should've removed it from the subscription.
- Assert.Throws(() => ServiceBus.GetSubscriptionMessageAsync(TopicName, SubscriptionName, TimeSpan.FromSeconds(10)).AsTask().Wait());
- }
-
- ///
- /// Tests peeking a message.
+ /// Tests getting a message from a non-existing topic.
///
[Fact]
- public void PeekMessage()
+ public void GettingMessageFromNonExistingTopic()
{
- string messageText = Guid.NewGuid().ToString();
- SendTextMessage(messageText);
-
- // Peeking is a non-destructive operation; should work two times in a row.
- for (int i = 0; i < 2; i++)
- {
- BrokeredMessageInfo message = ServiceBus.PeekSubscriptionMessageAsync(TopicName, SubscriptionName, TimeSpan.FromSeconds(10)).AsTask().Result;
- Assert.Equal(messageText, message.ReadContentAsStringAsync().AsTask().Result, StringComparer.Ordinal);
-
- // Unlock the message.
- ServiceBus.UnlockSubscriptionMessageAsync(TopicName, SubscriptionName, message.SequenceNumber, message.LockToken).AsTask().Wait();
- }
-
- // Remove the message.
- ServiceBus.GetSubscriptionMessageAsync(TopicName, SubscriptionName, TimeSpan.FromSeconds(0)).AsTask().Wait();
+ Assert.Throws(
+ () => Configuration.ServiceBus.GetSubscriptionMessageAsync(Configuration.GetUniqueTopicName(), SubscriptionName, TimeSpan.FromSeconds(10)).AsTask().Wait());
}
///
- /// Tests locking and deleting a message.
+ /// Tests getting a message from a non-existing subscription.
///
[Fact]
- public void DeleteMessage()
+ public void GettingMessageFromNonExistingSubscription()
{
- string messageText = Guid.NewGuid().ToString();
- SendTextMessage(messageText);
-
- BrokeredMessageInfo message = ServiceBus.PeekSubscriptionMessageAsync(TopicName, SubscriptionName, TimeSpan.FromSeconds(10)).AsTask().Result;
- ServiceBus.DeleteSubscriptionMessageAsync(TopicName, SubscriptionName, message.SequenceNumber, message.LockToken).AsTask().Wait();
-
- Assert.Throws(() => ServiceBus.GetSubscriptionMessageAsync(TopicName, SubscriptionName, TimeSpan.FromSeconds(10)).AsTask().Wait());
+ Assert.Throws(
+ () => Configuration.ServiceBus.GetSubscriptionMessageAsync(TopicName, Configuration.GetUniqueSubscriptionName(), TimeSpan.FromSeconds(10)).AsTask().Wait());
}
}
}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/UniqueQueueFixture.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/UniqueQueueFixture.cs
new file mode 100644
index 000000000000..8b282e421bb6
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/UniqueQueueFixture.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.UnitTests.ServiceBusTests
+{
+ ///
+ /// A fixture for generating unique queue for a group of tests.
+ ///
+ public class UniqueQueueFixture: IDisposable
+ {
+ public string QueueName { get; private set; }
+
+ ///
+ /// Initializes the fixture by creating a queue with the unique name.
+ ///
+ public UniqueQueueFixture()
+ {
+ QueueName = Configuration.GetUniqueQueueName();
+ Configuration.ServiceBus.CreateQueueAsync(QueueName).AsTask().Wait();
+ }
+
+ ///
+ /// Disposes the fixture by removing the queue.
+ ///
+ void IDisposable.Dispose()
+ {
+ Configuration.ServiceBus.DeleteQueueAsync(QueueName).AsTask().Wait();
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Constants.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Constants.cs
index 6841aeabba97..9f83948cb3e5 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Constants.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Constants.cs
@@ -53,9 +53,9 @@ internal static class Constants
internal const string SerializationContentType = "application/xml";
internal const string BodyContentType = "application/atom+xml";
- internal const string MessageContentType = "application/atom+xml";
+ internal const string DefaultMessageContentType = "text/plain";
internal const string WrapAuthenticationContentType = "application/x-www-form-urlencoded";
-
+
internal const string BrokerPropertiesHeader = "BrokerProperties"; // Header name for broker properties.
internal const int CompatibilityLevel = 20; // Compatibility level for rules.
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs
new file mode 100644
index 000000000000..8af047318405
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs
@@ -0,0 +1,194 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Windows.Foundation;
+using Windows.Storage.Streams;
+
+using NetHttpContent = System.Net.Http.HttpContent;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.Http
+{
+ ///
+ /// A data container for brokered messages, HTTP requests and responses.
+ ///
+ ///
+ /// The class represents a container for HTTP content, which is used in
+ /// body of an HTTP request. The class provides multiple methods for
+ /// reading stored data, however, unless the content is buffered into
+ /// memory, the data can be read only once. If you plan to read data more
+ /// than once, you should load content's data into memory by calling
+ /// CopyInfoBufferAsync.
+ public sealed class HttpContent
+ {
+ private IHttpContent _rawContent; // Container with data.
+
+ ///
+ /// Gets content type.
+ ///
+ public string ContentType { get; private set; }
+
+ ///
+ /// Creates a content from the given string.
+ ///
+ /// String content.
+ /// HTTP content type.
+ /// Content object.
+ public static HttpContent CreateFromText(string text, string contentType)
+ {
+ if (text == null)
+ {
+ throw new ArgumentNullException("text");
+ }
+ if (contentType == null)
+ {
+ throw new ArgumentNullException("contentType");
+ }
+
+ return new HttpContent(
+ new MemoryContent(text),
+ contentType);
+ }
+
+ ///
+ /// Creates a content from binary data specified in the array.
+ ///
+ /// Binary data.
+ /// Content object.
+ public static HttpContent CreateFromByteArray(byte[] bytes)
+ {
+ if (bytes == null)
+ {
+ throw new ArgumentNullException("bytes");
+ }
+
+ return new HttpContent(new MemoryContent(bytes));
+ }
+
+ ///
+ /// Creates a content from binary data specified in the stream.
+ ///
+ /// Binary data.
+ /// Content object.
+ public static HttpContent CreateFromStream(IInputStream stream)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ return new HttpContent(new StreamContent(stream.AsStreamForRead()));
+ }
+
+ ///
+ /// Initializes the content.
+ ///
+ /// Content container.
+ /// Content type.
+ private HttpContent(IHttpContent rawContent, string contentType = null)
+ {
+ _rawContent = rawContent;
+ ContentType = contentType;
+ }
+
+ ///
+ /// Reads content as a string.
+ ///
+ /// Content string.
+ public IAsyncOperation ReadAsStringAsync()
+ {
+ return _rawContent
+ .ReadAsStringAsync()
+ .AsAsyncOperation();
+ }
+
+ ///
+ /// Reads content as a byte array.
+ ///
+ /// Content bytes.
+ public IAsyncOperation> ReadAsByteArrayAsync()
+ {
+ //TODO: this mehtod returns IEnumerable instead of byte[] because
+ // winmd does not accept arrays as return values. Check this with the
+ // latest version and make this method consistent with
+ // CreateFromByteArray method.
+ return _rawContent
+ .ReadAsBytesAsync()
+ .ContinueWith>(t => t.Result, TaskContinuationOptions.OnlyOnRanToCompletion)
+ .AsAsyncOperation();
+ }
+
+ ///
+ /// Reads content as a stream of bytes.
+ ///
+ /// Content bytes.
+ public IAsyncOperation ReadAsStreamAsync()
+ {
+ return _rawContent
+ .ReadAsStreamAsync()
+ .ContinueWith(t => t.Result.AsInputStream(), TaskContinuationOptions.OnlyOnRanToCompletion)
+ .AsAsyncOperation();
+ }
+
+ ///
+ /// Copies content into the given stream.
+ ///
+ /// Target stream.
+ /// Result of the operation.
+ public IAsyncAction CopyToAsync(IOutputStream stream)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ return _rawContent
+ .CopyToAsync(stream.AsStreamForWrite())
+ .AsAsyncAction();
+ }
+
+ ///
+ /// Copies content into an internal buffer allowing multiple read
+ /// operations.
+ ///
+ /// Result of the operation.
+ public IAsyncAction CopyToBufferAsync()
+ {
+ return _rawContent.BufferContentAsync()
+ .ContinueWith(t => { _rawContent = t.Result; }, TaskContinuationOptions.OnlyOnRanToCompletion)
+ .AsAsyncAction();
+ }
+
+ ///
+ /// Submits content data into the given request.
+ ///
+ /// Target request.
+ internal void SubmitTo(HttpRequestMessage request)
+ {
+ NetHttpContent content = new System.Net.Http.StreamContent(
+ _rawContent.ReadAsStreamAsync().Result);
+
+ if (!string.IsNullOrEmpty(ContentType))
+ {
+ content.Headers.Add("Content-Type", ContentType);
+ }
+ request.Content = content;
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IHttpContent.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IHttpContent.cs
new file mode 100644
index 000000000000..8f0d9c40c193
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IHttpContent.cs
@@ -0,0 +1,65 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.Http
+{
+ ///
+ /// Content interface. The interface is used to hide details on physical
+ /// storage mechanism.
+ ///
+ internal interface IHttpContent
+ {
+ ///
+ /// Reads content as a string.
+ ///
+ /// Content string.
+ Task ReadAsStringAsync();
+
+ ///
+ /// Reads content as an array of bytes.
+ ///
+ /// Content bytes.
+ Task ReadAsBytesAsync();
+
+ ///
+ /// Reads content as a stream.
+ ///
+ /// Content bytes.
+ Task ReadAsStreamAsync();
+
+ ///
+ /// Copies content into the given stream.
+ ///
+ /// Target stream.
+ /// Result of the operation.
+ Task CopyToAsync(Stream stream);
+
+ ///
+ /// Buffers content into memory.
+ ///
+ /// Buffered content.
+ /// Buffering content allows multiple reading operations from
+ /// the same content. Without buffering, data from stream-based content
+ /// can be read only once.
+ Task BufferContentAsync();
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/MemoryContent.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/MemoryContent.cs
new file mode 100644
index 000000000000..82a935bd352c
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/MemoryContent.cs
@@ -0,0 +1,109 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.Http
+{
+ ///
+ /// A content whose data is stored in memory.
+ ///
+ internal class MemoryContent: IHttpContent
+ {
+ private byte[] _bytes; // Memory content.
+
+ ///
+ /// Initializes content with the text.
+ ///
+ /// Content text.
+ internal MemoryContent(string text)
+ {
+ Debug.Assert(text != null);
+ _bytes = Encoding.UTF8.GetBytes(text);
+ }
+
+ ///
+ /// Initializes content with the array of bytes.
+ ///
+ /// Content bytes.
+ internal MemoryContent(byte[] bytes)
+ {
+ Debug.Assert(bytes != null);
+ _bytes = bytes;
+ }
+
+ ///
+ /// Reads content as a string.
+ ///
+ /// Content string.
+ Task IHttpContent.ReadAsStringAsync()
+ {
+ using (MemoryStream stream = new MemoryStream(_bytes))
+ {
+ StreamReader reader = new StreamReader(stream);
+ return reader.ReadToEndAsync();
+ }
+ }
+
+ ///
+ /// Reads content as a bytes array.
+ ///
+ /// Content bytes.
+ Task IHttpContent.ReadAsBytesAsync()
+ {
+ TaskCompletionSource completion = new TaskCompletionSource();
+ completion.SetResult(_bytes);
+ return completion.Task;
+ }
+
+ ///
+ /// Reads content as a stream.
+ ///
+ /// Content bytes in a stream.
+ Task IHttpContent.ReadAsStreamAsync()
+ {
+ TaskCompletionSource completion = new TaskCompletionSource();
+ completion.SetResult(new MemoryStream(_bytes));
+ return completion.Task;
+ }
+
+ ///
+ /// Copies content into the given stream.
+ ///
+ /// Destination stream.
+ /// Result of the operation.
+ Task IHttpContent.CopyToAsync(Stream stream)
+ {
+ return stream.WriteAsync(_bytes, 0, _bytes.Length);
+ }
+
+ ///
+ /// Buffers content into memory.
+ ///
+ /// Buffered content.
+ Task IHttpContent.BufferContentAsync()
+ {
+ TaskCompletionSource completion = new TaskCompletionSource();
+ completion.SetResult(this);
+ return completion.Task;
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/StreamContent.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/StreamContent.cs
new file mode 100644
index 000000000000..ec02a1738fff
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/StreamContent.cs
@@ -0,0 +1,106 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.Http
+{
+ ///
+ /// Stream-based content.
+ ///
+ internal class StreamContent: IHttpContent
+ {
+ private Stream _stream; // Data stream.
+
+ ///
+ /// Initializes the content with the stream data.
+ ///
+ /// Content stream.
+ internal StreamContent(Stream stream)
+ {
+ Debug.Assert(stream != null);
+ _stream = stream;
+ }
+
+ ///
+ /// Reads content as a string.
+ ///
+ /// Content string.
+ Task IHttpContent.ReadAsStringAsync()
+ {
+ StreamReader reader = new StreamReader(_stream);
+ return reader.ReadToEndAsync();
+ }
+
+ ///
+ /// Reads content as a bytes array.
+ ///
+ /// Content bytes.
+ Task IHttpContent.ReadAsBytesAsync()
+ {
+ MemoryStream buffer = new MemoryStream();
+ return _stream
+ .CopyToAsync(buffer)
+ .ContinueWith(t => buffer.ToArray(), TaskContinuationOptions.OnlyOnRanToCompletion);
+ }
+
+ ///
+ /// Reads content as a stream of bytes.
+ ///
+ /// Content bytes.
+ Task IHttpContent.ReadAsStreamAsync()
+ {
+ TaskCompletionSource completion = new TaskCompletionSource();
+ completion.SetResult(_stream);
+ return completion.Task;
+ }
+
+ ///
+ /// Copies content into the given stream.
+ ///
+ /// Destination stream.
+ /// Result of the operation.
+ Task IHttpContent.CopyToAsync(Stream stream)
+ {
+ return _stream.CopyToAsync(stream);
+ }
+
+ ///
+ /// Buffers content into memory making all its read operations
+ /// reusable.
+ ///
+ /// Buffered content.
+ Task IHttpContent.BufferContentAsync()
+ {
+ MemoryStream buffer = new MemoryStream();
+
+ return _stream
+ .CopyToAsync(buffer)
+ .ContinueWith(t =>
+ {
+ buffer.Flush();
+ byte[] bytes = buffer.ToArray();
+ buffer.Dispose();
+ return new MemoryContent(bytes) as IHttpContent;
+ }, TaskContinuationOptions.OnlyOnRanToCompletion);
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj
index 9b78a2f7f42e..880172b39917 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Microsoft.WindowsAzure.ServiceLayer.csproj
@@ -105,6 +105,10 @@
true
+
+
+
+
@@ -115,6 +119,7 @@
+
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs
index c4d1e9ac3998..b9f719741331 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs
@@ -16,13 +16,16 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
+using Microsoft.WindowsAzure.ServiceLayer.Http;
using Windows.Foundation;
using Windows.Foundation.Metadata;
using Windows.Storage.Streams;
+using NetHttpContent = System.Net.Http.HttpContent;
+using NetHttpRequestMessage = System.Net.Http.HttpRequestMessage;
+
namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus
{
///
@@ -30,17 +33,13 @@ namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus
///
public sealed class BrokeredMessageSettings
{
- private HttpContent _content; // Body content.
private BrokerProperties _brokerProperties; // Message's broker properties.
private CustomPropertiesDictionary _customProperties; // Custom properties of the message.
///
- /// Gets the content type of the message.
+ /// Message content.
///
- public string ContentType
- {
- get { return _content.Headers.ContentType.ToString(); }
- }
+ public HttpContent Content { get; private set; }
///
/// Gets or sets the identifier of the correlation.
@@ -133,99 +132,66 @@ public string To
}
///
- /// Constructor for a message consisting of text.
- ///
- /// Text of the message.
- private BrokeredMessageSettings(string contentType, string messageText)
- {
- if (contentType == null)
- {
- throw new ArgumentNullException("contentType");
- }
- if (messageText == null)
- {
- throw new ArgumentNullException("messageText");
- }
-
- _content = new StringContent(messageText, Encoding.UTF8, contentType);
- _brokerProperties = new BrokerProperties();
- _customProperties = new CustomPropertiesDictionary();
- }
-
- ///
- /// Constructor for a message consisting of bytes.
+ /// Constructor.
///
- /// Content type.
- /// Content of the message.
- private BrokeredMessageSettings(byte[] messageBytes)
+ /// Message content.
+ public BrokeredMessageSettings(HttpContent content)
{
- if (messageBytes == null)
+ if (content == null)
{
- throw new ArgumentNullException("messageBytes");
+ throw new ArgumentNullException("content");
}
- _content = new ByteArrayContent(messageBytes);
- _brokerProperties = new BrokerProperties();
- _customProperties = new CustomPropertiesDictionary();
- }
-
- ///
- /// Constructor for a message with the content specified in the stream.
- ///
- /// Content type.
- /// Stream with the content.
- private BrokeredMessageSettings(IInputStream stream)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- _content = new StreamContent(stream.AsStreamForRead());
+ Content = content;
_brokerProperties = new BrokerProperties();
_customProperties = new CustomPropertiesDictionary();
}
///
/// Creates a message from the given text. This method exists only
- /// becase JavaScript cannot work with multiple constructors with
+ /// because JavaScript cannot work with multiple constructors with
/// identical number of parameters.
///
- /// Content type.
/// Message text.
+ /// Content type.
/// Message settings.
- public static BrokeredMessageSettings CreateFromText(string contentType, string messageText)
+ public static BrokeredMessageSettings CreateFromText(string messageText, string contentType = Constants.DefaultMessageContentType)
{
if (messageText == null)
{
throw new ArgumentNullException("messageText");
}
+ if (contentType == null)
+ {
+ throw new ArgumentNullException("contentType");
+ }
- return new BrokeredMessageSettings(contentType: contentType, messageText: messageText);
+ HttpContent content = HttpContent.CreateFromText(messageText, contentType);
+ return new BrokeredMessageSettings(content);
}
///
- /// Creates a message object from the array of bytes. This method
- /// simply instantiates the object with the corresponding constructor;
- /// it is defined only because JavaScript does not support multiple
- /// constructors with the same number of parameters.
+ /// Creates a message from the array of bytes. This method exists only
+ /// because JavaScript cannot work with multiple constructors with
+ /// identical number of parameters.
///
/// Array of bytes.
/// Message settings.
- public static BrokeredMessageSettings CreateFromBytes(byte[] messageBytes)
+ public static BrokeredMessageSettings CreateFromByteArray(byte[] messageBytes)
{
if (messageBytes == null)
{
throw new ArgumentNullException("messageBytes");
}
- return new BrokeredMessageSettings(messageBytes);
+ HttpContent content = HttpContent.CreateFromByteArray(messageBytes);
+ return new BrokeredMessageSettings(content);
}
///
- /// Creates a message object from the given stream. This method
- /// exists only because JavaScript does not support having multiple
- /// constructors with the same number of parameters.
+ /// Creates a message from the given stream. The method exists only
+ /// because JavaScript cannot work with multiple constructors with
+ /// identical number of parameters.
///
/// Stream with message data.
/// Message settings.
@@ -236,70 +202,20 @@ public static BrokeredMessageSettings CreateFromStream(IInputStream stream)
throw new ArgumentNullException("stream");
}
- return new BrokeredMessageSettings(stream);
+ HttpContent content = HttpContent.CreateFromStream(stream);
+ return new BrokeredMessageSettings(content);
}
- ///
- /// Reads message's body as a string. This method is not thread-safe.
- ///
- /// Message body.
- public IAsyncOperation ReadContentAsStringAsync()
- {
- return _content
- .ReadAsStringAsync()
- .AsAsyncOperation();
- }
-
- ///
- /// Reads message's body as an array of bytes.
- ///
- /// Message body.
- public IAsyncOperation> ReadContentAsBytesAsync()
- {
- return _content
- .ReadAsByteArrayAsync()
- .ContinueWith(t => (IEnumerable)t.Result, TaskContinuationOptions.OnlyOnRanToCompletion)
- .AsAsyncOperation();
- }
-
- ///
- /// Gets stream with the content of the message.
- ///
- /// Stream with the content.
- public IAsyncOperation ReadContentAsStreamAsync()
- {
- return _content
- .ReadAsStreamAsync()
- .ContinueWith(t => t.Result.AsInputStream(), TaskContinuationOptions.OnlyOnRanToCompletion)
- .AsAsyncOperation();
- }
-
- ///
- /// Copies content of the body to the given stream.
- ///
- /// Target stream.
- /// Result of the operation.
- public IAsyncAction CopyContentToAsync(IOutputStream stream)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- return _content
- .CopyToAsync(stream.AsStreamForWrite())
- .AsAsyncAction();
- }
///
/// Submits content to the given request.
///
/// Target request.
- internal void SubmitTo(HttpRequestMessage request)
+ internal void SubmitTo(NetHttpRequestMessage request)
{
_brokerProperties.SubmitTo(request);
_customProperties.SubmitTo(request);
- request.Content = _content;
+ Content.SubmitTo(request);
}
}
}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs
new file mode 100644
index 000000000000..f6738ea47576
--- /dev/null
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs
@@ -0,0 +1,42 @@
+//
+// Copyright 2012 Microsoft Corporation
+//
+// 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.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.WindowsAzure.ServiceLayer.Http;
+
+namespace Microsoft.WindowsAzure.ServiceLayer.ServiceBus
+{
+ ///
+ /// Helper class for dealing with messages.
+ ///
+ internal static class MessageHelper
+ {
+ ///
+ /// Creates a brokered message with the text content.
+ ///
+ /// Message text.
+ /// Brokered message.
+ internal static BrokeredMessageSettings CreateTextMessage(string messageText)
+ {
+ HttpContent content = HttpContent.CreateFromText(messageText, "text/plain");
+ BrokeredMessageSettings message = new BrokeredMessageSettings(content);
+ return message;
+ }
+ }
+}
diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs
index 773b5313578d..a4e7caa6661f 100644
--- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs
+++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/ServiceBusRestProxy.cs
@@ -102,8 +102,6 @@ IAsyncOperation> IServiceBusService.ListQueuesAsync(int f
ServiceConfig.GetQueuesContainerUri(),
firstItem, count,
InitQueue);
-
- throw new NotImplementedException();
}
///
@@ -622,7 +620,7 @@ IAsyncOperation IServiceBusService.PeekQueueMessageAsync(st
Uri uri = ServiceConfig.GetUnlockedMessageUri(queueName, lockInterval);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
- return SendAsync(request)
+ return SendAsync(request, CheckNoContent)
.ContinueWith((t) => BrokeredMessageInfo.CreateFromPeekResponse(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
.AsAsyncOperation();
}