public async Task TransactionalSendAndComplete()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                var    client    = GetClient();
                string queueName = scope.QueueName;
                #region Snippet:ServiceBusTransactionalSend
                //@@ string connectionString = "<connection_string>";
                //@@ string queueName = "<queue_name>";
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                //@@ await using var client = new ServiceBusClient(connectionString);
                ServiceBusSender sender = client.CreateSender(queueName);

                await sender.SendAsync(new ServiceBusMessage(Encoding.UTF8.GetBytes("First")));

                ServiceBusReceiver        receiver     = client.CreateReceiver(queueName);
                ServiceBusReceivedMessage firstMessage = await receiver.ReceiveAsync();

                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await sender.SendAsync(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second")));

                    await receiver.CompleteAsync(firstMessage);

                    ts.Complete();
                }
                #endregion

                ServiceBusReceivedMessage secondMessage = await receiver.ReceiveAsync(TimeSpan.FromSeconds(5));

                Assert.NotNull(secondMessage);
                await receiver.CompleteAsync(secondMessage);
            };
        }
        public async Task TransactionalSendAndReceiveSubscription()
        {
            await using (var scope = await ServiceBusScope.CreateWithTopic(enablePartitioning: false, enableSession: false))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.TopicName);

                ServiceBusMessage message = GetMessage();
                await sender.SendAsync(message);

                ServiceBusReceiver        receiver = client.CreateReceiver(scope.TopicName, scope.SubscriptionNames.First());
                ServiceBusReceivedMessage received = await receiver.ReceiveAsync();

                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await sender.SendAsync(GetMessage());

                    await receiver.CompleteAsync(received);

                    ts.Complete();
                }

                received = await receiver.ReceiveAsync(TimeSpan.FromSeconds(5));

                Assert.NotNull(received);
                await receiver.CompleteAsync(received);
            };
        }
        public async Task TransactionalSendMultipleSessions()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);

                ServiceBusMessage message1 = GetMessage("session1");
                ServiceBusMessage message2 = GetMessage("session2");
                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await sender.SendAsync(message1);

                    await sender.ScheduleMessageAsync(message2, DateTimeOffset.UtcNow);

                    ts.Complete();
                }

                ServiceBusReceiver receiver = await client.CreateSessionReceiverAsync(scope.QueueName);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message1.Body.ToArray(), receivedMessage.Body.ToArray());
                await receiver.CompleteAsync(receivedMessage);

                receiver = await client.CreateSessionReceiverAsync(scope.QueueName);

                receivedMessage = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message2.Body.ToArray(), receivedMessage.Body.ToArray());
                await receiver.CompleteAsync(receivedMessage);
            };
        }
        public async Task ForwardingEntity()
        {
            // queueName--Fwd to--> destinationName--fwd dlq to-- > dqlDestinationName
            var queueName          = Guid.NewGuid().ToString("D").Substring(0, 8);
            var destinationName    = Guid.NewGuid().ToString("D").Substring(0, 8);
            var dlqDestinationName = Guid.NewGuid().ToString("D").Substring(0, 8);
            var mgmtClient         = new ServiceBusManagementClient(TestEnvironment.ServiceBusConnectionString);

            await mgmtClient.CreateQueueAsync(dlqDestinationName);

            await mgmtClient.CreateQueueAsync(
                new QueueDescription(destinationName)
            {
                ForwardDeadLetteredMessagesTo = dlqDestinationName
            });

            await mgmtClient.CreateQueueAsync(
                new QueueDescription(queueName)
            {
                ForwardTo = destinationName
            });

            await using var sbClient = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
            ServiceBusSender sender = sbClient.CreateSender(queueName);
            await sender.SendAsync(new ServiceBusMessage()
            {
                MessageId = "mid"
            });

            ServiceBusReceiver        receiver = sbClient.CreateReceiver(destinationName);
            ServiceBusReceivedMessage msg      = await receiver.ReceiveAsync();

            Assert.NotNull(msg);
            Assert.AreEqual("mid", msg.MessageId);
            await receiver.DeadLetterAsync(msg.LockToken);

            receiver = sbClient.CreateReceiver(dlqDestinationName);
            msg      = await receiver.ReceiveAsync();

            Assert.NotNull(msg);
            Assert.AreEqual("mid", msg.MessageId);
            await receiver.CompleteAsync(msg.LockToken);

            await mgmtClient.DeleteQueueAsync(queueName);

            await mgmtClient.DeleteQueueAsync(destinationName);

            await mgmtClient.DeleteQueueAsync(dlqDestinationName);
        }
        public async Task TransactionalSendVia()
        {
            await using (var scopeA = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                var scopeB = await ServiceBusScope.CreateWithQueue(enablePartitioning : false, enableSession : false);

                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueA           = scopeA.QueueName;
                string queueB           = scopeB.QueueName;
                await using var client = GetClient();

                #region Snippet:ServiceBusTransactionalSendVia
                //@@ string connectionString = "<connection_string>";
                //@@ string queueA = "<queue_name>";
                //@@ string queueB = "<other_queue_name>";
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                //@@ await using var client = new ServiceBusClient(connectionString);

                ServiceBusSender senderA = client.CreateSender(queueA);
                await senderA.SendAsync(new ServiceBusMessage(Encoding.UTF8.GetBytes("First")));

                ServiceBusSender senderBViaA = client.CreateSender(queueB, new ServiceBusSenderOptions
                {
                    ViaQueueOrTopicName = queueA
                });

                ServiceBusReceiver        receiverA    = client.CreateReceiver(queueA);
                ServiceBusReceivedMessage firstMessage = await receiverA.ReceiveAsync();

                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await receiverA.CompleteAsync(firstMessage);

                    await senderBViaA.SendAsync(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second")));

                    ts.Complete();
                }
                #endregion

                ServiceBusReceivedMessage secondMessage = await receiverA.ReceiveAsync(TimeSpan.FromSeconds(5));

                Assert.Null(secondMessage);
                ServiceBusReceiver receiverB = client.CreateReceiver(queueB);
                secondMessage = await receiverB.ReceiveAsync(TimeSpan.FromSeconds(5));

                Assert.NotNull(secondMessage);
                await receiverB.CompleteAsync(secondMessage);
            };
        }
        public async Task <ServiceBusReceivedMessage> ReceiveMessageAsync(CancellationToken stoppingToken)
        {
            try
            {
                var message = await _serviceBusReceiver.ReceiveAsync();

                return(message);
            }

            catch (ServiceBusException ex)
            {
                _logger.LogError($"{nameof(ServiceBusException)} - error details: {ex.Message}");
                throw;
            }
        }
Beispiel #7
0
        public void ReceiveMessageExceptionLogsEvents()
        {
            var mockLogger            = new Mock <ServiceBusEventSource>();
            var mockTransportReceiver = new Mock <TransportReceiver>();
            var mockConnection        = GetMockConnection(mockTransportReceiver);

            mockTransportReceiver.Setup(
                transportReceiver => transportReceiver.ReceiveBatchAsync(
                    1,
                    It.IsAny <TimeSpan?>(),
                    It.IsAny <CancellationToken>()))
            .Throws(new Exception());
            var receiver = new ServiceBusReceiver(mockConnection.Object, "queueName", false, new ServiceBusReceiverOptions())
            {
                Logger = mockLogger.Object
            };

            Assert.That(
                async() => await receiver.ReceiveAsync(),
                Throws.InstanceOf <Exception>());

            mockLogger
            .Verify(
                log => log.ReceiveMessageStart(
                    receiver.Identifier,
                    1),
                Times.Once);
            mockLogger
            .Verify(
                log => log.ReceiveMessageException(
                    receiver.Identifier,
                    It.IsAny <string>()),
                Times.Once);
        }
Beispiel #8
0
        public async Task DeadLetterMessage()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueName        = scope.QueueName;
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                await using var client = new ServiceBusClient(connectionString);

                // create the sender
                ServiceBusSender sender = client.CreateSender(queueName);

                // create a message that we can send
                ServiceBusMessage message = new ServiceBusMessage(Encoding.Default.GetBytes("Hello world!"));

                // send the message
                await sender.SendAsync(message);

                // create a receiver that we can use to receive and settle the message
                ServiceBusReceiver receiver = client.CreateReceiver(queueName);

                #region Snippet:ServiceBusDeadLetterMessage
                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                // deadletter the message, thereby preventing the message from being received again without receiving from the dead letter queue.
                await receiver.DeadLetterAsync(receivedMessage);

                // receive the dead lettered message with receiver scoped to the dead letter queue.
                ServiceBusReceiver        dlqReceiver = client.CreateDeadLetterReceiver(queueName);
                ServiceBusReceivedMessage dlqMessage  = await dlqReceiver.ReceiveAsync();

                #endregion
                Assert.IsNotNull(dlqMessage);
            }
        }
        public async Task SendAndReceiveMessage()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueName        = scope.QueueName;
                #region Snippet:ServiceBusSendAndReceive
                //@@ string connectionString = "<connection_string>";
                //@@ string queueName = "<queue_name>";
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                await using var client = new ServiceBusClient(connectionString);

                // create the sender
                ServiceBusSender sender = client.CreateSender(queueName);

                // create a message that we can send
                ServiceBusMessage message = new ServiceBusMessage(Encoding.UTF8.GetBytes("Hello world!"));

                // send the message
                await sender.SendAsync(message);

                // create a receiver that we can use to receive the message
                ServiceBusReceiver receiver = client.CreateReceiver(queueName);

                // the received message is a different type as it contains some service set properties
                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                // get the message body as a string
                string body = Encoding.UTF8.GetString(receivedMessage.Body.ToArray());
                Console.WriteLine(body);
                #endregion
                Assert.AreEqual(Encoding.UTF8.GetBytes("Hello world!"), receivedMessage.Body.ToArray());
            }
        }
Beispiel #10
0
        public async Task TransactionalSendRollback(bool partitioned, bool sessionEnabled)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: partitioned, enableSession: sessionEnabled))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);

                ServiceBusMessage message = GetMessage(
                    sessionEnabled ? "sessionId" : null,
                    partitioned ? "sessionId" : null);
                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await sender.SendAsync(message);

                    // not completing the transaction
                }

                ServiceBusReceiver receiver = sessionEnabled ?
                                              await client.CreateSessionReceiverAsync(
                    scope.QueueName,
                    new ServiceBusSessionReceiverOptions
                {
                    SessionId = "sessionId"
                })
                    : client.CreateReceiver(scope.QueueName);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync(TimeSpan.FromSeconds(5));

                Assert.IsNull(receivedMessage);
            };
        }
        public async Task TransactionalSendCommit(bool partitioned, bool sessionEnabled)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: partitioned, enableSession: sessionEnabled))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);

                ServiceBusMessage message = GetMessage(
                    sessionEnabled ? "sessionId" : null,
                    partitioned ? "sessionId" : null);
                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await sender.SendAsync(message);

                    ts.Complete();
                }

                ServiceBusReceiver receiver = sessionEnabled ? await client.CreateSessionReceiverAsync(scope.QueueName) : client.CreateReceiver(scope.QueueName);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message.Body.ToArray(), receivedMessage.Body.ToArray());
                await receiver.CompleteAsync(receivedMessage);
            };
        }
        public async Task TransactionCommitThrowsUsingDifferentClientsToSameEntity()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                var client1                 = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender     = client1.CreateSender(scope.QueueName);
                var client2                 = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusReceiver receiver = client2.CreateReceiver(scope.QueueName);

                ServiceBusMessage message1 = GetMessage();
                ServiceBusMessage message2 = GetMessage();
                await sender.SendAsync(message1);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message1.Body.ToString(), receivedMessage.Body.ToString());

                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await receiver.CompleteAsync(receivedMessage);

                    Assert.That(
                        async() =>
                        await sender.SendAsync(message2), Throws.InstanceOf <ServiceBusException>());
                    ts.Complete();
                }
            }
        }
Beispiel #13
0
        public async Task AbandonMessage()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueName        = scope.QueueName;
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                await using var client = new ServiceBusClient(connectionString);

                // create the sender
                ServiceBusSender sender = client.CreateSender(queueName);

                // create a message that we can send
                ServiceBusMessage message = new ServiceBusMessage(Encoding.Default.GetBytes("Hello world!"));

                // send the message
                await sender.SendAsync(message);

                // create a receiver that we can use to receive and settle the message
                ServiceBusReceiver receiver = client.CreateReceiver(queueName);

                #region Snippet:ServiceBusAbandonMessage
                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                // abandon the message, thereby releasing the lock and allowing it to be received again by this or other receivers
                await receiver.AbandonAsync(receivedMessage);

                #endregion
                Assert.IsNotNull(GetNoRetryClient().CreateReceiver(queueName).ReceiveAsync());
            }
        }
Beispiel #14
0
        public async Task CompleteMessage()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueName        = scope.QueueName;
                #region Snippet:ServiceBusCompleteMessage
                //@@ string connectionString = "<connection_string>";
                //@@ string queueName = "<queue_name>";
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                await using var client = new ServiceBusClient(connectionString);

                // create the sender
                ServiceBusSender sender = client.CreateSender(queueName);

                // create a message that we can send
                ServiceBusMessage message = new ServiceBusMessage(Encoding.Default.GetBytes("Hello world!"));

                // send the message
                await sender.SendAsync(message);

                // create a receiver that we can use to receive and settle the message
                ServiceBusReceiver receiver = client.CreateReceiver(queueName);

                // the received message is a different type as it contains some service set properties
                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                // complete the message, thereby deleting it from the service
                await receiver.CompleteAsync(receivedMessage);

                #endregion
                Assert.IsNull(await GetNoRetryClient().CreateReceiver(queueName).ReceiveAsync());
            }
        }
Beispiel #15
0
        public async Task TransactionalCompleteRollback(bool partitioned, bool sessionEnabled, bool completeInTransactionAfterRollback)
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: partitioned, enableSession: sessionEnabled))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender sender = client.CreateSender(scope.QueueName);

                string            body    = Guid.NewGuid().ToString("N");
                ServiceBusMessage message = GetMessage(
                    sessionEnabled ? "sessionId" : null,
                    partitioned ? "sessionId" : null);
                await sender.SendAsync(message);

                ServiceBusReceiver receiver = sessionEnabled ? await client.CreateSessionReceiverAsync(scope.QueueName) : client.CreateReceiver(scope.QueueName);

                var receivedMessage = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(
                    message.Body.ToString(),
                    receivedMessage.Body.ToString());
                var sequenceNumber = receivedMessage.SequenceNumber;
                await receiver.DeferAsync(receivedMessage);

                ServiceBusReceivedMessage deferredMessage = await receiver.ReceiveDeferredMessageAsync(sequenceNumber);

                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await receiver.CompleteAsync(deferredMessage);
                }

                // 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));

                if (completeInTransactionAfterRollback)
                {
                    using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                    {
                        await receiver.CompleteAsync(deferredMessage);

                        ts.Complete();
                    }
                    // 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));
                }
                else
                {
                    await receiver.CompleteAsync(deferredMessage);
                }

                Assert.That(
                    async() =>
                    await receiver.CompleteAsync(deferredMessage), Throws.InstanceOf <ServiceBusException>()
                    .And.Property(nameof(ServiceBusException.Reason))
                    .EqualTo(ServiceBusException.FailureReason.MessageLockLost));
            }
        }
        public async Task TransactionCommitWorksUsingSendersAndReceiversFromSameClients()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender   sender   = client.CreateSender(scope.QueueName);
                ServiceBusReceiver receiver = client.CreateReceiver(scope.QueueName);

                ServiceBusMessage message1 = GetMessage();
                ServiceBusMessage message2 = GetMessage();
                await sender.SendAsync(message1);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message1.Body.ToString(), receivedMessage.Body.ToString());

                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await receiver.CompleteAsync(receivedMessage);

                    await sender.SendAsync(message2);

                    ts.Complete();
                }

                // 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));

                // Assert that complete did succeed
                Assert.That(
                    async() =>
                    await receiver.CompleteAsync(receivedMessage), Throws.InstanceOf <ServiceBusException>()
                    .And.Property(nameof(ServiceBusException.Reason))
                    .EqualTo(ServiceBusException.FailureReason.MessageLockLost));

                // Assert that send did succeed
                receivedMessage = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message2.Body.ToString(), receivedMessage.Body.ToString());
                await receiver.CompleteAsync(receivedMessage);
            }
        }
        public async Task TransactionRollbackWorksAcrossClientsUsingSameConnectionToSameEntity()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
                ServiceBusSender   sender   = client.CreateSender(scope.QueueName);
                ServiceBusReceiver receiver = client.CreateReceiver(scope.QueueName);

                ServiceBusMessage message1 = GetMessage();
                ServiceBusMessage message2 = GetMessage();
                await sender.SendAsync(message1);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message1.Body.ToString(), receivedMessage.Body.ToString());

                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    await receiver.CompleteAsync(receivedMessage.LockToken);

                    await sender.SendAsync(message2);
                }

                // 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));

                // Following should succeed without exceptions
                await receiver.CompleteAsync(receivedMessage.LockToken);

                // Assert that send failed
                receivedMessage = await receiver.ReceiveAsync(TimeSpan.FromSeconds(5));

                Assert.Null(receivedMessage);
            }
        }
Beispiel #18
0
        public async Task ReceiveSingleMessageLogsEvents()
        {
            var mockLogger            = new Mock <ServiceBusEventSource>();
            var mockTransportReceiver = new Mock <TransportReceiver>();
            var mockConnection        = GetMockConnection(mockTransportReceiver);

            mockTransportReceiver.Setup(
                transportReceiver => transportReceiver.ReceiveBatchAsync(
                    1,
                    It.IsAny <TimeSpan?>(),
                    It.IsAny <CancellationToken>()))
            .Returns(
                Task.FromResult((IList <ServiceBusReceivedMessage>)
                                new List <ServiceBusReceivedMessage> {
                new ServiceBusReceivedMessage()
            }));
            var receiver = new ServiceBusReceiver(mockConnection.Object, "queueName", false, new ServiceBusReceiverOptions())
            {
                Logger = mockLogger.Object
            };


            await receiver.ReceiveAsync();

            mockLogger
            .Verify(
                log => log.ReceiveMessageStart(
                    receiver.Identifier,
                    1),
                Times.Once);
            mockLogger
            .Verify(
                log => log.ReceiveMessageComplete(
                    receiver.Identifier,
                    1),
                Times.Once);
        }
        public async Task DeferMessage()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueName        = scope.QueueName;
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                await using var client = new ServiceBusClient(connectionString);

                // create the sender
                ServiceBusSender sender = client.CreateSender(queueName);

                // create a message that we can send
                ServiceBusMessage message = new ServiceBusMessage(Encoding.UTF8.GetBytes("Hello world!"));

                // send the message
                await sender.SendAsync(message);

                // create a receiver that we can use to receive and settle the message
                ServiceBusReceiver receiver = client.CreateReceiver(queueName);

                #region Snippet:ServiceBusDeferMessage
                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveAsync();

                // defer the message, thereby preventing the message from being received again without using
                // the received deferred message API.
                await receiver.DeferAsync(receivedMessage);

                // receive the deferred message by specifying the service set sequence number of the original
                // received message
                ServiceBusReceivedMessage deferredMessage = await receiver.ReceiveDeferredMessageAsync(receivedMessage.SequenceNumber);

                #endregion
                Assert.IsNotNull(deferredMessage);
            }
        }
        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 GetSubscriptionRuntimeInfoTest()
        {
            var topicName        = nameof(GetSubscriptionRuntimeInfoTest).ToLower() + Guid.NewGuid().ToString("D").Substring(0, 8);
            var subscriptionName = Guid.NewGuid().ToString("D").Substring(0, 8);
            var mgmtClient       = new ServiceBusManagementClient(TestEnvironment.ServiceBusConnectionString);

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

            TopicDescription topicDescription = await mgmtClient.CreateTopicAsync(topicName);

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

            SubscriptionDescription subscriptionDescription = await mgmtClient.CreateSubscriptionAsync(topicName, subscriptionName);

            // Changing Last Updated Time for subscription
            subscriptionDescription.AutoDeleteOnIdle = TimeSpan.FromMinutes(100);
            await mgmtClient.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.SendAsync(new ServiceBusMessage()
            {
                MessageId = "1"
            });

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

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

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

            await receiver.DeadLetterAsync(msg.LockToken);

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

            await foreach (SubscriptionRuntimeInfo subscriptionRuntimeInfo in mgmtClient.GetSubscriptionsRuntimeInfoAsync(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");
            SubscriptionRuntimeInfo 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.CountDetails.ActiveMessageCount);
            Assert.AreEqual(1, runtimeInfo.CountDetails.DeadLetterMessageCount);
            Assert.AreEqual(0, runtimeInfo.CountDetails.ScheduledMessageCount);
            Assert.AreEqual(2, runtimeInfo.MessageCount);

            SubscriptionRuntimeInfo singleRuntimeInfo = await mgmtClient.GetSubscriptionRuntimeInfoAsync(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.MessageCount, singleRuntimeInfo.MessageCount);
            Assert.AreEqual(runtimeInfo.CountDetails.ActiveMessageCount, singleRuntimeInfo.CountDetails.ActiveMessageCount);
            Assert.AreEqual(runtimeInfo.CountDetails.DeadLetterMessageCount, singleRuntimeInfo.CountDetails.DeadLetterMessageCount);
            Assert.AreEqual(runtimeInfo.CountDetails.ScheduledMessageCount, singleRuntimeInfo.CountDetails.ScheduledMessageCount);
            Assert.AreEqual(runtimeInfo.TopicName, singleRuntimeInfo.TopicName);

            await mgmtClient.DeleteTopicAsync(topicName);
        }