public async Task <AmqpObject> CreateAndOpenAmqpLinkAsync()
        {
            TimeoutHelper  timeoutHelper = new TimeoutHelper(this.serviceBusConnection.OperationTimeout);
            AmqpConnection connection    = await this.serviceBusConnection.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            // Authenticate over CBS
            AmqpCbsLink cbsLink  = connection.Extensions.Find <AmqpCbsLink>();
            Uri         address  = new Uri(this.serviceBusConnection.Endpoint, this.entityPath);
            string      audience = address.AbsoluteUri;
            string      resource = address.AbsoluteUri;
            await cbsLink.SendTokenAsync(this.cbsTokenProvider, address, audience, resource, this.requiredClaims, timeoutHelper.RemainingTime()).ConfigureAwait(false);

            AmqpSession session = null;

            try
            {
                // Create our Session
                AmqpSessionSettings sessionSettings = new AmqpSessionSettings {
                    Properties = new Fields()
                };
                session = connection.CreateSession(sessionSettings);
                await session.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                // Create our Link
                AmqpObject link = this.OnCreateAmqpLink(connection, this.amqpLinkSettings, session);
                await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                return(link);
            }
            catch (Exception)
            {
                session?.Abort();
                throw;
            }
        }
Ejemplo n.º 2
0
 protected override void SessionClosed(AmqpObject sender, Error error)
 {
     this.AmqpSession = null;
     this._amqpSender = null;
     Logger.TraceLog("AMQP Session Closed. Error: " + error.ToString());
     this.bPendingSend = false;
 }
        private static async Task OpenLinkAsync(AmqpObject link, TimeSpan timeout)
        {
            Logging.Enter(link, link.State, timeout, nameof(OpenLinkAsync));

            try
            {
                var timeoutHelper = new TimeoutHelper(timeout);
                try
                {
                    await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    Logging.Error(link, exception, nameof(OpenLinkAsync));

                    if (exception.IsFatal())
                    {
                        throw;
                    }

                    link.SafeClose(exception);

                    throw;
                }
            }
            finally
            {
                Logging.Exit(link, link.State, timeout, nameof(OpenLinkAsync));
            }
        }
        protected override async Task OpenLinkAsync(AmqpObject link, IotHubConnectionString doNotUse, string doNotUse2, TimeSpan timeout, CancellationToken token)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, timeout, token, $"{nameof(IotHubSingleTokenConnection)}.{nameof(OpenLinkAsync)}");
            }

            token.ThrowIfCancellationRequested();
            try
            {
                await link.OpenAsync(timeout).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                link.SafeClose(exception);

                throw;
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, timeout, token, $"{nameof(IotHubSingleTokenConnection)}.{nameof(OpenLinkAsync)}");
                }
            }
        }
        /// <summary>
        ///   Performs the actions needed to open an AMQP object, such
        ///   as a session or link for use.
        /// </summary>
        ///
        /// <param name="target">The target AMQP object to open.</param>
        /// <param name="timeout">The timeout to apply when opening the link.</param>
        protected virtual async Task OpenAmqpObjectAsync(
            AmqpObject target,
            TimeSpan timeout)
        {
            try
            {
                await target.OpenAsync(timeout).ConfigureAwait(false);
            }
            catch
            {
                switch (target)
                {
                case AmqpLink linkTarget:
                    linkTarget.Session?.SafeClose();
                    break;

                case RequestResponseAmqpLink linkTarget:
                    linkTarget.Session?.SafeClose();
                    break;

                default:
                    break;
                }

                target.SafeClose();
                throw;
            }
        }
 protected ActiveClientLinkObject(AmqpObject amqpLinkObject, Uri endpointUri, string audience, string[] requiredClaims)
 {
     this.LinkObject     = amqpLinkObject;
     this.EndpointUri    = endpointUri;
     this.Audience       = audience;
     this.requiredClaims = requiredClaims;
 }
        /// <summary>
        ///   Performs the actions needed to configure and begin tracking the specified AMQP
        ///   link as an active link bound to this scope.
        /// </summary>
        /// <param name="entityPath"></param>
        ///
        /// <param name="link">The link to begin tracking.</param>
        /// <param name="authorizationRefreshTimer">The timer used to manage refreshing authorization, if the link requires it.</param>
        ///
        /// <remarks>
        ///   This method does operate on the specified <paramref name="link"/> in order to configure it
        ///   for active tracking; no assumptions are made about the open/connected state of the link nor are
        ///   its communication properties modified.
        /// </remarks>
        ///
        protected virtual void BeginTrackingLinkAsActive(
            string entityPath,
            AmqpObject link,
            Timer authorizationRefreshTimer = null)
        {
            // Register the link as active and having authorization automatically refreshed, so that it can be
            // managed with the scope.

            if (!ActiveLinks.TryAdd(link, authorizationRefreshTimer))
            {
                throw new ServiceBusException(true, entityPath, Resources.CouldNotCreateLink);
            }

            // When the link is closed, stop refreshing authorization and remove it from the
            // set of associated links.

            var closeHandler = default(EventHandler);

            closeHandler = (snd, args) =>
            {
                ActiveLinks.TryRemove(link, out var timer);

                timer?.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
                timer?.Dispose();

                link.Closed -= closeHandler;
            };

            link.Closed += closeHandler;
        }
Ejemplo n.º 8
0
        public static Exception GetInnerException(this AmqpObject amqpObject)
        {
            var       connectionError = false;
            Exception innerException;

            switch (amqpObject)
            {
            case AmqpSession amqpSession:
                innerException = amqpSession.TerminalException ?? amqpSession.Connection.TerminalException;
                break;

            case AmqpLink amqpLink:
                connectionError = amqpLink.Session.IsClosing();
                innerException  = amqpLink.TerminalException ?? amqpLink.Session.TerminalException ?? amqpLink.Session.Connection.TerminalException;
                break;

            case RequestResponseAmqpLink amqpReqRespLink:
                innerException = amqpReqRespLink.TerminalException ?? amqpReqRespLink.Session.TerminalException ?? amqpReqRespLink.Session.Connection.TerminalException;
                break;

            default:
                return(null);
            }

            return(innerException == null ? null : GetClientException(innerException, null, null, connectionError));
        }
Ejemplo n.º 9
0
 void OnLinkClosed(AmqpObject sender, Error error)
 {
     lock (this.queue.publishers)
     {
         this.queue.publishers.Remove(this.id);
     }
 }
Ejemplo n.º 10
0
        protected override async Task OpenLinkAsync(AmqpObject link, IotHubConnectionString connectionString, string audience, TimeSpan timeout, CancellationToken token)
        {
            var timeoutHelper = new TimeoutHelper(timeout);

            token.ThrowIfCancellationRequested();
            try
            {
                // this is a device-scope connection string. We need to send a CBS token for this specific link before opening it.
                var iotHubLinkTokenRefresher = new IotHubTokenRefresher(this.FaultTolerantSession.Value, connectionString, audience);

                if (this.iotHubTokenRefreshers.TryAdd(link, iotHubLinkTokenRefresher))
                {
                    link.SafeAddClosed((s, e) =>
                    {
                        if (this.iotHubTokenRefreshers.TryRemove(link, out iotHubLinkTokenRefresher))
                        {
                            iotHubLinkTokenRefresher.Cancel();
                        }
                    });

                    // Send Cbs token for new link first
                    // This will throw an exception if the device is not valid or if the token is not valid
                    await iotHubLinkTokenRefresher.SendCbsTokenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);
                }

                token.ThrowIfCancellationRequested();
                // Open Amqp Link
                await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);
            }
            catch (Exception exception) when(!exception.IsFatal())
            {
                link.SafeClose(exception);
                throw;
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        ///   Creates the timer event handler to support refreshing AMQP link authorization
        ///   on a recurring basis.
        /// </summary>
        ///
        /// <param name="connection">The AMQP connection to which the link being refreshed is bound to.</param>
        /// <param name="amqpLink">The AMQO link to refresh authorization for.</param>
        /// <param name="tokenProvider">The <see cref="CbsTokenProvider" /> to use for obtaining access tokens.</param>
        /// <param name="endpoint">The Event Hubs service endpoint that the AMQP link is communicating with.</param>
        /// <param name="audience">The audience associated with the authorization.  This is likely the <paramref name="endpoint"/> absolute URI.</param>
        /// <param name="resource">The resource associated with the authorization.  This is likely the <paramref name="endpoint"/> absolute URI.</param>
        /// <param name="requiredClaims">The set of claims required to support the operations of the AMQP link.</param>
        /// <param name="refreshTimeout">The timeout to apply when requesting authorization refresh.</param>
        /// <param name="refreshTimerFactory">A function to allow retrieving the <see cref="Timer" /> associated with the link authorization.</param>
        ///
        /// <returns>A <see cref="TimerCallback"/> delegate to perform the refresh when a timer is due.</returns>
        ///
        protected virtual TimerCallback CreateAuthorizationRefreshHandler(AmqpConnection connection,
                                                                          AmqpObject amqpLink,
                                                                          CbsTokenProvider tokenProvider,
                                                                          Uri endpoint,
                                                                          string audience,
                                                                          string resource,
                                                                          string[] requiredClaims,
                                                                          TimeSpan refreshTimeout,
                                                                          Func <Timer> refreshTimerFactory)
        {
            return(async _ =>
            {
                EventHubsEventSource.Log.AmqpLinkAuthorizationRefreshStart(EventHubName, endpoint.AbsoluteUri);
                var refreshTimer = refreshTimerFactory();

                try
                {
                    var authExpirationUtc = await RequestAuthorizationUsingCbsAsync(connection, tokenProvider, endpoint, audience, resource, requiredClaims, refreshTimeout).ConfigureAwait(false);

                    // Reset the timer for the next refresh.

                    if (authExpirationUtc >= DateTimeOffset.UtcNow)
                    {
                        refreshTimer.Change(CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan);
                    }

                    EventHubsEventSource.Log.AmqpLinkAuthorizationRefreshComplete(EventHubName, endpoint.AbsoluteUri);
                }
                catch (Exception ex)
                {
                    EventHubsEventSource.Log.AmqpLinkAuthorizationRefreshError(EventHubName, endpoint.AbsoluteUri, ex.Message);
                    refreshTimer.Change(Timeout.Infinite, Timeout.Infinite);
                }
            });
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Callback for link close events
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="error"></param>
 protected virtual void OnLinkClosed(AmqpObject sender, Error error)
 {
     if (error != null)
     {
         Debug.WriteLine("Link Closed {0} {1}", error.Condition, error.Description);
     }
 }
Ejemplo n.º 13
0
 void OnConnectionClosed(AmqpObject sender, Error error)
 {
     lock (this.connections)
     {
         this.connections.Remove((Connection)sender);
     }
 }
Ejemplo n.º 14
0
        public async Task <Tuple <AmqpObject, DateTime> > CreateAndOpenAmqpLinkAsync()
        {
            var timeoutHelper = new TimeoutHelper(this.serviceBusConnection.OperationTimeout);

            MessagingEventSource.Log.AmqpGetOrCreateConnectionStart();
            var amqpConnection = await this.serviceBusConnection.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            MessagingEventSource.Log.AmqpGetOrCreateConnectionStop(this.entityPath, amqpConnection.ToString(), amqpConnection.State.ToString());

            // Authenticate over CBS
            var cbsLink = amqpConnection.Extensions.Find <AmqpCbsLink>();

            var resource = this.endpointAddress.AbsoluteUri;

            MessagingEventSource.Log.AmqpSendAuthenticationTokenStart(this.endpointAddress, resource, resource, this.requiredClaims);
            var cbsTokenExpiresAtUtc = await cbsLink.SendTokenAsync(this.cbsTokenProvider, this.endpointAddress, resource, resource, this.requiredClaims, timeoutHelper.RemainingTime()).ConfigureAwait(false);

            MessagingEventSource.Log.AmqpSendAuthenticationTokenStop();

            AmqpSession session = null;

            try
            {
                // Create Session
                var amqpSessionSettings = new AmqpSessionSettings {
                    Properties = new Fields()
                };
                session = amqpConnection.CreateSession(amqpSessionSettings);
                await session.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                MessagingEventSource.Log.AmqpSessionCreationException(this.entityPath, amqpConnection, exception);
                session?.Abort();
                throw AmqpExceptionHelper.GetClientException(exception, null, session.GetInnerException());
            }

            AmqpObject link = null;

            try
            {
                // Create Link
                link = this.OnCreateAmqpLink(amqpConnection, this.amqpLinkSettings, session);
                await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                return(new Tuple <AmqpObject, DateTime>(link, cbsTokenExpiresAtUtc));
            }
            catch (Exception exception)
            {
                MessagingEventSource.Log.AmqpLinkCreationException(
                    this.entityPath,
                    session,
                    amqpConnection,
                    exception);

                session.SafeClose(exception);
                throw AmqpExceptionHelper.GetClientException(exception, null, link?.GetInnerException(), session.IsClosing());
            }
        }
 protected ActiveClientLinkObject(AmqpObject amqpLinkObject, Uri endpointUri, string[] audience, string[] requiredClaims, DateTime authorizationValidUntilUtc)
 {
     this.LinkObject                 = amqpLinkObject;
     this.EndpointUri                = endpointUri;
     this.Audience                   = audience;
     this.requiredClaims             = requiredClaims;
     this.AuthorizationValidUntilUtc = authorizationValidUntilUtc;
 }
Ejemplo n.º 16
0
 /// <summary>
 /// Callback for connection close events
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="error"></param>
 protected virtual void OnConnectionClosed(AmqpObject sender, Error error)
 {
     if (error != null)
     {
         Debug.WriteLine("Connection Closed {0} {1}", error.Condition, error.Description);
     }
     m_closed = true;
 }
Ejemplo n.º 17
0
        protected override AmqpObject OnCreateAmqpLink(AmqpConnection connection, AmqpLinkSettings linkSettings, AmqpSession amqpSession)
        {
            AmqpObject link = (linkSettings.IsReceiver()) ? (AmqpObject) new ReceivingAmqpLink(linkSettings) : (AmqpObject) new SendingAmqpLink(linkSettings);

            linkSettings.LinkName = $"{connection.Settings.ContainerId};{connection.Identifier}:{amqpSession.Identifier}:{link.Identifier}";
            ((AmqpLink)link).AttachTo(amqpSession);
            return(link);
        }
Ejemplo n.º 18
0
            protected void OnSenderClosedCallback(AmqpObject sender, Error error)
            {
                _Logger.LogError("OnSenderClosedCallback: " + error.Info + error.Description);
                // signal the connection will fail
                SetDead( );

                // re-create the connection pro-actively
                EstablishSender( );
            }
 public ActiveClientLinkObject(AmqpObject amqpLinkObject, string audience, string endpointUri, string[] requiredClaims, bool isClientToken, DateTime authorizationValidToUtc)
 {
     this.amqpLinkObject          = amqpLinkObject;
     this.audience                = audience;
     this.endpointUri             = endpointUri;
     this.requiredClaims          = requiredClaims;
     this.isClientToken           = isClientToken;
     this.authorizationValidToUtc = authorizationValidToUtc;
 }
Ejemplo n.º 20
0
            void OnLinkClosed(AmqpObject sender, Error error)
            {
                ListenerLink link = (ListenerLink)sender;

                lock (this.collection)
                {
                    this.collection.Remove(link);
                }
            }
Ejemplo n.º 21
0
            static void OnLinkClosed(AmqpObject sender, Error error)
            {
                ListenerLink link    = (ListenerLink)sender;
                var          thisPtr = (MessageProcessor)link.State;

                lock (thisPtr.links)
                {
                    thisPtr.links.Remove(link);
                }
            }
 protected override void SessionClosed(AmqpObject sender, Error error)
 {
     Logger.TraceLog("AMQP Session Closed. Error: " + error.ToString());
     if (this._amqpReceiver != null)
     {
         this._amqpReceiver.Close();
         this._amqpReceiver = null;
     }
     this.AmqpSession = null;
 }
        /// <summary>
        ///   Creates the timer event handler to support refreshing AMQP link authorization
        ///   on a recurring basis.
        /// </summary>
        /// <param name="entityPath"></param>
        ///
        /// <param name="connection">The AMQP connection to which the link being refreshed is bound to.</param>
        /// <param name="amqpLink">The AMQO link to refresh authorization for.</param>
        /// <param name="tokenProvider">The <see cref="CbsTokenProvider" /> to use for obtaining access tokens.</param>
        /// <param name="endpoint">The Service Bus service endpoint that the AMQP link is communicating with.</param>
        /// <param name="audience">The audience associated with the authorization.  This is likely the <paramref name="endpoint"/> absolute URI.</param>
        /// <param name="resource">The resource associated with the authorization.  This is likely the <paramref name="endpoint"/> absolute URI.</param>
        /// <param name="requiredClaims">The set of claims required to support the operations of the AMQP link.</param>
        /// <param name="refreshTimeout">The timeout to apply when requesting authorization refresh.</param>
        /// <param name="refreshTimerFactory">A function to allow retrieving the <see cref="Timer" /> associated with the link authorization.</param>
        ///
        /// <returns>A <see cref="TimerCallback"/> delegate to perform the refresh when a timer is due.</returns>
        ///
        protected virtual TimerCallback CreateAuthorizationRefreshHandler(
            string entityPath,
            AmqpConnection connection,
            AmqpObject amqpLink,
            CbsTokenProvider tokenProvider,
            Uri endpoint,
            string audience,
            string resource,
            string[] requiredClaims,
            TimeSpan refreshTimeout,
            Func <Timer> refreshTimerFactory)
        {
            return(async _ =>
            {
                ServiceBusEventSource.Log.AmqpLinkAuthorizationRefreshStart(entityPath, endpoint.AbsoluteUri);
                Timer refreshTimer = refreshTimerFactory();

                try
                {
                    if (refreshTimer == null)
                    {
                        return;
                    }

                    DateTime authExpirationUtc = await RequestAuthorizationUsingCbsAsync(connection, tokenProvider, endpoint, audience, resource, requiredClaims, refreshTimeout).ConfigureAwait(false);

                    // Reset the timer for the next refresh.

                    if (authExpirationUtc >= DateTimeOffset.UtcNow)
                    {
                        refreshTimer.Change(CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan);
                    }
                }
                catch (ObjectDisposedException)
                {
                    // This can occur if the connection is closed or the scope disposed after the factory
                    // is called but before the timer is updated.  The callback may also fire while the timer is
                    // in the act of disposing.  Do not consider it an error.
                }
                catch (Exception ex)
                {
                    ServiceBusEventSource.Log.AmqpLinkAuthorizationRefreshError(entityPath, endpoint.AbsoluteUri, ex.Message);

                    // Attempt to unset the timer; there's a decent chance that it has been disposed at this point or
                    // that the connection has been closed.  Ignore potential exceptions, as they won't impact operation.
                    // At worse, another timer tick will occur and the operation will be retried.

                    try { refreshTimer.Change(Timeout.Infinite, Timeout.Infinite); } catch {}
                }
                finally
                {
                    ServiceBusEventSource.Log.AmqpLinkAuthorizationRefreshComplete(entityPath, endpoint.AbsoluteUri);
                }
            });
        }
        void ReceiverLinkClosed(AmqpObject sender, Error error)
        {
            Logger.TraceLog("AMQP Link Closed. Error: " + error.ToString());
            this._amqpReceiver = null;

            // TODO: Only reconnect on transient/recoverable errors
            if (error != null)
            {
                // TODO - keep retrying (on background thread) if network is down for longe time periods
                this.Start();
            }
        }
Ejemplo n.º 25
0
        internal static Exception ConvertToIoTHubException(Exception exception, AmqpObject source)
        {
            Exception e = ConvertToIoTHubException(exception);

            if (source.IsClosing() && (e is InvalidOperationException || e is OperationCanceledException))
            {
                return(RESOUCE_DISCONNECTED_EXCEPTION);
            }
            else
            {
                return(e);
            }
        }
        internal static Exception ConvertToIoTHubException(Exception exception, AmqpObject source)
        {
            Exception e = ConvertToIoTHubException(exception);

            if (source.IsClosing() && (e is InvalidOperationException || e is OperationCanceledException))
            {
                return(new IotHubCommunicationException("Amqp resource is disconnected."));
            }
            else
            {
                return(e);
            }
        }
Ejemplo n.º 27
0
        private void OnAmqpObjectClosed(object sender, EventArgs args)
        {
            AmqpObject amqpObject = (AmqpObject)sender;

            amqpObject.Closed -= this.onAmqpObjectClosed;
            Exception terminalException = amqpObject.TerminalException;

            if (terminalException == null)
            {
                terminalException = new ConnectionLostException("The connection to the connect service was lost.");
            }
            this.OnDisconnected(ExceptionHelper.ToRelayContract(terminalException));
        }
Ejemplo n.º 28
0
 private void Sender_Closed(AmqpObject sender, Amqp.Framing.Error error)
 {
     if (!_closing)
     {
         var senderLink = (SenderLink)sender;
         var key        =
             _senders.ToArray().Where(pair => pair.Value == senderLink).Select(pair => pair.Key).FirstOrDefault();
         if (key != null)
         {
             SenderLink returnedLink;
             _senders.TryRemove(key, out returnedLink);
         }
     }
 }
Ejemplo n.º 29
0
        void OnControllerClosed(AmqpObject obj, Error error)
        {
            var  controller = (Controller)obj;
            bool removed;

            lock (this.SyncRoot)
            {
                removed = this.controllers.Remove(controller.Session.Connection);
            }

            if (removed)
            {
                controller.Session.Close(0);
            }
        }
        /// <summary>
        ///   Creates the timer event handler to support refreshing AMQP link authorization
        ///   on a recurring basis.
        /// </summary>
        ///
        /// <param name="connection">The AMQP connection to which the link being refreshed is bound to.</param>
        /// <param name="amqpLink">The AMQO link to refresh authorization for.</param>
        /// <param name="tokenProvider">The <see cref="CbsTokenProvider" /> to use for obtaining access tokens.</param>
        /// <param name="endpoint">The Event Hubs service endpoint that the AMQP link is communicating with.</param>
        /// <param name="audience">The audience associated with the authorization.  This is likely the <paramref name="endpoint"/> absolute URI.</param>
        /// <param name="resource">The resource associated with the authorization.  This is likely the <paramref name="endpoint"/> absolute URI.</param>
        /// <param name="requiredClaims">The set of claims required to support the operations of the AMQP link.</param>
        /// <param name="refreshTimeout">The timeout to apply when requesting authorization refresh.</param>
        /// <param name="refreshTimerFactory">A function to allow retrieving the <see cref="Timer" /> associated with the link authorization.</param>
        ///
        /// <returns>A <see cref="TimerCallback"/> delegate to perform the refresh when a timer is due.</returns>
        ///
        protected virtual TimerCallback CreateAuthorizationRefreshHandler(AmqpConnection connection,
                                                                          AmqpObject amqpLink,
                                                                          CbsTokenProvider tokenProvider,
                                                                          Uri endpoint,
                                                                          string audience,
                                                                          string resource,
                                                                          string[] requiredClaims,
                                                                          TimeSpan refreshTimeout,
                                                                          Func <Timer> refreshTimerFactory)
        {
            return(async _ =>
            {
                EventHubsEventSource.Log.AmqpLinkAuthorizationRefreshStart(EventHubName, endpoint.AbsoluteUri);
                var refreshTimer = refreshTimerFactory();

                try
                {
                    if (refreshTimer == null)
                    {
                        return;
                    }

                    var authExpirationUtc = await RequestAuthorizationUsingCbsAsync(connection, tokenProvider, endpoint, audience, resource, requiredClaims, refreshTimeout).ConfigureAwait(false);

                    // Reset the timer for the next refresh.

                    if (authExpirationUtc >= DateTimeOffset.UtcNow)
                    {
                        refreshTimer.Change(CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan);
                    }
                }
                catch (ObjectDisposedException)
                {
                    // This can occur if the connection is closed or the scope disposed after the factory
                    // is called but before the timer is updated.  The callback may also fire while the timer is
                    // in the act of disposing.  Do not consider it an error.
                }
                catch (Exception ex)
                {
                    EventHubsEventSource.Log.AmqpLinkAuthorizationRefreshError(EventHubName, endpoint.AbsoluteUri, ex.Message);
                    refreshTimer.Change(Timeout.Infinite, Timeout.Infinite);
                }
                finally
                {
                    EventHubsEventSource.Log.AmqpLinkAuthorizationRefreshComplete(EventHubName, endpoint.AbsoluteUri);
                }
            });
        }
        protected override async Task OpenLinkAsync(AmqpObject link, IotHubConnectionString doNotUse, string doNotUse2, TimeSpan timeout)
        {
            try
            {
                await link.OpenAsync(timeout);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                link.SafeClose(exception);

                throw;
            }
        }
Ejemplo n.º 32
0
 void OnConnectionClosed(AmqpObject sender, Error error)
 {
     lock (this.connections)
     {
         this.connections.Remove((Connection)sender);
     }
 }
Ejemplo n.º 33
0
        static async Task OpenLinkAsync(AmqpObject link, TimeSpan timeout)
        {
            var timeoutHelper = new TimeoutHelper(timeout);
            try
            {
                await link.OpenAsync(timeoutHelper.RemainingTime());
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                link.SafeClose(exception);

                throw;
            }
        }
        protected override async Task OpenLinkAsync(AmqpObject link, IotHubConnectionString connectionString, string audience, TimeSpan timeout)
        {
            var timeoutHelper = new TimeoutHelper(timeout);
       
            try
            {
                // this is a device-scope connection string. We need to send a CBS token for this specific link before opening it.
                var iotHubLinkTokenRefresher = new IotHubTokenRefresher(
                    this.FaultTolerantSession.Value, 
                    connectionString, 
                    audience
                    );

                if (this.iotHubTokenRefreshers.TryAdd(link, iotHubLinkTokenRefresher))
                {
                    link.SafeAddClosed((s, e) =>
                    {
                        if (this.iotHubTokenRefreshers.TryRemove(link, out iotHubLinkTokenRefresher))
                        {
                            iotHubLinkTokenRefresher.Cancel();
                        }
                    });

                    // Send Cbs token for new link first
                    await iotHubLinkTokenRefresher.SendCbsTokenAsync(timeoutHelper.RemainingTime());
                }

                // Open Amqp Link
                await link.OpenAsync(timeoutHelper.RemainingTime());
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                link.SafeClose(exception);
                throw;
            }
        }
Ejemplo n.º 35
0
 protected abstract Task OpenLinkAsync(AmqpObject link, IotHubConnectionString connectionString, string audience, TimeSpan timeout);
Ejemplo n.º 36
0
 void OnLinkClosed(AmqpObject sender, Error error)
 {
     this.Credit = 0;
     this.queue.OnConsumerClosed(this.id, this);
 }
Ejemplo n.º 37
0
 void OnLinkClosed(AmqpObject sender, Error error)
 {
     lock (this.queue.publishers)
     {
         this.queue.publishers.Remove(this.id);
     }
 }
Ejemplo n.º 38
0
        void OnOperationComplete(AmqpObject link, IAsyncResult result, bool isOpen)
        {
            Exception completeException = null;
            try
            {
                if (isOpen)
                {
                    link.EndOpen(result);
                }
                else
                {
                    link.EndClose(result);
                }
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                completeException = exception;
            }

            bool shouldComplete = true;
            if (completeException == null)
            {
                AmqpObjectState initialState = isOpen ? AmqpObjectState.OpenSent : AmqpObjectState.CloseSent;
                lock (this.ThisLock)
                {
                    shouldComplete = this.sender.State != initialState && this.receiver.State != initialState;
                }
            }

            if (shouldComplete)
            {
                if (isOpen)
                {
                    this.CompleteOpen(false, completeException);
                }
                else
                {
                    this.CompleteClose(false, completeException);
                }
            }
        }