///<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 UserSettledPropertySetCorrectly() { var msg = new ServiceBusReceivedMessage(); var args = new ProcessMessageEventArgs( msg, new Mock <ServiceBusReceiver>().Object, CancellationToken.None); Assert.IsFalse(msg.IsSettled); msg.IsSettled = false; await args.AbandonMessageAsync(msg); Assert.IsTrue(msg.IsSettled); await args.CompleteMessageAsync(msg); Assert.IsTrue(msg.IsSettled); msg.IsSettled = false; await args.DeadLetterMessageAsync(msg); Assert.IsTrue(msg.IsSettled); msg.IsSettled = false; await args.DeadLetterMessageAsync(msg, "reason"); Assert.IsTrue(msg.IsSettled); msg.IsSettled = false; await args.DeferMessageAsync(msg); Assert.IsTrue(msg.IsSettled); }
private async Task MessageHandler(ProcessMessageEventArgs args) { try { _logger.LogInformation($"client '{_systemInfo.ClientId}' received message '{args.Message.MessageId}'. Processing..."); var message = await _messageParser.DeserializeAsync <TM>(args.Message.Body); await _messageProcessor.ProcessAsync((dynamic)message, args.CancellationToken); await args.CompleteMessageAsync(args.Message).ConfigureAwait(false); } catch (Exception ex) { _logger.LogError(ex, $"an error has occurred while processing message '{args.Message.MessageId}': {ex.Message}"); if (args.Message.DeliveryCount > 3) { await args.DeadLetterMessageAsync(args.Message).ConfigureAwait(false); } else { await args.AbandonMessageAsync(args.Message).ConfigureAwait(false); } } }
private async Task MessageHandlerAsync(ProcessMessageEventArgs arg) { var message = arg.Message; var body = Encoding.UTF8.GetString(message.Body.ToArray()); var data = JsonSerializer.Deserialize <TEntity>(body, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); if (ValidateMessage(data)) { if (await ProcessDataAsync(data).ConfigureAwait(false)) { // Now that we're done with "processing" the message, we tell the broker about that being the // case. The MessageReceiver.CompleteAsync operation will settle the message transfer with // the broker and remove it from the broker. await arg.CompleteMessageAsync(message) .ConfigureAwait(false); } else { // If the message does not meet our processing criteria, we will dead letter it, meaning // it is put into a special queue for handling defective messages. The broker will automatically // dead letter the message, if delivery has been attempted too many times. await arg.DeadLetterMessageAsync(message) .ConfigureAwait(false); } } }
private async Task OnMessageReceivedAsync <TEvent, TConsumer>(EventRegistration ereg, EventConsumerRegistration creg, ProcessMessageEventArgs args) where TEvent : class where TConsumer : IEventConsumer <TEvent> { var message = args.Message; var messageId = message.MessageId; var cancellationToken = args.CancellationToken; message.ApplicationProperties.TryGetValue(AttributeNames.ActivityId, out var parentActivityId); using var log_scope = Logger.BeginScopeForConsume(id: messageId, correlationId: message.CorrelationId, sequenceNumber: message.SequenceNumber, extras: new Dictionary <string, string> { ["EnqueuedSequenceNumber"] = message.EnqueuedSequenceNumber.ToString(), }); // Instrumentation using var activity = EventBusActivitySource.StartActivity(ActivityNames.Consume, ActivityKind.Consumer, parentActivityId?.ToString()); activity?.AddTag(ActivityTagNames.EventBusEventType, typeof(TEvent).FullName); activity?.AddTag(ActivityTagNames.EventBusConsumerType, typeof(TConsumer).FullName); activity?.AddTag(ActivityTagNames.MessagingSystem, Name); var destination = TransportOptions.UseBasicTier || ereg.UseQueueInsteadOfTopic() ? ereg.EventName : creg.ConsumerName; activity?.AddTag(ActivityTagNames.MessagingDestination, destination); // name of the queue/subscription activity?.AddTag(ActivityTagNames.MessagingDestinationKind, "queue"); // the spec does not know subscription so we can only use queue for both try { Logger.LogDebug("Processing '{MessageId}'", messageId); using var scope = CreateScope(); using var ms = message.Body.ToStream(); var contentType = new ContentType(message.ContentType); var context = await DeserializeAsync <TEvent>(body : ms, contentType : contentType, registration : ereg, scope : scope, cancellationToken : cancellationToken); Logger.LogInformation("Received message: '{MessageId}' containing Event '{Id}'", messageId, context.Id); await ConsumeAsync <TEvent, TConsumer>(@event : context, scope : scope, cancellationToken : cancellationToken); // Complete the message Logger.LogDebug("Completing message: {MessageId}.", messageId); await args.CompleteMessageAsync(message : message, cancellationToken : cancellationToken); } catch (Exception ex) { Logger.LogError(ex, "Event processing failed. Moving to deadletter."); await args.DeadLetterMessageAsync(message : message, cancellationToken : cancellationToken); } }
private async Task MessageHandler(ProcessMessageEventArgs args) { try { var message = _messageParser.Resolve <TM>(args.Message.Body); await _messageProcessor.ProcessAsync((dynamic)message, args.CancellationToken); await args.CompleteMessageAsync(args.Message).ConfigureAwait(false); } catch (Exception ex) { _logger.LogError(ex, $"an error has occurred while processing message '{args.Message.MessageId}': {ex.Message}"); if (args.Message.DeliveryCount > 3) { await args.DeadLetterMessageAsync(args.Message).ConfigureAwait(false); } else { await args.AbandonMessageAsync(args.Message).ConfigureAwait(false); } } }
public void UserSettledPropertySetCorrectlyOnException() { var msg = new ServiceBusReceivedMessage(); var mockReceiver = new Mock <ServiceBusReceiver>(); mockReceiver .Setup(receiver => receiver.AbandonMessageAsync( It.IsAny <ServiceBusReceivedMessage>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <CancellationToken>())) .Throws(new Exception()); mockReceiver .Setup(receiver => receiver.DeferMessageAsync( It.IsAny <ServiceBusReceivedMessage>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <CancellationToken>())) .Throws(new Exception()); mockReceiver .Setup(receiver => receiver.CompleteMessageAsync( It.IsAny <ServiceBusReceivedMessage>(), It.IsAny <CancellationToken>())) .Throws(new Exception()); mockReceiver .Setup(receiver => receiver.DeadLetterMessageAsync( It.IsAny <ServiceBusReceivedMessage>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <CancellationToken>())) .Throws(new Exception()); mockReceiver .Setup(receiver => receiver.DeadLetterMessageAsync( It.IsAny <ServiceBusReceivedMessage>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Throws(new Exception()); var args = new ProcessMessageEventArgs( msg, mockReceiver.Object, CancellationToken.None); Assert.IsFalse(msg.IsSettled); msg.IsSettled = false; Assert.That(async() => await args.AbandonMessageAsync(msg), Throws.InstanceOf <Exception>()); Assert.IsFalse(msg.IsSettled); Assert.That(async() => await args.CompleteMessageAsync(msg), Throws.InstanceOf <Exception>()); Assert.IsFalse(msg.IsSettled); msg.IsSettled = false; Assert.That(async() => await args.DeadLetterMessageAsync(msg), Throws.InstanceOf <Exception>()); Assert.IsFalse(msg.IsSettled); msg.IsSettled = false; Assert.That(async() => await args.DeadLetterMessageAsync(msg, "reason"), Throws.InstanceOf <Exception>()); Assert.IsFalse(msg.IsSettled); msg.IsSettled = false; Assert.That(async() => await args.DeferMessageAsync(msg), Throws.InstanceOf <Exception>()); Assert.IsFalse(msg.IsSettled); }
public static Task DeadLetterByDeliveryLimitAsync(this ServiceBusReceivedMessage message, ProcessMessageEventArgs client, int deliveryLimit) { return(client.DeadLetterMessageAsync(message, "MaxDeliveryCountExceeded", $"DeliveryCount exceeded limit of {deliveryLimit}")); }