Esempio n. 1
0
        private async Task OpenMethodsSenderLinkAsync(AmqpIotSession amqpIotSession, string correlationIdSuffix, CancellationToken cancellationToken)
        {
            if (_methodSendingLink == null ||
                _methodSendingLink.IsClosing())
            {
                _methodSendingLink?.SafeClose();

                _methodSendingLink = await amqpIotSession
                                     .OpenMethodsSenderLinkAsync(_deviceIdentity, correlationIdSuffix, cancellationToken)
                                     .ConfigureAwait(false);

                if (_methodSenderLinkDisconnected == null)
                {
                    _methodSenderLinkDisconnected = (obj, arg) =>
                    {
                        amqpIotSession.SafeClose();
                    };
                }

                _methodSendingLink.Closed += _methodSenderLinkDisconnected;

                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, _methodSendingLink, nameof(_methodSendingLink));
                }
            }
        }
Esempio n. 2
0
        private async Task OpenMethodsSenderLinkAsync(AmqpIotSession amqpIotSession, string correlationIdSuffix, TimeSpan timeout)
        {
            if (_methodSendingLink == null || _methodSendingLink.IsClosing())
            {
                _methodSendingLink?.SafeClose();

                _methodSendingLink = await amqpIotSession.OpenMethodsSenderLinkAsync(_deviceIdentity, correlationIdSuffix, timeout).ConfigureAwait(false);

                _methodSendingLink.Closed += (obj, arg) =>
                {
                    amqpIotSession.SafeClose();
                };
                Logging.Associate(this, _methodSendingLink, nameof(_methodSendingLink));
            }
        }
Esempio n. 3
0
        public async Task DisableMethodsAsync(TimeSpan timeout)
        {
            Logging.Enter(this, timeout, nameof(DisableMethodsAsync));

            Debug.Assert(_methodSendingLink != null);
            Debug.Assert(_methodReceivingLink != null);

            bool enteredSemaphore = await _methodLinkSemaphore.WaitAsync(timeout).ConfigureAwait(false);

            if (!enteredSemaphore)
            {
                throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP method sender and receiver links are closed.");
            }

            try
            {
                ICollection <Task> tasks = new List <Task>();
                if (_methodReceivingLink != null)
                {
                    tasks.Add(_methodReceivingLink.CloseAsync(timeout));
                }

                if (_methodSendingLink != null)
                {
                    tasks.Add(_methodSendingLink.CloseAsync(timeout));
                }

                if (tasks.Count > 0)
                {
                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    _methodReceivingLink = null;
                    _methodSendingLink   = null;
                }
            }
            finally
            {
                Logging.Exit(this, timeout, nameof(DisableMethodsAsync));
                _methodLinkSemaphore.Release();
            }
        }
Esempio n. 4
0
        internal async Task <AmqpIotSession> EnsureSessionIsOpenAsync(TimeSpan timeout)
        {
            if (_closed)
            {
                throw new IotHubException("Device is now offline.", false);
            }

            Logging.Enter(this, timeout, nameof(EnsureSessionIsOpenAsync));

            bool enteredSemaphore = await _sessionSemaphore.WaitAsync(timeout).ConfigureAwait(false);

            if (!enteredSemaphore)
            {
                throw new TimeoutException("Failed to enter the semaphore required for opening an AMQP session.");
            }

            try
            {
                if (_amqpIotSession == null || _amqpIotSession.IsClosing())
                {
                    _amqpIotSession?.SafeClose();

                    _amqpIotSession = await _amqpConnectionHolder.OpenSessionAsync(_deviceIdentity, timeout).ConfigureAwait(false);

                    Logging.Associate(this, _amqpIotSession, nameof(_amqpIotSession));

                    if (_deviceIdentity.AuthenticationModel == AuthenticationModel.SasIndividual)
                    {
                        _amqpAuthenticationRefresher = await _amqpConnectionHolder.CreateRefresherAsync(_deviceIdentity, timeout).ConfigureAwait(false);

                        Logging.Associate(this, _amqpAuthenticationRefresher, nameof(_amqpAuthenticationRefresher));
                    }

                    _amqpIotSession.Closed += OnSessionDisconnected;
                    _messageSendingLink     = await _amqpIotSession.OpenTelemetrySenderLinkAsync(_deviceIdentity, timeout).ConfigureAwait(false);

                    _messageSendingLink.Closed += (obj, arg) =>
                    {
                        _amqpIotSession.SafeClose();
                    };

                    Logging.Associate(this, _messageSendingLink, nameof(_messageSendingLink));
                }

                if (_disposed)
                {
                    throw new IotHubException("Device is now offline.", false);
                }
            }
            catch (Exception)
            {
                Cleanup();
                throw;
            }
            finally
            {
                _sessionSemaphore.Release();
            }

            Logging.Exit(this, timeout, nameof(EnsureSessionIsOpenAsync));

            return(_amqpIotSession);
        }
Esempio n. 5
0
        public async Task DisableMethodsAsync(CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(DisableMethodsAsync));
            }

            Debug.Assert(_methodSendingLink != null);
            Debug.Assert(_methodReceivingLink != null);

            try
            {
                await _methodLinkSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP method sender and receiver links are closed.");
            }

            // These event handlers are in place for network drop cases and will try to close the session that this
            // link belongs to, but that isn't necessary when the client is deliberately closing just the link.
            if (_methodReceiverLinkDisconnected != null)
            {
                _methodReceivingLink.Closed -= _methodReceiverLinkDisconnected;
            }

            if (_methodSenderLinkDisconnected != null)
            {
                _methodSendingLink.Closed -= _methodSenderLinkDisconnected;
            }

            try
            {
                ICollection <Task> tasks = new List <Task>(2);
                if (_methodReceivingLink != null)
                {
                    tasks.Add(_methodReceivingLink.CloseAsync(cancellationToken));
                }

                if (_methodSendingLink != null)
                {
                    tasks.Add(_methodSendingLink.CloseAsync(cancellationToken));
                }

                if (tasks.Count > 0)
                {
                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    _methodReceivingLink = null;
                    _methodSendingLink   = null;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(DisableMethodsAsync));
                }
                _methodLinkSemaphore.Release();
            }
        }