コード例 #1
0
        public async Task Dispatch <TMessage>(TMessage message, IMessageHandlerContext messageHandlerContext) where TMessage : IMessage
        {
            try
            {
                await _messageDispatcher.Dispatch(message, messageHandlerContext).ConfigureAwait(false);

                if (messageHandlerContext is IMessageBrokerContext messageBrokerContext)
                {
                    messageBrokerContext.Container.TryGet <ReplyToRoutingContext>(out var replyContext);
                    await _replyRouter.Route(messageBrokerContext.BrokeredMessage, messageBrokerContext.GetTransactionContext(), replyContext).ConfigureAwait(false);

                    messageBrokerContext.Container.TryGet <RoutingContext>(out var forwardContext);
                    await _forwardMessages.Route(messageBrokerContext.BrokeredMessage, forwardContext?.DestinationPath, messageBrokerContext.GetTransactionContext()).ConfigureAwait(false);
                }
            }
            catch (Exception dispatchFailureException)
            {
                if (messageHandlerContext is IMessageBrokerContext messageBrokerContext)
                {
                    if (!(messageBrokerContext.Container.TryGet <CompensationRoutingContext>(out var compensateContext)))
                    {
                        throw;
                    }

                    var details     = $"{dispatchFailureException.Message} -> {dispatchFailureException.StackTrace}";
                    var description = $"'{typeof(TMessage).Name}' was not received successfully";

                    var newContext = new CompensationRoutingContext(compensateContext?.DestinationPath,
                                                                    details,
                                                                    description,
                                                                    messageBrokerContext?.Container);

                    messageBrokerContext?.Container.Include(newContext);

                    messageBrokerContext.Container.TryGet <CompensationRoutingContext>(out var compensationRoutingContext);
                    await _compensatingRouter.Route(messageBrokerContext.BrokeredMessage, messageBrokerContext.GetTransactionContext(), compensationRoutingContext).ConfigureAwait(false);
                }
                else
                {
                    throw;
                }
            }
        }
コード例 #2
0
        ///<inheritdoc/>
        public Task Route(InboundBrokeredMessage inboundBrokeredMessage, TransactionContext transactionContext, CompensationRoutingContext compensateContext)
        {
            if (!(compensateContext.Container.TryGet <Message>(out var receivedMessage)))
            {
                throw new InvalidOperationException($"The received {nameof(CompensationRoutingContext)} did not contain a {typeof(Message).Name}");
            }

            if (!(transactionContext.Container.TryGet <MessageReceiver>(out var receiver)))
            {
                throw new InvalidOperationException($"The received {nameof(TransactionContext)} did not contain a {typeof(MessageReceiver).Name}");
            }

            return(receiver.DeadLetterAsync(receivedMessage.SystemProperties.LockToken, (IDictionary <string, object>)inboundBrokeredMessage.ApplicationProperties));
        }
コード例 #3
0
        /// <summary>
        /// Routes a brokered message to a brokered message receiver responsible for compensating a received message
        /// </summary>
        /// <param name="inboundBrokeredMessage">The inbound brokered message to be routed to the compensation destination</param>
        /// <param name="transactionContext">The transaction information that was received with <paramref name="inboundBrokeredMessage"/></param>
        /// <param name="destinationRouterContext">The <see cref="CompensationRoutingContext"/> containing contextual information describing the compensating action</param>
        /// <exception cref="CompensationRoutingException">An exception containing contextual information describing the failure during compensation and routing details</exception>
        /// <returns>An awaitable <see cref="Task"/></returns>
        public Task Route(InboundBrokeredMessage inboundBrokeredMessage, TransactionContext transactionContext, CompensationRoutingContext destinationRouterContext)
        {
            if (destinationRouterContext is null)
            {
                //TODO: log
                return(Task.CompletedTask);
            }

            try
            {
                if (destinationRouterContext is null)
                {
                    throw new ArgumentNullException(nameof(destinationRouterContext), $"A '{typeof(CompensationRoutingContext).Name}' is required to route a compensation message");
                }

                if (string.IsNullOrWhiteSpace(destinationRouterContext.CompensateDetails))
                {
                    throw new ArgumentNullException(nameof(destinationRouterContext.CompensateDetails), $"A compensation reason is required to route a compensation message");
                }

                if (string.IsNullOrWhiteSpace(destinationRouterContext.CompensateDescription))
                {
                    throw new ArgumentNullException(nameof(destinationRouterContext.CompensateDescription), $"A compensation description is required to route a compensation message");
                }

                var outbound = OutboundBrokeredMessage.Forward(inboundBrokeredMessage, destinationRouterContext.DestinationPath)
                               .WithFailureDetails(destinationRouterContext.CompensateDetails)
                               .WithFailureDescription(destinationRouterContext.CompensateDescription)
                               .SetFailure();

                return(_router.Route(outbound, transactionContext));
            }
            catch (Exception causeOfRoutingFailure)
            {
                throw new CompensationRoutingException(destinationRouterContext, causeOfRoutingFailure);
            }
        }
コード例 #4
0
 public CompensationRoutingException(CompensationRoutingContext compensateContext, Exception causeOfRoutingFailure)
     : base(compensateContext, causeOfRoutingFailure, "Routing message broker compensation message failed.")
 {
     _compensateContext = compensateContext ?? throw new ArgumentNullException(nameof(compensateContext), "A compensate context is required.");
 }