From 2a7980f4aa2dba2612158d4c064148e4a620ff07 Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Fri, 24 Apr 2020 10:51:08 -0700 Subject: [PATCH 1/4] Sender updates --- .../src/Client/ServiceBusClient.cs | 20 +++--- .../src/Sender/ServiceBusMessageBatch.cs | 5 +- .../src/Sender/ServiceBusSender.cs | 21 ++++--- .../src/Sender/ServiceBusSenderOptions.cs | 62 +++++++++++++++++++ .../tests/Processor/ProcessorLiveTests.cs | 8 +-- .../Processor/SessionProcessorLiveTests.cs | 4 +- .../tests/Receiver/ReceiverLiveTests.cs | 12 ++-- .../Receiver/SessionReceiverLiveTests.cs | 24 +++---- .../tests/Samples/Sample01_HelloWorld.cs | 2 +- .../Samples/Sample03_SendReceiveSessions.cs | 2 +- .../tests/Samples/Sample04_Processor.cs | 2 +- .../Samples/Sample05_SessionProcessor.cs | 2 +- .../tests/Sender/SenderLiveTests.cs | 8 +-- .../tests/Sender/SenderTests.cs | 4 +- .../Transactions/TransactionLiveTests.cs | 10 ++- 15 files changed, 127 insertions(+), 59 deletions(-) create mode 100644 sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSenderOptions.cs diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Client/ServiceBusClient.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Client/ServiceBusClient.cs index c60f3bc5b34e..c5af6da032c0 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Client/ServiceBusClient.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Client/ServiceBusClient.cs @@ -175,34 +175,28 @@ public ServiceBusSender CreateSender(string queueOrTopicName) return new ServiceBusSender( entityPath: queueOrTopicName, - viaEntityPath: null, + options: new ServiceBusSenderOptions(), connection: Connection); } /// /// Creates a instance that can be used for sending messages to a specific - /// queue or topic via a different queue or topic. + /// queue or topic. /// /// /// The queue or topic to create a for. - /// - /// - /// - /// This is mainly to be used when sending messages in a transaction. - /// When messages need to be sent across entities in a single transaction, this can be used to ensure - /// all the messages land initially in the same entity/partition for local transactions, and then - /// let Service Bus handle transferring the message to the actual destination. - /// + /// The set of to use for configuring + /// this . /// /// A scoped to the specified queue or topic. - public ServiceBusSender CreateSender(string queueOrTopicName, string viaQueueOrTopicName) + public ServiceBusSender CreateSender(string queueOrTopicName, ServiceBusSenderOptions options) { - ValidateEntityName(viaQueueOrTopicName); + ValidateEntityName(options?.ViaQueueOrTopicName); ValidateEntityName(queueOrTopicName); return new ServiceBusSender( entityPath: queueOrTopicName, - viaEntityPath: viaQueueOrTopicName, + options: options, connection: Connection); } diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusMessageBatch.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusMessageBatch.cs index 14c89ada7d05..b54c5232fa63 100755 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusMessageBatch.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusMessageBatch.cs @@ -9,8 +9,11 @@ namespace Azure.Messaging.ServiceBus { /// - /// A set of with size constraints known up-front, + /// A set of with size constraints known up-front, /// intended to be sent to the Queue/Topic as a single batch. + /// A can be created using + /// . + /// Messages can be added to the batch using the method on the batch. /// /// public sealed class ServiceBusMessageBatch : IDisposable diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSender.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSender.cs index 541dfeef697b..baf7f8966bcd 100755 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSender.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSender.cs @@ -83,12 +83,13 @@ public class ServiceBusSender : IAsyncDisposable /// Initializes a new instance of the class. /// /// The entity path to send the message to. - /// The entity path to route the message through. Useful when using transactions. + /// The set of to use for configuring + /// this . /// The connection for the sender. /// internal ServiceBusSender( string entityPath, - string viaEntityPath, + ServiceBusSenderOptions options, ServiceBusConnection connection) { Argument.AssertNotNull(connection, nameof(connection)); @@ -96,14 +97,15 @@ internal ServiceBusSender( Argument.AssertNotNullOrWhiteSpace(entityPath, nameof(entityPath)); connection.ThrowIfClosed(); + options = options?.Clone() ?? new ServiceBusSenderOptions(); EntityPath = entityPath; - ViaEntityPath = viaEntityPath; + ViaEntityPath = options.ViaQueueOrTopicName; Identifier = DiagnosticUtilities.GenerateIdentifier(EntityPath); _connection = connection; _retryPolicy = _connection.RetryOptions.ToRetryPolicy(); _innerSender = _connection.CreateTransportSender( entityPath, - viaEntityPath, + ViaEntityPath, _retryPolicy); } @@ -138,7 +140,7 @@ await SendAsync( /// Sends a set of messages to the associated Service Bus entity using a batched approach. /// If the size of the messages exceed the maximum size of a single batch, /// an exception will be triggered and the send will fail. In order to ensure that the messages - /// being sent will fit in a batch, use instead. + /// being sent will fit in a batch, use instead. /// /// /// The set of messages to send. @@ -233,15 +235,16 @@ public virtual async ValueTask CreateBatchAsync( } /// - /// Sends a set of messages to the associated Service Bus entity using a batched approach. If the size of messages exceed the - /// maximum size of a single batch, an exception will be triggered and the send will fail. + /// Sends a + /// containing a set of to + /// the associated Service Bus entity. /// /// - /// The set of messages to send. A batch may be created using . + /// The batch of messages to send. A batch may be created using . /// An optional instance to signal the request to cancel the operation. /// A task to be resolved on when the operation has completed. /// - public virtual async Task SendBatchAsync( + public virtual async Task SendAsync( ServiceBusMessageBatch messageBatch, CancellationToken cancellationToken = default) { diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSenderOptions.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSenderOptions.cs new file mode 100644 index 000000000000..7c9c96d2658e --- /dev/null +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSenderOptions.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.ComponentModel; + +namespace Azure.Messaging.ServiceBus +{ + /// + /// The set of options that can be specified when creating a + /// to configure its behavior. + /// + public class ServiceBusSenderOptions + { + /// + /// The queue or topic name to route the message through. This is useful when using transactions, in order + /// to allow for completing a transaction involving multiple entities. For instance, if you want to + /// settle a message on Entity A and send a message to Entity B as part of the same transaction, + /// you can use a for Entity B, with the + /// property set to Entity A. + /// + public string ViaQueueOrTopicName { get; set; } + + /// + /// Determines whether the specified is equal to this instance. + /// + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object obj) => base.Equals(obj); + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => base.GetHashCode(); + + /// + /// Converts the instance to string representation. + /// + /// + /// A that represents this instance. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() => base.ToString(); + + /// + /// Creates a new copy of the current , cloning its attributes into a new instance. + /// + /// + /// A new copy of . + internal ServiceBusSenderOptions Clone() => + new ServiceBusSenderOptions + { + ViaQueueOrTopicName = ViaQueueOrTopicName + }; + } +} diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Processor/ProcessorLiveTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Processor/ProcessorLiveTests.cs index fc9a9d6ddd0f..bfbc20d408ff 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Processor/ProcessorLiveTests.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Processor/ProcessorLiveTests.cs @@ -32,7 +32,7 @@ public async Task ProcessEvent(int numThreads, bool autoComplete) var messageSendCt = numThreads * 2; ServiceBusMessageBatch messageBatch = AddMessages(batch, messageSendCt); - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); var options = new ServiceBusProcessorOptions { @@ -105,7 +105,7 @@ public async Task AutoLockRenewalWorks(int numThreads) var messageSendCt = numThreads; ServiceBusMessageBatch messageBatch = AddMessages(batch, messageSendCt); - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); var options = new ServiceBusProcessorOptions { @@ -171,7 +171,7 @@ public async Task MaxAutoLockRenewalDurationRespected(int numThreads, int autoLo var messageSendCt = numThreads; ServiceBusMessageBatch messageBatch = AddMessages(batch, messageSendCt); - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); var options = new ServiceBusProcessorOptions { @@ -242,7 +242,7 @@ public async Task CanStopProcessingFromHandler(int numThreads) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); ServiceBusMessageBatch messageBatch = AddMessages(batch, numMessages); - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); var options = new ServiceBusProcessorOptions { MaxConcurrentCalls = numThreads, diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Processor/SessionProcessorLiveTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Processor/SessionProcessorLiveTests.cs index 56c1d5b15beb..f6ad52c47a2d 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Processor/SessionProcessorLiveTests.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Processor/SessionProcessorLiveTests.cs @@ -387,7 +387,7 @@ public async Task AutoLockRenewalWorks(int numThreads) AddMessages(batch, 1, Guid.NewGuid().ToString()); } - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var options = new ServiceBusProcessorOptions { @@ -456,7 +456,7 @@ public async Task MaxAutoLockRenewalDurationRespected(int numThreads, int autoLo AddMessages(batch, 1, Guid.NewGuid().ToString()); } - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var options = new ServiceBusProcessorOptions { diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Receiver/ReceiverLiveTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Receiver/ReceiverLiveTests.cs index 0a08bb983809..472950b46ef0 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Receiver/ReceiverLiveTests.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Receiver/ReceiverLiveTests.cs @@ -25,7 +25,7 @@ public async Task Peek() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable sentMessages = AddMessages(batch, messageCt).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); await using var receiver = client.CreateReceiver(scope.QueueName); @@ -61,7 +61,7 @@ public async Task ReceiveMessagesInPeekLockMode() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var receiver = client.CreateReceiver(scope.QueueName); var messageEnum = messages.GetEnumerator(); @@ -98,7 +98,7 @@ public async Task CompleteMessages() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var receiver = client.CreateReceiver(scope.QueueName); var messageEnum = messages.GetEnumerator(); @@ -133,7 +133,7 @@ public async Task AbandonMessages() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var receiver = client.CreateReceiver(scope.QueueName); @@ -238,7 +238,7 @@ public async Task DeferMessages() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var receiver = client.CreateReceiver(scope.QueueName); var messageEnum = messages.GetEnumerator(); @@ -281,7 +281,7 @@ public async Task ReceiveMessagesInReceiveAndDeleteMode() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var clientOptions = new ServiceBusReceiverOptions() { diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Receiver/SessionReceiverLiveTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Receiver/SessionReceiverLiveTests.cs index f311ea927bb2..43703d7e54a9 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Receiver/SessionReceiverLiveTests.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Receiver/SessionReceiverLiveTests.cs @@ -32,7 +32,7 @@ public async Task PeekSession(long? sequenceNumber, string partitionKey) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable sentMessages = AddMessages(batch, messageCt, sessionId, partitionKey).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); Dictionary sentMessageIdToMsg = new Dictionary(); foreach (ServiceBusMessage message in sentMessages) { @@ -83,7 +83,7 @@ public async Task LockSameSessionShouldThrow() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); ServiceBusMessageBatch messageBatch = AddMessages(batch, messageCt, sessionId); - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); ServiceBusReceiver receiver1 = await client.CreateSessionReceiverAsync( scope.QueueName, @@ -115,7 +115,7 @@ public async Task PeekRangeIncrementsSequenceNumber(int messageCt, int peekCt) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); ServiceBusMessageBatch messagebatch = AddMessages(batch, messageCt, sessionId); - await sender.SendBatchAsync(messagebatch); + await sender.SendAsync(messagebatch); ServiceBusReceiver receiver = await client.CreateSessionReceiverAsync(scope.QueueName); long seq = 0; @@ -149,7 +149,7 @@ public async Task PeekIncrementsSequenceNumber(int messageCt) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); ServiceBusMessageBatch messagebatch = AddMessages(batch, messageCt, sessionId); - await sender.SendBatchAsync(messagebatch); + await sender.SendAsync(messagebatch); ServiceBusReceiver receiver = await client.CreateSessionReceiverAsync(scope.QueueName); @@ -182,7 +182,7 @@ public async Task RoundRobinSessions() { using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); ServiceBusMessageBatch messageBatch = AddMessages(batch, messageCt, session); - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); } // create receiver not scoped to a specific session @@ -216,7 +216,7 @@ public async Task ReceiveMessagesInPeekLockMode() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount, sessionId).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); ServiceBusReceiver receiver = await client.CreateSessionReceiverAsync(scope.QueueName); @@ -253,7 +253,7 @@ public async Task ReceiveMessagesInReceiveAndDeleteMode() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount, sessionId).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var clientOptions = new ServiceBusReceiverOptions() { @@ -300,7 +300,7 @@ public async Task CompleteMessages(bool useSpecificSession) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount, sessionId).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); ServiceBusReceiver receiver = await client.CreateSessionReceiverAsync( scope.QueueName, @@ -341,7 +341,7 @@ public async Task AbandonMessages(bool useSpecificSession) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount, sessionId).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); ServiceBusReceiver receiver = await client.CreateSessionReceiverAsync( scope.QueueName, @@ -398,7 +398,7 @@ public async Task DeadLetterMessages(bool useSpecificSession) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount, sessionId).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var receiver = await client.CreateSessionReceiverAsync( scope.QueueName, @@ -460,7 +460,7 @@ public async Task DeadLetterMessagesSubscription(bool useSpecificSession) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount, sessionId).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var topicName = scope.TopicName; var subscriptionName = scope.SubscriptionNames.First(); @@ -533,7 +533,7 @@ public async Task DeferMessages(bool useSpecificSession) using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); IEnumerable messages = AddMessages(batch, messageCount, sessionId).AsEnumerable(); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); var receiver = await client.CreateSessionReceiverAsync( scope.QueueName, 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 eb173b21fb12..1859af7a0e72 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample01_HelloWorld.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample01_HelloWorld.cs @@ -101,7 +101,7 @@ public async Task SendAndReceiveMessageBatch() messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))); // send the message batch - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); // create a receiver that we can use to receive the messages ServiceBusReceiver receiver = client.CreateReceiver(queueName); diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample03_SendReceiveSessions.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample03_SendReceiveSessions.cs index 512daa8a832f..712abc2add0e 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample03_SendReceiveSessions.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample03_SendReceiveSessions.cs @@ -84,7 +84,7 @@ public async Task ReceiveFromSpecificSession() }); // send the message batch - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); #region Snippet:ServiceBusReceiveFromSpecificSession // create a receiver specifying a particular session diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample04_Processor.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample04_Processor.cs index 0810fb07144d..4d128baaeefc 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample04_Processor.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample04_Processor.cs @@ -35,7 +35,7 @@ public async Task ProcessMessages() messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))); // send the message batch - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); // get the options to use for configuring the processor var options = new ServiceBusProcessorOptions diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample05_SessionProcessor.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample05_SessionProcessor.cs index 0463914b11f1..aad0babbb45e 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample05_SessionProcessor.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Samples/Sample05_SessionProcessor.cs @@ -42,7 +42,7 @@ public async Task ProcessSessionMessages() }); // send the message batch - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); // get the options to use for configuring the processor var options = new ServiceBusProcessorOptions diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderLiveTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderLiveTests.cs index e9faedb95f99..cbcadbacbdf2 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderLiveTests.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderLiveTests.cs @@ -86,7 +86,7 @@ public async Task CanSendAMessageBatch() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); ServiceBusMessageBatch messageBatch = AddMessages(batch, 3); - await sender.SendBatchAsync(messageBatch); + await sender.SendAsync(messageBatch); } } @@ -100,7 +100,7 @@ public async Task CanSendAnEmptyBodyMessageBatch() using ServiceBusMessageBatch batch = await sender.CreateBatchAsync(); batch.TryAdd(new ServiceBusMessage(Array.Empty())); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); } } @@ -118,7 +118,7 @@ public async Task CanSendLargeMessageBatch() batch.TryAdd(new ServiceBusMessage(new byte[100000 / 3])); batch.TryAdd(new ServiceBusMessage(new byte[100000 / 3])); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); } } @@ -151,7 +151,7 @@ public async Task TryAddReturnsFalseIfSizeExceed() Assert.That(() => batch.TryAdd(new ServiceBusMessage(new byte[200000])), Is.True, "A message was rejected by the batch; all messages should be accepted."); Assert.That(() => batch.TryAdd(new ServiceBusMessage(new byte[200000])), Is.False, "A message was rejected by the batch; message size exceed."); - await sender.SendBatchAsync(batch); + await sender.SendAsync(batch); } } diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderTests.cs index c57b42f9ccd3..9d8664942293 100755 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderTests.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderTests.cs @@ -70,7 +70,7 @@ public void SendNullBatchShouldThrow() { CallBase = true }; - Assert.ThrowsAsync(async () => await mock.Object.SendBatchAsync(null)); + Assert.ThrowsAsync(async () => await mock.Object.SendAsync((ServiceBusMessageBatch)null)); } [Test] @@ -125,7 +125,7 @@ public async Task SendBatchManagesLockingTheBatch() Assert.That(batch.TryAdd(new ServiceBusMessage(Array.Empty())), Is.True, "The batch should not be locked before sending."); var sender = new ServiceBusSender("dummy", null, mockConnection.Object); - var sendTask = sender.SendBatchAsync(batch); + var sendTask = sender.SendAsync(batch); Assert.That(() => batch.TryAdd(new ServiceBusMessage(Array.Empty())), Throws.InstanceOf(), "The batch should be locked while sending."); completionSource.TrySetResult(true); diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Transactions/TransactionLiveTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Transactions/TransactionLiveTests.cs index 844ab3571138..8a7ecd44fcf9 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Transactions/TransactionLiveTests.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Transactions/TransactionLiveTests.cs @@ -524,8 +524,14 @@ public async Task TransactionalSendViaCommitTest() var intermediateSender = client.CreateSender(intermediateQueue.QueueName); var intermediateReceiver = client.CreateReceiver(intermediateQueue.QueueName); var destination1Sender = client.CreateSender(destination1.TopicName); - var destination1ViaSender = client.CreateSender(destination1.TopicName, intermediateQueue.QueueName); - var destination2ViaSender = client.CreateSender(destination2.QueueName, intermediateQueue.QueueName); + var destination1ViaSender = client.CreateSender(destination1.TopicName, new ServiceBusSenderOptions + { + ViaQueueOrTopicName = intermediateQueue.QueueName + }); + var destination2ViaSender = client.CreateSender(destination2.QueueName, new ServiceBusSenderOptions + { + ViaQueueOrTopicName = intermediateQueue.QueueName + }); var destination1Receiver = client.CreateReceiver(destination1.TopicName, destination1.SubscriptionNames.First()); var destination2Receiver = client.CreateReceiver(destination2.QueueName); From 2230b9825cff4a2ddc6911c8e0ecb398f312d9f9 Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Fri, 24 Apr 2020 12:15:22 -0700 Subject: [PATCH 2/4] Update snippets --- sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md | 2 +- sdk/servicebus/Azure.Messaging.ServiceBus/README.md | 4 ++-- .../Azure.Messaging.ServiceBus/samples/Sample01_HelloWorld.md | 2 +- .../Azure.Messaging.ServiceBus/samples/Sample04_Processor.md | 4 ++-- .../samples/Sample05_SessionProcessor.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md b/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md index 5ad217140260..84e90b6b71a1 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md @@ -216,7 +216,7 @@ messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("First"))); messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))); // send the message batch -await sender.SendBatchAsync(messageBatch); +await sender.SendAsync(messageBatch); // create a receiver that we can use to receive the messages ServiceBusReceiver receiver = client.CreateReceiver(queueName); diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/README.md b/sdk/servicebus/Azure.Messaging.ServiceBus/README.md index 4d7b7650647a..c89c1cafaa35 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/README.md +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/README.md @@ -135,7 +135,7 @@ messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("First"))); messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))); // send the message batch -await sender.SendBatchAsync(messageBatch); +await sender.SendAsync(messageBatch); // create a receiver that we can use to receive the messages ServiceBusReceiver receiver = client.CreateReceiver(queueName); @@ -233,7 +233,7 @@ messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("First"))); messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))); // send the message batch -await sender.SendBatchAsync(messageBatch); +await sender.SendAsync(messageBatch); // get the options to use for configuring the processor var options = new ServiceBusProcessorOptions diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample01_HelloWorld.md b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample01_HelloWorld.md index a010db9a3151..ed4c5f22efe4 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample01_HelloWorld.md +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample01_HelloWorld.md @@ -52,7 +52,7 @@ messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("First"))); messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))); // send the message batch -await sender.SendBatchAsync(messageBatch); +await sender.SendAsync(messageBatch); // create a receiver that we can use to receive the messages ServiceBusReceiver receiver = client.CreateReceiver(queueName); diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample04_Processor.md b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample04_Processor.md index 88c9ae704274..18f443683875 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample04_Processor.md +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample04_Processor.md @@ -19,7 +19,7 @@ messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("First"))); messageBatch.TryAdd(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))); // send the message batch -await sender.SendBatchAsync(messageBatch); +await sender.SendAsync(messageBatch); // get the options to use for configuring the processor var options = new ServiceBusProcessorOptions @@ -100,7 +100,7 @@ messageBatch.TryAdd( }); // send the message batch -await sender.SendBatchAsync(messageBatch); +await sender.SendAsync(messageBatch); // get the options to use for configuring the processor var options = new ServiceBusProcessorOptions diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample05_SessionProcessor.md b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample05_SessionProcessor.md index bd23197e0147..1bd9602ec026 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample05_SessionProcessor.md +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample05_SessionProcessor.md @@ -30,7 +30,7 @@ messageBatch.TryAdd( }); // send the message batch -await sender.SendBatchAsync(messageBatch); +await sender.SendAsync(messageBatch); // get the options to use for configuring the processor var options = new ServiceBusProcessorOptions From f04ed5215651385ae65ac567f3ee336ee818f0a5 Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Fri, 24 Apr 2020 14:21:55 -0700 Subject: [PATCH 3/4] PR comments --- .../Azure.Messaging.ServiceBus.sln | 1 + .../Azure.Messaging.ServiceBus/MigrationGuide.md | 4 ++-- .../src/Sender/ServiceBusSender.cs | 15 ++++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/Azure.Messaging.ServiceBus.sln b/sdk/servicebus/Azure.Messaging.ServiceBus/Azure.Messaging.ServiceBus.sln index a369b4879e6c..be26a5be4b69 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/Azure.Messaging.ServiceBus.sln +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/Azure.Messaging.ServiceBus.sln @@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject CHANGELOG.md = CHANGELOG.md CONTRIBUTING.md = CONTRIBUTING.md + MigrationGuide.md = MigrationGuide.md README.md = README.md EndProjectSection EndProject diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md b/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md index 84e90b6b71a1..4610f170debd 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md @@ -68,7 +68,7 @@ The v4 client allowed for sending a single message or a list of messages, which | In v4 | Equivalent in v7 | Sample | |------------------------------------------------|------------------------------------------------------------------|--------| | `QueueClient.SendAsync(Message)` or `MessageSender.SendAsync(Message)` | `ServiceBusSender.SendAsync(ServiceBusMessage)` | [Send a message](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample01_HelloWorld.md#sending-and-receiving-a-message) | -| `QueueClient.SendAsync(IList)` or `MessageSender.SendAsync(IList)` | `messageBatch = ServiceBusSender.CreateBatchAsync()` `messageBatch.TryAdd(ServiceBusMessage)` `ServiceBusSender.SendBatchAsync(messageBatch)` | [Send a batch of messages](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample01_HelloWorld.md#sending-and-receiving-a-batch-of-messages) | +| `QueueClient.SendAsync(IList)` or `MessageSender.SendAsync(IList)` | `messageBatch = ServiceBusSender.CreateBatchAsync()` `messageBatch.TryAdd(ServiceBusMessage)` `ServiceBusSender.SendAsync(messageBatch)` | [Send a batch of messages](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/servicebus/Azure.Messaging.ServiceBus/samples/Sample01_HelloWorld.md#sending-and-receiving-a-batch-of-messages) | ### Receiving messages @@ -157,7 +157,7 @@ Console.WriteLine(body); In v4, `QueueClient`/`MessageSender`/`MessageReceiver` would be created directly, after which user would call `SendAsync()` method via `QueueClient`/`MessageSender` to send a batch of messages and `ReceiveAsync()` method via `MessageReceiver` to receive a batch of messages. -In v7, user would initialize the `ServiceBusClient` and call `CreateSender()` method to create a `ServiceBusSender` and `CreateReceiver()` method to create a `ServiceBusReceiver`. To send a batch of messages, user would call `CreateBatchAsync()` method to create `ServiceBusMessageBatch` and try to add messages to it using `TryAdd()` method. If the `ServiceBusMessageBatch` accepts a message, user can be confident that it will not violate size constraints when calling `SendBatchAsync()` via `ServiceBusSender`. To receive a batch of messages, user would call `ReceiveBatchAsync()` method via `ServiceBusReceiver`. +In v7, user would initialize the `ServiceBusClient` and call `CreateSender()` method to create a `ServiceBusSender` and `CreateReceiver()` method to create a `ServiceBusReceiver`. To send a batch of messages, user would call `CreateBatchAsync()` method to create `ServiceBusMessageBatch` and try to add messages to it using `TryAdd()` method. If the `ServiceBusMessageBatch` accepts a message, user can be confident that it will not violate size constraints when calling `SendAsync()` via `ServiceBusSender`. To receive a batch of messages, user would call `ReceiveBatchAsync()` method via `ServiceBusReceiver`. In v4: diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSender.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSender.cs index baf7f8966bcd..b4c8d122f887 100755 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSender.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Sender/ServiceBusSender.cs @@ -83,8 +83,8 @@ public class ServiceBusSender : IAsyncDisposable /// Initializes a new instance of the class. /// /// The entity path to send the message to. - /// The set of to use for configuring - /// this . + /// The set of to use for configuring + /// this . /// The connection for the sender. /// internal ServiceBusSender( @@ -178,12 +178,13 @@ await _innerSender.SendAsync( } /// - /// Creates a size-constraint batch to which may be added using a try-based pattern. If a message would - /// exceed the maximum allowable size of the batch, the batch will not allow adding the message and signal that scenario using its - /// return value. + /// Creates a size-constraint batch to which may be added using + /// a . If a message would exceed the maximum + /// allowable size of the batch, the batch will not allow adding the message and signal that + /// scenario using it return value. /// - /// Because messages that would violate the size constraint cannot be added, publishing a batch will not trigger an exception when - /// attempting to send the messages to the Queue/Topic. + /// Because messages that would violate the size constraint cannot be added, publishing a batch + /// will not trigger an exception when attempting to send the messages to the Queue/Topic. /// /// /// An optional instance to signal the request to cancel the operation. From c391cc09ae30a425ffba5702e688ffdf92c05591 Mon Sep 17 00:00:00 2001 From: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> Date: Mon, 27 Apr 2020 14:19:15 -0700 Subject: [PATCH 4/4] Use different exception for sendvia entity path --- .../src/Client/ServiceBusClient.cs | 28 ++++++- .../src/Resources.Designer.cs | 9 +++ .../src/Resources.resx | 3 + .../tests/Sender/SenderTests.cs | 78 +++++++++++++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) mode change 100755 => 100644 sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.resx diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Client/ServiceBusClient.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Client/ServiceBusClient.cs index c5af6da032c0..ec66a466d5ce 100644 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Client/ServiceBusClient.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Client/ServiceBusClient.cs @@ -191,8 +191,7 @@ public ServiceBusSender CreateSender(string queueOrTopicName) /// A scoped to the specified queue or topic. public ServiceBusSender CreateSender(string queueOrTopicName, ServiceBusSenderOptions options) { - ValidateEntityName(options?.ViaQueueOrTopicName); - ValidateEntityName(queueOrTopicName); + ValidateSendViaEntityName(queueOrTopicName, options?.ViaQueueOrTopicName); return new ServiceBusSender( entityPath: queueOrTopicName, @@ -610,5 +609,30 @@ private void ValidateEntityName(string entityName) throw new ArgumentException(Resources.OnlyOneEntityNameMayBeSpecified); } } + + /// + /// Validates that the specified entity name matches the entity path in the Connection, + /// if an entity path is specified in the connection. + /// + /// Entity name to validate + /// + /// The send via entity name to validate + private void ValidateSendViaEntityName(string entityName, string sendViaEntityName) + { + if (sendViaEntityName == null || + string.Equals(sendViaEntityName, entityName, StringComparison.InvariantCultureIgnoreCase)) + { + ValidateEntityName(sendViaEntityName); + return; + } + + // we've established they are not equal, so anything specified in connection string will cause + // a mismatch with one of the entities. + + if (!string.IsNullOrEmpty(Connection.EntityPath)) + { + throw new ArgumentException(Resources.SendViaCannotBeUsedWithEntityInConnectionString); + } + } } } diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.Designer.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.Designer.cs index 448832491811..8129b8bb65fe 100755 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.Designer.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.Designer.cs @@ -465,6 +465,15 @@ internal static string RunningMessageProcessorCannotPerformOperation { } } + /// + /// Looks up a localized string similar to When sending via a different entity, an entity path is not allowed to specified in the connection string.. + /// + internal static string SendViaCannotBeUsedWithEntityInConnectionString { + get { + return ResourceManager.GetString("SendViaCannotBeUsedWithEntityInConnectionString", resourceCulture); + } + } + /// /// Looks up a localized string similar to Failed to retreive session filter from broker. Please retry.. /// diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.resx b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.resx old mode 100755 new mode 100644 index 9a01a717fe62..7dc6fd958026 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.resx +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Resources.resx @@ -300,4 +300,7 @@ The operation is not supported for peeked message. Only received message can be settled. + + When sending via a different entity, an entity path is not allowed to specified in the connection string. + \ No newline at end of file diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderTests.cs index 9d8664942293..902301f2c8e4 100755 --- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderTests.cs +++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Sender/SenderTests.cs @@ -86,6 +86,84 @@ public void ClientProperties() Assert.IsNotNull(sender.Identifier); } + [Test] + public void CreateSenderUsingSendVia() + { + var account = Encoding.Default.GetString(GetRandomBuffer(12)); + var fullyQualifiedNamespace = new UriBuilder($"{account}.servicebus.windows.net/").Host; + var connString = $"Endpoint=sb://{fullyQualifiedNamespace};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey={Encoding.Default.GetString(GetRandomBuffer(64))}"; + var queueName = Encoding.Default.GetString(GetRandomBuffer(12)); + var client = new ServiceBusClient(connString); + var sender = client.CreateSender(queueName, + new ServiceBusSenderOptions + { + ViaQueueOrTopicName = "sendViaName" + }); + } + + [Test] + public void CreateSenderUsingSendViaThrowsWhenEntityPath() + { + var account = Encoding.Default.GetString(GetRandomBuffer(12)); + var fullyQualifiedNamespace = new UriBuilder($"{account}.servicebus.windows.net/").Host; + var connString = $"Endpoint=sb://{fullyQualifiedNamespace};SharedAccessKeyName=RootManageSharedAccessKey;EntityPath=something;SharedAccessKey={Encoding.Default.GetString(GetRandomBuffer(64))}"; + var queueName = Encoding.Default.GetString(GetRandomBuffer(12)); + var client = new ServiceBusClient(connString); + Assert.That(() => client.CreateSender(queueName, + new ServiceBusSenderOptions + { + ViaQueueOrTopicName = "sendViaName" + }), + Throws.InstanceOf()); + Assert.That(() => client.CreateSender(queueName, + new ServiceBusSenderOptions + { + ViaQueueOrTopicName = queueName + }), + Throws.InstanceOf()); + } + + [Test] + public void CreateSenderUsingSendViaDoesNotThrowWhenSameEntityPath() + { + var account = Encoding.Default.GetString(GetRandomBuffer(12)); + var fullyQualifiedNamespace = new UriBuilder($"{account}.servicebus.windows.net/").Host; + var connString = $"Endpoint=sb://{fullyQualifiedNamespace};SharedAccessKeyName=RootManageSharedAccessKey;EntityPath=something;SharedAccessKey={Encoding.Default.GetString(GetRandomBuffer(64))}"; + var client = new ServiceBusClient(connString); + client.CreateSender("something", + new ServiceBusSenderOptions + { + ViaQueueOrTopicName = "something" + }); + } + + [Test] + public void CreateSenderUsingNullOptionsDoesNotThrow() + { + var account = Encoding.Default.GetString(GetRandomBuffer(12)); + var fullyQualifiedNamespace = new UriBuilder($"{account}.servicebus.windows.net/").Host; + var connString = $"Endpoint=sb://{fullyQualifiedNamespace};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey={Encoding.Default.GetString(GetRandomBuffer(64))}"; + var queueName = Encoding.Default.GetString(GetRandomBuffer(12)); + var client = new ServiceBusClient(connString); + var sender = client.CreateSender(queueName, + null); + } + + [Test] + public void CreateSenderUsingNullSendViaDoesNotThrow() + { + var account = Encoding.Default.GetString(GetRandomBuffer(12)); + var fullyQualifiedNamespace = new UriBuilder($"{account}.servicebus.windows.net/").Host; + var connString = $"Endpoint=sb://{fullyQualifiedNamespace};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey={Encoding.Default.GetString(GetRandomBuffer(64))}"; + var queueName = Encoding.Default.GetString(GetRandomBuffer(12)); + var client = new ServiceBusClient(connString); + var sender = client.CreateSender(queueName, + new ServiceBusSenderOptions + { + ViaQueueOrTopicName = null + }); + } + /// /// Verifies functionality of the /// method.