Beispiel #1
0
        public static async Task CompleteOrAbandonMessageAsync(string connectionString, string queueName, bool abandon)
        {
            await using var client = new ServiceBusClient(connectionString);

            // 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.ReceiveMessageAsync();

            Console.WriteLine($"Message received {receivedMessage.Body} to be abandoned {abandon}");

            if (!abandon) // complete the message, thereby deleting it from the service
            {
                await receiver.CompleteMessageAsync(receivedMessage);
            }
            else // abandon the message, thereby releasing the lock and allowing it to be received again by this or other receivers
            {
                await receiver.AbandonMessageAsync(receivedMessage);
            }
        }
Beispiel #2
0
        public void ReceiveMessageExceptionLogsEvents()
        {
            var mockLogger            = new Mock <ServiceBusEventSource>();
            var mockTransportReceiver = new Mock <TransportReceiver>();
            var mockConnection        = GetMockConnection(mockTransportReceiver);

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

            Assert.That(
                async() => await receiver.ReceiveMessageAsync(),
                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 #3
0
        /// <summary>
        /// Received Message
        /// </summary>
        /// <returns></returns>
        public async Task ReceivedMessageAsync()
        {
            var a = new Appsettings();

            await using var queueClient = new ServiceBusClient(Appsettings.app("ServiceBus", "PrimaryConnectionString"));
            try
            {
                // create a receiver that we can use to receive the message
                ServiceBusReceiver receiver = queueClient.CreateReceiver(Appsettings.app("ServiceBus", "QueueName"));

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

                // get the message body as a string
                string body = receivedMessage.Body.ToString();
                Console.WriteLine(body);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
Beispiel #4
0
        public async void RecevoirAsync()
        {
            var client = new ServiceBusClient(_chaineConnexion);

            ServiceBusReceiver consommateur = client.CreateReceiver(_nomFile);

            while (true)
            {
                Console.WriteLine("En attente de message sur la file : " + _nomFile + " ...");

                try
                {
                    ServiceBusReceivedMessage messageRecu = await consommateur.ReceiveMessageAsync(TimeSpan.FromMilliseconds(2000));

                    if (messageRecu is null)
                    {
                        continue;
                    }

                    string contenuMessage = messageRecu.Body.ToString();

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Message recu : " + contenuMessage);
                    Console.ForegroundColor = ConsoleColor.White;

                    await consommateur.CompleteMessageAsync(messageRecu);

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Confirmation de traitement Envoyée  : " + contenuMessage);
                    Console.ForegroundColor = ConsoleColor.White;
                }
                catch (Exception e)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Une erreur est survenue lors de la reception du message : " + e.Message);
                    Console.ForegroundColor = ConsoleColor.White;
                }
            }
        }
        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("Hello world!");

                // send the message
                await sender.SendMessageAsync(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.ReceiveMessageAsync();

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

                // receive the dead lettered message with receiver scoped to the dead letter queue.
                ServiceBusReceiver dlqReceiver = client.CreateReceiver(queueName, new ServiceBusReceiverOptions
                {
                    SubQueue = SubQueue.DeadLetter
                });
                ServiceBusReceivedMessage dlqMessage = await dlqReceiver.ReceiveMessageAsync();

                #endregion
                Assert.IsNotNull(dlqMessage);
            }
        }
Beispiel #6
0
        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
                #region Snippet:ServiceBusSendSingleMessage
                //@@ 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. UTF-8 encoding is used when providing a string.
                ServiceBusMessage message = new ServiceBusMessage("Hello world!");

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

                #endregion
                #region Snippet:ServiceBusReceiveSingleMessage
                // 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.ReceiveMessageAsync();

                // get the message body as a string
                string body = receivedMessage.Body.ToString();
                Console.WriteLine(body);
                #endregion
                #endregion
                Assert.AreEqual("Hello world!", receivedMessage.Body.ToString());
            }
        }
Beispiel #7
0
        static async Task Main(string[] args)
        {
            string connectionString = "<connection_string>";
            string queueName        = "<queue_name>";

            // Because ServiceBusClient implements IAsyncDisposable, we'll create it
            // with "await using" so that it is automatically disposed for us.
            await using var client = new ServiceBusClient(connectionString);

            // The sender is responsible for publishing messages to the queue.
            ServiceBusSender  sender  = client.CreateSender(queueName);
            ServiceBusMessage message = new ServiceBusMessage("Hello world!");

            await sender.SendMessageAsync(message);

            // The receiver is responsible for reading messages from the queue.
            ServiceBusReceiver        receiver        = client.CreateReceiver(queueName);
            ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

            string body = receivedMessage.Body.ToString();

            Console.WriteLine(body);
        }
        public async Task CompleteMessage()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                #region Snippet:ServiceBusCompleteMessage
#if SNIPPET
                string connectionString = "<connection_string>";
                string queueName        = "<queue_name>";
#else
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string queueName        = scope.QueueName;
#endif
                // since ServiceBusClient implements IAsyncDisposable we create it with "await using"
                await using var client = new ServiceBusClient(connectionString);

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

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

                // send the message
                await sender.SendMessageAsync(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.ReceiveMessageAsync();

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

                #endregion
                Assert.IsNull(await CreateNoRetryClient().CreateReceiver(queueName).ReceiveMessageAsync());
            }
        }
Beispiel #9
0
        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.SendMessageAsync(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.ReceiveMessageAsync();

                // defer the message, thereby preventing the message from being received again without using
                // the received deferred message API.
                await receiver.DeferMessageAsync(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);
            }
        }
Beispiel #10
0
        public async Task TransactionGroupSendsFirst(bool partitioned, bool enableSessions)
        {
            await using var client = CreateCrossEntityTxnClient();
            await using var queueA = await ServiceBusScope.CreateWithQueue(enablePartitioning : partitioned, enableSession : enableSessions);

            await using var queueB = await ServiceBusScope.CreateWithQueue(enablePartitioning : partitioned, enableSession : enableSessions);

            await using var queueC = await ServiceBusScope.CreateWithQueue(enablePartitioning : partitioned, enableSession : enableSessions);

            await using var noTxClient = CreateClient();

            var senderA = noTxClient.CreateSender(queueA.QueueName);
            ServiceBusReceiver receiverA = null;
            ServiceBusReceiver receiverB = null;
            ServiceBusReceiver receiverC = null;

            if (!enableSessions)
            {
                receiverA = client.CreateReceiver(queueA.QueueName);
                receiverB = client.CreateReceiver(queueB.QueueName);
                receiverC = noTxClient.CreateReceiver(queueC.QueueName);
            }
            var senderB = client.CreateSender(queueB.QueueName);
            var senderC = client.CreateSender(queueC.QueueName);

            var message = new ServiceBusMessage
            {
                SessionId = enableSessions ? "sessionId" : null,
                TransactionPartitionKey = partitioned ? "sessionId" : null
            };

            // B is the send via entity since it is first
            await senderB.SendMessageAsync(message);

            await senderA.SendMessageAsync(message);

            if (enableSessions)
            {
                // you can't use a receiver after a sender (for a different entity) when using a Transaction Group because it would be
                // saying that you want to receive via the sender entity which isn't possible

                Assert.ThrowsAsync <InvalidOperationException>(
                    async() =>
                    await client.AcceptNextSessionAsync(queueA.QueueName));

                receiverB = await client.AcceptNextSessionAsync(queueB.QueueName);
            }
            else
            {
                Assert.ThrowsAsync <InvalidOperationException>(async() => await receiverA.ReceiveMessageAsync());
            }
            // After the above throws, the session gets closed by the AMQP lib, so we are testing whether the fault tolerant session/controller
            // objects get re-created correctly.

            ServiceBusReceivedMessage receivedMessageB = await receiverB.ReceiveMessageAsync();

            // If the transaction succeeds, then all the operations occurred on the same partition.
            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                // this is allowed because it is on B
                await receiverB.CompleteMessageAsync(receivedMessageB);

                // send to C via B - this is allowed because we are sending
                await senderC.SendMessageAsync(message);

                ts.Complete();
            }

            if (enableSessions)
            {
                receiverC = await noTxClient.AcceptNextSessionAsync(queueC.QueueName);
            }

            var receivedMessageC = await receiverC.ReceiveMessageAsync();

            Assert.IsNotNull(receivedMessageC);

            receivedMessageB = await receiverB.ReceiveMessageAsync();

            Assert.IsNull(receivedMessageB);

            await senderB.SendMessageAsync(message);

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

                // this is allowed because it is on B
                await receiverB.CompleteMessageAsync(receivedMessageB);

                // this will fail because it is not part of txn group
                Assert.ThrowsAsync <ServiceBusException>(async() => await senderA.SendMessageAsync(message));

                ts.Complete();
            }
        }
        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.LockToken);

            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);
        }
        public async Task GetQueueRuntimeInfo()
        {
            var queueName  = nameof(GetQueueRuntimeInfo).ToLower() + Recording.Random.NewGuid().ToString("D").Substring(0, 8);
            var mgmtClient = CreateClient();

            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);
        }
        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.SendMessageAsync(message1);

                    Assert.ThrowsAsync <InvalidOperationException>(
                        async() => await sender.SendMessageAsync(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.SendMessageAsync(message1);

                await sender.SendMessageAsync(message2);

                ServiceBusReceivedMessage receivedMessage1 = await receiver.ReceiveMessageAsync();

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

                Assert.NotNull(receivedMessage2);

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

                    Assert.ThrowsAsync <InvalidOperationException>(
                        async() => await receiver.CompleteMessageAsync(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.CompleteMessageAsync(receivedMessage1);

                // the service seems to abandon the message that
                // triggered the InvalidOperationException
                // in the transaction
                Assert.That(
                    async() =>
                    await receiver.CompleteMessageAsync(receivedMessage2), Throws.InstanceOf <ServiceBusException>()
                    .And.Property(nameof(ServiceBusException.Reason))
                    .EqualTo(ServiceBusFailureReason.MessageLockLost));
            }
        }
Beispiel #14
0
        public async Task PluginsSessions()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
#if SNIPPET
                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);
#else
                await using var client = CreateClient();
                string queueName = scope.QueueName;
#endif
                await using ServiceBusSender sender = client.CreatePluginSender(queueName, new List <Func <ServiceBusMessage, Task> >()
                {
                    message =>
                    {
                        message.Subject   = "Updated subject";
                        message.SessionId = "sessionId";
#if SNIPPET
                        Console.WriteLine("First send plugin executed!");
#endif
                        return(Task.CompletedTask);
                    },
                    message =>
                    {
#if SNIPPET
                        Console.WriteLine(message.Subject); // prints "Updated subject"
                        Console.WriteLine("Second send plugin executed!");
#else
                        Assert.AreEqual("Updated subject", message.Subject);
#endif
                        return(Task.CompletedTask);
                    },
                });

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

                await using ServiceBusReceiver receiver = await client.AccextNextSessionPluginAsync(queueName, new List <Func <ServiceBusReceivedMessage, Task> >()
                {
                    message =>
                    {
#if SNIPPET
                        Console.WriteLine("First receive plugin executed!");
#else
                        Assert.AreEqual("Updated subject", message.Subject);
#endif
                        var rawMessage = message.GetRawAmqpMessage();
                        rawMessage.Properties.Subject = "Received subject";
                        return(Task.CompletedTask);
                    },
                    message =>
                    {
#if SNIPPET
                        Console.WriteLine(message.Subject); // prints "Received subject"
#else
                        Assert.AreEqual("Received subject", message.Subject);
#endif
                        var rawMessage = message.GetRawAmqpMessage();
                        rawMessage.Properties.Subject = "Last subject";
                        Console.WriteLine("Second receive plugin executed!");
                        return(Task.CompletedTask);
                    },
                });

                ServiceBusReceivedMessage message = await receiver.ReceiveMessageAsync();

#if SNIPPET
                Console.WriteLine(message.Subject);
#else
                Assert.AreEqual("Last subject", message.Subject);
#endif
            };
        }
Beispiel #15
0
        async Task ReceiveMessage(CancellationToken messageReceivingCancellationToken)
        {
            ServiceBusReceivedMessage message = null;

            try
            {
                message = await receiver.ReceiveMessageAsync(cancellationToken : messageReceivingCancellationToken).ConfigureAwait(false);

                circuitBreaker.Success();
            }
            catch (ServiceBusException ex) when(ex.IsTransient)
            {
            }
            catch (ObjectDisposedException)
            {
                // Can happen during endpoint shutdown
            }
            catch (Exception ex) when(!ex.IsCausedBy(messageReceivingCancellationToken))
            {
                Logger.Warn($"Failed to receive a message. Exception: {ex.Message}", ex);

                await circuitBreaker.Failure(ex, messageReceivingCancellationToken).ConfigureAwait(false);
            }

            // By default, ASB client long polls for a minute and returns null if it times out
            if (message == null)
            {
                return;
            }

            messageReceivingCancellationToken.ThrowIfCancellationRequested();

            string messageId;
            Dictionary <string, string> headers;
            BinaryData body;

            try
            {
                messageId = message.GetMessageId();
                headers   = message.GetNServiceBusHeaders();
                body      = message.GetBody();
            }
            catch (Exception ex)
            {
                var tryDeadlettering = transportSettings.TransportTransactionMode != TransportTransactionMode.None;

                Logger.Warn($"Poison message detected. " +
                            $"Message {(tryDeadlettering ? "will be moved to the poison queue" : "will be discarded, transaction mode is set to None")}. " +
                            $"Exception: {ex.Message}", ex);

                if (tryDeadlettering)
                {
                    try
                    {
                        await receiver.DeadLetterMessageAsync(message, deadLetterReason : "Poisoned message", deadLetterErrorDescription : ex.Message, cancellationToken : messageReceivingCancellationToken).ConfigureAwait(false);
                    }
                    catch (Exception deadLetterEx) when(!deadLetterEx.IsCausedBy(messageReceivingCancellationToken))
                    {
                        // nothing we can do about it, message will be retried
                        Logger.Debug("Error dead lettering poisoned message.", deadLetterEx);
                    }
                }

                return;
            }

            // need to catch OCE here because we are switching token
            try
            {
                await ProcessMessage(message, messageId, headers, body, messageProcessingCancellationTokenSource.Token).ConfigureAwait(false);
            }
            catch (Exception ex) when(ex.IsCausedBy(messageProcessingCancellationTokenSource.Token))
            {
                Logger.Debug("Message processing canceled.", ex);
            }
        }
        public async Task TransactionGroupReceivesFirst(bool partitioned, bool enableSessions)
        {
            var transactionGroup = "myTxn";

            await using var client = CreateClient();
            await using var queueA = await ServiceBusScope.CreateWithQueue(enablePartitioning : partitioned, enableSession : enableSessions);

            await using var queueB = await ServiceBusScope.CreateWithQueue(enablePartitioning : partitioned, enableSession : enableSessions);

            await using var topicC = await ServiceBusScope.CreateWithTopic(enablePartitioning : partitioned, enableSession : enableSessions);

            var senderA = client.CreateSender(queueA.QueueName);
            ServiceBusReceiver receiverA = null;

            if (!enableSessions)
            {
                receiverA = client.CreateReceiver(queueA.QueueName, new ServiceBusReceiverOptions
                {
                    TransactionGroup = transactionGroup
                });
            }
            var senderB = client.CreateSender(queueB.QueueName, new ServiceBusSenderOptions
            {
                TransactionGroup = transactionGroup
            });
            var senderC = client.CreateSender(topicC.TopicName, new ServiceBusSenderOptions
            {
                TransactionGroup = transactionGroup
            });

            var message = new ServiceBusMessage
            {
                SessionId = enableSessions ? "sessionId" : null,
                TransactionPartitionKey = partitioned ? "sessionId" : null
            };

            await senderA.SendMessageAsync(message);

            if (enableSessions)
            {
                receiverA = await client.AcceptNextSessionAsync(queueA.QueueName, new ServiceBusSessionReceiverOptions
                {
                    TransactionGroup = transactionGroup
                });
            }

            ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

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

                await senderB.SendMessageAsync(message);

                await senderC.SendMessageAsync(message);

                ts.Complete();
            }

            receivedMessage = await receiverA.ReceiveMessageAsync();

            Assert.IsNull(receivedMessage);
        }
Beispiel #17
0
        public async Task ManageRules()
        {
            await using (var scope = await ServiceBusScope.CreateWithTopic(enablePartitioning: false, enableSession: false))
            {
                #region Snippet:ServiceBusManageRules
#if SNIPPET
                string connectionString = "<connection_string>";
                string topicName        = "<topic_name>";
                string subscriptionName = "<subscription_name>";
#else
                string connectionString = TestEnvironment.ServiceBusConnectionString;
                string topicName        = scope.TopicName;
                string subscriptionName = scope.SubscriptionNames.First();
#endif

                await using var client = new ServiceBusClient(connectionString);

                await using ServiceBusRuleManager ruleManager = client.CreateRuleManager(topicName, subscriptionName);

                // By default, subscriptions are created with a default rule that always evaluates to True. In order to filter, we need
                // to delete the default rule. You can skip this step if you create the subscription with the ServiceBusAdministrationClient,
                // and specify a the FalseRuleFilter in the create rule options.
                await ruleManager.DeleteRuleAsync(RuleProperties.DefaultRuleName);

                await ruleManager.CreateRuleAsync("brand-filter", new CorrelationRuleFilter { Subject = "Toyota" });

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

                ServiceBusMessage[] messages =
                {
                    new ServiceBusMessage {
                        Subject = "Ford", ApplicationProperties ={                         { "Price", 25000 } }
                    },
                    new ServiceBusMessage {
                        Subject = "Toyota", ApplicationProperties ={                         { "Price", 28000 } }
                    },
                    new ServiceBusMessage {
                        Subject = "Honda", ApplicationProperties ={                         { "Price", 35000 } }
                    }
                };

                // send the messages
                await sender.SendMessagesAsync(messages);

                // create a receiver for our subscription that we can use to receive and settle the message
                ServiceBusReceiver receiver = client.CreateReceiver(topicName, subscriptionName);

                // receive the message - we only get back the Toyota message
                while (true)
                {
                    ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync(TimeSpan.FromSeconds(5));

                    if (receivedMessage == null)
                    {
                        break;
                    }
                    Console.WriteLine($"Brand: {receivedMessage.Subject}, Price: {receivedMessage.ApplicationProperties["Price"]}");
                    await receiver.CompleteMessageAsync(receivedMessage);
                }

                await ruleManager.CreateRuleAsync("price-filter", new SqlRuleFilter("Price < 30000"));

                await ruleManager.DeleteRuleAsync("brand-filter");

                // we can also use the rule manager to iterate over the rules on the subscription.
                await foreach (RuleProperties rule in ruleManager.GetRulesAsync())
                {
                    // we should only have 1 rule at this point - "price-filter"
                    Console.WriteLine(rule.Name);
                }

                // send the messages again - because the subscription rules are evaluated when the messages are first enqueued, adding rules
                // for messages that are already in a subscription would have no effect.
                await sender.SendMessagesAsync(messages);

                // receive the messages - we get back both the Ford and the Toyota
                while (true)
                {
                    ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync(TimeSpan.FromSeconds(5));

                    if (receivedMessage == null)
                    {
                        break;
                    }
                    Console.WriteLine($"Brand: {receivedMessage.Subject}, Price: {receivedMessage.ApplicationProperties["Price"]}");
                }
                #endregion
            }
        }
        public async Task ClaimCheck()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                #region Snippet:CreateBlobContainer
#if SNIPPET
                var containerClient = new BlobContainerClient("<storage connection string>", "claim-checks");
#else
                var containerClient = new BlobContainerClient(TestEnvironment.StorageClaimCheckConnectionString, "claim-checks");
#endif
                await containerClient.CreateIfNotExistsAsync();

                #endregion

                try
                {
                    #region Snippet:UploadMessage

                    byte[] body     = ServiceBusTestUtilities.GetRandomBuffer(1000000);
                    string blobName = Guid.NewGuid().ToString();
                    await containerClient.UploadBlobAsync(blobName, new BinaryData(body));

                    var message = new ServiceBusMessage
                    {
                        ApplicationProperties =
                        {
                            ["blob-name"] = blobName
                        }
                    };

                    #endregion

                    #region Snippet:ClaimCheckSendMessage

#if SNIPPET
                    var client = new ServiceBusClient("<service bus connection string>");
#else
                    var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString);
#endif
                    ServiceBusSender sender = client.CreateSender(scope.QueueName);
                    await sender.SendMessageAsync(message);

                    #endregion

                    #region Snippet:ReceiveClaimCheck

                    ServiceBusReceiver        receiver        = client.CreateReceiver(scope.QueueName);
                    ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

                    if (receivedMessage.ApplicationProperties.TryGetValue("blob-name", out object blobNameReceived))
                    {
#if SNIPPET
                        var blobClient = new BlobClient("<storage connection string>", "claim-checks", (string)blobNameReceived);
#else
                        var blobClient = new BlobClient(
                            TestEnvironment.StorageClaimCheckConnectionString,
                            "claim-checks",
                            (string)blobNameReceived);
#endif
                        BlobDownloadResult downloadResult = await blobClient.DownloadContentAsync();

                        BinaryData messageBody = downloadResult.Content;

                        // Once we determine that we are done with the message, we complete it and delete the corresponding blob.
                        await receiver.CompleteMessageAsync(receivedMessage);

                        await blobClient.DeleteAsync();

#if !SNIPPET
                        Assert.AreEqual(body, messageBody.ToArray());
#endif
                    }
                    #endregion
                }
                finally
                {
                    await containerClient.DeleteAsync();
                }
            }
        }