From 31e0b9e0513088c6b94371b4ea2fed13d3a32cb9 Mon Sep 17 00:00:00 2001 From: Aliaksei Baturytski Date: Wed, 21 Mar 2012 14:25:17 -0700 Subject: [PATCH 1/3] Public HTTP content class --- .../Configuration.cs | 2 +- ...WindowsAzure.ServiceLayer.UnitTests.csproj | 4 + .../ServiceBusTests/ContentTests.cs | 273 +++++++++++++ .../ServiceBusTests/MessageHelper.cs | 64 +++ .../ServiceBusTests/MessagePropertiesTests.cs | 6 +- .../ServiceBusTests/MessageSettingsTests.cs | 57 +-- .../ServiceBusTests/MessagingTestsBase.cs | 365 ++++++++++++++++++ .../ServiceBusTests/QueueMessagingTests.cs | 317 ++------------- .../SubscriptionMessagingTests.cs | 128 +++--- .../ServiceBusTests/UniqueQueueFixture.cs | 33 ++ .../Http/Content.cs | 191 +++++++++ .../Http/IContent.cs | 65 ++++ .../Http/MemoryContent.cs | 109 ++++++ .../Http/StreamContent.cs | 106 +++++ ...Microsoft.WindowsAzure.ServiceLayer.csproj | 5 + .../ServiceBus/BrokeredMessageSettings.cs | 166 +------- .../ServiceBus/MessageHelper.cs | 42 ++ .../ServiceBus/ServiceBusRestProxy.cs | 4 +- 18 files changed, 1383 insertions(+), 554 deletions(-) create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/UniqueQueueFixture.cs create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/Content.cs create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IContent.cs create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/MemoryContent.cs create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/StreamContent.cs create mode 100644 microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs 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..c2025c463f00 --- /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 Content CreateMemoryContent(string text) + { + return Content.CreateFromString(text, "text/plain"); + } + + /// + /// Creates a memory content from the given bytes. + /// + /// Content data. + /// Memory-initialized content with the given bytes. + private static Content CreateMemoryContent(params byte[] bytes) + { + return Content.CreateFromByteArray(bytes); + } + + /// + /// Creates a stream content from the array of bytes. + /// + /// Content bytes. + /// Stream-initialized content with the given bytes. + private static Content CreateStreamContent(params byte[] bytes) + { + MemoryStream stream = new MemoryStream(bytes); + return Content.CreateFromStream(stream.AsInputStream()); + } + + /// + /// Creates a stream content from the given string. + /// + /// Content string. + /// Stream-initialized text content. + private static Content CreateStreamContent(string text) + { + byte[] bytes = Encoding.UTF8.GetBytes(text); + MemoryStream stream = new MemoryStream(bytes); + return Content.CreateFromStream(stream.AsInputStream()); + } + + + /// + /// Tests passing invalid arguments into content's constructors. + /// + [Fact] + public void InvalidArgs() + { + Assert.Throws(() => Content.CreateFromString(null, "text/plain")); + Assert.Throws(() => Content.CreateFromString("test", null)); + Assert.Throws(() => Content.CreateFromByteArray(null)); + Assert.Throws(() => Content.CreateFromStream(null)); + + Content content = Content.CreateFromString("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(); + Content 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(); + Content content = Content.CreateFromString(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(); + Content content = Content.CreateFromString(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(); + Content 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, }; + Content 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(); + Content 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, }; + Content 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, }; + Content 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, }; + Content 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..e71bab76c4b2 --- /dev/null +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs @@ -0,0 +1,64 @@ +// +// 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") + { + Content content = Content.CreateFromString(messageText, contentType); + return new BrokeredMessageSettings(content); + } + + /// + /// Creates a brokered message with the binary content. + /// + /// Message content. + /// Brokered message. + internal static BrokeredMessageSettings CreateMessage(byte[] bytes) + { + Content content = Content.CreateFromByteArray(bytes); + return new BrokeredMessageSettings(content); + } + + /// + /// Creates a brokered message with the binary content. + /// + /// Message content. + /// Brokered message. + internal static BrokeredMessageSettings CreateMessage(Stream stream) + { + Content content = Content.CreateFromStream(stream.AsInputStream()); + return new BrokeredMessageSettings(content); + } + } +} 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..bd57e5433ad8 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageSettingsTests.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageSettingsTests.cs @@ -21,62 +21,7 @@ public sealed class MessageSettingsTests [Fact] public void NullArgumentsInConstructors() { - 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)); } } } 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..babb97a4163c --- /dev/null +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs @@ -0,0 +1,365 @@ +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); + } + } + } + } +} 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/Http/Content.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/Content.cs new file mode 100644 index 000000000000..5145bc85a19e --- /dev/null +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/Content.cs @@ -0,0 +1,191 @@ +// +// 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; + +namespace Microsoft.WindowsAzure.ServiceLayer.Http +{ + /// + /// HTTP content. + /// + /// 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 Content + { + private IContent _rawContent; // Raw content. + + /// + /// 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 Content CreateFromString(string text, string contentType) + { + if (text == null) + { + throw new ArgumentNullException("text"); + } + if (contentType == null) + { + throw new ArgumentNullException("contentType"); + } + + return new Content( + new MemoryContent(text), + contentType); + } + + /// + /// Creates a content from binary data specified in the array. + /// + /// Binary data. + /// Content object. + public static Content CreateFromByteArray(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + + return new Content(new MemoryContent(bytes)); + } + + /// + /// Creates a content from binary data specified in the stream. + /// + /// Binary data. + /// Content object. + public static Content CreateFromStream(IInputStream stream) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + return new Content(new StreamContent(stream.AsStreamForRead())); + } + + /// + /// Initializes the content. + /// + /// Content container. + /// Content type. + private Content(IContent 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) + { + HttpContent 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/IContent.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IContent.cs new file mode 100644 index 000000000000..cbde57dab831 --- /dev/null +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IContent.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. + /// + interface IContent + { + /// + /// 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..c0fa0ea42b07 --- /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: IContent + { + 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 IContent.ReadAsStringAsync() + { + using (MemoryStream stream = new MemoryStream(_bytes)) + { + StreamReader reader = new StreamReader(stream); + return reader.ReadToEndAsync(); + } + } + + /// + /// Reads content as a bytes array. + /// + /// Content bytes. + Task IContent.ReadAsBytesAsync() + { + TaskCompletionSource completion = new TaskCompletionSource(); + completion.SetResult(_bytes); + return completion.Task; + } + + /// + /// Reads content as a stream. + /// + /// Content bytes in a stream. + Task IContent.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 IContent.CopyToAsync(Stream stream) + { + return stream.WriteAsync(_bytes, 0, _bytes.Length); + } + + /// + /// Buffers content into memory. + /// + /// Buffered content. + Task IContent.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..c973964b56e1 --- /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: IContent + { + 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 IContent.ReadAsStringAsync() + { + StreamReader reader = new StreamReader(_stream); + return reader.ReadToEndAsync(); + } + + /// + /// Reads content as a bytes array. + /// + /// Content bytes. + Task IContent.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 IContent.ReadAsStreamAsync() + { + TaskCompletionSource completion = new TaskCompletionSource(); + completion.SetResult(_stream); + return completion.Task; + } + + /// + /// Copies content into the given stream. + /// + /// Destination stream. + /// Result of the operation. + Task IContent.CopyToAsync(Stream stream) + { + return _stream.CopyToAsync(stream); + } + + /// + /// Buffers content into memory making all its read operations + /// reusable. + /// + /// Buffered content. + Task IContent.BufferContentAsync() + { + MemoryStream buffer = new MemoryStream(); + + return _stream + .CopyToAsync(buffer) + .ContinueWith(t => + { + buffer.Flush(); + byte[] bytes = buffer.ToArray(); + buffer.Dispose(); + return new MemoryContent(bytes) as IContent; + }, 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..536f73f042fc 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..b3138bf33f68 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs @@ -19,6 +19,7 @@ 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; @@ -30,17 +31,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 Content Content { get; set; } /// /// Gets or sets the identifier of the correlation. @@ -133,164 +130,21 @@ 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. - /// - /// Content type. - /// Content of the message. - private BrokeredMessageSettings(byte[] messageBytes) - { - if (messageBytes == null) - { - throw new ArgumentNullException("messageBytes"); - } - - _content = new ByteArrayContent(messageBytes); - _brokerProperties = new BrokerProperties(); - _customProperties = new CustomPropertiesDictionary(); - } - - /// - /// Constructor for a message with the content specified in the stream. + /// Constructor. /// - /// Content type. - /// Stream with the content. - private BrokeredMessageSettings(IInputStream stream) + /// Message content. + public BrokeredMessageSettings(Content content) { - if (stream == null) + if (content == null) { - throw new ArgumentNullException("stream"); + throw new ArgumentNullException("content"); } - _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 - /// identical number of parameters. - /// - /// Content type. - /// Message text. - /// Message settings. - public static BrokeredMessageSettings CreateFromText(string contentType, string messageText) - { - if (messageText == null) - { - throw new ArgumentNullException("messageText"); - } - - return new BrokeredMessageSettings(contentType: contentType, messageText: messageText); - } - - /// - /// 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. - /// - /// Array of bytes. - /// Message settings. - public static BrokeredMessageSettings CreateFromBytes(byte[] messageBytes) - { - if (messageBytes == null) - { - throw new ArgumentNullException("messageBytes"); - } - - return new BrokeredMessageSettings(messageBytes); - } - - /// - /// 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. - /// - /// Stream with message data. - /// Message settings. - public static BrokeredMessageSettings CreateFromStream(IInputStream stream) - { - if (stream == null) - { - throw new ArgumentNullException("stream"); - } - - return new BrokeredMessageSettings(stream); - } - - /// - /// 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. /// @@ -299,7 +153,7 @@ internal void SubmitTo(HttpRequestMessage 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..2a403b0533e2 --- /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) + { + Content content = Content.CreateFromString(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(); } From 22aa9df86623e794c4a66ff2f09ec406c4fc63e4 Mon Sep 17 00:00:00 2001 From: Aliaksei Baturytski Date: Thu, 22 Mar 2012 10:20:24 -0700 Subject: [PATCH 2/3] Restoring static methods for creating brokered messages. --- .../ServiceBusTests/ContentTests.cs | 12 ++-- .../ServiceBusTests/MessageHelper.cs | 9 +-- .../ServiceBusTests/MessageSettingsTests.cs | 6 +- .../Constants.cs | 4 +- .../Http/Content.cs | 2 +- .../ServiceBus/BrokeredMessageSettings.cs | 62 ++++++++++++++++++- .../ServiceBus/MessageHelper.cs | 2 +- 7 files changed, 79 insertions(+), 18 deletions(-) diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs index c2025c463f00..44f7e02efd95 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs @@ -37,7 +37,7 @@ public sealed class ContentTests /// Memory-initialized content with the given text. private static Content CreateMemoryContent(string text) { - return Content.CreateFromString(text, "text/plain"); + return Content.CreateFromText(text, "text/plain"); } /// @@ -80,12 +80,12 @@ private static Content CreateStreamContent(string text) [Fact] public void InvalidArgs() { - Assert.Throws(() => Content.CreateFromString(null, "text/plain")); - Assert.Throws(() => Content.CreateFromString("test", null)); + Assert.Throws(() => Content.CreateFromText(null, "text/plain")); + Assert.Throws(() => Content.CreateFromText("test", null)); Assert.Throws(() => Content.CreateFromByteArray(null)); Assert.Throws(() => Content.CreateFromStream(null)); - Content content = Content.CreateFromString("this is a test.", "text/plain"); + Content content = Content.CreateFromText("this is a test.", "text/plain"); Assert.Throws(() => content.CopyToAsync(null)); } @@ -113,7 +113,7 @@ public void ReadTextAsString() public void ReadTextAsBytes() { string originalContent = Guid.NewGuid().ToString(); - Content content = Content.CreateFromString(originalContent, "text/plain"); + Content content = Content.CreateFromText(originalContent, "text/plain"); // Must be able to read multiple times. for (int i = 0; i < 2; i++) @@ -132,7 +132,7 @@ public void ReadTextAsBytes() public void ReadTextAsStream() { string originalContent = Guid.NewGuid().ToString(); - Content content = Content.CreateFromString(originalContent, "text/plain"); + Content content = Content.CreateFromText(originalContent, "text/plain"); // Must be able to read multiple times. for (int i = 0; i < 2; i++) diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs index e71bab76c4b2..f3622bc9ab78 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessageHelper.cs @@ -35,8 +35,7 @@ internal static class MessageHelper /// Brokered message. internal static BrokeredMessageSettings CreateMessage(string messageText, string contentType = "text/plain") { - Content content = Content.CreateFromString(messageText, contentType); - return new BrokeredMessageSettings(content); + return BrokeredMessageSettings.CreateFromText(messageText, contentType); } /// @@ -46,8 +45,7 @@ internal static BrokeredMessageSettings CreateMessage(string messageText, string /// Brokered message. internal static BrokeredMessageSettings CreateMessage(byte[] bytes) { - Content content = Content.CreateFromByteArray(bytes); - return new BrokeredMessageSettings(content); + return BrokeredMessageSettings.CreateFromByteArray(bytes); } /// @@ -57,8 +55,7 @@ internal static BrokeredMessageSettings CreateMessage(byte[] bytes) /// Brokered message. internal static BrokeredMessageSettings CreateMessage(Stream stream) { - Content content = Content.CreateFromStream(stream.AsInputStream()); - return new BrokeredMessageSettings(content); + return BrokeredMessageSettings.CreateFromStream(stream.AsInputStream()); } } } 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 bd57e5433ad8..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,9 +19,13 @@ public sealed class MessageSettingsTests /// Tests specifying null arguments in constructors. /// [Fact] - public void NullArgumentsInConstructors() + public void InvalidArgumentsInMethods() { 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/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/Content.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/Content.cs index 5145bc85a19e..33c32d54d6fb 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/Content.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/Content.cs @@ -47,7 +47,7 @@ public sealed class Content /// String content. /// HTTP content type. /// Content object. - public static Content CreateFromString(string text, string contentType) + public static Content CreateFromText(string text, string contentType) { if (text == null) { diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs index b3138bf33f68..217f0931cc3c 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs @@ -37,7 +37,7 @@ public sealed class BrokeredMessageSettings /// /// Message content. /// - public Content Content { get; set; } + public Content Content { get; private set; } /// /// Gets or sets the identifier of the correlation. @@ -145,6 +145,66 @@ public BrokeredMessageSettings(Content content) _customProperties = new CustomPropertiesDictionary(); } + /// + /// Creates a message from the given text. This method exists only + /// because JavaScript cannot work with multiple constructors with + /// identical number of parameters. + /// + /// Message text. + /// Content type. + /// Message settings. + public static BrokeredMessageSettings CreateFromText(string messageText, string contentType = Constants.DefaultMessageContentType) + { + if (messageText == null) + { + throw new ArgumentNullException("messageText"); + } + if (contentType == null) + { + throw new ArgumentNullException("contentType"); + } + + Content content = Content.CreateFromText(messageText, contentType); + return new BrokeredMessageSettings(content); + } + + /// + /// 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 CreateFromByteArray(byte[] messageBytes) + { + if (messageBytes == null) + { + throw new ArgumentNullException("messageBytes"); + } + + Content content = Content.CreateFromByteArray(messageBytes); + return new BrokeredMessageSettings(content); + } + + /// + /// 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. + public static BrokeredMessageSettings CreateFromStream(IInputStream stream) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + Content content = Content.CreateFromStream(stream); + return new BrokeredMessageSettings(content); + } + + /// /// Submits content to the given request. /// diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs index 2a403b0533e2..df98b6675e5e 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs @@ -34,7 +34,7 @@ internal static class MessageHelper /// Brokered message. internal static BrokeredMessageSettings CreateTextMessage(string messageText) { - Content content = Content.CreateFromString(messageText, "text/plain"); + Content content = Content.CreateFromText(messageText, "text/plain"); BrokeredMessageSettings message = new BrokeredMessageSettings(content); return message; } From b46cdde28be3e132e80909fe7b2cf71cc611650a Mon Sep 17 00:00:00 2001 From: Aliaksei Baturytski Date: Thu, 22 Mar 2012 11:11:51 -0700 Subject: [PATCH 3/3] Code review updates --- .../ServiceBusTests/ContentTests.cs | 44 +++++++++---------- .../ServiceBusTests/MessagingTestsBase.cs | 29 ++++++++++++ .../Http/{Content.cs => HttpContent.cs} | 31 +++++++------ .../Http/{IContent.cs => IHttpContent.cs} | 4 +- .../Http/MemoryContent.cs | 14 +++--- .../Http/StreamContent.cs | 14 +++--- ...Microsoft.WindowsAzure.ServiceLayer.csproj | 4 +- .../ServiceBus/BrokeredMessageSettings.cs | 16 ++++--- .../ServiceBus/MessageHelper.cs | 2 +- 9 files changed, 96 insertions(+), 62 deletions(-) rename microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/{Content.cs => HttpContent.cs} (84%) rename microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/{IContent.cs => IHttpContent.cs} (96%) diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs index 44f7e02efd95..cb22569ae4ea 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/ContentTests.cs @@ -35,9 +35,9 @@ public sealed class ContentTests /// /// Content text. /// Memory-initialized content with the given text. - private static Content CreateMemoryContent(string text) + private static HttpContent CreateMemoryContent(string text) { - return Content.CreateFromText(text, "text/plain"); + return HttpContent.CreateFromText(text, "text/plain"); } /// @@ -45,9 +45,9 @@ private static Content CreateMemoryContent(string text) /// /// Content data. /// Memory-initialized content with the given bytes. - private static Content CreateMemoryContent(params byte[] bytes) + private static HttpContent CreateMemoryContent(params byte[] bytes) { - return Content.CreateFromByteArray(bytes); + return HttpContent.CreateFromByteArray(bytes); } /// @@ -55,10 +55,10 @@ private static Content CreateMemoryContent(params byte[] bytes) /// /// Content bytes. /// Stream-initialized content with the given bytes. - private static Content CreateStreamContent(params byte[] bytes) + private static HttpContent CreateStreamContent(params byte[] bytes) { MemoryStream stream = new MemoryStream(bytes); - return Content.CreateFromStream(stream.AsInputStream()); + return HttpContent.CreateFromStream(stream.AsInputStream()); } /// @@ -66,11 +66,11 @@ private static Content CreateStreamContent(params byte[] bytes) /// /// Content string. /// Stream-initialized text content. - private static Content CreateStreamContent(string text) + private static HttpContent CreateStreamContent(string text) { byte[] bytes = Encoding.UTF8.GetBytes(text); MemoryStream stream = new MemoryStream(bytes); - return Content.CreateFromStream(stream.AsInputStream()); + return HttpContent.CreateFromStream(stream.AsInputStream()); } @@ -80,12 +80,12 @@ private static Content CreateStreamContent(string text) [Fact] public void InvalidArgs() { - Assert.Throws(() => Content.CreateFromText(null, "text/plain")); - Assert.Throws(() => Content.CreateFromText("test", null)); - Assert.Throws(() => Content.CreateFromByteArray(null)); - Assert.Throws(() => Content.CreateFromStream(null)); + Assert.Throws(() => HttpContent.CreateFromText(null, "text/plain")); + Assert.Throws(() => HttpContent.CreateFromText("test", null)); + Assert.Throws(() => HttpContent.CreateFromByteArray(null)); + Assert.Throws(() => HttpContent.CreateFromStream(null)); - Content content = Content.CreateFromText("this is a test.", "text/plain"); + HttpContent content = HttpContent.CreateFromText("this is a test.", "text/plain"); Assert.Throws(() => content.CopyToAsync(null)); } @@ -96,7 +96,7 @@ public void InvalidArgs() public void ReadTextAsString() { string originalContent = Guid.NewGuid().ToString(); - Content content = CreateMemoryContent(originalContent); + HttpContent content = CreateMemoryContent(originalContent); // Must be able to read multiple times for (int i = 0; i < 2; i++) @@ -113,7 +113,7 @@ public void ReadTextAsString() public void ReadTextAsBytes() { string originalContent = Guid.NewGuid().ToString(); - Content content = Content.CreateFromText(originalContent, "text/plain"); + HttpContent content = HttpContent.CreateFromText(originalContent, "text/plain"); // Must be able to read multiple times. for (int i = 0; i < 2; i++) @@ -132,7 +132,7 @@ public void ReadTextAsBytes() public void ReadTextAsStream() { string originalContent = Guid.NewGuid().ToString(); - Content content = Content.CreateFromText(originalContent, "text/plain"); + HttpContent content = HttpContent.CreateFromText(originalContent, "text/plain"); // Must be able to read multiple times. for (int i = 0; i < 2; i++) @@ -153,7 +153,7 @@ public void ReadTextAsStream() public void BufferMemoryContent() { string originalContent = Guid.NewGuid().ToString(); - Content content = CreateMemoryContent(originalContent); + HttpContent content = CreateMemoryContent(originalContent); content.CopyToBufferAsync().AsTask().Wait(); @@ -172,7 +172,7 @@ public void BufferMemoryContent() public void CopyMemoryContent() { byte[] originalContent = new byte[] { 1, 2, 3, 4, }; - Content content = CreateMemoryContent(originalContent); + HttpContent content = CreateMemoryContent(originalContent); // Memory content allows multiple reads. for (int i = 0; i < 2; i++) @@ -195,7 +195,7 @@ public void CopyMemoryContent() public void ReadStreamAsText() { string originalContent = Guid.NewGuid().ToString(); - Content content = CreateStreamContent(originalContent); + HttpContent content = CreateStreamContent(originalContent); // Reading the first time should be OK. string readContent = content.ReadAsStringAsync().AsTask().Result; @@ -213,7 +213,7 @@ public void ReadStreamAsText() public void ReadStreamAsBytes() { byte[] originalBytes = new byte[] { 1, 2, 3, 4, }; - Content content = CreateStreamContent(originalBytes); + HttpContent content = CreateStreamContent(originalBytes); List readBytes = new List(content.ReadAsByteArrayAsync().AsTask().Result); Assert.Equal(originalBytes, readBytes); @@ -230,7 +230,7 @@ public void ReadStreamAsBytes() public void BufferStreamContent() { byte[] originalBytes = new byte[] { 1, 2, 3, 4, }; - Content content = CreateStreamContent(originalBytes); + HttpContent content = CreateStreamContent(originalBytes); // Reading multiple times should work after buffering. content.CopyToBufferAsync().AsTask().Wait(); @@ -250,7 +250,7 @@ public void BufferStreamContent() public void CopyStreamContent() { byte[] originalContent = new byte[] { 1, 2, 3, 4, }; - Content content = CreateStreamContent(originalContent); + HttpContent content = CreateStreamContent(originalContent); using (MemoryStream stream = new MemoryStream()) { diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs index babb97a4163c..9fee31a534c1 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer.UnitTests/ServiceBusTests/MessagingTestsBase.cs @@ -361,5 +361,34 @@ public void PreserveStream() } } } + + /// + /// 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/Http/Content.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs similarity index 84% rename from microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/Content.cs rename to microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs index 33c32d54d6fb..8af047318405 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/Content.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/HttpContent.cs @@ -21,20 +21,23 @@ using Windows.Foundation; using Windows.Storage.Streams; +using NetHttpContent = System.Net.Http.HttpContent; + namespace Microsoft.WindowsAzure.ServiceLayer.Http { /// - /// HTTP content. + /// 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 + /// + /// 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 Content + public sealed class HttpContent { - private IContent _rawContent; // Raw content. + private IHttpContent _rawContent; // Container with data. /// /// Gets content type. @@ -47,7 +50,7 @@ public sealed class Content /// String content. /// HTTP content type. /// Content object. - public static Content CreateFromText(string text, string contentType) + public static HttpContent CreateFromText(string text, string contentType) { if (text == null) { @@ -58,7 +61,7 @@ public static Content CreateFromText(string text, string contentType) throw new ArgumentNullException("contentType"); } - return new Content( + return new HttpContent( new MemoryContent(text), contentType); } @@ -68,14 +71,14 @@ public static Content CreateFromText(string text, string contentType) /// /// Binary data. /// Content object. - public static Content CreateFromByteArray(byte[] bytes) + public static HttpContent CreateFromByteArray(byte[] bytes) { if (bytes == null) { throw new ArgumentNullException("bytes"); } - return new Content(new MemoryContent(bytes)); + return new HttpContent(new MemoryContent(bytes)); } /// @@ -83,14 +86,14 @@ public static Content CreateFromByteArray(byte[] bytes) /// /// Binary data. /// Content object. - public static Content CreateFromStream(IInputStream stream) + public static HttpContent CreateFromStream(IInputStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } - return new Content(new StreamContent(stream.AsStreamForRead())); + return new HttpContent(new StreamContent(stream.AsStreamForRead())); } /// @@ -98,7 +101,7 @@ public static Content CreateFromStream(IInputStream stream) /// /// Content container. /// Content type. - private Content(IContent rawContent, string contentType = null) + private HttpContent(IHttpContent rawContent, string contentType = null) { _rawContent = rawContent; ContentType = contentType; @@ -178,7 +181,7 @@ public IAsyncAction CopyToBufferAsync() /// Target request. internal void SubmitTo(HttpRequestMessage request) { - HttpContent content = new System.Net.Http.StreamContent( + NetHttpContent content = new System.Net.Http.StreamContent( _rawContent.ReadAsStreamAsync().Result); if (!string.IsNullOrEmpty(ContentType)) diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IContent.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IHttpContent.cs similarity index 96% rename from microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IContent.cs rename to microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IHttpContent.cs index cbde57dab831..8f0d9c40c193 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IContent.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/IHttpContent.cs @@ -26,7 +26,7 @@ namespace Microsoft.WindowsAzure.ServiceLayer.Http /// Content interface. The interface is used to hide details on physical /// storage mechanism. /// - interface IContent + internal interface IHttpContent { /// /// Reads content as a string. @@ -60,6 +60,6 @@ interface IContent /// Buffering content allows multiple reading operations from /// the same content. Without buffering, data from stream-based content /// can be read only once. - Task BufferContentAsync(); + Task BufferContentAsync(); } } diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/MemoryContent.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/MemoryContent.cs index c0fa0ea42b07..82a935bd352c 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/MemoryContent.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/MemoryContent.cs @@ -26,7 +26,7 @@ namespace Microsoft.WindowsAzure.ServiceLayer.Http /// /// A content whose data is stored in memory. /// - internal class MemoryContent: IContent + internal class MemoryContent: IHttpContent { private byte[] _bytes; // Memory content. @@ -54,7 +54,7 @@ internal MemoryContent(byte[] bytes) /// Reads content as a string. /// /// Content string. - Task IContent.ReadAsStringAsync() + Task IHttpContent.ReadAsStringAsync() { using (MemoryStream stream = new MemoryStream(_bytes)) { @@ -67,7 +67,7 @@ Task IContent.ReadAsStringAsync() /// Reads content as a bytes array. /// /// Content bytes. - Task IContent.ReadAsBytesAsync() + Task IHttpContent.ReadAsBytesAsync() { TaskCompletionSource completion = new TaskCompletionSource(); completion.SetResult(_bytes); @@ -78,7 +78,7 @@ Task IContent.ReadAsBytesAsync() /// Reads content as a stream. /// /// Content bytes in a stream. - Task IContent.ReadAsStreamAsync() + Task IHttpContent.ReadAsStreamAsync() { TaskCompletionSource completion = new TaskCompletionSource(); completion.SetResult(new MemoryStream(_bytes)); @@ -90,7 +90,7 @@ Task IContent.ReadAsStreamAsync() /// /// Destination stream. /// Result of the operation. - Task IContent.CopyToAsync(Stream stream) + Task IHttpContent.CopyToAsync(Stream stream) { return stream.WriteAsync(_bytes, 0, _bytes.Length); } @@ -99,9 +99,9 @@ Task IContent.CopyToAsync(Stream stream) /// Buffers content into memory. /// /// Buffered content. - Task IContent.BufferContentAsync() + Task IHttpContent.BufferContentAsync() { - TaskCompletionSource completion = new TaskCompletionSource(); + 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 index c973964b56e1..ec02a1738fff 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/StreamContent.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/Http/StreamContent.cs @@ -26,7 +26,7 @@ namespace Microsoft.WindowsAzure.ServiceLayer.Http /// /// Stream-based content. /// - internal class StreamContent: IContent + internal class StreamContent: IHttpContent { private Stream _stream; // Data stream. @@ -44,7 +44,7 @@ internal StreamContent(Stream stream) /// Reads content as a string. /// /// Content string. - Task IContent.ReadAsStringAsync() + Task IHttpContent.ReadAsStringAsync() { StreamReader reader = new StreamReader(_stream); return reader.ReadToEndAsync(); @@ -54,7 +54,7 @@ Task IContent.ReadAsStringAsync() /// Reads content as a bytes array. /// /// Content bytes. - Task IContent.ReadAsBytesAsync() + Task IHttpContent.ReadAsBytesAsync() { MemoryStream buffer = new MemoryStream(); return _stream @@ -66,7 +66,7 @@ Task IContent.ReadAsBytesAsync() /// Reads content as a stream of bytes. /// /// Content bytes. - Task IContent.ReadAsStreamAsync() + Task IHttpContent.ReadAsStreamAsync() { TaskCompletionSource completion = new TaskCompletionSource(); completion.SetResult(_stream); @@ -78,7 +78,7 @@ Task IContent.ReadAsStreamAsync() /// /// Destination stream. /// Result of the operation. - Task IContent.CopyToAsync(Stream stream) + Task IHttpContent.CopyToAsync(Stream stream) { return _stream.CopyToAsync(stream); } @@ -88,7 +88,7 @@ Task IContent.CopyToAsync(Stream stream) /// reusable. /// /// Buffered content. - Task IContent.BufferContentAsync() + Task IHttpContent.BufferContentAsync() { MemoryStream buffer = new MemoryStream(); @@ -99,7 +99,7 @@ Task IContent.BufferContentAsync() buffer.Flush(); byte[] bytes = buffer.ToArray(); buffer.Dispose(); - return new MemoryContent(bytes) as IContent; + 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 536f73f042fc..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,8 +105,8 @@ true - - + + diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs index 217f0931cc3c..b9f719741331 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/BrokeredMessageSettings.cs @@ -16,7 +16,6 @@ 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; @@ -24,6 +23,9 @@ 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 { /// @@ -37,7 +39,7 @@ public sealed class BrokeredMessageSettings /// /// Message content. /// - public Content Content { get; private set; } + public HttpContent Content { get; private set; } /// /// Gets or sets the identifier of the correlation. @@ -133,7 +135,7 @@ public string To /// Constructor. /// /// Message content. - public BrokeredMessageSettings(Content content) + public BrokeredMessageSettings(HttpContent content) { if (content == null) { @@ -164,7 +166,7 @@ public static BrokeredMessageSettings CreateFromText(string messageText, string throw new ArgumentNullException("contentType"); } - Content content = Content.CreateFromText(messageText, contentType); + HttpContent content = HttpContent.CreateFromText(messageText, contentType); return new BrokeredMessageSettings(content); } @@ -182,7 +184,7 @@ public static BrokeredMessageSettings CreateFromByteArray(byte[] messageBytes) throw new ArgumentNullException("messageBytes"); } - Content content = Content.CreateFromByteArray(messageBytes); + HttpContent content = HttpContent.CreateFromByteArray(messageBytes); return new BrokeredMessageSettings(content); } @@ -200,7 +202,7 @@ public static BrokeredMessageSettings CreateFromStream(IInputStream stream) throw new ArgumentNullException("stream"); } - Content content = Content.CreateFromStream(stream); + HttpContent content = HttpContent.CreateFromStream(stream); return new BrokeredMessageSettings(content); } @@ -209,7 +211,7 @@ public static BrokeredMessageSettings CreateFromStream(IInputStream stream) /// Submits content to the given request. /// /// Target request. - internal void SubmitTo(HttpRequestMessage request) + internal void SubmitTo(NetHttpRequestMessage request) { _brokerProperties.SubmitTo(request); _customProperties.SubmitTo(request); diff --git a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs index df98b6675e5e..f6738ea47576 100644 --- a/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs +++ b/microsoft-azure-servicelayer/Microsoft.WindowsAzure.ServiceLayer/ServiceBus/MessageHelper.cs @@ -34,7 +34,7 @@ internal static class MessageHelper /// Brokered message. internal static BrokeredMessageSettings CreateTextMessage(string messageText) { - Content content = Content.CreateFromText(messageText, "text/plain"); + HttpContent content = HttpContent.CreateFromText(messageText, "text/plain"); BrokeredMessageSettings message = new BrokeredMessageSettings(content); return message; }