public async Task <bool> DeadletterMessageAsync(MessageBrokerContext context, TransactionContext transactionContext, string deadLetterReason, string deadLetterErrorDescription, CancellationToken cancellationToken) { ReceivedMessage msg = null; if (!context?.Container.TryGet(out msg) ?? false) { throw new ArgumentException($"Unable to deadletter message. No {nameof(ReceivedMessage)} contained in {nameof(context)}.", nameof(msg)); } transactionContext.Container.TryGet <SqlConnection>(out var connection); transactionContext.Container.TryGet <SqlTransaction>(out var transaction); try { var edc = new EndDialogConversationCommand(connection, msg.ConvHandle, enableCleanup: _ssbOptions.CleanupOnEndConversation, transaction: transaction); await edc.ExecuteAsync(cancellationToken); using var scope = _serviceFactory.CreateScope(); var ssbSender = scope.ServiceProvider.GetRequiredService <SqlServiceBrokerSender>(); var bodyConverter = _bodyConverterFactory.CreateBodyConverter(_ssbOptions.MessageBodyType); _localReceiverDeliveryAttempts.TryGetValue(msg.ConvHandle, out var deliveryAttempts); var headers = new Dictionary <string, object>() { [SSBMessageContext.ConversationHandle] = msg.ConvHandle, [SSBMessageContext.ServiceName] = msg.ServiceName, [MessageContext.FailureDescription] = deadLetterErrorDescription, [MessageContext.FailureDetails] = deadLetterReason, [MessageContext.InfrastructureType] = SSBMessageContext.InfrastructureType, [SSBMessageContext.MessageTypeName] = ServicesMessageTypes.ChatterBrokeredMessageType, [SSBMessageContext.ServiceContractName] = ServicesMessageTypes.ChatterServiceContract, [MessageContext.ReceiveAttempts] = deliveryAttempts }; await ssbSender.Dispatch(new OutboundBrokeredMessage(context.BrokeredMessage.MessageId, msg.Body, headers, _options.DeadLetterQueuePath, bodyConverter), transactionContext); await transaction?.CommitAsync(cancellationToken); _localReceiverDeliveryAttempts.TryRemove(msg.ConvHandle, out var _); _logger.LogTrace($"Message deadlettered."); return(true); } finally { transaction?.Dispose(); connection?.Dispose(); } }
public async Task <bool> AckMessageAsync(MessageBrokerContext context, TransactionContext transactionContext, CancellationToken cancellationToken) { ReceivedMessage msg = null; if (!context?.Container.TryGet(out msg) ?? false) { _logger.LogTrace($"No {nameof(ReceivedMessage)} contained in {nameof(context)}."); } transactionContext.Container.TryGet <SqlConnection>(out var connection); transactionContext.Container.TryGet <SqlTransaction>(out var transaction); try { if (msg != null) { var edc = new EndDialogConversationCommand(connection, msg.ConvHandle, enableCleanup: _ssbOptions.CleanupOnEndConversation, transaction: transaction); await edc.ExecuteAsync(cancellationToken); _localReceiverDeliveryAttempts.TryRemove(msg.ConvHandle, out var _); } else { _logger.LogTrace($"Unable end dialog conversation during message acknowledgment. {nameof(msg)} is null."); } await transaction?.CommitAsync(cancellationToken); _logger.LogTrace("Message acknowledgment complete"); return(true); } finally { transaction?.Dispose(); connection?.Dispose(); } }