public void Should_use_passed_in_queue_parameters_if_specified()
        {
            // Given
            var description = new QueueDescription(this.queueName);
            var listener = new ServiceBusClient(
                this.serialiser,
                this.bus);

            // When
            listener.Connect(this.connectionString, this.queueName, description);

            // Then
            this.bus.VerifyQueueDescription.ShouldBeSameAs(description);
        }
        public void Should_verify_queue_on_connect()
        {
            // Given
            var listener = new ServiceBusClient(
                this.serialiser,
                this.bus);

            // When
            listener.Connect(this.connectionString, this.queueName);

            // Then
            this.bus.VerifyQueueConnectionString.ShouldEqual(this.connectionString);
            this.bus.VerifyQueueDescription.ShouldNotBeNull();
            this.bus.VerifyQueueDescription.Path.ShouldEqual(this.queueName);
        }
        public void Should_serialise_message()
        {
            // Given
            object passedPayload = null;
            var description = new QueueDescription(this.queueName);
            var listener = new ServiceBusClient(
                this.serialiser,
                this.bus);
            listener.Connect(this.connectionString, this.queueName, description);
            var payload = new Object();
            A.CallTo(() => this.serialiser.Serialise(payload))
             .Invokes(foc => passedPayload = foc.Arguments[0])
             .Returns("FooBarBaz");

            // When
            listener.Send("messageType", payload).Wait();

            // Then
            passedPayload.ShouldBeSameAs(payload);
        }
        public async Task TransactionalSendViaCommitTest()
        {
            var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);

            await using var intermediateQueue = await ServiceBusScope.CreateWithQueue(enablePartitioning : true, enableSession : false);

            await using var destination1 = await ServiceBusScope.CreateWithTopic(enablePartitioning : true, enableSession : false);

            await using var destination2 = await ServiceBusScope.CreateWithQueue(enablePartitioning : true, enableSession : false);

            var intermediateSender    = client.CreateSender(intermediateQueue.QueueName);
            var intermediateReceiver  = client.CreateReceiver(intermediateQueue.QueueName);
            var destination1Sender    = client.CreateSender(destination1.TopicName);
            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);

            var body     = Encoding.Default.GetBytes(Guid.NewGuid().ToString("N"));
            var message1 = new ServiceBusMessage(body)
            {
                MessageId = "1", PartitionKey = "pk1"
            };
            var message2 = new ServiceBusMessage(body)
            {
                MessageId = "2", PartitionKey = "pk2", ViaPartitionKey = "pk1"
            };
            var message3 = new ServiceBusMessage(body)
            {
                MessageId = "3", PartitionKey = "pk3", ViaPartitionKey = "pk1"
            };

            await intermediateSender.SendAsync(message1).ConfigureAwait(false);

            var receivedMessage = await intermediateReceiver.ReceiveAsync();

            Assert.NotNull(receivedMessage);
            Assert.AreEqual("pk1", receivedMessage.PartitionKey);

            // If the transaction succeeds, then all the operations occurred on the same partition.
            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                await intermediateReceiver.CompleteAsync(receivedMessage);

                await destination1ViaSender.SendAsync(message2);

                await destination2ViaSender.SendAsync(message3);

                ts.Complete();
            }

            // Assert that first message indeed completed.
            receivedMessage = await intermediateReceiver.ReceiveAsync(TimeSpan.FromSeconds(5));

            Assert.Null(receivedMessage);

            // Assert that second message reached its destination.
            var receivedMessage1 = await destination1Receiver.ReceiveAsync();

            Assert.NotNull(receivedMessage1);
            Assert.AreEqual("pk2", receivedMessage1.PartitionKey);

            // Assert destination1 message actually used partitionKey in the destination entity.
            var destination1Message = new ServiceBusMessage(body)
            {
                PartitionKey = "pk2"
            };

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                await destination1Receiver.CompleteAsync(receivedMessage1);

                await destination1Sender.SendAsync(destination1Message);

                ts.Complete();
            }

            // Assert that third message reached its destination.
            var receivedMessage2 = await destination2Receiver.ReceiveAsync();

            Assert.NotNull(receivedMessage2);
            Assert.AreEqual("pk3", receivedMessage2.PartitionKey);
            await destination2Receiver.CompleteAsync(receivedMessage2);

            // Cleanup
            receivedMessage1 = await destination1Receiver.ReceiveAsync();

            await destination1Receiver.CompleteAsync(receivedMessage1);
        }
Example #5
0
        public async Task GetSubscriptionRuntimeInfoTest()
        {
            var topicName        = nameof(GetSubscriptionRuntimeInfoTest).ToLower() + Recording.Random.NewGuid().ToString("D").Substring(0, 8);
            var subscriptionName = Recording.Random.NewGuid().ToString("D").Substring(0, 8);
            var client           = CreateClient();

            await using var sbClient = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);

            await client.CreateTopicAsync(topicName);

            TopicProperties getTopic = await client.GetTopicAsync(topicName);

            // Changing Last Updated Time
            getTopic.AutoDeleteOnIdle = TimeSpan.FromMinutes(100);
            await client.UpdateTopicAsync(getTopic);

            SubscriptionProperties subscriptionDescription = await client.CreateSubscriptionAsync(topicName, subscriptionName);

            // Changing Last Updated Time for subscription
            subscriptionDescription.AutoDeleteOnIdle = TimeSpan.FromMinutes(100);
            await client.UpdateSubscriptionAsync(subscriptionDescription);

            // Populating 1 active message, 1 dead letter message and 1 scheduled message
            // Changing Last Accessed Time

            ServiceBusSender sender = sbClient.CreateSender(topicName);
            await sender.SendMessageAsync(new ServiceBusMessage()
            {
                MessageId = "1"
            });

            await sender.SendMessageAsync(new ServiceBusMessage()
            {
                MessageId = "2"
            });

            await sender.SendMessageAsync(new ServiceBusMessage()
            {
                MessageId = "3", ScheduledEnqueueTime = DateTime.UtcNow.AddDays(1)
            });

            ServiceBusReceiver        receiver = sbClient.CreateReceiver(topicName, subscriptionName);
            ServiceBusReceivedMessage msg      = await receiver.ReceiveMessageAsync();

            await receiver.DeadLetterMessageAsync(msg);

            List <SubscriptionRuntimeProperties> runtimeInfoList = new List <SubscriptionRuntimeProperties>();

            await foreach (SubscriptionRuntimeProperties subscriptionRuntimeInfo in client.GetSubscriptionsRuntimePropertiesAsync(topicName))
            {
                runtimeInfoList.Add(subscriptionRuntimeInfo);
            }
            runtimeInfoList = runtimeInfoList.Where(e => e.TopicName.StartsWith(nameof(GetSubscriptionRuntimeInfoTest).ToLower())).ToList();
            Assert.True(runtimeInfoList.Count == 1, $"Expected 1 subscription but {runtimeInfoList.Count} subscriptions returned");
            SubscriptionRuntimeProperties runtimeInfo = runtimeInfoList.First();

            Assert.NotNull(runtimeInfo);

            Assert.AreEqual(topicName, runtimeInfo.TopicName);
            Assert.AreEqual(subscriptionName, runtimeInfo.SubscriptionName);

            Assert.True(runtimeInfo.CreatedAt < runtimeInfo.UpdatedAt);
            Assert.True(runtimeInfo.UpdatedAt < runtimeInfo.AccessedAt);

            Assert.AreEqual(1, runtimeInfo.ActiveMessageCount);
            Assert.AreEqual(1, runtimeInfo.DeadLetterMessageCount);
            Assert.AreEqual(2, runtimeInfo.TotalMessageCount);

            SubscriptionRuntimeProperties singleRuntimeInfo = await client.GetSubscriptionRuntimePropertiesAsync(topicName, subscriptionName);

            Assert.AreEqual(runtimeInfo.CreatedAt, singleRuntimeInfo.CreatedAt);
            Assert.AreEqual(runtimeInfo.AccessedAt, singleRuntimeInfo.AccessedAt);
            Assert.AreEqual(runtimeInfo.UpdatedAt, singleRuntimeInfo.UpdatedAt);
            Assert.AreEqual(runtimeInfo.SubscriptionName, singleRuntimeInfo.SubscriptionName);
            Assert.AreEqual(runtimeInfo.TotalMessageCount, singleRuntimeInfo.TotalMessageCount);
            Assert.AreEqual(runtimeInfo.ActiveMessageCount, singleRuntimeInfo.ActiveMessageCount);
            Assert.AreEqual(runtimeInfo.DeadLetterMessageCount, singleRuntimeInfo.DeadLetterMessageCount);
            Assert.AreEqual(runtimeInfo.TopicName, singleRuntimeInfo.TopicName);

            List <TopicRuntimeProperties> topicRuntimePropertiesList = new List <TopicRuntimeProperties>();

            await foreach (TopicRuntimeProperties topicRuntime in client.GetTopicsRuntimePropertiesAsync())
            {
                topicRuntimePropertiesList.Add(topicRuntime);
            }
            topicRuntimePropertiesList = topicRuntimePropertiesList.Where(e => e.Name.StartsWith(nameof(GetSubscriptionRuntimeInfoTest).ToLower())).ToList();
            Assert.True(topicRuntimePropertiesList.Count == 1, $"Expected 1 subscription but {topicRuntimePropertiesList.Count} subscriptions returned");
            TopicRuntimeProperties topicRuntimeProperties = topicRuntimePropertiesList.First();

            Assert.NotNull(topicRuntimeProperties);

            Assert.AreEqual(topicName, topicRuntimeProperties.Name);
            Assert.True(topicRuntimeProperties.CreatedAt < topicRuntimeProperties.UpdatedAt);
            Assert.True(topicRuntimeProperties.UpdatedAt < topicRuntimeProperties.AccessedAt);

            Assert.AreEqual(1, topicRuntimeProperties.ScheduledMessageCount);

            TopicRuntimeProperties singleTopicRuntimeProperties = await client.GetTopicRuntimePropertiesAsync(topicName);

            Assert.AreEqual(topicRuntimeProperties.CreatedAt, singleTopicRuntimeProperties.CreatedAt);
            Assert.AreEqual(topicRuntimeProperties.AccessedAt, singleTopicRuntimeProperties.AccessedAt);
            Assert.AreEqual(topicRuntimeProperties.UpdatedAt, singleTopicRuntimeProperties.UpdatedAt);
            Assert.AreEqual(topicRuntimeProperties.ScheduledMessageCount, singleTopicRuntimeProperties.ScheduledMessageCount);
            Assert.AreEqual(topicRuntimeProperties.Name, singleTopicRuntimeProperties.Name);

            await client.DeleteTopicAsync(topicName);
        }
Example #6
0
 public SbQueueLoadGenerator(ServiceBusClient sBusClient, ILogger <SbQueueLoadGenerator> logger)
 {
     _sBusClient = sBusClient;
     _logger     = logger;
 }
        private async Task RunBatchReceiveLoopAsync(CancellationToken cancellationToken)
        {
            ServiceBusClient   sessionClient = null;
            ServiceBusReceiver receiver      = null;

            if (_isSessionsEnabled)
            {
                sessionClient = _client.Value;
            }
            else
            {
                receiver = _batchReceiver.Value;
            }

            // The batch receive loop below only executes functions at a concurrency level of 1,
            // so we don't need to do anything special when DynamicConcurrency is enabled. If in
            // the future we make this loop concurrent, we'll have to check with ConcurrencyManager.
            while (true)
            {
                try
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        _logger.LogInformation($"Message processing has been stopped or cancelled ({_details.Value})");
                        return;
                    }

                    if (_isSessionsEnabled && (receiver == null || receiver.IsClosed))
                    {
                        try
                        {
                            receiver = await sessionClient.AcceptNextSessionAsync(
                                _entityPath,
                                new ServiceBusSessionReceiverOptions
                            {
                                PrefetchCount = _serviceBusOptions.PrefetchCount
                            },
                                cancellationToken).ConfigureAwait(false);
                        }
                        catch (ServiceBusException ex)
                            when(ex.Reason == ServiceBusFailureReason.ServiceTimeout)
                            {
                                // it's expected if the entity is empty, try next time
                                continue;
                            }
                    }

                    IReadOnlyList <ServiceBusReceivedMessage> messages =
                        await receiver.ReceiveMessagesAsync(
                            _serviceBusOptions.MaxMessageBatchSize,
                            cancellationToken : cancellationToken).AwaitWithCancellation(cancellationToken);

                    if (messages.Count > 0)
                    {
                        var actions = _isSessionsEnabled
                            ? new ServiceBusSessionMessageActions((ServiceBusSessionReceiver)receiver)
                            : new ServiceBusMessageActions(receiver);
                        ServiceBusReceivedMessage[] messagesArray = messages.ToArray();
                        ServiceBusTriggerInput      input         = ServiceBusTriggerInput.CreateBatch(
                            messagesArray,
                            actions,
                            _client.Value);

                        FunctionResult result = await _triggerExecutor.TryExecuteAsync(input.GetTriggerFunctionData(), cancellationToken).ConfigureAwait(false);

                        // Complete batch of messages only if the execution was successful
                        if (_autoCompleteMessagesOptionEvaluatedValue)
                        {
                            if (result.Succeeded)
                            {
                                List <Task> completeTasks = new List <Task>();
                                foreach (ServiceBusReceivedMessage message in messagesArray)
                                {
                                    // skip messages that were settled in the user's function
                                    if (input.MessageActions.SettledMessages.ContainsKey(message))
                                    {
                                        continue;
                                    }

                                    // Pass CancellationToken.None to allow autocompletion to finish even when shutting down
                                    completeTasks.Add(receiver.CompleteMessageAsync(message, CancellationToken.None));
                                }

                                await Task.WhenAll(completeTasks).ConfigureAwait(false);
                            }
                            else
                            {
                                List <Task> abandonTasks = new List <Task>();
                                foreach (ServiceBusReceivedMessage message in messagesArray)
                                {
                                    // skip messages that were settled in the user's function
                                    if (input.MessageActions.SettledMessages.ContainsKey(message))
                                    {
                                        continue;
                                    }

                                    // Pass CancellationToken.None to allow abandon to finish even when shutting down
                                    abandonTasks.Add(receiver.AbandonMessageAsync(message, cancellationToken: CancellationToken.None));
                                }

                                await Task.WhenAll(abandonTasks).ConfigureAwait(false);
                            }
                        }

                        if (_isSessionsEnabled)
                        {
                            if (((ServiceBusSessionMessageActions)actions).ShouldReleaseSession)
                            {
                                // Use CancellationToken.None to attempt to close the receiver even when shutting down
                                await receiver.CloseAsync(CancellationToken.None).ConfigureAwait(false);
                            }
                        }
                    }
                    else
                    {
                        // Close the session and release the session lock after draining all messages for the accepted session.
                        if (_isSessionsEnabled)
                        {
                            // Use CancellationToken.None to attempt to close the receiver even when shutting down
                            await receiver.CloseAsync(CancellationToken.None).ConfigureAwait(false);
                        }
                    }
                }
                catch (ObjectDisposedException)
                {
                    // Ignore as we are stopping the host
                }
                catch (OperationCanceledException)
                    when(cancellationToken.IsCancellationRequested)
                    {
                        // Ignore as we are stopping the host
                        _logger.LogInformation($"Message processing has been stopped or cancelled ({_details.Value})");
                    }
                catch (Exception ex)
                {
                    // Log another exception
                    _logger.LogError(ex, $"An unhandled exception occurred in the message batch receive loop ({_details.Value})");

                    if (_isSessionsEnabled && receiver != null)
                    {
                        // Attempt to close the session and release session lock to accept a new session on the next loop iteration
                        try
                        {
                            // Use CancellationToken.None to attempt to close the receiver even when shutting down
                            await receiver.CloseAsync(CancellationToken.None).ConfigureAwait(false);
                        }
                        catch
                        {
                            // Best effort
                            receiver = null;
                        }
                    }
                }
            }
        }
        public async Task ReceiverCanReconnectToSameSession(bool isSessionSpecified)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true, lockDuration: TimeSpan.FromSeconds(5)))
            {
                await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);

                await sender.SendMessagesAsync(GetMessages(3, "sessionId1"));

                // send another session message before the one we are interested in to make sure that when isSessionSpecified=true, it is being respected
                await sender.SendMessagesAsync(GetMessages(3, "sessionId2"));

                ServiceBusSessionReceiver receiver = await client.CreateSessionReceiverAsync(
                    scope.QueueName,
                    new ServiceBusSessionReceiverOptions
                {
                    SessionId = isSessionSpecified ? "sessionId1" : null
                });

                if (isSessionSpecified)
                {
                    Assert.AreEqual("sessionId1", receiver.SessionId);
                }

                var firstMessage = await receiver.ReceiveMessageAsync();

                Assert.AreEqual(receiver.SessionId, firstMessage.SessionId);
                var sessionId = receiver.SessionId;
                await Task.Delay((receiver.SessionLockedUntil - DateTime.UtcNow) + TimeSpan.FromSeconds(5));

                var secondMessage = await receiver.ReceiveMessageAsync();

                Assert.AreEqual(sessionId, receiver.SessionId);
                Assert.AreEqual(receiver.SessionId, secondMessage.SessionId);

                // Even though the receiver has re-established the session link, since the first message was
                // received before we reconnected, the message won't be able to be settled. This is analogous
                // to the case of reconnecting a regular non-session link and getting a MessageLockLost error.
                Assert.That(
                    async() => await receiver.CompleteMessageAsync(firstMessage),
                    Throws.InstanceOf <ServiceBusException>().And.Property(nameof(ServiceBusException.Reason)).EqualTo(ServiceBusFailureReason.SessionLockLost));
                await Task.Delay((receiver.SessionLockedUntil - DateTime.UtcNow) + TimeSpan.FromSeconds(5));

                // If another receiver accepts the session after the lock is lost, we expect a SessionCannotBeLocked error,
                // when we try to receive again with our initial receiver.
                ServiceBusSessionReceiver secondReceiver = await client.CreateSessionReceiverAsync(
                    scope.QueueName,
                    new ServiceBusSessionReceiverOptions
                {
                    SessionId = sessionId
                });

                try
                {
                    await receiver.ReceiveMessageAsync();
                }
                catch (ServiceBusException ex) when(ex.Reason == ServiceBusFailureReason.SessionCannotBeLocked)
                {
                    return;
                }
                catch (Exception ex)
                {
                    Assert.Fail($"Expected exception not thrown: {ex}");
                }
                Assert.Fail("No exception thrown!");
            }
        }
        public async Task DeadLetterMessages(bool useSpecificSession)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);
                var messageCount        = 10;
                var sessionId           = "sessionId1";
                using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync();

                IEnumerable <ServiceBusMessage> messages = AddMessages(batch, messageCount, sessionId).AsEnumerable <ServiceBusMessage>();

                await sender.SendMessagesAsync(batch);

                var receiver = await client.CreateSessionReceiverAsync(
                    scope.QueueName,
                    new ServiceBusSessionReceiverOptions
                {
                    SessionId = useSpecificSession ? sessionId : null
                });

                var remainingMessages = messageCount;
                var messageEnum       = messages.GetEnumerator();

                while (remainingMessages > 0)
                {
                    foreach (var item in await receiver.ReceiveMessagesAsync(remainingMessages))
                    {
                        remainingMessages--;
                        messageEnum.MoveNext();
                        Assert.AreEqual(messageEnum.Current.MessageId, item.MessageId);
                        Assert.AreEqual(messageEnum.Current.SessionId, item.SessionId);
                        await receiver.DeadLetterMessageAsync(item.LockToken, "testReason", "testDescription");
                    }
                }
                Assert.AreEqual(0, remainingMessages);

                var peekedMessage = receiver.PeekMessageAsync();
                Assert.IsNull(peekedMessage.Result);

                messageEnum.Reset();
                remainingMessages = messageCount;
                var deadLetterReceiver = client.CreateReceiver(scope.QueueName, new ServiceBusReceiverOptions
                {
                    SubQueue = SubQueue.DeadLetter
                });

                while (remainingMessages > 0)
                {
                    foreach (var msg in await deadLetterReceiver.ReceiveMessagesAsync(remainingMessages))
                    {
                        remainingMessages--;
                        messageEnum.MoveNext();
                        Assert.AreEqual(messageEnum.Current.MessageId, msg.MessageId);
                        Assert.AreEqual(messageEnum.Current.SessionId, msg.SessionId);
                        Assert.AreEqual("testReason", msg.DeadLetterReason);
                        Assert.AreEqual("testDescription", msg.DeadLetterErrorDescription);
                        await deadLetterReceiver.CompleteMessageAsync(msg.LockToken);
                    }
                }
                Assert.AreEqual(0, remainingMessages);

                var deadLetterMessage = await deadLetterReceiver.PeekMessageAsync();

                Assert.IsNull(deadLetterMessage);
            }
        }
 private ServiceBusProcessor BuildServiceBusProcessor(ServiceBusClient serviceBusClient, string topic,
                                                      string subscription, ServiceBusProcessorOptions?serviceBusProcessorOptions)
 => serviceBusProcessorOptions is null
     ? serviceBusClient.CreateProcessor(topic, subscription)
     : serviceBusClient.CreateProcessor(topic, subscription, serviceBusProcessorOptions);
        public override void ExecuteCmdlet()
        {
            try
            {
                PSSharedAccessAuthorizationRuleAttributes sasRule = new PSSharedAccessAuthorizationRuleAttributes();

                if (InputObject != null)
                {
                    sasRule = InputObject;
                }
                else
                {
                    sasRule.Rights = new List <AccessRights?>();
                    if (Rights != null && Rights.Length > 0)
                    {
                        if (Array.Exists(Rights, element => element == "Manage") && !Array.Exists(Rights, element => element == "Listen") || !Array.Exists(Rights, element => element == "Send"))
                        {
                            Exception exManage = new Exception("Assigning 'Manage' to rights requires ‘Listen and ‘Send' to be included with. e.g. @(\"Manage\",\"Listen\",\"Send\")");
                            throw exManage;
                        }

                        foreach (string test in Rights)
                        {
                            sasRule.Rights.Add(ParseAccessRights(test));
                        }
                    }
                }

                if (ParameterSetName.Equals(AuthoRuleInputObjectParameterSet))
                {
                    if (Topic != null)
                    {
                        if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateTopicAuthorizationrule, Name, Topic)))
                        {
                            WriteObject(Client.CreateOrUpdateServiceBusTopicAuthorizationRules(ResourceGroupName, Namespace, Topic, Name, sasRule));
                        }
                    }
                    else if (Queue != null)
                    {
                        if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateQueueAuthorizationrule, Name, Queue)))
                        {
                            WriteObject(Client.CreateOrUpdateServiceBusQueueAuthorizationRules(ResourceGroupName, Namespace, Queue, Name, sasRule));
                        }
                    }
                    else if (Namespace != null)
                    {
                        if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateNamespaceAuthorizationrule, Name, Namespace)))
                        {
                            WriteObject(Client.CreateOrUpdateNamespaceAuthorizationRules(ResourceGroupName, Namespace, Name, sasRule));
                        }
                    }
                }

                // update Namespace Authorization Rule
                if (ParameterSetName.Equals(NamespaceAuthoRuleParameterSet))
                {
                    if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateNamespaceAuthorizationrule, Name, Namespace)))
                    {
                        WriteObject(Client.CreateOrUpdateNamespaceAuthorizationRules(ResourceGroupName, Namespace, Name, sasRule));
                    }
                }


                // Update Topic authorizationRule
                if (ParameterSetName.Equals(QueueAuthoRuleParameterSet))
                {
                    if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateQueueAuthorizationrule, Name, Queue)))
                    {
                        WriteObject(Client.CreateOrUpdateServiceBusQueueAuthorizationRules(ResourceGroupName, Namespace, Queue, Name, sasRule));
                    }
                }

                // Update Topic authorizationRule
                if (ParameterSetName.Equals(TopicAuthoRuleParameterSet))
                {
                    if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateTopicAuthorizationrule, Name, Topic)))
                    {
                        WriteObject(Client.CreateOrUpdateServiceBusTopicAuthorizationRules(ResourceGroupName, Namespace, Topic, Name, sasRule));
                    }
                }
            }
            catch (ErrorResponseException ex)
            {
                WriteError(ServiceBusClient.WriteErrorforBadrequest(ex));
            }
            catch (Exception ex)
            {
                WriteError(new ErrorRecord(ex, ex.Message, ErrorCategory.OpenError, ex));
            }
        }
 /// <inheritdoc />
 public override Task DeadLetter(Message message, IDictionary <string, object> propertiesToModify = null)
 {
     return(ServiceBusClient.DeadLetterAsync(message.SystemProperties.LockToken, propertiesToModify));
 }
        public async Task TransactionThrowsWhenOperationsOfDifferentPartitionsAreInSameTransaction()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: true, enableSession: false))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender   sender   = client.CreateSender(scope.QueueName);
                ServiceBusReceiver receiver = client.CreateReceiver(scope.QueueName);

                string            body     = Guid.NewGuid().ToString("N");
                ServiceBusMessage message1 = GetMessage(partitionKey: "1");
                ServiceBusMessage message2 = GetMessage(partitionKey: "2");

                // Two send operations to different partitions.
                var transaction = new CommittableTransaction();
                using (TransactionScope ts = new TransactionScope(transaction, TransactionScopeAsyncFlowOption.Enabled))
                {
                    await sender.SendAsync(message1);

                    Assert.ThrowsAsync <InvalidOperationException>(
                        async() => await sender.SendAsync(message2));
                    ts.Complete();
                }

                transaction.Rollback();

                // Adding delay since transaction Commit/Rollback is an asynchronous operation.
                // Operating on the same message should not be done.
                await Task.Delay(TimeSpan.FromSeconds(2));

                // Two complete operations to different partitions.
                await sender.SendAsync(message1);

                await sender.SendAsync(message2);

                ServiceBusReceivedMessage receivedMessage1 = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage1);
                ServiceBusReceivedMessage receivedMessage2 = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage2);

                transaction = new CommittableTransaction();
                using (TransactionScope ts = new TransactionScope(transaction, TransactionScopeAsyncFlowOption.Enabled))
                {
                    await receiver.CompleteAsync(receivedMessage1);

                    Assert.ThrowsAsync <InvalidOperationException>(
                        async() => await receiver.CompleteAsync(receivedMessage2));
                    ts.Complete();
                }

                transaction.Rollback();

                // Adding delay since transaction Commit/Rollback is an asynchronous operation.
                // Operating on the same message should not be done.
                await Task.Delay(TimeSpan.FromSeconds(2));

                await receiver.CompleteAsync(receivedMessage1);

                // the service seems to abandon the message that
                // triggered the InvalidOperationException
                // in the transaction
                Assert.That(
                    async() =>
                    await receiver.CompleteAsync(receivedMessage2), Throws.InstanceOf <ServiceBusException>()
                    .And.Property(nameof(ServiceBusException.Reason))
                    .EqualTo(ServiceBusException.FailureReason.MessageLockLost));
            }
        }
        public async Task UserSettlingWithAutoCompleteDoesNotThrow(int numThreads)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(
                             enablePartitioning: false,
                             enableSession: false))
            {
                await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);

                // use double the number of threads so we can make sure we test that we don't
                // retrieve more messages than expected when there are more messages available
                using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync();

                var messageSendCt = numThreads * 2;
                ServiceBusMessageBatch messageBatch = AddMessages(batch, messageSendCt);

                await sender.SendMessagesAsync(messageBatch);

                var options = new ServiceBusProcessorOptions
                {
                    MaxConcurrentCalls = numThreads,
                    AutoComplete       = true,
                    MaxReceiveWaitTime = TimeSpan.FromSeconds(30)
                };
                var processor = client.CreateProcessor(scope.QueueName, options);
                int messageCt = 0;

                TaskCompletionSource <bool>[] completionSources = Enumerable
                                                                  .Range(0, numThreads)
                                                                  .Select(index => new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously))
                                                                  .ToArray();
                var completionSourceIndex = -1;

                processor.ProcessMessageAsync += ProcessMessage;
                processor.ProcessErrorAsync   += ExceptionHandler;
                await processor.StartProcessingAsync();

                async Task ProcessMessage(ProcessMessageEventArgs args)
                {
                    try
                    {
                        var message = args.Message;
                        switch (numThreads)
                        {
                        case 1:
                            await args.CompleteMessageAsync(message, args.CancellationToken);

                            break;

                        case 5:
                            await args.AbandonMessageAsync(message);

                            break;

                        case 10:
                            await args.DeadLetterMessageAsync(message);

                            break;

                        case 20:
                            await args.DeferMessageAsync(message);

                            break;
                        }
                        Interlocked.Increment(ref messageCt);
                    }
                    finally
                    {
                        var setIndex = Interlocked.Increment(ref completionSourceIndex);
                        if (setIndex < numThreads)
                        {
                            completionSources[setIndex].SetResult(true);
                        }
                    }
                }

                await Task.WhenAll(completionSources.Select(source => source.Task));

                await processor.StopProcessingAsync();

                // we complete each task after one message being processed, so the total number of messages
                // processed should equal the number of threads, but it's possible that we may process a few more per thread.
                Assert.IsTrue(messageCt >= numThreads);
                Assert.IsTrue(messageCt <= messageSendCt, messageCt.ToString());
            }
        }
        public async Task SenderReceiverActivities(bool useSessions)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: useSessions))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender    = client.CreateSender(scope.QueueName);
                string           sessionId = null;
                if (useSessions)
                {
                    sessionId = "sessionId";
                }
                int numMessages = 5;
                var msgs        = ServiceBusTestUtilities.GetMessages(numMessages, sessionId);
                await sender.SendMessagesAsync(msgs);

                Activity[] sendActivities = AssertSendActivities(useSessions, sender, msgs);

                ServiceBusReceiver receiver = null;
                if (useSessions)
                {
                    receiver = await client.AcceptNextSessionAsync(scope.QueueName);
                }
                else
                {
                    receiver = client.CreateReceiver(scope.QueueName);
                }

                var remaining = numMessages;
                List <ServiceBusReceivedMessage> receivedMsgs = new List <ServiceBusReceivedMessage>();
                while (remaining > 0)
                {
                    // loop in case we don't receive all messages in one attempt
                    var received = await receiver.ReceiveMessagesAsync(remaining);

                    receivedMsgs.AddRange(received);
                    var receiveScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveActivityName);
                    AssertCommonTags(receiveScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace);

                    var receiveLinkedActivities = receiveScope.LinkedActivities;
                    for (int i = 0; i < receiveLinkedActivities.Count; i++)
                    {
                        Assert.AreEqual(sendActivities[i].ParentId, receiveLinkedActivities[i].ParentId);
                    }
                    remaining -= received.Count;
                }

                var msgIndex = 0;

                var completed = receivedMsgs[msgIndex];
                await receiver.CompleteMessageAsync(completed);

                var completeScope = _listener.AssertAndRemoveScope(DiagnosticProperty.CompleteActivityName);
                AssertCommonTags(completeScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace);

                var deferred = receivedMsgs[++msgIndex];
                await receiver.DeferMessageAsync(deferred);

                var deferredScope = _listener.AssertAndRemoveScope(DiagnosticProperty.DeferActivityName);
                AssertCommonTags(deferredScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace);

                var deadLettered = receivedMsgs[++msgIndex];
                await receiver.DeadLetterMessageAsync(deadLettered);

                var deadLetterScope = _listener.AssertAndRemoveScope(DiagnosticProperty.DeadLetterActivityName);
                AssertCommonTags(deadLetterScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace);

                var abandoned = receivedMsgs[++msgIndex];
                await receiver.AbandonMessageAsync(abandoned);

                var abandonScope = _listener.AssertAndRemoveScope(DiagnosticProperty.AbandonActivityName);
                AssertCommonTags(abandonScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace);

                var receiveDeferMsg = await receiver.ReceiveDeferredMessageAsync(deferred.SequenceNumber);

                var receiveDeferScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveDeferredActivityName);
                AssertCommonTags(receiveDeferScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace);

                // renew lock
                if (useSessions)
                {
                    var sessionReceiver = (ServiceBusSessionReceiver)receiver;
                    await sessionReceiver.RenewSessionLockAsync();

                    var renewSessionScope = _listener.AssertAndRemoveScope(DiagnosticProperty.RenewSessionLockActivityName);
                    AssertCommonTags(renewSessionScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace);

                    // set state
                    var state = new BinaryData("state");
                    await sessionReceiver.SetSessionStateAsync(state);

                    var setStateScope = _listener.AssertAndRemoveScope(DiagnosticProperty.SetSessionStateActivityName);
                    AssertCommonTags(setStateScope.Activity, sessionReceiver.EntityPath, sessionReceiver.FullyQualifiedNamespace);

                    // get state
                    var getState = await sessionReceiver.GetSessionStateAsync();

                    Assert.AreEqual(state.ToArray(), getState.ToArray());
                    var getStateScope = _listener.AssertAndRemoveScope(DiagnosticProperty.GetSessionStateActivityName);
                    AssertCommonTags(getStateScope.Activity, sessionReceiver.EntityPath, sessionReceiver.FullyQualifiedNamespace);
                }
                else
                {
                    await receiver.RenewMessageLockAsync(receivedMsgs[4]);

                    var renewMessageScope = _listener.AssertAndRemoveScope(DiagnosticProperty.RenewMessageLockActivityName);
                    AssertCommonTags(renewMessageScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace);
                }

                // schedule
                msgs = ServiceBusTestUtilities.GetMessages(numMessages, sessionId);

                foreach (var msg in msgs)
                {
                    var seq = await sender.ScheduleMessageAsync(msg, DateTimeOffset.UtcNow.AddMinutes(1));

                    Assert.IsNotNull(msg.ApplicationProperties[DiagnosticProperty.DiagnosticIdAttribute]);

                    var messageScope = _listener.AssertAndRemoveScope(DiagnosticProperty.MessageActivityName);
                    AssertCommonTags(messageScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace);

                    var scheduleScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ScheduleActivityName);
                    AssertCommonTags(scheduleScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace);

                    var linkedActivities = scheduleScope.LinkedActivities;
                    Assert.AreEqual(1, linkedActivities.Count);
                    Assert.AreEqual(messageScope.Activity.Id, linkedActivities[0].ParentId);

                    await sender.CancelScheduledMessageAsync(seq);

                    var cancelScope = _listener.AssertAndRemoveScope(DiagnosticProperty.CancelActivityName);
                    AssertCommonTags(cancelScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace);
                }

                // send a batch
                var batch = await sender.CreateMessageBatchAsync();

                for (int i = 0; i < numMessages; i++)
                {
                    batch.TryAddMessage(ServiceBusTestUtilities.GetMessage(sessionId));
                }
                await sender.SendMessagesAsync(batch);

                AssertSendActivities(useSessions, sender, batch.AsReadOnly <ServiceBusMessage>());
            };
        }
        public async Task SessionProcessorActivities()
        {
            ClientDiagnosticListener.ProducedLink[] messageActivities = null;
            int  messageProcessedCt = 0;
            bool callbackExecuted   = false;

            _listener = new ClientDiagnosticListener(
                EntityScopeFactory.DiagnosticNamespace,
                scopeStartCallback: scope =>
            {
                if (scope.Name == DiagnosticProperty.ProcessSessionMessageActivityName)
                {
                    Assert.IsNotNull(messageActivities);
                    Assert.AreEqual(
                        messageActivities[messageProcessedCt],
                        scope.Links.Single());
                    callbackExecuted = true;
                }
            });
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);
                var messageCt           = 2;
                var msgs = ServiceBusTestUtilities.GetMessages(messageCt, "sessionId");
                await sender.SendMessagesAsync(msgs);

                Activity[] sendActivities = AssertSendActivities(false, sender, msgs);
                messageActivities = sendActivities.Select(a => new ClientDiagnosticListener.ProducedLink(a.ParentId, a.TraceStateString)).ToArray();

                ServiceBusSessionProcessor processor = client.CreateSessionProcessor(scope.QueueName,
                                                                                     new ServiceBusSessionProcessorOptions
                {
                    AutoCompleteMessages  = false,
                    SessionIdleTimeout    = TimeSpan.FromSeconds(10),
                    MaxConcurrentSessions = 1
                });
                TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>();
                processor.ProcessMessageAsync += args =>
                {
                    if (++messageProcessedCt == messageCt)
                    {
                        tcs.SetResult(true);
                    }
                    return(Task.CompletedTask);
                };
                processor.ProcessErrorAsync += ServiceBusTestUtilities.ExceptionHandler;
                await processor.StartProcessingAsync();

                await tcs.Task;
                await processor.StopProcessingAsync();

                for (int i = 0; i < messageCt; i++)
                {
                    _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveActivityName);
                    var processScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ProcessSessionMessageActivityName);
                    AssertCommonTags(processScope.Activity, processor.EntityPath, processor.FullyQualifiedNamespace);
                }
                Assert.IsTrue(callbackExecuted);
            }
        }
Example #17
0
        public async Task CreateFromReceivedMessageCopiesProperties()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: true, enableSession: true))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                var sender = client.CreateSender(scope.QueueName);
                var msg    = new ServiceBusMessage(new BinaryData(GetRandomBuffer(100)));
                msg.ContentType   = "contenttype";
                msg.CorrelationId = "correlationid";
                msg.Subject       = "label";
                msg.MessageId     = "messageId";
                msg.PartitionKey  = "key";
                msg.ApplicationProperties.Add("testProp", "my prop");
                msg.ReplyTo              = "replyto";
                msg.ReplyToSessionId     = "replytosession";
                msg.ScheduledEnqueueTime = DateTimeOffset.Now;
                msg.SessionId            = "key";
                msg.TimeToLive           = TimeSpan.FromSeconds(60);
                msg.To = "to";
                await sender.SendMessageAsync(msg);

                ServiceBusSessionReceiver receiver = await client.AcceptNextSessionAsync(scope.QueueName);

                ServiceBusReceivedMessage received = await receiver.ReceiveMessageAsync();

                AmqpAnnotatedMessage rawReceived = received.GetRawAmqpMessage();
                Assert.IsNotNull(rawReceived.Header.DeliveryCount);
                Assert.IsTrue(rawReceived.MessageAnnotations.ContainsKey(AmqpMessageConstants.LockedUntilName));
                Assert.IsTrue(rawReceived.MessageAnnotations.ContainsKey(AmqpMessageConstants.SequenceNumberName));
                Assert.IsTrue(rawReceived.MessageAnnotations.ContainsKey(AmqpMessageConstants.EnqueueSequenceNumberName));
                Assert.IsTrue(rawReceived.MessageAnnotations.ContainsKey(AmqpMessageConstants.EnqueuedTimeUtcName));

                AssertMessagesEqual(msg, received);
                var toSend = new ServiceBusMessage(received);
                AmqpAnnotatedMessage rawSend = toSend.GetRawAmqpMessage();

                // verify that all system set properties have been cleared out
                Assert.IsNull(rawSend.Header.DeliveryCount);
                Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.LockedUntilName));
                Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.SequenceNumberName));
                Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.DeadLetterSourceName));
                Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.EnqueueSequenceNumberName));
                Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.EnqueuedTimeUtcName));
                Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.DeadLetterSourceName));
                Assert.IsFalse(toSend.ApplicationProperties.ContainsKey(AmqpMessageConstants.DeadLetterReasonHeader));
                Assert.IsFalse(toSend.ApplicationProperties.ContainsKey(AmqpMessageConstants.DeadLetterErrorDescriptionHeader));

                AssertMessagesEqual(toSend, received);

                void AssertMessagesEqual(ServiceBusMessage sentMessage, ServiceBusReceivedMessage received)
                {
                    Assert.IsTrue(received.Body.ToArray().SequenceEqual(sentMessage.Body.ToArray()));
                    Assert.AreEqual(received.ContentType, sentMessage.ContentType);
                    Assert.AreEqual(received.CorrelationId, sentMessage.CorrelationId);
                    Assert.AreEqual(received.Subject, sentMessage.Subject);
                    Assert.AreEqual(received.ContentType, sentMessage.ContentType);
                    Assert.AreEqual(received.CorrelationId, sentMessage.CorrelationId);
                    Assert.AreEqual(received.MessageId, sentMessage.MessageId);
                    Assert.AreEqual(received.PartitionKey, sentMessage.PartitionKey);
                    Assert.AreEqual((string)received.ApplicationProperties["testProp"], (string)sentMessage.ApplicationProperties["testProp"]);
                    Assert.AreEqual(received.ReplyTo, sentMessage.ReplyTo);
                    Assert.AreEqual(received.ReplyToSessionId, sentMessage.ReplyToSessionId);
                    Assert.AreEqual(received.ScheduledEnqueueTime.UtcDateTime.Second, sentMessage.ScheduledEnqueueTime.UtcDateTime.Second);
                    Assert.AreEqual(received.SessionId, sentMessage.SessionId);
                    Assert.AreEqual(received.TimeToLive, sentMessage.TimeToLive);
                    Assert.AreEqual(received.To, sentMessage.To);
                    Assert.AreEqual(received.TransactionPartitionKey, sentMessage.TransactionPartitionKey);
                }
            }
        }
        public void Should_set_message_type()
        {
            // Given
            var description = new QueueDescription(this.queueName);
            var listener = new ServiceBusClient(
                this.serialiser,
                this.bus);
            listener.Connect(this.connectionString, this.queueName, description);
            var payload = new Object();
            A.CallTo(() => this.serialiser.Serialise(payload))
             .Returns("FooBarBaz");

            // When
            listener.Send("messageType", payload).Wait();

            // Then
            this.bus.SentMessageType.ShouldEqual("messageType");
        }
Example #19
0
        private static async Task Main(string[] args)
        {
            await using var stage = await Prepare.Stage(connectionString, destination);

            await using var serviceBusClient = new ServiceBusClient(connectionString);

            await using var sender = serviceBusClient.CreateSender(destination);

            var messages = new List <ServiceBusMessage>();

            for (var i = 0; i < 10; i++)
            {
                var message = new ServiceBusMessage("Deep Dive{i}");
                messages.Add(message);
            }

            WriteLine($"Sending {messages.Count} messages in a batch.");
            await sender.SendMessagesAsync(messages);

            messages.Clear();
            WriteLine();

            for (var i = 0; i < 6500; i++)
            {
                var message = new ServiceBusMessage($"Deep Dive{i}");
                messages.Add(message);
            }

            try
            {
                WriteLine($"Sending {messages.Count} messages in a batch.");
                await sender.SendMessagesAsync(messages);
            }
            catch (ServiceBusException ex) when(ex.Reason == ServiceBusFailureReason.MessageSizeExceeded)
            {
                await Error.WriteLineAsync(ex.Message);
            }

            messages.Clear();
            WriteLine();

            for (var i = 0; i < 101; i++)
            {
                var message = new ServiceBusMessage($"Deep Dive{i}");
                messages.Add(message);
            }

            try
            {
                using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    WriteLine($"Sending {messages.Count} messages in a batch with in transaction '{Transaction.Current.TransactionInformation.LocalIdentifier}'.");
                    await sender.SendMessagesAsync(messages);

                    scope.Complete();
                }
            }
            catch (ServiceBusException ex) when(ex.Reason == ServiceBusFailureReason.QuotaExceeded)
            {
                await Error.WriteLineAsync(ex.Message);
            }

            var messagesToSend = new Queue <ServiceBusMessage>();

            for (var i = 0; i < 4500; i++)
            {
                var message = new ServiceBusMessage($"Deep Dive{i}. Deep Dive{i}. Deep Dive{i}.");
                messagesToSend.Enqueue(message);
            }

            var messageCount = messagesToSend.Count;
            int batchCount   = 1;

            while (messagesToSend.Count > 0)
            {
                using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();

                if (messageBatch.TryAddMessage(messagesToSend.Peek()))
                {
                    messagesToSend.Dequeue();
                }
                else
                {
                    throw new Exception($"Message {messageCount - messagesToSend.Count} is too large and cannot be sent.");
                }

                while (messagesToSend.Count > 0 && messageBatch.TryAddMessage(messagesToSend.Peek()))
                {
                    messagesToSend.Dequeue();
                }

                WriteLine($"Sending {messageBatch.Count} messages in a batch {batchCount++}.");
                await sender.SendMessagesAsync(messageBatch);
            }
        }
Example #20
0
 public ServiceBus(AppSettings settings)
 {
     _client = new ServiceBusClient(settings.ServiceBusSettings.ConnectionString);
 }
Example #21
0
 public async Task GetSessionStateAsyncValidatesClientIsNotDisposed()
 {
     await using var client   = new ServiceBusClient("not.real.com", Mock.Of <TokenCredential>());
     await using var receiver = new ServiceBusSessionReceiver(client.Connection, "fake", default, CancellationToken.None);
 public async Task SendToServiceBusQueueAsync(Models.Customer customer, string reqUrl)
 {
     await ServiceBusClient.SendPostMessageAsync(customer, reqUrl);
 }
        public override void ExecuteCmdlet()
        {
            try
            {
                // Delete Namespace authorizationRule
                if (ParameterSetName.Equals(NamespaceAuthoRuleParameterSet))
                {
                    ConfirmAction(
                        Force.IsPresent,
                        string.Format(Resources.RemovingNamespaceAuthorizationRule, Name, Namespace),
                        string.Format(Resources.RemoveNamespaceAuthorizationRule, Name, Namespace),
                        Name,
                        () =>
                    {
                        Client.DeleteNamespaceAuthorizationRules(ResourceGroupName, Namespace, Name);

                        if (PassThru)
                        {
                            WriteObject(true);
                        }
                    });
                }

                // Delete Queue authorizationRule
                if (ParameterSetName.Equals(QueueAuthoRuleParameterSet))
                {
                    ConfirmAction(
                        Force.IsPresent,
                        string.Format(Resources.RemovingQueueAuthorizationRule, Namespace, Queue, Name),
                        string.Format(Resources.RemoveQueueAuthorizationRule, Namespace, Queue, Name),
                        Name,
                        () =>
                    {
                        Client.DeleteServiceBusQueueAuthorizationRules(ResourceGroupName, Namespace, Queue, Name);
                        if (PassThru)
                        {
                            WriteObject(true);
                        }
                    });
                }

                // Delete Topic authorizationRule
                if (ParameterSetName.Equals(TopicAuthoRuleParameterSet))
                {
                    ConfirmAction(
                        Force.IsPresent,
                        string.Format(Resources.RemovingTopicAuthorizationRule, Namespace, Topic, Name),
                        string.Format(Resources.RemoveTopicAuthorizationRule, Namespace, Topic, Name),
                        Name,
                        () =>
                    {
                        Client.DeleteServiceBusTopicAuthorizationRule(ResourceGroupName, Namespace, Topic, Name);
                        if (PassThru)
                        {
                            WriteObject(true);
                        }
                    });
                }
            }
            catch (Management.ServiceBus.Models.ErrorResponseException ex)
            {
                WriteError(ServiceBusClient.WriteErrorforBadrequest(ex));
            }
        }
 public DefaultServiceBusPersisterConnection(string serviceBusConnectionString)
 {
     _serviceBusConnectionString = serviceBusConnectionString;
     _subscriptionClient         = new ServiceBusAdministrationClient(_serviceBusConnectionString);
     _topicClient = new ServiceBusClient(_serviceBusConnectionString);
 }
        public async Task DeadLetterMessagesSubscription(bool useSpecificSession)
        {
            await using (var scope = await ServiceBusScope.CreateWithTopic(enablePartitioning: false, enableSession: true))
            {
                await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.TopicName);
                var messageCount        = 10;
                var sessionId           = "sessionId1";
                using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync();

                IEnumerable <ServiceBusMessage> messages = AddMessages(batch, messageCount, sessionId).AsEnumerable <ServiceBusMessage>();

                await sender.SendMessagesAsync(batch);

                var topicName        = scope.TopicName;
                var subscriptionName = scope.SubscriptionNames.First();

                var receiver = await client.CreateSessionReceiverAsync(
                    topicName : topicName,
                    subscriptionName : subscriptionName,
                    new ServiceBusSessionReceiverOptions
                {
                    SessionId = useSpecificSession ? sessionId : null
                });

                var remainingMessages = messageCount;
                var messageEnum       = messages.GetEnumerator();

                while (remainingMessages > 0)
                {
                    foreach (var item in await receiver.ReceiveMessagesAsync(remainingMessages))
                    {
                        remainingMessages--;
                        messageEnum.MoveNext();
                        Assert.AreEqual(messageEnum.Current.MessageId, item.MessageId);
                        Assert.AreEqual(messageEnum.Current.SessionId, item.SessionId);
                        var props = new Dictionary <string, object>();
                        // these should be ignored by DeadLetter property getters as they are not strings
                        props[ServiceBusReceivedMessage.DeadLetterReasonHeader]           = DateTime.UtcNow;
                        props[ServiceBusReceivedMessage.DeadLetterErrorDescriptionHeader] = DateTime.UtcNow;

                        await receiver.DeadLetterMessageAsync(item.LockToken, props);
                    }
                }
                Assert.AreEqual(0, remainingMessages);

                var peekedMessage = receiver.PeekMessageAsync();
                Assert.IsNull(peekedMessage.Result);

                messageEnum.Reset();
                remainingMessages = messageCount;
                var deadLetterReceiver = client.CreateReceiver(topicName, subscriptionName, new ServiceBusReceiverOptions
                {
                    SubQueue = SubQueue.DeadLetter
                });

                while (remainingMessages > 0)
                {
                    foreach (var msg in await deadLetterReceiver.ReceiveMessagesAsync(remainingMessages))
                    {
                        remainingMessages--;
                        messageEnum.MoveNext();
                        Assert.AreEqual(messageEnum.Current.MessageId, msg.MessageId);
                        Assert.AreEqual(messageEnum.Current.SessionId, msg.SessionId);
                        Assert.IsNull(msg.DeadLetterErrorDescription);
                        Assert.IsNull(msg.DeadLetterReason);
                        Assert.IsNotNull(msg.ApplicationProperties[ServiceBusReceivedMessage.DeadLetterReasonHeader]);
                        Assert.IsNotNull(msg.ApplicationProperties[ServiceBusReceivedMessage.DeadLetterErrorDescriptionHeader]);
                        await deadLetterReceiver.CompleteMessageAsync(msg.LockToken);
                    }
                }
                Assert.AreEqual(0, remainingMessages);

                var deadLetterMessage = await deadLetterReceiver.PeekMessageAsync();

                Assert.IsNull(deadLetterMessage);
            }
        }
Example #26
0
 public HomeController(IOptions <ServiceBusConfiguration> serviceBusConfig)
 {
     Config = serviceBusConfig.Value;
     client = new ServiceBusClient(Config.Namespace, new DefaultAzureCredential());
     _startProcessingTask = ReceivedMessageStore.InitializeAsync(Config, client);
 }
Example #27
0
        public static int Main(string[] args)
        {
            var app = new CommandLineApplication();

            app.HelpOption("-h|--help");
            var connectionStringOption   = app.Option("-c|--connection-string <string>", "The Azure Service Bus connection string", CommandOptionType.SingleValue).IsRequired();
            var queueOption              = app.Option("-q|--queue <string>", "The Azure Service Bus queue name", CommandOptionType.SingleValue).IsRequired();
            var jobDefinitionsPathOption = app.Option("-j|--jobs <path>", "The path for the job definitions file", CommandOptionType.SingleValue).IsRequired();

            app.OnExecuteAsync(async cancellationToken =>
            {
                if (!File.Exists(jobDefinitionsPathOption.Value()))
                {
                    Console.WriteLine($"The file '{0}' could not be found", jobDefinitionsPathOption.Value());
                    return;
                }

                var jobDefinitions = JsonSerializer.Deserialize <JobDefinitions>(File.ReadAllText(jobDefinitionsPathOption.Value()), new JsonSerializerOptions {
                    PropertyNameCaseInsensitive = true
                });

                ConnectionString = connectionStringOption.Value();

                // Substitute with ENV value if it exists
                if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable(ConnectionString)))
                {
                    ConnectionString = Environment.GetEnvironmentVariable(ConnectionString);
                }

                Queue = queueOption.Value();

                // Substitute with ENV value if it exists
                if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable(Queue)))
                {
                    Queue = Environment.GetEnvironmentVariable(Queue);
                }

                foreach (var job in jobDefinitions.Jobs)
                {
                    if (!File.Exists(job.Value.Executable))
                    {
                        Console.WriteLine($"The executable for the job '{job.Key}' could not be found at '{job.Value.Executable}'");
                        return;
                    }
                }

                var client    = new ServiceBusClient(ConnectionString);
                var processor = client.CreateProcessor(Queue, new ServiceBusProcessorOptions
                {
                    AutoComplete       = false,
                    MaxConcurrentCalls = 1, // Process one message at a time
                });

                // Whenever a message is available on the queue
                processor.ProcessMessageAsync += async args =>
                {
                    Console.WriteLine("Processing message '{0}'", args.Message.ToString());

                    var message = args.Message;

                    JobPayload jobPayload;
                    DevopsMessage devopsMessage = null;
                    Job driverJob = null;

                    try
                    {
                        // The DevopsMessage does the communications with AzDo
                        devopsMessage = new DevopsMessage(message);

                        // The Body contains the parameters for the application to run
                        jobPayload = JobPayload.Deserialize(message.Body.ToArray());


                        if (!jobDefinitions.Jobs.TryGetValue(jobPayload.Name, out var job))
                        {
                            throw new Exception("Invalid job name: " + jobPayload.Name);
                        }

                        await devopsMessage.SendTaskStartedEventAsync();

                        // The arguments are built from the Task payload and the ones
                        // set on the command line
                        var allArguments = jobPayload.Args.Union(job.Arguments).ToArray();

                        // Convert any arguments with the custom bindings

                        foreach (var binding in job.Bindings.Keys)
                        {
                            if (job.Bindings[binding].StartsWith("env:"))
                            {
                                job.Bindings[binding] = Environment.GetEnvironmentVariable(binding.Substring(4));
                            }
                        }

                        // Create protected arguments string by hiding binding values
                        for (var i = 0; i < allArguments.Length; i++)
                        {
                            var argument = allArguments[i];

                            if (job.Bindings.ContainsKey(argument))
                            {
                                allArguments[i] = "****";
                            }
                        }

                        var sanitizedArguments = String.Join(' ', allArguments);

                        for (var i = 0; i < allArguments.Length; i++)
                        {
                            var argument = allArguments[i];

                            if (job.Bindings.ContainsKey(argument))
                            {
                                allArguments[i] = job.Bindings[argument];
                            }
                        }

                        var arguments = String.Join(' ', allArguments);

                        Console.WriteLine("Invoking application with arguments: " + sanitizedArguments);

                        // The DriverJob manages the application's lifetime and standard output
                        driverJob = new Job(job.Executable, arguments);

                        driverJob.OnStandardOutput = log => Console.WriteLine(log);

                        Console.WriteLine("Processing...");

                        driverJob.Start();

                        // Pump application standard output while it's running
                        while (driverJob.IsRunning)
                        {
                            if ((DateTime.UtcNow - driverJob.StartTimeUtc) > jobPayload.Timeout)
                            {
                                throw new Exception("Job timed out");
                            }

                            var logs = driverJob.FlushStandardOutput().ToArray();

                            // Send any page of logs to the AzDo task log feed
                            if (logs.Any())
                            {
                                await devopsMessage.SendTaskLogFeedsAsync(String.Join("\r\n", logs));
                            }

                            await Task.Delay(TaskLogFeedDelay);
                        }

                        // Mark the task as completed
                        await devopsMessage.SendTaskCompletedEventAsync(succeeded: driverJob.WasSuccessful);

                        // Create a task log entry
                        var taskLogObjectString = await devopsMessage?.CreateTaskLogAsync();

                        var taskLogObject = JsonSerializer.Deserialize <Dictionary <string, object> >(taskLogObjectString);

                        var taskLogId = taskLogObject["id"].ToString();

                        await devopsMessage?.AppendToTaskLogAsync(taskLogId, driverJob.OutputBuilder.ToString());

                        // Attach task log to the timeline record
                        await devopsMessage?.UpdateTaskTimelineRecordAsync(taskLogObjectString);

                        // Mark the message as completed
                        await args.CompleteAsync(message);

                        driverJob.Stop();

                        Console.WriteLine("Job completed");
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Job failed: " + e.Message);

                        try
                        {
                            await devopsMessage?.SendTaskCompletedEventAsync(succeeded: false);
                            await args.AbandonAsync(message);
                        }
                        catch (Exception f)
                        {
                            Console.WriteLine("Failed to abandon task: " + f.Message);
                        }
                    }
                    finally
                    {
                        driverJob?.Dispose();
                    }
                };

                processor.ProcessErrorAsync += args =>
                {
                    Console.WriteLine("Process error: " + args.Exception.ToString());

                    return(Task.CompletedTask);
                };

                await processor.StartProcessingAsync();

                Console.WriteLine("Press ENTER to exit...");
                Console.ReadLine();
            });

            return(app.Execute(args));
        }
        public async Task AddGetAndRemoveRules()
        {
            await using (var scope = await ServiceBusScope.CreateWithTopic(enablePartitioning: false, enableSession: false))
            {
                await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);

                ServiceBusRuleManager ruleManager = client.CreateRuleManager(scope.TopicName, scope.SubscriptionNames.First());
                var sqlRuleName         = "sqlRule";
                var correlationRuleName = "correlationRule";

                var rules = (await ruleManager.GetRulesAsync()).ToList();
                Assert.AreEqual(1, rules.Count());
                var firstRule = rules[0];
                Assert.AreEqual(RuleDescription.DefaultRuleName, firstRule.Name);
                Assert.Null(firstRule.Action);

                await ruleManager.AddRuleAsync(sqlRuleName, new SqlRuleFilter("price > 10"));

                var ruleDescription = new RuleDescription(correlationRuleName)
                {
                    Filter = new CorrelationRuleFilter
                    {
                        CorrelationId = "correlationId",
                        Label         = "label",
                        MessageId     = "messageId",
                        Properties    =
                        {
                            { "key1", "value1" }
                        },
                        ReplyTo          = "replyTo",
                        ReplyToSessionId = "replyToSessionId",
                        SessionId        = "sessionId",
                        To = "to"
                    },
                    Action = new SqlRuleAction("Set CorrelationId = 'newValue'")
                };
                await ruleManager.AddRuleAsync(ruleDescription);

                rules = (await ruleManager.GetRulesAsync()).ToList();
                Assert.AreEqual(3, rules.Count);

                var sqlRule = rules.FirstOrDefault(rule => rule.Name.Equals(sqlRuleName));
                Assert.NotNull(sqlRule);
                Assert.Null(sqlRule.Action);
                Assert.IsInstanceOf <SqlRuleFilter>(sqlRule.Filter);
                Assert.AreEqual("price > 10", ((SqlRuleFilter)sqlRule.Filter).SqlExpression);

                var correlationRule = rules.FirstOrDefault(rule => rule.Name.Equals(correlationRuleName));
                Assert.NotNull(correlationRule);
                Assert.IsInstanceOf <SqlRuleAction>(correlationRule.Action);
                var sqlRuleAction = correlationRule.Action as SqlRuleAction;
                Assert.NotNull(sqlRuleAction);
                Assert.AreEqual("Set CorrelationId = 'newValue'", sqlRuleAction.SqlExpression);
                Assert.IsInstanceOf <CorrelationRuleFilter>(correlationRule.Filter);
                var correlationRuleFilter = correlationRule.Filter as CorrelationRuleFilter;
                Assert.NotNull(correlationRuleFilter);
                Assert.AreEqual("correlationId", correlationRuleFilter.CorrelationId);
                Assert.AreEqual("label", correlationRuleFilter.Label);
                Assert.AreEqual("messageId", correlationRuleFilter.MessageId);
                Assert.AreEqual("replyTo", correlationRuleFilter.ReplyTo);
                Assert.AreEqual("replyToSessionId", correlationRuleFilter.ReplyToSessionId);
                Assert.AreEqual("sessionId", correlationRuleFilter.SessionId);
                Assert.AreEqual("to", correlationRuleFilter.To);
                Assert.NotNull(correlationRuleFilter.Properties);
                Assert.AreEqual("value1", correlationRuleFilter.Properties["key1"]);

                await ruleManager.RemoveRuleAsync(RuleDescription.DefaultRuleName);

                await ruleManager.RemoveRuleAsync(sqlRuleName);

                await ruleManager.RemoveRuleAsync(correlationRuleName);

                rules = (await ruleManager.GetRulesAsync()).ToList();
                Assert.AreEqual(0, rules.Count());
            }
        }
Example #29
0
        internal void StartMessageBatchReceiver(CancellationToken cancellationToken)
        {
            ServiceBusClient   sessionClient = null;
            ServiceBusReceiver receiver      = null;

            if (_isSessionsEnabled)
            {
                sessionClient = _sessionClient.Value;
            }
            else
            {
                receiver = BatchReceiver;
            }

            Task.Run(async() =>
            {
                while (true)
                {
                    try
                    {
                        if (!_started || cancellationToken.IsCancellationRequested)
                        {
                            _logger.LogInformation("Message processing has been stopped or cancelled");
                            return;
                        }

                        if (_isSessionsEnabled && (receiver == null || receiver.IsClosed))
                        {
                            try
                            {
                                receiver = await sessionClient.AcceptNextSessionAsync(_entityPath, new ServiceBusSessionReceiverOptions
                                {
                                    PrefetchCount = _serviceBusOptions.PrefetchCount
                                }).ConfigureAwait(false);
                            }
                            catch (ServiceBusException ex)
                                when(ex.Reason == ServiceBusFailureReason.ServiceTimeout)
                                {
                                    // it's expected if the entity is empty, try next time
                                    continue;
                                }
                        }

                        IReadOnlyList <ServiceBusReceivedMessage> messages =
                            await receiver.ReceiveMessagesAsync(_serviceBusOptions.MaxMessages).ConfigureAwait(false);

                        if (messages != null)
                        {
                            ServiceBusReceivedMessage[] messagesArray = messages.ToArray();
                            ServiceBusTriggerInput input = ServiceBusTriggerInput.CreateBatch(messagesArray);
                            if (_isSessionsEnabled)
                            {
                                input.MessageActions = new ServiceBusSessionMessageActions((ServiceBusSessionReceiver)receiver);
                            }
                            else
                            {
                                input.MessageActions = new ServiceBusMessageActions(receiver);
                            }
                            FunctionResult result = await _triggerExecutor.TryExecuteAsync(input.GetTriggerFunctionData(), cancellationToken).ConfigureAwait(false);

                            if (cancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            // Complete batch of messages only if the execution was successful
                            if (_serviceBusOptions.AutoCompleteMessages && _started)
                            {
                                if (result.Succeeded)
                                {
                                    List <Task> completeTasks = new List <Task>();
                                    foreach (ServiceBusReceivedMessage message in messagesArray)
                                    {
                                        completeTasks.Add(receiver.CompleteMessageAsync(message));
                                    }
                                    await Task.WhenAll(completeTasks).ConfigureAwait(false);
                                }
                                else
                                {
                                    List <Task> abandonTasks = new List <Task>();
                                    foreach (ServiceBusReceivedMessage message in messagesArray)
                                    {
                                        abandonTasks.Add(receiver.AbandonMessageAsync(message));
                                    }
                                    await Task.WhenAll(abandonTasks).ConfigureAwait(false);
                                }
                            }
                        }
                        else
                        {
                            // Close the session and release the session lock after draining all messages for the accepted session.
                            if (_isSessionsEnabled)
                            {
                                await receiver.CloseAsync().ConfigureAwait(false);
                            }
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        // Ignore as we are stopping the host
                    }
                    catch (Exception ex)
                    {
                        // Log another exception
                        _logger.LogError(ex, $"An unhandled exception occurred in the message batch receive loop");

                        if (_isSessionsEnabled && receiver != null)
                        {
                            // Attempt to close the session and release session lock to accept a new session on the next loop iteration
                            try
                            {
                                await receiver.CloseAsync().ConfigureAwait(false);
                            }
                            catch
                            {
                                // Best effort
                                receiver = null;
                            }
                        }
                    }
                }
            }, cancellationToken);
        }
 public async Task SendToServiceBusQueueAsync(Models.Goal Goals, Guid customerId, string reqUrl)
 {
     await ServiceBusClient.SendPatchMessageAsync(Goals, customerId, reqUrl);
 }
Example #31
0
 public ServiceBusEventBus(ServiceBusClient serviceBusClient)
 {
     this.serviceBusClient = serviceBusClient;
     serviceBusSender      = serviceBusClient.CreateSender(queueName);
 }
 /// <summary>
 /// This method causes the communication listener to close. Close is a terminal state and
 ///             this method allows the communication listener to transition to this state in a
 ///             graceful manner.
 /// </summary>
 /// <param name="cancellationToken">Cancellation token</param>
 /// <returns>
 /// A <see cref="T:System.Threading.Tasks.Task">Task</see> that represents outstanding operation.
 /// </returns>
 protected override async Task CloseImplAsync(CancellationToken cancellationToken)
 {
     await ServiceBusClient.CloseAsync();
 }
        public async Task GetQueueRuntimeInfo()
        {
            var queueName  = nameof(GetQueueRuntimeInfo).ToLower() + Recording.Random.NewGuid().ToString("D").Substring(0, 8);
            var mgmtClient = GetClient();

            await using var sbClient = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);

            QueueProperties queue = await mgmtClient.CreateQueueAsync(queueName);

            queue = await mgmtClient.GetQueueAsync(queueName);

            // Changing Last Updated Time
            queue.AutoDeleteOnIdle = TimeSpan.FromMinutes(100);
            QueueProperties updatedQueue = await mgmtClient.UpdateQueueAsync(queue);

            // Populating 1 active message, 1 dead letter message and 1 scheduled message
            // Changing Last Accessed Time

            ServiceBusSender sender = sbClient.CreateSender(queueName);
            await sender.SendMessageAsync(new ServiceBusMessage()
            {
                MessageId = "1"
            });

            await sender.SendMessageAsync(new ServiceBusMessage()
            {
                MessageId = "2"
            });

            await sender.SendMessageAsync(new ServiceBusMessage()
            {
                MessageId = "3", ScheduledEnqueueTime = DateTime.UtcNow.AddDays(1)
            });

            ServiceBusReceiver        receiver = sbClient.CreateReceiver(queueName);
            ServiceBusReceivedMessage msg      = await receiver.ReceiveMessageAsync();

            await receiver.DeadLetterMessageAsync(msg.LockToken);

            List <QueueRuntimeProperties> runtimeInfoList = new List <QueueRuntimeProperties>();

            await foreach (QueueRuntimeProperties queueRuntimeInfo in mgmtClient.GetQueuesRuntimePropertiesAsync())
            {
                runtimeInfoList.Add(queueRuntimeInfo);
            }
            runtimeInfoList = runtimeInfoList.Where(e => e.Name.StartsWith(nameof(GetQueueRuntimeInfo).ToLower())).ToList();
            Assert.True(runtimeInfoList.Count == 1, $"Expected 1 queue but {runtimeInfoList.Count} queues returned");
            QueueRuntimeProperties runtimeInfo = runtimeInfoList.First();

            Assert.NotNull(runtimeInfo);

            Assert.AreEqual(queueName, runtimeInfo.Name);
            Assert.True(runtimeInfo.CreatedAt < runtimeInfo.UpdatedAt);
            Assert.True(runtimeInfo.UpdatedAt < runtimeInfo.AccessedAt);
            Assert.AreEqual(1, runtimeInfo.ActiveMessageCount);
            Assert.AreEqual(1, runtimeInfo.DeadLetterMessageCount);
            Assert.AreEqual(1, runtimeInfo.ScheduledMessageCount);
            Assert.AreEqual(3, runtimeInfo.TotalMessageCount);
            Assert.True(runtimeInfo.SizeInBytes > 0);

            QueueRuntimeProperties singleRuntimeInfo = await mgmtClient.GetQueueRuntimePropertiesAsync(runtimeInfo.Name);

            Assert.AreEqual(runtimeInfo.AccessedAt, singleRuntimeInfo.AccessedAt);
            Assert.AreEqual(runtimeInfo.CreatedAt, singleRuntimeInfo.CreatedAt);
            Assert.AreEqual(runtimeInfo.UpdatedAt, singleRuntimeInfo.UpdatedAt);
            Assert.AreEqual(runtimeInfo.TotalMessageCount, singleRuntimeInfo.TotalMessageCount);
            Assert.AreEqual(runtimeInfo.ActiveMessageCount, singleRuntimeInfo.ActiveMessageCount);
            Assert.AreEqual(runtimeInfo.DeadLetterMessageCount, singleRuntimeInfo.DeadLetterMessageCount);
            Assert.AreEqual(runtimeInfo.ScheduledMessageCount, singleRuntimeInfo.ScheduledMessageCount);
            Assert.AreEqual(runtimeInfo.SizeInBytes, singleRuntimeInfo.SizeInBytes);

            await mgmtClient.DeleteQueueAsync(queueName);
        }
 /// <inheritdoc />
 public override Task Complete(Message message)
 {
     return(ServiceBusClient.CompleteAsync(message.SystemProperties.LockToken));
 }