///<inheritdoc cref="ServiceBusReceiver.DeadLetterMessageAsync(ServiceBusReceivedMessage, string, string, CancellationToken)"/> public virtual async Task DeadLetterMessageAsync( ServiceBusReceivedMessage message, string deadLetterReason, string deadLetterErrorDescription = default, CancellationToken cancellationToken = default) { if (_receiver != null) { await _receiver.DeadLetterMessageAsync( message, deadLetterReason, deadLetterErrorDescription, cancellationToken) .ConfigureAwait(false); } else if (_eventArgs != null) { await _eventArgs.DeadLetterMessageAsync( message, deadLetterReason, deadLetterErrorDescription, cancellationToken) .ConfigureAwait(false); } else { await _sessionEventArgs.DeadLetterMessageAsync( message, deadLetterReason, deadLetterErrorDescription, cancellationToken) .ConfigureAwait(false); } }
public async Task DeadLetterMessageLogsEvents() { 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.DeadLetterMessageAsync(msg); mockLogger .Verify( log => log.DeadLetterMessageStart( receiver.Identifier, 1, msg.LockToken), Times.Once); mockLogger .Verify( log => log.DeadLetterMessageComplete( receiver.Identifier), Times.Once); }
public async Task DeadLetterMessage() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false)) { string connectionString = TestEnvironment.ServiceBusConnectionString; string queueName = scope.QueueName; // since ServiceBusClient implements IAsyncDisposable we create it with "await using" await using var client = new ServiceBusClient(connectionString); // create the sender ServiceBusSender sender = client.CreateSender(queueName); // create a message that we can send ServiceBusMessage message = new ServiceBusMessage(Encoding.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:ServiceBusDeadLetterMessage ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync(); // deadletter 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.CreateDeadLetterReceiver(queueName); ServiceBusReceivedMessage dlqMessage = await dlqReceiver.ReceiveMessageAsync(); #endregion Assert.IsNotNull(dlqMessage); } }
public Task DeadLetterAsync(IEnumerable <ServiceBusReceivedMessage> messages) { var tasks = messages .Where(x => x.LockedUntil > DateTime.UtcNow) .Select(x => _messageReceiver.DeadLetterMessageAsync(x)); return(Task.WhenAll(tasks)); }
public static async Task DeadLetterMessageAsync(string connectionString, string queueName) { await using var client = new ServiceBusClient(connectionString); // create a receiver that we can use to receive the message ServiceBusReceiver receiver = client.CreateReceiver(queueName); 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); }
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 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 void DeadLetterMessageExceptionLogsEvents() { var mockLogger = new Mock <ServiceBusEventSource>(); var mockTransportReceiver = new Mock <TransportReceiver>(); var mockConnection = GetMockConnection(mockTransportReceiver); mockTransportReceiver.Setup( transportReceiver => transportReceiver.DeadLetterAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <CancellationToken>())) .Throws(new Exception()); var receiver = new ServiceBusReceiver( mockConnection.Object, "queueName", false, new ServiceBusPlugin[] { }, new ServiceBusReceiverOptions()) { Logger = mockLogger.Object }; var msg = new ServiceBusReceivedMessage() { LockTokenGuid = Guid.NewGuid() }; Assert.That( async() => await receiver.DeadLetterMessageAsync(msg), Throws.InstanceOf <Exception>()); mockLogger .Verify( log => log.DeadLetterMessageStart( receiver.Identifier, 1, msg.LockToken), Times.Once); mockLogger .Verify( log => log.DeadLetterMessageException( receiver.Identifier, It.IsAny <string>()), Times.Once); }
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 Run([TimerTrigger("*/10 * * * * *")] TimerInfo myTimer, ILogger log) { Stopwatch runStopwatch = new Stopwatch(); runStopwatch.Start(); string runId = Guid.NewGuid().ToString(); log.LogInformation($"TimersSubmissionConsumer function executing: {runId}"); ServiceBusReceiver serviceBusReceiver = _submissionServiceBusService.SubmissionServiceBusClient.CreateReceiver("submission"); var messages = await _submissionServiceBusService.ReceiveMessagesAsync(serviceBusReceiver); log.LogInformation($"Received message count: {messages.Count} : {runId}"); foreach (var message in messages) { Stopwatch stopStopwatch = new Stopwatch(); stopStopwatch.Start(); await serviceBusReceiver.RenewMessageLockAsync(message); SubmissionMessage submissionMessage = DeserializeQueueItem(log, Encoding.UTF8.GetString(message.Body)); if (submissionMessage == null) { await serviceBusReceiver.DeadLetterMessageAsync(message); continue; } // Get Stop Stop stop = await GetStop(log, submissionMessage.StopId, runId); if (stop == null) { log.LogWarning($"Failed to find stop: {submissionMessage.StopId} : {runId}"); await serviceBusReceiver.AbandonMessageAsync(message); // allows for retry to occur. continue; } DateTime dateSubmitted = DateTime.UtcNow; // Get File Name string fileName = GetFileName(log, submissionMessage.SubmissionId, dateSubmitted, stop.Ori, stop.Id, runId); log.LogInformation($"Using filename: {fileName} : {runId}"); if (fileName == null) { await serviceBusReceiver.AbandonMessageAsync(message); // allows for retry to occur. continue; } // Get Doj Stop DojStop dojStop = GetDojStop(log, stop, runId); if (dojStop == null) { // if the cast error fails report, retry the message if (!await HandledDojCastError(log, stop, dateSubmitted, fileName, submissionMessage.SubmissionId, runId)) { await serviceBusReceiver.AbandonMessageAsync(message); // allows for retry to occur. continue; } else { await serviceBusReceiver.CompleteMessageAsync(message); // message complete continue; } } //Get File Bytes byte[] bytes = GetFileBytes(log, dojStop, runId); if (bytes == null) { log.LogWarning($"Failed to get file contents: {dojStop.LEARecordID} : {runId}"); await serviceBusReceiver.AbandonMessageAsync(message); // allows for retry to occur. continue; } //Upload Blob if (!await UploadBlob(log, bytes, fileName, stop.Id, runId)) { log.LogWarning($"Failed to upload blob: {stop.Id} : {runId}"); await serviceBusReceiver.AbandonMessageAsync(message); // allows for retry to occur. continue; } if (!await UploadSftpFile(log, bytes, fileName, stop.Id, runId, stop)) { log.LogWarning($"Failed to upload to FTP: {stop.Id} : {runId}"); await RemoveBlob(log, fileName, stop.Id, runId); // delete the blob to clean up the failed run await serviceBusReceiver.AbandonMessageAsync(message); // allows for retry to occur. continue; } if (!await HandleDojSubmitSuccess(log, stop, dateSubmitted, submissionMessage.SubmissionId, fileName, runId)) { log.LogWarning($"Failed to handle doj submit success: {stop.Id} : {runId}"); RemoveSftpFile(log, fileName, stop.Id, runId); // remove the file from the SFTP server so it doesnt get duplicated. await serviceBusReceiver.AbandonMessageAsync(message); // allows for retry to occur. continue; } await serviceBusReceiver.CompleteMessageAsync(message); // message complete stopStopwatch.Stop(); log.LogInformation($"Finished processing STOP : {stop.Id} : {stopStopwatch.ElapsedMilliseconds} : {runId}"); } runStopwatch.Stop(); log.LogInformation($"TimersSubmissionConsumer finished: {runStopwatch.ElapsedMilliseconds} : {runId}"); }
public async Task SenderReceiverActivities(bool useSessions) { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: useSessions)) { var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.QueueName); string sessionId = null; if (useSessions) { sessionId = "sessionId"; } int numMessages = 5; var msgs = ServiceBusTestUtilities.GetMessages(numMessages, sessionId); await sender.SendMessagesAsync(msgs); Activity[] sendActivities = AssertSendActivities(useSessions, sender, msgs); ServiceBusReceiver receiver = null; if (useSessions) { receiver = await client.AcceptNextSessionAsync(scope.QueueName); } else { receiver = client.CreateReceiver(scope.QueueName); } var remaining = numMessages; List <ServiceBusReceivedMessage> receivedMsgs = new List <ServiceBusReceivedMessage>(); while (remaining > 0) { // loop in case we don't receive all messages in one attempt var received = await receiver.ReceiveMessagesAsync(remaining); receivedMsgs.AddRange(received); var receiveScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveActivityName); AssertCommonTags(receiveScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var receiveLinkedActivities = receiveScope.LinkedActivities; for (int i = 0; i < receiveLinkedActivities.Count; i++) { Assert.AreEqual(sendActivities[i].ParentId, receiveLinkedActivities[i].ParentId); } remaining -= received.Count; } var msgIndex = 0; var completed = receivedMsgs[msgIndex]; await receiver.CompleteMessageAsync(completed); var completeScope = _listener.AssertAndRemoveScope(DiagnosticProperty.CompleteActivityName); AssertCommonTags(completeScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var deferred = receivedMsgs[++msgIndex]; await receiver.DeferMessageAsync(deferred); var deferredScope = _listener.AssertAndRemoveScope(DiagnosticProperty.DeferActivityName); AssertCommonTags(deferredScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var deadLettered = receivedMsgs[++msgIndex]; await receiver.DeadLetterMessageAsync(deadLettered); var deadLetterScope = _listener.AssertAndRemoveScope(DiagnosticProperty.DeadLetterActivityName); AssertCommonTags(deadLetterScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var abandoned = receivedMsgs[++msgIndex]; await receiver.AbandonMessageAsync(abandoned); var abandonScope = _listener.AssertAndRemoveScope(DiagnosticProperty.AbandonActivityName); AssertCommonTags(abandonScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var receiveDeferMsg = await receiver.ReceiveDeferredMessageAsync(deferred.SequenceNumber); var receiveDeferScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveDeferredActivityName); AssertCommonTags(receiveDeferScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); // renew lock if (useSessions) { var sessionReceiver = (ServiceBusSessionReceiver)receiver; await sessionReceiver.RenewSessionLockAsync(); var renewSessionScope = _listener.AssertAndRemoveScope(DiagnosticProperty.RenewSessionLockActivityName); AssertCommonTags(renewSessionScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); // set state var state = new BinaryData("state"); await sessionReceiver.SetSessionStateAsync(state); var setStateScope = _listener.AssertAndRemoveScope(DiagnosticProperty.SetSessionStateActivityName); AssertCommonTags(setStateScope.Activity, sessionReceiver.EntityPath, sessionReceiver.FullyQualifiedNamespace); // get state var getState = await sessionReceiver.GetSessionStateAsync(); Assert.AreEqual(state.ToArray(), getState.ToArray()); var getStateScope = _listener.AssertAndRemoveScope(DiagnosticProperty.GetSessionStateActivityName); AssertCommonTags(getStateScope.Activity, sessionReceiver.EntityPath, sessionReceiver.FullyQualifiedNamespace); } else { await receiver.RenewMessageLockAsync(receivedMsgs[4]); var renewMessageScope = _listener.AssertAndRemoveScope(DiagnosticProperty.RenewMessageLockActivityName); AssertCommonTags(renewMessageScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); } // schedule msgs = ServiceBusTestUtilities.GetMessages(numMessages, sessionId); foreach (var msg in msgs) { var seq = await sender.ScheduleMessageAsync(msg, DateTimeOffset.UtcNow.AddMinutes(1)); Assert.IsNotNull(msg.ApplicationProperties[DiagnosticProperty.DiagnosticIdAttribute]); var messageScope = _listener.AssertAndRemoveScope(DiagnosticProperty.MessageActivityName); AssertCommonTags(messageScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace); var scheduleScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ScheduleActivityName); AssertCommonTags(scheduleScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace); var linkedActivities = scheduleScope.LinkedActivities; Assert.AreEqual(1, linkedActivities.Count); Assert.AreEqual(messageScope.Activity.Id, linkedActivities[0].ParentId); await sender.CancelScheduledMessageAsync(seq); var cancelScope = _listener.AssertAndRemoveScope(DiagnosticProperty.CancelActivityName); AssertCommonTags(cancelScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace); } // send a batch var batch = await sender.CreateMessageBatchAsync(); for (int i = 0; i < numMessages; i++) { batch.TryAddMessage(ServiceBusTestUtilities.GetMessage(sessionId)); } await sender.SendMessagesAsync(batch); AssertSendActivities(useSessions, sender, batch.AsReadOnly <ServiceBusMessage>()); }; }
public async Task SenderReceiverActivities(bool useSessions) { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: useSessions)) { using var listener = new TestDiagnosticListener(EntityScopeFactory.DiagnosticNamespace); var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.QueueName); string sessionId = null; if (useSessions) { sessionId = "sessionId"; } int numMessages = 5; var msgs = GetMessages(numMessages, sessionId); await sender.SendMessagesAsync(msgs); Activity[] sendActivities = AssertSendActivities(useSessions, sender, msgs, listener); ServiceBusReceiver receiver = null; if (useSessions) { receiver = await client.CreateSessionReceiverAsync(scope.QueueName); } else { receiver = client.CreateReceiver(scope.QueueName); } var remaining = numMessages; List <ServiceBusReceivedMessage> receivedMsgs = new List <ServiceBusReceivedMessage>(); while (remaining > 0) { // loop in case we don't receive all messages in one attempt var received = await receiver.ReceiveMessagesAsync(remaining); receivedMsgs.AddRange(received); (string Key, object Value, DiagnosticListener)receiveStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.ReceiveActivityName + ".Start", receiveStart.Key); Activity receiveActivity = (Activity)receiveStart.Value; AssertCommonTags(receiveActivity, receiver.EntityPath, receiver.FullyQualifiedNamespace); CollectionAssert.Contains( receiveActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.RequestedMessageCountAttribute, remaining.ToString())); CollectionAssert.Contains( receiveActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.MessageIdAttribute, string.Join(",", received.Select(m => m.MessageId).ToArray()))); remaining -= received.Count; if (useSessions) { CollectionAssert.Contains( receiveActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.SessionIdAttribute, string.Join(",", msgs.Select(m => m.SessionId).Distinct().ToArray()))); } var receiveLinkedActivities = ((IEnumerable <Activity>)receiveActivity.GetType().GetProperty("Links").GetValue(receiveActivity)).ToArray(); for (int i = 0; i < receiveLinkedActivities.Length; i++) { Assert.AreEqual(sendActivities[i].ParentId, receiveLinkedActivities[i].ParentId); } (string Key, object Value, DiagnosticListener)receiveStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.ReceiveActivityName + ".Stop", receiveStop.Key); } var msgIndex = 0; var completed = receivedMsgs[msgIndex]; await receiver.CompleteMessageAsync(completed); (string Key, object Value, DiagnosticListener)completeStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.CompleteActivityName + ".Start", completeStart.Key); Activity completeActivity = (Activity)completeStart.Value; AssertCommonTags(completeActivity, receiver.EntityPath, receiver.FullyQualifiedNamespace); AssertLockTokensTag(completeActivity, completed.LockToken); (string Key, object Value, DiagnosticListener)completeStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.CompleteActivityName + ".Stop", completeStop.Key); var deferred = receivedMsgs[++msgIndex]; await receiver.DeferMessageAsync(deferred); (string Key, object Value, DiagnosticListener)deferStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.DeferActivityName + ".Start", deferStart.Key); Activity deferActivity = (Activity)deferStart.Value; AssertCommonTags(deferActivity, receiver.EntityPath, receiver.FullyQualifiedNamespace); AssertLockTokensTag(deferActivity, deferred.LockToken); (string Key, object Value, DiagnosticListener)deferStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.DeferActivityName + ".Stop", deferStop.Key); var deadLettered = receivedMsgs[++msgIndex]; await receiver.DeadLetterMessageAsync(deadLettered); (string Key, object Value, DiagnosticListener)deadLetterStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.DeadLetterActivityName + ".Start", deadLetterStart.Key); Activity deadLetterActivity = (Activity)deadLetterStart.Value; AssertCommonTags(deadLetterActivity, receiver.EntityPath, receiver.FullyQualifiedNamespace); AssertLockTokensTag(deadLetterActivity, deadLettered.LockToken); (string Key, object Value, DiagnosticListener)deadletterStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.DeadLetterActivityName + ".Stop", deadletterStop.Key); var abandoned = receivedMsgs[++msgIndex]; await receiver.AbandonMessageAsync(abandoned); (string Key, object Value, DiagnosticListener)abandonStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.AbandonActivityName + ".Start", abandonStart.Key); Activity abandonActivity = (Activity)abandonStart.Value; AssertCommonTags(abandonActivity, receiver.EntityPath, receiver.FullyQualifiedNamespace); AssertLockTokensTag(abandonActivity, abandoned.LockToken); (string Key, object Value, DiagnosticListener)abandonStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.AbandonActivityName + ".Stop", abandonStop.Key); var receiveDeferMsg = await receiver.ReceiveDeferredMessageAsync(deferred.SequenceNumber); (string Key, object Value, DiagnosticListener)receiveDeferStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.ReceiveDeferredActivityName + ".Start", receiveDeferStart.Key); Activity receiveDeferActivity = (Activity)receiveDeferStart.Value; AssertCommonTags(receiveDeferActivity, receiver.EntityPath, receiver.FullyQualifiedNamespace); CollectionAssert.Contains( receiveDeferActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.MessageIdAttribute, deferred.MessageId)); CollectionAssert.Contains( receiveDeferActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.SequenceNumbersAttribute, deferred.SequenceNumber.ToString())); (string Key, object Value, DiagnosticListener)receiveDeferStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.ReceiveDeferredActivityName + ".Stop", receiveDeferStop.Key); // renew lock if (useSessions) { var sessionReceiver = (ServiceBusSessionReceiver)receiver; await sessionReceiver.RenewSessionLockAsync(); (string Key, object Value, DiagnosticListener)renewStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.RenewSessionLockActivityName + ".Start", renewStart.Key); Activity renewActivity = (Activity)renewStart.Value; AssertCommonTags(renewActivity, receiver.EntityPath, receiver.FullyQualifiedNamespace); CollectionAssert.Contains( renewActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.SessionIdAttribute, "sessionId")); (string Key, object Value, DiagnosticListener)renewStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.RenewSessionLockActivityName + ".Stop", renewStop.Key); // set state var state = Encoding.UTF8.GetBytes("state"); await sessionReceiver.SetSessionStateAsync(state); (string Key, object Value, DiagnosticListener)setStateStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.SetSessionStateActivityName + ".Start", setStateStart.Key); Activity setStateActivity = (Activity)setStateStart.Value; AssertCommonTags(setStateActivity, sessionReceiver.EntityPath, sessionReceiver.FullyQualifiedNamespace); CollectionAssert.Contains( setStateActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.SessionIdAttribute, "sessionId")); (string Key, object Value, DiagnosticListener)setStateStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.SetSessionStateActivityName + ".Stop", setStateStop.Key); // get state var getState = await sessionReceiver.GetSessionStateAsync(); Assert.AreEqual(state, getState); (string Key, object Value, DiagnosticListener)getStateStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.GetSessionStateActivityName + ".Start", getStateStart.Key); Activity getStateActivity = (Activity)getStateStart.Value; AssertCommonTags(getStateActivity, sessionReceiver.EntityPath, sessionReceiver.FullyQualifiedNamespace); CollectionAssert.Contains( getStateActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.SessionIdAttribute, "sessionId")); (string Key, object Value, DiagnosticListener)getStateStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.GetSessionStateActivityName + ".Stop", getStateStop.Key); } else { await receiver.RenewMessageLockAsync(receivedMsgs[4]); (string Key, object Value, DiagnosticListener)renewStart = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.RenewMessageLockActivityName + ".Start", renewStart.Key); Activity renewActivity = (Activity)renewStart.Value; AssertCommonTags(renewActivity, receiver.EntityPath, receiver.FullyQualifiedNamespace); AssertLockTokensTag(renewActivity, receivedMsgs[4].LockToken); CollectionAssert.Contains( renewActivity.Tags, new KeyValuePair <string, string>( DiagnosticProperty.LockedUntilAttribute, receivedMsgs[4].LockedUntil.ToString())); (string Key, object Value, DiagnosticListener)renewStop = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.RenewMessageLockActivityName + ".Stop", renewStop.Key); } // schedule msgs = GetMessages(numMessages, sessionId); foreach (var msg in msgs) { var seq = await sender.ScheduleMessageAsync(msg, DateTimeOffset.UtcNow.AddMinutes(1)); Assert.IsNotNull(msg.Properties[DiagnosticProperty.DiagnosticIdAttribute]); (string Key, object Value, DiagnosticListener)startMessage = listener.Events.Dequeue(); Activity messageActivity = (Activity)startMessage.Value; AssertCommonTags(messageActivity, sender.EntityPath, sender.FullyQualifiedNamespace); Assert.AreEqual(DiagnosticProperty.MessageActivityName + ".Start", startMessage.Key); (string Key, object Value, DiagnosticListener)stopMessage = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.MessageActivityName + ".Stop", stopMessage.Key); (string Key, object Value, DiagnosticListener)startSchedule = listener.Events.Dequeue(); AssertCommonTags((Activity)startSchedule.Value, sender.EntityPath, sender.FullyQualifiedNamespace); Assert.AreEqual(DiagnosticProperty.ScheduleActivityName + ".Start", startSchedule.Key); (string Key, object Value, DiagnosticListener)stopSchedule = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.ScheduleActivityName + ".Stop", stopSchedule.Key); var linkedActivities = ((IEnumerable <Activity>)startSchedule.Value.GetType().GetProperty("Links").GetValue(startSchedule.Value)).ToArray(); Assert.AreEqual(1, linkedActivities.Length); Assert.AreEqual(messageActivity.Id, linkedActivities[0].ParentId); await sender.CancelScheduledMessageAsync(seq); (string Key, object Value, DiagnosticListener)startCancel = listener.Events.Dequeue(); AssertCommonTags((Activity)startCancel.Value, sender.EntityPath, sender.FullyQualifiedNamespace); Assert.AreEqual(DiagnosticProperty.CancelActivityName + ".Start", startCancel.Key); (string Key, object Value, DiagnosticListener)stopCancel = listener.Events.Dequeue(); Assert.AreEqual(DiagnosticProperty.CancelActivityName + ".Stop", stopCancel.Key); } // send a batch var batch = await sender.CreateMessageBatchAsync(); for (int i = 0; i < numMessages; i++) { batch.TryAddMessage(GetMessage(sessionId)); } await sender.SendMessagesAsync(batch); AssertSendActivities(useSessions, sender, batch.AsEnumerable <ServiceBusMessage>(), listener); }; }
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 DeadLetter(string lockToken) { await _messageReceiver.DeadLetterMessageAsync(CreateMessageShiv(lockToken)); }