コード例 #1
0
        public void TestRetryWithinOnMessageAdapter()
        {
            var config   = new ConfigurationBuilder().Build();
            var services = new ServiceCollection().BuildServiceProvider();
            var context  = new GenericApplicationContext(services, config);

            var connectionFactory = new Mock <Messaging.RabbitMQ.Connection.IConnectionFactory>();
            var container         = new DirectMessageListenerContainer();
            var adapter           = new RabbitInboundChannelAdapter(context, container);

            adapter.OutputChannel = new DirectChannel(context);
            adapter.RetryTemplate = new PollyRetryTemplate(3, 1, 1, 1);
            var errors           = new QueueChannel(context);
            var recoveryCallback = new ErrorMessageSendingRecoverer(context, errors);

            recoveryCallback.ErrorMessageStrategy = new RabbitMessageHeaderErrorMessageStrategy();
            adapter.RecoveryCallback = recoveryCallback;
            var listener = container.MessageListener as IChannelAwareMessageListener;
            var message  = MessageBuilder.WithPayload <byte[]>(Encoding.UTF8.GetBytes("foo")).CopyHeaders(new MessageHeaders()).Build();

            listener.OnMessage(message, null);
            var errorMessage = errors.Receive(0);

            Assert.NotNull(errorMessage);
            var payload = errorMessage.Payload as MessagingException;

            Assert.NotNull(payload);
            Assert.Contains("Dispatcher has no", payload.Message);
            var deliveryAttempts = payload.FailedMessage.Headers.Get <AtomicInteger>(IntegrationMessageHeaderAccessor.DELIVERY_ATTEMPT);

            Assert.NotNull(deliveryAttempts);
            Assert.Equal(3, deliveryAttempts.Value);
            var amqpMessage = errorMessage.Headers.Get <IMessage>(RabbitMessageHeaderErrorMessageStrategy.AMQP_RAW_MESSAGE);

            Assert.NotNull(amqpMessage);
            Assert.Null(errors.Receive(0));
        }
コード例 #2
0
 public ErrorInfrastructure(ISubscribableChannel errorChannel, ErrorMessageSendingRecoverer recoverer, IMessageHandler handler)
 {
     ErrorChannel = errorChannel;
     Recoverer    = recoverer;
     Handler      = handler;
 }
コード例 #3
0
        protected virtual ErrorInfrastructure RegisterErrorInfrastructure(IConsumerDestination destination, string group, IConsumerOptions consumerOptions, bool polled)
        {
            var errorMessageStrategy = GetErrorMessageStrategy();

            var errorChannelName = GetErrorsBaseName(destination, group, consumerOptions);
            ISubscribableChannel errorChannel;
            var errorChannelObject = _destinationRegistry.Lookup(errorChannelName);

            if (errorChannelObject != null)
            {
                if (!(errorChannelObject is ISubscribableChannel))
                {
                    throw new ArgumentException("Error channel '" + errorChannelName + "' must be a ISubscribableChannel");
                }

                errorChannel = (ISubscribableChannel)errorChannelObject;
            }
            else
            {
                errorChannel = new BinderErrorChannel(ServiceProvider, errorChannelName);
                _destinationRegistry.Register(errorChannelName, errorChannel);
            }

            ErrorMessageSendingRecoverer recoverer;

            if (errorMessageStrategy == null)
            {
                recoverer = new ErrorMessageSendingRecoverer(ServiceProvider, errorChannel);
            }
            else
            {
                recoverer = new ErrorMessageSendingRecoverer(ServiceProvider, errorChannel, errorMessageStrategy);
            }

            var recovererBeanName = GetErrorRecovererName(destination, group, consumerOptions);

            _destinationRegistry.Register(recovererBeanName, recoverer);

            IMessageHandler handler;

            if (polled)
            {
                handler = GetPolledConsumerErrorMessageHandler(destination, group, consumerOptions);
            }
            else
            {
                handler = GetErrorMessageHandler(destination, group, consumerOptions);
            }

            var defaultErrorChannel = (IMessageChannel)_destinationRegistry.Lookup(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);

            if (handler == null && errorChannel is ILastSubscriberAwareChannel)
            {
                handler = GetDefaultErrorMessageHandler((ILastSubscriberAwareChannel)errorChannel, defaultErrorChannel != null);
            }

            var errorMessageHandlerName = GetErrorMessageHandlerName(destination, group, consumerOptions);

            if (handler != null)
            {
                if (IsSubscribable(errorChannel))
                {
                    var errorHandler = handler;
                    _destinationRegistry.Register(errorMessageHandlerName, errorHandler);
                    errorChannel.Subscribe(handler);
                }
                else
                {
                    // this.logger.warn("The provided errorChannel '" + errorChannelName
                    //        + "' is an instance of DirectChannel, "
                    //        + "so no more subscribers could be added which may affect DLQ processing. "
                    //        + "Resolution: Configure your own errorChannel as "
                    //        + "an instance of PublishSubscribeChannel");
                }
            }

            if (defaultErrorChannel != null)
            {
                if (IsSubscribable(errorChannel))
                {
                    var errorBridge = new BridgeHandler(ServiceProvider)
                    {
                        OutputChannel = defaultErrorChannel
                    };
                    errorChannel.Subscribe(errorBridge);

                    var errorBridgeHandlerName = GetErrorBridgeName(destination, group, consumerOptions);
                    _destinationRegistry.Register(errorBridgeHandlerName, errorBridge);
                }
                else
                {
                    // this.logger.warn("The provided errorChannel '" + errorChannelName
                    //        + "' is an instance of DirectChannel, "
                    //        + "so no more subscribers could be added and no error messages will be sent to global error channel. "
                    //        + "Resolution: Configure your own errorChannel as "
                    //        + "an instance of PublishSubscribeChannel");
                }
            }

            return(new ErrorInfrastructure(errorChannel, recoverer, handler));
        }
コード例 #4
0
        protected virtual ErrorInfrastructure RegisterErrorInfrastructure(IConsumerDestination destination, string group, IConsumerOptions consumerOptions, bool polled, ILogger logger)
        {
            var errorMessageStrategy = GetErrorMessageStrategy();

            var errorChannelName = GetErrorsBaseName(destination, group, consumerOptions);

            var errorChannel = GetErrorChannel(logger, errorChannelName);

            var recoverer = new ErrorMessageSendingRecoverer(ApplicationContext, errorChannel, errorMessageStrategy);

            var recovererBeanName = GetErrorRecovererName(destination, group, consumerOptions);

            ApplicationContext.Register(recovererBeanName, recoverer);

            IMessageHandler handler;

            if (polled)
            {
                handler = GetPolledConsumerErrorMessageHandler(destination, group, consumerOptions);
            }
            else
            {
                handler = GetErrorMessageHandler(destination, group, consumerOptions);
            }

            var defaultErrorChannel = ApplicationContext.GetService <IMessageChannel>(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);

            if (handler == null && errorChannel is ILastSubscriberAwareChannel channel)
            {
                handler = GetDefaultErrorMessageHandler(channel, defaultErrorChannel != null);
            }

            var errorMessageHandlerName = GetErrorMessageHandlerName(destination, group, consumerOptions);

            if (handler != null)
            {
                handler.ServiceName = errorMessageHandlerName;
                if (IsSubscribable(errorChannel))
                {
                    var errorHandler = handler;
                    ApplicationContext.Register(errorMessageHandlerName, errorHandler);
                    errorChannel.Subscribe(handler);
                }
                else
                {
                    _logger?.LogWarning("The provided errorChannel '" + errorChannelName
                                        + "' is an instance of DirectChannel, "
                                        + "so no more subscribers could be added which may affect DLQ processing. "
                                        + "Resolution: Configure your own errorChannel as "
                                        + "an instance of PublishSubscribeChannel");
                }
            }

            if (defaultErrorChannel != null)
            {
                if (IsSubscribable(errorChannel))
                {
                    var errorBridge = new BridgeHandler(ApplicationContext)
                    {
                        OutputChannel = defaultErrorChannel
                    };
                    errorChannel.Subscribe(errorBridge);

                    var errorBridgeHandlerName = GetErrorBridgeName(destination, group, consumerOptions);
                    errorBridge.ServiceName = errorBridgeHandlerName;
                    ApplicationContext.Register(errorBridgeHandlerName, errorBridge);
                }
                else
                {
                    _logger?.LogWarning("The provided errorChannel '" + errorChannelName
                                        + "' is an instance of DirectChannel, "
                                        + "so no more subscribers could be added and no error messages will be sent to global error channel. "
                                        + "Resolution: Configure your own errorChannel as "
                                        + "an instance of PublishSubscribeChannel");
                }
            }

            return(new ErrorInfrastructure(errorChannel, recoverer, handler));
        }