Beispiel #1
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.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);

                // 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 GetNoRetryClient().CreateReceiver(queueName).ReceiveMessageAsync());
            }
        }
        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.SendMessageAsync(message1);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

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

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

                    Assert.That(
                        async() =>
                        await sender.SendMessageAsync(message2), Throws.InstanceOf <ServiceBusException>());
                    ts.Complete();
                }
            }
        }
        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.SendMessageAsync(message);

                    ts.Complete();
                }

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

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message.Body.ToString(), receivedMessage.Body.ToString());
                await receiver.CompleteMessageAsync(receivedMessage);
            };
        }
Beispiel #4
0
        public async Task CompleteMessageLogsEvents()
        {
            var mockLogger            = new Mock <ServiceBusEventSource>();
            var mockTransportReceiver = new Mock <TransportReceiver>();
            var mockConnection        = GetMockConnection(mockTransportReceiver);
            var receiver = new ServiceBusReceiver(
                mockConnection.Object,
                "queueName",
                false,
                new ServiceBusPlugin[] { },
                new ServiceBusReceiverOptions())
            {
                Logger = mockLogger.Object
            };

            var msg = new ServiceBusReceivedMessage()
            {
                LockTokenGuid = Guid.NewGuid()
            };
            await receiver.CompleteMessageAsync(msg);

            mockLogger
            .Verify(
                log => log.CompleteMessageStart(
                    receiver.Identifier,
                    1,
                    msg.LockToken),
                Times.Once);
            mockLogger
            .Verify(
                log => log.CompleteMessageComplete(
                    receiver.Identifier),
                Times.Once);
        }
Beispiel #5
0
        public async Task CrossEntityTransactionWrongOrder()
        {
            await using var queueA = await ServiceBusScope.CreateWithQueue(enablePartitioning : false, enableSession : false);

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

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

            #region Snippet:ServiceBusCrossEntityTransactionWrongOrder
#if SNIPPET
            string connectionString = "<connection_string>";
            var    options          = new ServiceBusClientOptions {
                EnableCrossEntityTransactions = true
            };
            await using var client = new ServiceBusClient(connectionString, options);

            ServiceBusReceiver receiverA = client.CreateReceiver("queueA");
            ServiceBusSender   senderB   = client.CreateSender("queueB");
            ServiceBusSender   senderC   = client.CreateSender("topicC");
#else
            await using var client = new ServiceBusClient(
                            TestEnvironment.ServiceBusConnectionString,
                            new ServiceBusClientOptions
            {
                EnableCrossEntityTransactions = true
            });

            ServiceBusSender senderA = client.CreateSender(queueA.QueueName);
            await senderA.SendMessageAsync(new ServiceBusMessage());

            ServiceBusReceiver receiverA = client.CreateReceiver(queueA.QueueName);
            ServiceBusSender   senderB   = client.CreateSender(queueB.QueueName);
            ServiceBusSender   senderC   = client.CreateSender(topicC.TopicName);
#endif

            // SenderB becomes the entity through which subsequent "sends" are routed through, since it is the first
            // entity on which an operation is performed with the cross-entity transaction client.
            await senderB.SendMessageAsync(new ServiceBusMessage());

            ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                // This will through an InvalidOperationException because a "receive" cannot be
                // routed through a different entity.
                await receiverA.CompleteMessageAsync(receivedMessage);

                await senderB.SendMessageAsync(new ServiceBusMessage());

                await senderC.SendMessageAsync(new ServiceBusMessage());

                ts.Complete();
            }
            #endregion

            receivedMessage = await receiverA.ReceiveMessageAsync();

            Assert.IsNull(receivedMessage);
        }
        public async Task RoundTripCloudEvent()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                #region Snippet:ServiceBusCloudEvents
#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 payload using the CloudEvent type
                var cloudEvent = new CloudEvent(
                    "/cloudevents/example/source",
                    "Example.Employee",
                    new Employee {
                    Name = "Homer", Age = 39
                });
                ServiceBusMessage message = new ServiceBusMessage(new BinaryData(cloudEvent));

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

                // receive the message
                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

                // deserialize the message body into a CloudEvent
                CloudEvent receivedCloudEvent = CloudEvent.Parse(receivedMessage.Body);

                // deserialize to our Employee model
                Employee receivedEmployee = receivedCloudEvent.Data.ToObjectFromJson <Employee>();

                // prints 'Homer'
                Console.WriteLine(receivedEmployee.Name);

                // prints '39'
                Console.WriteLine(receivedEmployee.Age);

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

                #endregion

                Assert.AreEqual("Homer", receivedEmployee.Name);
                Assert.AreEqual(39, receivedEmployee.Age);
                Assert.IsNull(await CreateNoRetryClient().CreateReceiver(queueName).ReceiveMessageAsync());
            }
        }
        public override async Task RunAsync(CancellationToken cancellationToken)
        {
            await ServiceBusSender.SendMessageAsync(new ServiceBusMessage(_payload));

            var receivedMessage = await ServiceBusReceiver.ReceiveMessageAsync();

            await ServiceBusReceiver.CompleteMessageAsync(receivedMessage);
        }
        public Task CompleteAsync(IEnumerable <ServiceBusReceivedMessage> messages)
        {
            var lockTokens = messages
                             .Where(x => x.LockedUntil > DateTime.UtcNow)
                             .Select(x => _messageReceiver.CompleteMessageAsync(x));

            return(Task.WhenAll(lockTokens));
        }
Beispiel #9
0
        private static async Task ExceedMaxDeliveryAsync(string queueName)
        {
            ServiceBusReceiver receiver = _client.CreateReceiver(queueName);

            while (true)
            {
                // Ask the broker to return any message readily available or return with no
                // result after 2 seconds (allowing for clients with great network latency)
                ServiceBusReceivedMessage msg = await receiver.ReceiveMessageAsync(TimeSpan.FromSeconds(2));

                if (msg != null)
                {
                    // Now we immediately abandon the message, which increments the DeliveryCount
                    Console.WriteLine($"Picked up message: Id = {msg.MessageId}; DeliveryCount {msg.DeliveryCount}");
                    await receiver.AbandonMessageAsync(msg);
                }
                else
                {
                    // Once the system moves the message to the DLQ, the main queue is empty
                    // and the loop exits as ReceiveAsync returns null.
                    break;
                }
            }

            // For picking up the message from a DLQ, we make a receiver just like for a
            // regular queue. We could also use QueueClient and a registered handler here.
            // The required path is constructed with the EntityNameHelper.FormatDeadLetterPath()
            // helper method, and always follows the pattern "{entity}/$DeadLetterQueue",
            // meaning that for a queue "Q1", the path is "Q1/$DeadLetterQueue" and for a
            // topic "T1" and subscription "S1", the path is "T1/Subscriptions/S1/$DeadLetterQueue"
            ServiceBusReceiver deadletterReceiver = _client.CreateReceiver(queueName,
                                                                           new ServiceBusReceiverOptions {
                SubQueue = SubQueue.DeadLetter
            });

            while (true)
            {
                // receive a message
                ServiceBusReceivedMessage message =
                    await deadletterReceiver.ReceiveMessageAsync(TimeSpan.FromSeconds(10));

                if (message != null)
                {
                    // write out the message deadletter information
                    Console.WriteLine("Deadletter message:");
                    Console.WriteLine($"DeadLetterReason = {message.DeadLetterReason}");
                    Console.WriteLine($"DeadLetterErrorDescription = {message.DeadLetterErrorDescription}");

                    // complete and therefore remove the message from the DLQ
                    await deadletterReceiver.CompleteMessageAsync(message);
                }
                else
                {
                    // DLQ was empty on last receive attempt
                    break;
                }
            }
        }
        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.SendMessageAsync(message1);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

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

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

                    await sender.SendMessageAsync(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.CompleteMessageAsync(receivedMessage), Throws.InstanceOf <ServiceBusException>()
                    .And.Property(nameof(ServiceBusException.Reason))
                    .EqualTo(ServiceBusFailureReason.MessageLockLost));

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

                Assert.NotNull(receivedMessage);
                Assert.AreEqual(message2.Body.ToString(), receivedMessage.Body.ToString());
                await receiver.CompleteMessageAsync(receivedMessage);
            }
        }
        public async Task TransactionGroupWrongOrder()
        {
            await using var client = CreateClient();
            await using var queueA = await ServiceBusScope.CreateWithQueue(enablePartitioning : false, enableSession : false);

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

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

            #region Snippet:ServiceBusTransactionGroupWrongOrder
            // The first sender won't be part of our transaction group.
            ServiceBusSender senderA = client.CreateSender(queueA.QueueName);

            string transactionGroup = "myTxn";

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

            var message = new ServiceBusMessage();

            // SenderB becomes the entity through which subsequent "sends" are routed through.
            await senderB.SendMessageAsync(message);

            await senderA.SendMessageAsync(message);

            ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                // This will through an InvalidOperationException because a "receive" cannot be
                // routed through a different entity.
                await receiverA.CompleteMessageAsync(receivedMessage);

                await senderB.SendMessageAsync(message);

                await senderC.SendMessageAsync(message);

                ts.Complete();
            }
            #endregion

            receivedMessage = await receiverA.ReceiveMessageAsync();

            Assert.IsNull(receivedMessage);
        }
Beispiel #12
0
        public async Task TransactionGroupWrongOrder()
        {
            await using var client = new ServiceBusClient(
                            TestEnvironment.ServiceBusConnectionString,
                            new ServiceBusClientOptions
            {
                EnableCrossEntityTransactions = true
            });
            await using var queueA = await ServiceBusScope.CreateWithQueue(enablePartitioning : false, enableSession : false);

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

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

            // The first sender won't be part of our transaction and is
            // used only to populate the queue.
            ServiceBusSender senderA = client.CreateSender(queueA.QueueName);
            await senderA.SendMessageAsync(new ServiceBusMessage());

            ServiceBusReceiver receiverA = client.CreateReceiver(queueA.QueueName);
            ServiceBusSender   senderB   = client.CreateSender(queueB.QueueName);
            ServiceBusSender   senderC   = client.CreateSender(topicC.TopicName);

            #region Snippet:ServiceBusTransactionGroupWrongOrder
            //@@ var options = new ServiceBusClientOptions { EnableCrossEntityTransactions = true };
            //@@ await using var client = new ServiceBusClient(connectionString, options);

            //@@ ServiceBusReceiver receiverA = client.CreateReceiver("queueA");
            //@@ ServiceBusSender senderB = client.CreateSender("queueB");
            //@@ ServiceBusSender senderC = client.CreateSender("topicC");

            // SenderB becomes the entity through which subsequent "sends" are routed through.
            await senderB.SendMessageAsync(new ServiceBusMessage());

            ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                // This will through an InvalidOperationException because a "receive" cannot be
                // routed through a different entity.
                await receiverA.CompleteMessageAsync(receivedMessage);

                await senderB.SendMessageAsync(new ServiceBusMessage());

                await senderC.SendMessageAsync(new ServiceBusMessage());

                ts.Complete();
            }
            #endregion

            receivedMessage = await receiverA.ReceiveMessageAsync();

            Assert.IsNull(receivedMessage);
        }
        private async Task ProcessMessages(string platform, CancellationToken stoppingToken)
        {
            await using ServiceBusReceiver receiver = _sBusClient.CreateReceiver(topicName, platform);

            await foreach (var message in receiver.ReceiveMessagesAsync(stoppingToken))
            {
                _logger.LogInformation("New show message received for {Platform}", platform);
                _logger.LogInformation($"Show Message ID=> {message.MessageId}");
                _logger.LogInformation($"Show Message Body=> {message.Body.ToString()}");
                await receiver.CompleteMessageAsync(message, stoppingToken);
            }
        }
Beispiel #14
0
        public static async Task SafeCompleteMessageAsync(this ServiceBusReceiver messageReceiver, ServiceBusReceivedMessage message, TransportTransactionMode transportTransactionMode, Transaction committableTransaction = null, CancellationToken cancellationToken = default)
        {
            if (transportTransactionMode != TransportTransactionMode.None)
            {
                using (var scope = committableTransaction.ToScope())
                {
                    await messageReceiver.CompleteMessageAsync(message, cancellationToken).ConfigureAwait(false);

                    scope.Complete();
                }
            }
        }
        private async Task ProcessMessages(CancellationToken stoppingToken)
        {
            ServiceBusReceiver receiver = _sBusClient.CreateReceiver(queueName);

            await foreach (var message in receiver.ReceiveMessagesAsync(stoppingToken))
            {
                _logger.LogInformation("Message received");
                _logger.LogInformation($"Message ID=> {message.MessageId}");
                _logger.LogInformation($"Message Body=> {message.Body.ToString()}");
                await receiver.CompleteMessageAsync(message, stoppingToken);
            }
        }
Beispiel #16
0
        public async Task CrossEntityTransaction()
        {
            await using var queueA = await ServiceBusScope.CreateWithQueue(enablePartitioning : false, enableSession : false);

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

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

            #region Snippet:ServiceBusCrossEntityTransaction
#if SNIPPET
            string connectionString = "<connection_string>";
            var    options          = new ServiceBusClientOptions {
                EnableCrossEntityTransactions = true
            };
            await using var client = new ServiceBusClient(connectionString, options);

            ServiceBusReceiver receiverA = client.CreateReceiver("queueA");
            ServiceBusSender   senderB   = client.CreateSender("queueB");
            ServiceBusSender   senderC   = client.CreateSender("topicC");
#else
            await using var client = new ServiceBusClient(
                            TestEnvironment.ServiceBusConnectionString,
                            new ServiceBusClientOptions
            {
                EnableCrossEntityTransactions = true
            });
            ServiceBusSender senderA = client.CreateSender(queueA.QueueName);
            await senderA.SendMessageAsync(new ServiceBusMessage());

            ServiceBusReceiver receiverA = client.CreateReceiver(queueA.QueueName);
            ServiceBusSender   senderB   = client.CreateSender(queueB.QueueName);
            ServiceBusSender   senderC   = client.CreateSender(topicC.TopicName);
#endif

            ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                await receiverA.CompleteMessageAsync(receivedMessage);

                await senderB.SendMessageAsync(new ServiceBusMessage());

                await senderC.SendMessageAsync(new ServiceBusMessage());

                ts.Complete();
            }
            #endregion

            receivedMessage = await receiverA.ReceiveMessageAsync(TimeSpan.FromSeconds(5));

            Assert.IsNull(receivedMessage);
        }
Beispiel #17
0
        public async Task TransactionGroupReceivesFirst(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 topicC = await ServiceBusScope.CreateWithTopic(enablePartitioning : partitioned, enableSession : enableSessions);

            await using var noTxClient = CreateClient();
            var senderA = noTxClient.CreateSender(queueA.QueueName);

            ServiceBusReceiver receiverA = null;

            if (!enableSessions)
            {
                receiverA = client.CreateReceiver(queueA.QueueName);
            }
            var senderB = client.CreateSender(queueB.QueueName);
            var senderC = client.CreateSender(topicC.TopicName);

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

            await senderA.SendMessageAsync(message);

            if (enableSessions)
            {
                receiverA = await client.AcceptNextSessionAsync(queueA.QueueName);
            }

            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 #18
0
        private Task RecieveMessages(ServiceBusReceivedMessage sbMessage, CancellationToken token)
        {
            if (sbMessage.DeliveryCount >= maxDequeueCount)
            {
                return(reciever.DeadLetterMessageAsync(sbMessage, sbMessage.LockToken));
            }

            IActorMessage msg = null;

            if (typeof(MsgType) == typeof(byte[]))
            {
                msg = sbMessage.Body.ToArray().ToActorMessage();
            }
            else if (typeof(MsgType) == typeof(string))
            {
                msg = Encoding.UTF8.GetString(sbMessage.Body.ToArray()).ToActorMessage();
            }
            else
            {
                byte[] msgBytes = sbMessage.Body.ToArray();
                var    t        = Telegraph.Instance.Ask(new DeserializeMessage <MsgType>(msgBytes));
                msg = t.Result as IActorMessage;
            }

            msgQueue.Enqueue(msg);

            if (null == msg.Status)
            {
                msg.Status = new TaskCompletionSource <IActorMessage>();
            }

            // Complete the message so that it is not received again.
            // This can be done only if the queueClient is created in ReceiveMode.PeekLock mode (which is default).
            msg.Status.Task.ContinueWith(p =>
            {
                // Note: Use the cancellationToken passed as necessary to determine if the queueClient has already been closed.
                // If queueClient has already been Closed, you may chose to not call CompleteAsync() or AbandonAsync() etc. calls
                // to avoid unnecessary exceptions.

                if (token.IsCancellationRequested)
                {
                    reciever.AbandonMessageAsync(sbMessage, null, token).Wait();
                }
                else
                {
                    reciever.CompleteMessageAsync(sbMessage, token).Wait();
                }
            });

            return(msg.Status.Task);
        }
        public async Task TransactionGroup()
        {
            await using var client = CreateClient();
            await using var queueA = await ServiceBusScope.CreateWithQueue(enablePartitioning : false, enableSession : false);

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

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

            #region Snippet:ServiceBusTransactionGroup

            // The first sender won't be part of our transaction group.
            ServiceBusSender senderA = client.CreateSender(queueA.QueueName);

            string transactionGroup = "myTxn";

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

            var message = new ServiceBusMessage();

            await senderA.SendMessageAsync(message);

            ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                await receiverA.CompleteMessageAsync(receivedMessage);

                await senderB.SendMessageAsync(message);

                await senderC.SendMessageAsync(message);

                ts.Complete();
            }
            #endregion

            receivedMessage = await receiverA.ReceiveMessageAsync();

            Assert.IsNull(receivedMessage);
        }
        private async Task ReceiveMessages(string subscription)
        {
            await using var client = new ServiceBusClient(ServiceBusConnectionString);
            ServiceBusReceiver receiver = client.CreateReceiver(TopicName, subscription);

            // In reality you would not break out of the loop like in this example but would keep looping. The receiver keeps the connection open
            // to the broker for the specified amount of seconds and the broker returns messages as soon as they arrive. The client then initiates
            // a new connection. So in reality you would not want to break out of the loop.
            // Also note that the code shows how to batch receive, which you would do for performance reasons. For convenience you can also always
            // use the regular receive pump which we show in our Quick Start and in other github samples.
            while (true)
            {
                try
                {
                    //IList<Message> messages = await receiver.ReceiveAsync(10, TimeSpan.FromSeconds(2));
                    // Note the extension class which is serializing an deserializing messages and testing messages is null or 0.
                    // If you think you did not receive all messages, just press M and receive again via the menu.
                    IReadOnlyList <ServiceBusReceivedMessage> messages = await receiver.ReceiveMessagesAsync(maxMessages : 100);

                    if (messages.Any())
                    {
                        foreach (ServiceBusReceivedMessage message in messages)
                        {
                            lock (Console.Out)
                            {
                                Item item = message.As <Item>();
                                IReadOnlyDictionary <string, object> myUserProperties = message.ApplicationProperties;
                                Console.WriteLine($"StoreId={myUserProperties["StoreId"]}");
                                if (message.Subject != null)
                                {
                                    Console.WriteLine($"Subject={message.Subject}");
                                }
                                Console.WriteLine(
                                    $"Item data: Price={item.GetPrice()}, Color={item.GetColor()}, Category={item.GetItemCategory()}");
                            }

                            await receiver.CompleteMessageAsync(message);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
        }
Beispiel #21
0
        public async Task TransactionalSendAndComplete()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false))
            {
                #region Snippet:ServiceBusTransactionalSend
#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
                ServiceBusSender sender = client.CreateSender(queueName);

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

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

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

                    await receiver.CompleteMessageAsync(firstMessage);

                    ts.Complete();
                }
                #endregion

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

                Assert.NotNull(secondMessage);
                await receiver.CompleteMessageAsync(secondMessage);
            };
        }
        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.SendMessageAsync(message1);

                ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();

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

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

                    await sender.SendMessageAsync(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.CompleteMessageAsync(receivedMessage.LockToken);

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

                Assert.Null(receivedMessage);
            }
        }
Beispiel #23
0
        public async Task TransactionGroup()
        {
            await using var client = new ServiceBusClient(
                            TestEnvironment.ServiceBusConnectionString,
                            new ServiceBusClientOptions
            {
                EnableCrossEntityTransactions = true
            });
            await using var queueA = await ServiceBusScope.CreateWithQueue(enablePartitioning : false, enableSession : false);

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

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

            // The first sender won't be part of our transaction and is
            // used only to populate the queue.
            ServiceBusSender senderA = client.CreateSender(queueA.QueueName);
            await senderA.SendMessageAsync(new ServiceBusMessage());

            ServiceBusReceiver receiverA = client.CreateReceiver(queueA.QueueName);
            ServiceBusSender   senderB   = client.CreateSender(queueB.QueueName);
            ServiceBusSender   senderC   = client.CreateSender(topicC.TopicName);

            #region Snippet:ServiceBusTransactionGroup
            //@@ var options = new ServiceBusClientOptions { EnableCrossEntityTransactions = true };
            //@@ await using var client = new ServiceBusClient(connectionString, options);

            //@@ ServiceBusReceiver receiverA = client.CreateReceiver("queueA");
            //@@ ServiceBusSender senderB = client.CreateSender("queueB");
            //@@ ServiceBusSender senderC = client.CreateSender("topicC");

            ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                await receiverA.CompleteMessageAsync(receivedMessage);

                await senderB.SendMessageAsync(new ServiceBusMessage());

                await senderC.SendMessageAsync(new ServiceBusMessage());

                ts.Complete();
            }
            #endregion

            receivedMessage = await receiverA.ReceiveMessageAsync();

            Assert.IsNull(receivedMessage);
        }
        public async Task ForwardingEntity()
        {
            // queueName--Fwd to--> destinationName--fwd dlq to-- > dqlDestinationName
            var queueName          = Recording.Random.NewGuid().ToString("D").Substring(0, 8);
            var destinationName    = Recording.Random.NewGuid().ToString("D").Substring(0, 8);
            var dlqDestinationName = Recording.Random.NewGuid().ToString("D").Substring(0, 8);
            var mgmtClient         = CreateClient();

            await mgmtClient.CreateQueueAsync(dlqDestinationName);

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

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

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

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

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

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

            Assert.NotNull(msg);
            Assert.AreEqual("mid", msg.MessageId);
            await receiver.CompleteMessageAsync(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.SendMessageAsync(new ServiceBusMessage(Encoding.UTF8.GetBytes("First")));

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

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

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

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

                    ts.Complete();
                }
                #endregion

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

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

                Assert.NotNull(secondMessage);
                await receiverB.CompleteMessageAsync(secondMessage);
            };
        }
Beispiel #26
0
            public static async Task TopicNoSessions(
                [ServiceBusTrigger(TopicNameKey, FirstSubscriptionNameKey)] ServiceBusReceivedMessage msg,
                ServiceBusReceiver messageReceiver,
                CancellationToken cancellationToken,
                ILogger logger)
            {
                logger.LogInformation($"DrainModeValidationFunctions.NoSessions: message data {msg.Body}");
                _drainValidationPreDelay.Set();
                await DrainModeHelper.WaitForCancellation(cancellationToken);

                Assert.True(cancellationToken.IsCancellationRequested);
                await messageReceiver.CompleteMessageAsync(msg);

                _drainValidationPostDelay.Set();
            }
        public async Task ReceiveMessagesWhenQueueEmpty()
        {
            await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true))
            {
                await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString, new ServiceBusClientOptions
                {
                    RetryOptions =
                    {
                        // very high TryTimeout
                        TryTimeout = TimeSpan.FromSeconds(120)
                    }
                });

                var messageCount        = 2;
                var sessionId           = "sessionId1";
                ServiceBusSender sender = client.CreateSender(scope.QueueName);
                using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync();

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

                ServiceBusReceiver receiver = await client.AcceptNextSessionAsync(
                    scope.QueueName,
                    new ServiceBusSessionReceiverOptions
                {
                    PrefetchCount = 100
                });

                var remainingMessages = messageCount;
                while (remainingMessages > 0)
                {
                    foreach (var message in await receiver.ReceiveMessagesAsync(remainingMessages))
                    {
                        await receiver.CompleteMessageAsync(message);

                        remainingMessages--;
                    }
                }

                using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));

                var start = DateTime.UtcNow;
                Assert.ThrowsAsync <TaskCanceledException>(async() => await receiver.ReceiveMessagesAsync(1, cancellationToken: cancellationTokenSource.Token));
                var stop = DateTime.UtcNow;

                Assert.That(stop - start, Is.EqualTo(TimeSpan.FromSeconds(3)).Within(TimeSpan.FromSeconds(3)));
            }
        }
 ///<inheritdoc cref="ServiceBusReceiver.CompleteMessageAsync(ServiceBusReceivedMessage, CancellationToken)"/>
 public virtual async Task CompleteMessageAsync(
     ServiceBusReceivedMessage message,
     CancellationToken cancellationToken = default)
 {
     if (_receiver != null)
     {
         await _receiver.CompleteMessageAsync(message, cancellationToken).ConfigureAwait(false);
     }
     else if (_eventArgs != null)
     {
         await _eventArgs.CompleteMessageAsync(message, cancellationToken).ConfigureAwait(false);
     }
     else
     {
         await _sessionEventArgs.CompleteMessageAsync(message, cancellationToken).ConfigureAwait(false);
     }
 }
Beispiel #29
0
        /// <summary>
        /// Delete Messages
        /// </summary>
        /// <returns></returns>
        public async Task DeleteMessagesAsync()
        {
            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"));
                ServiceBusReceivedMessage peekedMessage = await receiver.ReceiveMessageAsync();

                await receiver.CompleteMessageAsync(peekedMessage);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
Beispiel #30
0
            public static async Task TopicNoSessionsBatch(
                [ServiceBusTrigger(TopicNameKey, FirstSubscriptionNameKey)] ServiceBusReceivedMessage[] array,
                ServiceBusReceiver messageReceiver,
                CancellationToken cancellationToken,
                ILogger logger)
            {
                Assert.True(array.Length > 0);
                logger.LogInformation($"DrainModeTestJobBatch.TopicNoSessionsBatch: received {array.Length} messages");
                _drainValidationPreDelay.Set();
                await DrainModeHelper.WaitForCancellation(cancellationToken);

                Assert.True(cancellationToken.IsCancellationRequested);
                foreach (ServiceBusReceivedMessage msg in array)
                {
                    await messageReceiver.CompleteMessageAsync(msg);
                }
                _drainValidationPostDelay.Set();
            }