Exemple #1
0
        public static NMSException CreateConnectionException(short errorCode)
        {
            NMSException result = null;

            if (errorCode == 1)
            {
                result = new NMSException("Invalid MQTT Protocol Version specified");
            }
            else if (errorCode == 2)
            {
                result = new InvalidClientIDException("Client ID not accepted by Broker");
            }
            else if (errorCode == 3)
            {
                result = new InvalidClientIDException("Server is Unavailable");
            }
            else if (errorCode == 4)
            {
                result = new NMSSecurityException("Bad user anem or password provided.");
            }
            else if (errorCode == 5)
            {
                result = new NMSSecurityException("User is not Authorized.");
            }
            else
            {
                result = new NMSException("Received unknown error code.");
            }

            return(result);
        }
        private void AckRejected(IMessageDelivery delivery, NMSException ex)
        {
            Error err = new Error(NMSErrorCode.INTERNAL_ERROR);

            err.Description = ex.Message;
            AckRejected(delivery, err);
        }
Exemple #3
0
        public async Task Unsubscribe(string subscriptionName)
        {
            TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            ReceiverLink receiverLink = new ReceiverLink(UnderlyingSession, subscriptionName, new Attach
            {
                LinkName = subscriptionName
            }, (link, attach) =>
            {
                Tracer.InfoFormat("Attempting to close subscription {0}. Attach response {1}", subscriptionName, attach);
                if (attach.Source is Source source)
                {
                    Tracer.InfoFormat("Found subscription {0} on remote with source {1}.", subscriptionName, source);
                    tcs.TrySetResult(true);
                }
            });

            receiverLink.AddClosedCallback((sender, error) =>
            {
                string failureMessage = string.Equals(sender.Error?.Condition, ErrorCode.NotFound)
                    ? $"Cannot remove Subscription {subscriptionName} that does not exists"
                    : $"Subscription {subscriptionName} unsubscribe operation failure";

                NMSException exception = ExceptionSupport.GetException(sender, failureMessage);
                tcs.TrySetException(exception);
            });

            await tcs.Task;

            receiverLink.Close(TimeSpan.FromMilliseconds(sessionInfo.closeTimeout));
        }
Exemple #4
0
        public static NMSException Wrap(Exception e, string message = "")
        {
            if (e == null)
            {
                return(null);
            }
            NMSException nmsEx     = null;
            string       exMessage = message;

            if (exMessage == null || exMessage.Length == 0)
            {
                exMessage = e.Message;
            }
            if (e is NMSException)
            {
                return(e as NMSException);
            }
            else if (e is AmqpException)
            {
                Error err = (e as AmqpException).Error;
                nmsEx = GetException(err, message, e);
                Tracer.DebugFormat("Encoutered AmqpException {0} and created NMS Exception {1}.", e, nmsEx);
            }
            else
            {
                nmsEx = new NMSException(exMessage, NMSErrorCode.INTERNAL_ERROR, e);
            }

            return(nmsEx);
        }
Exemple #5
0
        public Task Attach()
        {
            Source source = CreateSource();
            Target target = CreateTarget();
            Attach frame  = new Attach
            {
                Source               = source,
                Target               = target,
                SndSettleMode        = SenderSettleMode.Unsettled,
                IncompleteUnsettled  = false,
                InitialDeliveryCount = 0
            };

            string linkName             = info.Id + ":" + target.Address;
            var    taskCompletionSource = new TaskCompletionSource <bool>();

            senderLink = new SenderLink(session.UnderlyingSession, linkName, frame, HandleOpened(taskCompletionSource));

            senderLink.AddClosedCallback((sender, error) =>
            {
                NMSException exception = ExceptionSupport.GetException(error, "Received Amqp link detach with Error for link {0}", info.Id);
                if (!taskCompletionSource.TrySetException(exception))
                {
                    session.RemoveProducer(info.Id);

                    // If session is not closed it means that the link was remotely detached
                    if (!senderLink.Session.IsClosed)
                    {
                        session.Connection.Provider.FireResourceClosed(info, exception);
                    }
                }
            });

            return(taskCompletionSource.Task);
        }
 public void Close()
 {
     try
     {
         UnderlyingConnection?.Close();
     }
     catch (Exception ex)
     {
         // log network errors
         NMSException nmse = ExceptionSupport.Wrap(ex, "Amqp Connection close failure for NMS Connection {0}", this.Info.Id);
         Tracer.DebugFormat("Caught Exception while closing Amqp Connection {0}. Exception {1}", this.Info.Id, nmse);
     }
 }
Exemple #7
0
        private ClosedCallback HandleClosed(TaskCompletionSource <bool> tsc) => (sender, error) =>
        {
            NMSException exception = ExceptionSupport.GetException(error, "Received Amqp link detach with Error for link {0}", info.Id);
            if (!tsc.TrySetException(exception))
            {
                session.RemoveConsumer(info.Id);

                // If session is not closed it means that the link was remotely detached
                if (!receiverLink.Session.IsClosed)
                {
                    session.Connection.Provider.FireResourceClosed(info, exception);
                }
            }
        };
 public static NMSException Create(Exception cause)
 {
     if(cause is NMSException)
     {
         return (NMSException) cause;
     }
     string msg = cause.Message;
     if(msg == null || msg.Length == 0)
     {
         msg = cause.ToString();
     }
     NMSException exception = new NMSException(msg, cause);
     return exception;
 }
        internal void HandleProviderError(IProvider provider, NMSException cause)
        {
            if (closed)
            {
                return;
            }

            lock (SyncRoot)
            {
                // It is possible that another failed request signaled an error for the same provider
                // and we already cleaned up the old failed provider and scheduled a reconnect that
                // has already succeeded, so we need to ensure that we don't kill a valid provider.
                if (provider == this.provider)
                {
                    Tracer.Debug($"handling Provider failure: {cause.ToString()}");
                    this.provider = null;
                    provider.SetProviderListener(null);
                    Uri failedUri = provider.RemoteUri;
                    try
                    {
                        provider.Close();
                    }
                    catch (Exception exception)
                    {
                        Tracer.Debug($"Caught exception while closing failed provider: {exception.Message}");
                    }

                    if (reconnectControl.IsReconnectAllowed(cause))
                    {
                        // Start watching for request timeouts while we are offline, unless we already are.
                        foreach (FailoverRequest failoverRequest in GetPendingRequests())
                        {
                            failoverRequest.ScheduleTimeout();
                        }

                        TriggerReconnectionAttempt();

                        listener?.OnConnectionInterrupted(failedUri);
                    }
                    else
                    {
                        listener?.OnConnectionFailure(cause);
                    }
                }
                else
                {
                    Tracer.Debug($"Ignoring duplicate provider failed event for provider: {provider}");
                }
            }
        }
Exemple #10
0
 public async Task CloseAsync()
 {
     try
     {
         if (UnderlyingConnection != null)
         {
             await UnderlyingConnection.CloseAsync().AwaitRunContinuationAsync();
         }
     }
     catch (Exception ex)
     {
         // log network errors
         NMSException nmse = ExceptionSupport.Wrap(ex, "Amqp Connection close failure for NMS Connection {0}", this.Info.Id);
         Tracer.DebugFormat("Caught Exception while closing Amqp Connection {0}. Exception {1}", this.Info.Id, nmse);
     }
 }
        public static NMSException Create(Exception cause)
        {
            if (cause is NMSException)
            {
                return((NMSException)cause);
            }
            string msg = cause.Message;

            if (msg == null || msg.Length == 0)
            {
                msg = cause.ToString();
            }
            NMSException exception = new NMSException(msg, cause);

            return(exception);
        }
        public Task Attach()
        {
            Target target = new Target();
            Source source = CreateSource();

            Attach attach = new Attach
            {
                Target        = target,
                Source        = source,
                RcvSettleMode = ReceiverSettleMode.First,
                SndSettleMode = (info.IsBrowser) ? SenderSettleMode.Settled : SenderSettleMode.Unsettled,
            };
            string name;

            if (info.IsDurable)
            {
                name = info.SubscriptionName;
            }
            else
            {
                string destinationAddress = source.Address ?? "";
                name = "nms:receiver:" + info.Id
                       + (destinationAddress.Length == 0 ? "" : (":" + destinationAddress));
            }

            var taskCompletionSource = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            link = new ReceiverLink(session.UnderlyingSession, name, attach, (link1, attach1) => { taskCompletionSource.SetResult(true); });

            link.AddClosedCallback((sender, error) =>
            {
                NMSException exception = ExceptionSupport.GetException(error, "Received Amqp link detach with Error for link {0}", info.Id);
                if (!taskCompletionSource.TrySetException(exception))
                {
                    session.RemoveConsumer(info.Id);

                    // If session is not closed it means that the link was remotely detached
                    if (!link.Session.IsClosed)
                    {
                        session.Connection.Provider.FireResourceClosed(info, exception);
                    }
                }
            });
            return(taskCompletionSource.Task);
        }
Exemple #13
0
        public static NMSException GetException(Error amqpErr, string message = "", Exception e = null)
        {
            string errCode           = null;
            string errMessage        = null;
            string additionalErrInfo = null;

            if (amqpErr == null)
            {
                amqpErr = NMSError.INTERNAL;
            }

            errCode    = amqpErr.Condition.ToString();
            errMessage = amqpErr.Description;

            errMessage = errMessage != null ? ", Description = " + errMessage : "";

            if (amqpErr.Info != null && amqpErr.Info.Count > 0)
            {
                additionalErrInfo = ", ErrorInfo = " + Types.ConversionSupport.ToString(amqpErr.Info);
            }
            if (null == e)
            {
                // no exception given, create a NMSunthrownException to hold the
                // stack and use it as the innerException in the constructors for
                // the NMSexception we create., the custom StackTrace() will allow exception listeners to
                // see the stack to here
                e = new NMSProviderError(errCode, errMessage);
            }
            NMSException ex     = null;
            Type         exType = null;

            if (errTypeMap.TryGetValue(errCode, out exType))
            {
                ConstructorInfo ci   = exType.GetConstructor(new[] { typeof(string), typeof(string), typeof(Exception) });
                object          inst = ci.Invoke(new object[] { message + errMessage + additionalErrInfo, errCode, e });
                ex = inst as NMSException;
            }
            else
            {
                ex = new NMSException(message + errMessage + additionalErrInfo, errCode, e);
            }
            return(ex);
        }
        public void RegisteredExceptionListenerIsInvokedOnException()
        {
            SimpleMessageConsumer messageConsumer = new SimpleMessageConsumer();

            ISession session = (ISession)mocks.CreateMock(typeof(ISession));

            Expect.Call(session.GetQueue(DESTINATION_NAME)).Return(QUEUE_DESTINATION);
            Expect.Call(session.CreateConsumer(QUEUE_DESTINATION, null)).Return(messageConsumer);
            // an exception is thrown, so the rollback logic is being applied here...
            Expect.Call(session.Transacted).Return(false);

            IConnection connection = (IConnection)mocks.CreateMock(typeof(IConnection));

            connection.ExceptionListener += container.OnException;
            Expect.Call(connection.CreateSession(container.SessionAcknowledgeMode)).Return(session);
            connection.Start();

            IConnectionFactory connectionFactory = (IConnectionFactory)mocks.CreateMock(typeof(IConnectionFactory));

            Expect.Call(connectionFactory.CreateConnection()).Return(connection);

            NMSException theException = new NMSException(EXCEPTION_MESSAGE);

            IExceptionListener exceptionListener = (IExceptionListener)mocks.CreateMock(typeof(IExceptionListener));

            exceptionListener.OnException(theException);

            IMessage message = (IMessage)mocks.CreateMock(typeof(IMessage));

            mocks.ReplayAll();


            container.ConnectionFactory = connectionFactory;
            container.DestinationName   = DESTINATION_NAME;
            container.MessageListener   = new BadSessionAwareMessageListener(theException);
            container.ExceptionListener = exceptionListener;
            container.AfterPropertiesSet();

            // manually trigger an Exception with the above bad MessageListener...
            messageConsumer.SendMessage(message);
            mocks.VerifyAll();
        }
Exemple #15
0
        private void OnInternalClosed(IAmqpObject sender, Error error)
        {
            string     name = null;
            Connection self = null;

            try
            {
                self = this;
                // name should throw should the finalizer of the Connection object already completed.
                name = self.ClientId;
                Tracer.InfoFormat("Received Close Request for Connection {0}.", name);
                if (self.state.CompareAndSet(ConnectionState.CONNECTED, ConnectionState.CLOSED))
                {
                    // unexpected or amqp transport close.

                    // notify any error to exception Dispatcher.
                    if (error != null)
                    {
                        NMSException nmse = ExceptionSupport.GetException(error, "Connection {0} Closed.", name);
                        self.OnException(nmse);
                    }

                    // shutdown connection facilities.
                    if (self.IsStarted)
                    {
                        self.Shutdown();
                    }
                    MessageFactory <ConnectionInfo> .Unregister(self);
                }
                else if (self.state.CompareAndSet(ConnectionState.CLOSING, ConnectionState.CLOSED))
                {
                    // application close.
                    MessageFactory <ConnectionInfo> .Unregister(self);
                }
                self.latch?.countDown();
            }
            catch (Exception ex)
            {
                Tracer.DebugFormat("Caught Exception during Amqp Connection close for NMS Connection{0}. Exception {1}",
                                   name != null ? (" " + name) : "", ex);
            }
        }
        public void Close()
        {
            connectionSession?.Close();

            foreach (var session in sessions.Values.ToArray())
            {
                session.Close();
            }

            try
            {
                UnderlyingConnection?.Close();
            }
            catch (Exception ex)
            {
                // log network errors
                NMSException nmse = ExceptionSupport.Wrap(ex, "Amqp Connection close failure for NMS Connection {0}", this.info.Id);
                Tracer.DebugFormat("Caught Exception while closing Amqp Connection {0}. Exception {1}", this.info.Id, nmse);
            }
        }
Exemple #17
0
        internal void OnAsyncException(Exception error)
        {
            if (!this.closed.Value && !this.closing.Value)
            {
                if (this.ExceptionListener != null)
                {
                    if (!(error is NMSException))
                    {
                        error = NMSExceptionSupport.Create(error);
                    }
                    NMSException e = (NMSException)error;

                    // Called in another thread so that processing can continue
                    // here, ensures no lock contention.
                    executor.QueueUserWorkItem(AsyncCallExceptionListener, e);
                }
                else
                {
                    Tracer.Debug("Async exception with no exception listener: " + error);
                }
            }
        }
Exemple #18
0
        public void RegisteredExceptionListenerIsInvokedOnException()
        {
            SimpleMessageConsumer messageConsumer = new SimpleMessageConsumer();

            ISession session = A.Fake <ISession>();

            A.CallTo(() => session.GetQueue(DESTINATION_NAME)).Returns(QUEUE_DESTINATION);
            A.CallTo(() => session.CreateConsumer(QUEUE_DESTINATION, null)).Returns(messageConsumer);
            // an exception is thrown, so the rollback logic is being applied here...
            A.CallTo(() => session.Transacted).Returns(false);

            IConnection connection = A.Fake <IConnection>();

            connection.ExceptionListener += container.OnException;
            A.CallTo(() => connection.CreateSession(container.SessionAcknowledgeMode)).Returns(session);
            connection.Start();

            IConnectionFactory connectionFactory = A.Fake <IConnectionFactory>();

            A.CallTo(() => connectionFactory.CreateConnection()).Returns(connection);

            NMSException theException = new NMSException(EXCEPTION_MESSAGE);

            IExceptionListener exceptionListener = A.Fake <IExceptionListener>();

            exceptionListener.OnException(theException);

            IMessage message = A.Fake <IMessage>();

            container.ConnectionFactory = connectionFactory;
            container.DestinationName   = DESTINATION_NAME;
            container.MessageListener   = new BadSessionAwareMessageListener(theException);
            container.ExceptionListener = exceptionListener;
            container.AfterPropertiesSet();

            // manually trigger an Exception with the above bad MessageListener...
            messageConsumer.SendMessage(message);
        }
Exemple #19
0
        public void Shutdown(NMSException exception = null)
        {
            if (closed.CompareAndSet(false, true))
            {
                Stop();

                try
                {
                    foreach (NmsMessageConsumer consumer in consumers.Values.ToArray())
                    {
                        consumer.Shutdown(exception);
                    }

                    foreach (NmsMessageProducer producer in producers.Values.ToArray())
                    {
                        producer.Shutdown(exception);
                    }
                }
                finally
                {
                    Connection.RemoveSession(SessionInfo);
                }
            }
        }
 public BadSessionAwareMessageListener(NMSException exception)
 {
     this.exception = exception;
 }
 public void OnConnectionFailure(NMSException exception)
 {
     Tracer.Debug($"Failover: the provider reports failure: {exception.Message}");
     HandleProviderError(provider, exception);
 }
        /// <summary>
        /// Check and ensure that the connection objcet is connected.  If it is not
        /// connected or is closed, a ConnectionClosedException is thrown.
        /// </summary>
        internal void CheckConnected()
        {
            if (closed.Value)
            {
                throw new ConnectionClosedException();
            }

            if (!connected.Value)
            {
                DateTime timeoutTime = DateTime.Now + this.RequestTimeout;
                int      waitCount   = 1;

                while (true)
                {
                    if (Monitor.TryEnter(connectedLock))
                    {
                        try
                        {
                            if (closed.Value || closing.Value)
                            {
                                break;
                            }
                            else if (!connected.Value)
                            {
                                if (!this.userSpecifiedClientID)
                                {
                                    this.info.ClientId = this.clientIdGenerator.GenerateId();
                                }

                                try
                                {
                                    if (null != transport)
                                    {
                                        // Make sure the transport is started.
                                        if (!this.transport.IsStarted)
                                        {
                                            this.transport.Start();
                                        }

                                        // Send the connection and see if an ack/nak is returned.
                                        Response response = transport.Request(this.info, this.RequestTimeout);
                                        if (!(response is ExceptionResponse))
                                        {
                                            connected.Value = true;
                                        }
                                        else
                                        {
                                            ExceptionResponse error     = response as ExceptionResponse;
                                            NMSException      exception = CreateExceptionFromBrokerError(error.Exception);
                                            // This is non-recoverable.
                                            // Shutdown the transport connection, and re-create it, but don't start it.
                                            // It will be started if the connection is re-attempted.
                                            this.transport.Stop();
                                            ITransport newTransport = TransportFactory.CreateTransport(this.brokerUri);
                                            SetTransport(newTransport);
                                            throw exception;
                                        }
                                    }
                                }
                                catch
                                {
                                }
                            }
                        }
                        finally
                        {
                            Monitor.Exit(connectedLock);
                        }
                    }

                    if (connected.Value || closed.Value || closing.Value || DateTime.Now > timeoutTime)
                    {
                        break;
                    }

                    // Back off from being overly aggressive.  Having too many threads
                    // aggressively trying to connect to a down broker pegs the CPU.
                    Thread.Sleep(5 * (waitCount++));
                }

                if (!connected.Value)
                {
                    throw new ConnectionClosedException();
                }
            }
        }
 public static NMSException Create(string message, Exception cause)
 {
     NMSException exception = new NMSException(message, cause);
     return exception;
 }
Exemple #24
0
        private void AsyncCallExceptionListener(object error)
        {
            NMSException exception = error as NMSException;

            this.ExceptionListener(exception);
        }
        public static NMSException Create(string message, Exception cause)
        {
            NMSException exception = new NMSException(message, cause);

            return(exception);
        }
Exemple #26
0
 public NMSProviderError(string message, NMSException innerException) : base(message, innerException)
 {
     System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(1, true);
     InstanceTrace      = trace.ToString();
     exceptionErrorCode = innerException.ErrorCode ?? NMSErrorCode.INTERNAL_ERROR;
 }