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