private static IConnection TryToCreateConnection(Func <IConnection> connectionFunction, int numberOfRetries, int timeoutMilliseconds)
        {
            ValidateArguments(numberOfRetries, timeoutMilliseconds);

            var attempts = 0;
            BrokerUnreachableException latestException = null;

            while (attempts < numberOfRetries)
            {
                try
                {
                    if (attempts > 0)
                    {
                        Thread.Sleep(timeoutMilliseconds);
                    }

                    return(connectionFunction());
                }
                catch (BrokerUnreachableException exception)
                {
                    attempts++;
                    latestException = exception;
                }
            }

            throw new InitialConnectionException($"Could not establish an initial connection in {numberOfRetries} retries", latestException)
                  {
                      NumberOfRetries = attempts
                  };
        }
Exemple #2
0
        /// <summary>
        /// Connects the specified queue name.
        /// </summary>
        /// <param name="queueName">Name of the queue.</param>
        /// <param name="routingKey"></param>
        /// <param name="createQueues"></param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        protected virtual bool Connect(string queueName = "", string routingKey = "", bool createQueues = false)
        {
            try
            {
                if (Connection == null || !Connection.IsOpen)
                {
                    Logger.Debug(m => m("RMQMessagingGateway: Creating connection to Rabbit MQ on AMPQUri {0}", Configuration.AMPQUri.Uri.ToString()));
                    Connection = Connect(connectionFactory);

                    Logger.Debug(m => m("RMQMessagingGateway: Opening channel to Rabbit MQ on connection {0}", Configuration.AMPQUri.Uri.ToString()));
                    Channel = OpenChannel(Connection);
                    Channel.BasicQos(0, 1, false);

                    Logger.Debug(m => m("RMQMessagingGateway: Declaring exchange {0} on connection {1}", Configuration.Exchange.Name, Configuration.AMPQUri.Uri.ToString()));
                    DeclareExchange(Channel, Configuration);

                    if (createQueues)
                    {
                        Logger.Debug(m => m("RMQMessagingGateway: Declaring queue {0} on connection {1}", queueName, Configuration.AMPQUri.Uri.ToString()));
                        Channel.QueueDeclare(queueName, false, false, false, null);
                        Channel.QueueBind(queueName, Configuration.Exchange.Name, routingKey);
                    }
                }
            }
            catch (BrokerUnreachableException e)
            {
                ConnectionFailure = e;
                return(false);
            }

            return(true);
        }
 static bool IsExceptionTransient(Exception exception)
 {
     return(exception switch
     {
         BrokerUnreachableException bue => bue.InnerException switch
         {
             AuthenticationFailureException _ => false,
             _ => true
         },
Exemple #4
0
        internal bool InternalStart(int maxConnectionRetry, ConnectionFailureException callReason = null)
        {
            var ok         = false;
            var retries    = 0;
            var exceptions = new Dictionary <AmqpTcpEndpoint, Exception>(1);
            var attempts   = new Dictionary <AmqpTcpEndpoint, int>(1);

            if (HasAlreadyStartedOnce)
            {
                OnTemporaryConnectionFailureFailure(callReason);
            }
            while (!ok && (retries++ <= maxConnectionRetry || maxConnectionRetry == -1 || maxConnectionRetry == Timeout.Infinite) && !Cancellation.IsCancellationRequested)
            {
                try
                {
                    if (Model != null)
                    {
                        try
                        {
                            Model.Close();
                        }
                        catch
                        {
                            // best effort to close the previous channel, ignore errors
                        }
                    }

                    Connection           = CreateConnection();
                    Model                = Connection.CreateModel();
                    Connection.AutoClose = true;
                    TryRedeclareTopology();
                    SpecificRestart(Model);
                    ok = true;
                    HasAlreadyStartedOnce = true;
                }
                catch (Exception e)
                {
                    var endpoint = new AmqpTcpEndpoint();
                    if (_settings.ConnectionFactory != null && _settings.ConnectionFactory.Endpoint != null)
                    {
                        endpoint = _settings.ConnectionFactory.Endpoint;
                    }
                    exceptions[endpoint] = e;
                    attempts[endpoint]   = retries;
                    OnTemporaryConnectionFailureFailure(e);
                    Thread.Sleep(_settings.IntervalConnectionTries);
                }
            }
            if (!ok)
            {
                var e = new BrokerUnreachableException(attempts, exceptions);
                OnPermanentConnectionFailureFailure(e);
            }
            return(ok);
        }
Exemple #5
0
        public void Constructor_MessageInput()
        {
            //Arrange
            var expected = "test message";

            //Act
            var exception = new BrokerUnreachableException(expected);

            //Assert
            Assert.Equal(expected, exception.Message);
        }
Exemple #6
0
        public void Constructor_Empty()
        {
            //Arrange
            var expected = "The message broker could not be reached.";

            //Act
            var exception = new BrokerUnreachableException();

            //Assert
            Assert.Equal(expected, exception.Message);
        }
Exemple #7
0
        public void Constructor_MessageAndExceptionInput()
        {
            //Arrange
            var expectedMessage   = "test message";
            var expectedException = new Exception();

            //Act
            var exception = new BrokerUnreachableException(expectedMessage, expectedException);

            //Assert
            Assert.Equal(expectedMessage, exception.Message);
            Assert.Same(expectedException, exception.InnerException);
        }
Exemple #8
0
        protected void OnPermanentConnectionFailureFailure(BrokerUnreachableException e)
        {
            var copy = PermanentConnectionFailureHandler; //see http://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety

            //this behavior allow thread safety and allow to expose event publicly
            if (copy != null)
            {
                try
                {
                    copy(e);
                }
                catch (Exception ee)
                {
                    OnEventHandlerFailure(ee);
                }
            }
        }
        /// <summary>
        /// Connects the specified queue name.
        /// </summary>
        /// <param name="queueName">Name of the queue.</param>
        /// <param name="routingKey"></param>
        /// <param name="createQueues"></param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        protected virtual bool Connect(string queueName = "", string routingKey = "", bool createQueues = false)
        {
            try
            {
                if (NotConnected())
                {
                    Logger.Debug(m => m("RMQMessagingGateway: Creating connection to Rabbit MQ on AMPQUri {0}", Configuration.AMPQUri.Uri.ToString()));
                    Connection = Connect(connectionFactory);

                    Logger.Debug(m => m("RMQMessagingGateway: Opening channel to Rabbit MQ on connection {0}", Configuration.AMPQUri.Uri.ToString()));
                    Channel = OpenChannel(Connection);

                    // Configure the Quality of service for the model.
                    // BasicQos(0="Don't send me a new message until I’ve finished",  1= "Send me one message at a time", false ="Applied separately to each new consumer on the channel")
                    Channel.BasicQos(0, Configuration.Queues.QosPrefetchSize, false);

                    Logger.Debug(m => m("RMQMessagingGateway: Declaring exchange {0} on connection {1}", Configuration.Exchange.Name, Configuration.AMPQUri.Uri.ToString()));
                    DeclareExchange(Channel, Configuration);

                    if (createQueues)
                    {
                        Logger.Debug(m => m("RMQMessagingGateway: Creating queue {0} on connection {1}", queueName, Configuration.AMPQUri.Uri.ToString()));

                        Channel.QueueDeclare(queueName, false, false, false, SetQueueArguments());
                        Channel.QueueBind(queueName, Configuration.Exchange.Name, routingKey);
                    }
                }
            }
            catch (BrokerUnreachableException e)
            {
                Logger.Debug(m => m("RMQMessagingGateway: BrokerUnreachableException on connection to queue {0} via exchange {1} on connection {2}", queueName, Configuration.Exchange.Name, Configuration.AMPQUri.Uri.ToString()), e);
                ConnectionFailure = e;
                return(false);
            }
            catch (Exception e)
            {
                Logger.Debug(m => m("RMQMessagingGateway: Exception on connection to queue {0} via exchange {1} on connection {2}", queueName, Configuration.Exchange.Name, Configuration.AMPQUri.Uri.ToString()), e);
                throw;
            }

            return(true);
        }
        private void LogConnectionException(BrokerConnectionSettings settings,
                                            int retryCount = 0,
                                            BrokerUnreachableException connEx = null)
        {
            var connInfo = new { settings.BrokerName, settings.HostName, settings.UserName };

            if (retryCount > 0)
            {
                _logger.LogErrorDetails(RabbitMqLogEvents.BROKER_EXCEPTION,
                                        "Error connecting to broker. Attempt: {attempt}",
                                        connInfo, retryCount);
            }

            if (connEx != null)
            {
                _logger.LogErrorDetails(RabbitMqLogEvents.BROKER_EXCEPTION, connEx,
                                        "Error connecting to broker.",
                                        connInfo);

                throw connEx;
            }
        }