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