diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/Azure.Messaging.ServiceBus.sln b/sdk/servicebus/Azure.Messaging.ServiceBus/Azure.Messaging.ServiceBus.sln index a1d3eb936139..950416722b2a 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/Azure.Messaging.ServiceBus.sln +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/Azure.Messaging.ServiceBus.sln @@ -27,6 +27,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{8B8C samples\Sample05_SessionProcessor.md = samples\Sample05_SessionProcessor.md samples\Sample06_Transactions.md = samples\Sample06_Transactions.md samples\Sample07_CrudOperations.md = samples\Sample07_CrudOperations.md + samples\Sample08_Interop.md = samples\Sample08_Interop.md EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core", "..\..\core\Azure.Core\src\Azure.Core.csproj", "{9CD1905A-19B9-4F71-8BE6-D25CF49DA5B3}" diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/README.md b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/README.md index 91932ba75e7b..efec3f800806 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/README.md +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/README.md @@ -18,3 +18,4 @@ description: Samples for the Azure.Messaging.ServiceBus client library - [Using the Session Processor](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample05_SessionProcessor.md) - [Working with Transactions](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample06_Transactions.md) - [CRUD Operations](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample07_CrudOperations.md) +- [Interop](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample08_Interop.md) diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample08_Interop.md b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample08_Interop.md new file mode 100644 index 000000000000..40618ac22bd9 --- /dev/null +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample08_Interop.md @@ -0,0 +1,52 @@ +## Interop with `WindowsAzure.ServiceBus` + +This sample demonstrates how to interoperate with messages that are sent or received using the `WindowsAzure.ServiceBus` library. The `WindowsAzure.ServiceBus` library uses the `DataContractSerializer` to serialize the `BrokeredMessage` body. Because of this, when attempting to interoperate with this library, there a few additional steps that are needed. + +### Sending a message using `Azure.Messaging.ServiceBus` that will be received with `WindowsAzure.ServiceBus` + +```C# Snippet:ServiceBusInteropSend +ServiceBusSender sender = client.CreateSender(queueName); +// When constructing the `DataContractSerializer`, We pass in the type for the model, which can be a strongly typed model or some pre-serialized data. +// If you use a strongly typed model here, the model properties will be serialized into XML. Since JSON is more commonly used, we will use it in our example, and +// and specify the type as string, since we will provide a JSON string. +var serializer = new DataContractSerializer(typeof(string)); +using var stream = new MemoryStream(); +XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream); + +// serialize an instance of our type into a JSON string +string json = JsonSerializer.Serialize(new TestModel {A = "Hello world", B = 5, C = true}); + +// serialize our JSON string into the XML envelope using the DataContractSerializer +serializer.WriteObject(writer, json); +writer.Flush(); + +// construct the ServiceBusMessage using the DataContract serialized JSON +var message = new ServiceBusMessage(stream.ToArray()); + +await sender.SendMessageAsync(message); +``` + +### Receiving a message using `Azure.Messaging.Service` that was sent with `WindowsAzure.ServiceBus` + +```C# Snippet:ServiceBusInteropReceive +ServiceBusReceiver receiver = client.CreateReceiver(queueName); +ServiceBusReceivedMessage received = await receiver.ReceiveMessageAsync(); + +// Similar to the send scenario, we still rely on the DataContractSerializer and we use string as our type because we are expecting a JSON +// message body. +var deserializer = new DataContractSerializer(typeof(string)); +XmlDictionaryReader reader = + XmlDictionaryReader.CreateBinaryReader(received.Body.ToStream(), XmlDictionaryReaderQuotas.Max); + +// deserialize the XML envelope into a string +string receivedJson = (string) deserializer.ReadObject(reader); + +// deserialize the JSON string into TestModel +TestModel output = JsonSerializer.Deserialize(receivedJson); +``` + +## Source + +To see the full example source, see: + +* [Sample08_Interop.cs](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample08_Interop.cs) diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample01_HelloWorld.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample01_HelloWorld.cs index d00eed83a5e7..61d1ac42d25f 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample01_HelloWorld.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample01_HelloWorld.cs @@ -90,14 +90,9 @@ public async Task SendAndReceiveMessageBatch() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false)) { - #region Snippet:ServiceBusInitializeSend -#if SNIPPET - string connectionString = ""; - string queueName = ""; -#else string connectionString = TestEnvironment.ServiceBusConnectionString; string queueName = scope.QueueName; -#endif + // since ServiceBusClient implements IAsyncDisposable we create it with "await using" await using var client = new ServiceBusClient(connectionString); @@ -110,8 +105,6 @@ public async Task SendAndReceiveMessageBatch() // send the messages await sender.SendMessagesAsync(messages); #endregion - #endregion - #region Snippet:ServiceBusReceiveBatch // create a receiver that we can use to receive the messages ServiceBusReceiver receiver = client.CreateReceiver(queueName); @@ -124,7 +117,6 @@ public async Task SendAndReceiveMessageBatch() string body = receivedMessage.Body.ToString(); Console.WriteLine(body); } - #endregion var sentMessagesEnum = messages.GetEnumerator(); foreach (ServiceBusReceivedMessage receivedMessage in receivedMessages) diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample08_Interop.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample08_Interop.cs new file mode 100644 index 000000000000..90ca4baf72f2 --- /dev/null +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample08_Interop.cs @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.IO; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Threading.Tasks; +using System.Xml; +using NUnit.Framework; + +namespace Azure.Messaging.ServiceBus.Tests.Samples +{ + public class Sample08_Interop : ServiceBusLiveTestBase + { + [Test] + public async Task TestInterop() + { + await using (var scope = await ServiceBusScope.CreateWithQueue( + enablePartitioning: false, + enableSession: false)) + { + var queueName = scope.QueueName; + await using var client = CreateClient(); + + // Scenario #1 - Sending a message using Azure.Messaging.ServiceBus that will be received with WindowsAzure.ServiceBus + #region Snippet:ServiceBusInteropSend + ServiceBusSender sender = client.CreateSender(queueName); + // When constructing the `DataContractSerializer`, We pass in the type for the model, which can be a strongly typed model or some pre-serialized data. + // If you use a strongly typed model here, the model properties will be serialized into XML. Since JSON is more commonly used, we will use it in our example, and + // and specify the type as string, since we will provide a JSON string. + var serializer = new DataContractSerializer(typeof(string)); + using var stream = new MemoryStream(); + XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream); + + // serialize an instance of our type into a JSON string + string json = JsonSerializer.Serialize(new TestModel {A = "Hello world", B = 5, C = true}); + + // serialize our JSON string into the XML envelope using the DataContractSerializer + serializer.WriteObject(writer, json); + writer.Flush(); + + // construct the ServiceBusMessage using the DataContract serialized JSON + var message = new ServiceBusMessage(stream.ToArray()); + + await sender.SendMessageAsync(message); + #endregion + + // Scenario #2 - Receiving a message using Azure.Messaging.ServiceBus that was sent with WindowsAzure.ServiceBus + #region Snippet:ServiceBusInteropReceive + ServiceBusReceiver receiver = client.CreateReceiver(queueName); + ServiceBusReceivedMessage received = await receiver.ReceiveMessageAsync(); + + // Similar to the send scenario, we still rely on the DataContractSerializer and we use string as our type because we are expecting a JSON + // message body. + var deserializer = new DataContractSerializer(typeof(string)); + XmlDictionaryReader reader = + XmlDictionaryReader.CreateBinaryReader(received.Body.ToStream(), XmlDictionaryReaderQuotas.Max); + + // deserialize the XML envelope into a string + string receivedJson = (string) deserializer.ReadObject(reader); + + // deserialize the JSON string into TestModel + TestModel output = JsonSerializer.Deserialize(receivedJson); + #endregion + + Assert.AreEqual("Hello world", output.A); + Assert.AreEqual(5, output.B); + Assert.IsTrue(output.C); + } + } + + public class TestModel + { + public string A { get; set; } + public int B { get; set; } + public bool C { get; set; } + } + } +} \ No newline at end of file