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); }
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)); }
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); }
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); } }
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}"); } } }
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); }
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(); }
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); } }
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); } } }
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); }
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; }
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); }
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; }