Пример #1
0
        public async Task EnableMethodsAsync(TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, timeout, $"{nameof(EnableMethodsAsync)}");
            }

            try
            {
                Debug.Assert(_methodSendingLink == null);
                Debug.Assert(_methodReceivingLink == null);

                string correlationIdSuffix = Guid.NewGuid().ToString();

                Task <AmqpIoTReceivingLink> receiveLinkCreator = _amqpIoTSession.OpenMethodsReceiverLinkAsync(_deviceIdentity, correlationIdSuffix, timeout);
                Task <AmqpIoTSendingLink>   sendingLinkCreator = _amqpIoTSession.OpenMethodsSenderLinkAsync(_deviceIdentity, correlationIdSuffix, timeout);
                await Task.WhenAll(receiveLinkCreator, sendingLinkCreator).ConfigureAwait(false);

                _methodReceivingLink = receiveLinkCreator.Result;
                _methodSendingLink   = sendingLinkCreator.Result;

                _methodReceivingLink.RegisterMethodListener(OnMethodReceived);
                _methodSendingLink.Closed   += OnLinkDisconnected;
                _methodReceivingLink.Closed += OnLinkDisconnected;

                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, _methodReceivingLink, $"{nameof(_methodReceivingLink)}");
                }
                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, _methodSendingLink, $"{nameof(_methodSendingLink)}");
                }
            }
            catch (Exception)
            {
                _methodReceivingLink?.Abort();
                _methodReceivingLink = null;

                _methodSendingLink?.Abort();
                _methodSendingLink = null;

                throw;
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, timeout, $"{nameof(EnableMethodsAsync)}");
                }
            }
        }
Пример #2
0
        private async Task OpenTwinSenderLinkAsync(AmqpIoTSession amqpIoTSession, string correlationIdSuffix, TimeSpan timeout)
        {
            if (_twinSendingLink == null || _twinSendingLink.IsClosing())
            {
                _twinSendingLink = await amqpIoTSession.OpenTwinSenderLinkAsync(_deviceIdentity, correlationIdSuffix, timeout).ConfigureAwait(false);

                _twinSendingLink.Closed += (obj, arg) => {
                    amqpIoTSession.SafeClose();
                };
                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, _twinSendingLink, $"{nameof(_twinSendingLink)}");
                }
            }
        }
Пример #3
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));
            }
        }
Пример #4
0
        public async Task DisableTwinLinksAsync(TimeSpan timeout)
        {
            Logging.Enter(this, timeout, nameof(DisableTwinLinksAsync));

            Debug.Assert(_twinSendingLink != null);
            Debug.Assert(_twinReceivingLink != null);

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

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

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

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

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

                    _twinReceivingLink = null;
                    _twinSendingLink   = null;
                }
            }
            finally
            {
                Logging.Exit(this, timeout, nameof(DisableTwinLinksAsync));
                _twinLinksSemaphore.Release();
            }
        }
Пример #5
0
        public async Task DisableMethodsAsync(TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, timeout, $"{nameof(DisableMethodsAsync)}");
            }

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

            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
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, timeout, $"{nameof(DisableMethodsAsync)}");
                }
            }
        }
Пример #6
0
        internal async Task <AmqpIoTSession> EnsureSessionAsync(TimeSpan timeout)
        {
            if (_closed)
            {
                throw new IotHubException("Device is now offline.", false);
            }

            if (Logging.IsEnabled)
            {
                Logging.Enter(this, timeout, $"{nameof(EnsureSessionAsync)}");
            }
            bool gain = await _sessionLock.WaitAsync(timeout).ConfigureAwait(false);

            if (!gain)
            {
                throw new TimeoutException();
            }

            try
            {
                if (_amqpIoTSession == null || _amqpIoTSession.IsClosing())
                {
                    _amqpIoTSession = await _amqpConnectionHolder.OpenSessionAsync(_deviceIdentity, timeout).ConfigureAwait(false);

                    if (Logging.IsEnabled)
                    {
                        Logging.Associate(this, _amqpIoTSession, $"{nameof(_amqpIoTSession)}");
                    }
                    if (_deviceIdentity.AuthenticationModel == AuthenticationModel.SasIndividual)
                    {
                        _amqpAuthenticationRefresher = await _amqpConnectionHolder.CreateRefresherAsync(_deviceIdentity, timeout).ConfigureAwait(false);

                        if (Logging.IsEnabled)
                        {
                            Logging.Associate(this, _amqpAuthenticationRefresher, $"{nameof(_amqpAuthenticationRefresher)}");
                        }
                    }

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

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

                    if (Logging.IsEnabled)
                    {
                        Logging.Associate(this, _messageSendingLink, $"{nameof(_messageSendingLink)}");
                    }
                }

                if (_disposed)
                {
                    _amqpAuthenticationRefresher?.StopLoop();
                    _amqpIoTSession.SafeClose();
                    if (!_deviceIdentity.IsPooling())
                    {
                        _amqpConnectionHolder.Dispose();
                    }
                    throw new IotHubException("Device is now offline.", false);
                }
            }
            finally
            {
                _sessionLock.Release();
            }


            if (Logging.IsEnabled)
            {
                Logging.Exit(this, timeout, $"{nameof(EnsureSessionAsync)}");
            }
            return(_amqpIoTSession);
        }
Пример #7
0
        public async Task OpenAsync(TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, timeout, $"{nameof(OpenAsync)}");
            }

            try
            {
                Debug.Assert(_amqpIoTSession == null);
                Debug.Assert(IsUsable());

                _amqpIoTSession = await _amqpSessionCreator.CreateSession(
                    _deviceIdentity,
                    timeout).ConfigureAwait(false);

                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, _amqpIoTSession, $"{nameof(_amqpIoTSession)}");
                }
                await _amqpIoTSession.OpenAsync(timeout).ConfigureAwait(false);

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

                    if (Logging.IsEnabled)
                    {
                        Logging.Associate(this, _amqpAuthenticationRefresher, $"{nameof(_amqpAuthenticationRefresher)}");
                    }
                }

                _amqpIoTSession.Closed += OnSessionDisconnected;

                _messageSendingLink = await _amqpIoTSession.OpenTelemetrySenderLinkAsync(
                    _deviceIdentity,
                    timeout).ConfigureAwait(false);

                _messageSendingLink.Closed += OnLinkDisconnected;

                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, _messageSendingLink, $"{nameof(_messageSendingLink)}");
                }
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                if (SetNotUsable() == 0)
                {
                    OnUnitDisconnected?.Invoke(false, EventArgs.Empty);
                }

                throw;
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, timeout, $"{nameof(OpenAsync)}");
                }
            }
        }
Пример #8
0
        public async Task EnsureTwinLinksAreOpenedAsync(TimeSpan timeout)
        {
            if (Volatile.Read(ref _twinLinksOpened) == true)
            {
                return;
            }
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, timeout, $"{nameof(EnsureTwinLinksAreOpenedAsync)}");
            }

            try
            {
                await _twinLinksLock.WaitAsync().ConfigureAwait(false);

                if (_twinLinksOpened)
                {
                    return;
                }

                Debug.Assert(_twinSendingLink == null);
                Debug.Assert(_twinReceivingLink == null);

                string correlationIdSuffix = Guid.NewGuid().ToString();

                Task <AmqpIoTReceivingLink> receiveLinkCreator = _amqpIoTSession.OpenTwinReceiverLinkAsync(_deviceIdentity, correlationIdSuffix, timeout);
                Task <AmqpIoTSendingLink>   sendingLinkCreator = _amqpIoTSession.OpenTwinSenderLinkAsync(_deviceIdentity, correlationIdSuffix, timeout);
                await Task.WhenAll(receiveLinkCreator, sendingLinkCreator).ConfigureAwait(false);

                _twinSendingLink         = sendingLinkCreator.Result;
                _twinSendingLink.Closed += OnLinkDisconnected;

                _twinReceivingLink = receiveLinkCreator.Result;
                _twinReceivingLink.RegisterTwinListener(OnDesiredPropertyReceived);
                _twinReceivingLink.Closed += OnLinkDisconnected;

                _twinLinksOpened = true;

                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, this, _twinReceivingLink, $"{nameof(EnsureTwinLinksAreOpenedAsync)}");
                }
                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, this, _twinSendingLink, $"{nameof(EnsureTwinLinksAreOpenedAsync)}");
                }
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                _twinReceivingLink?.Abort();
                _twinSendingLink?.Abort();
                _twinReceivingLink = null;
                _twinSendingLink   = null;

                throw;
            }
            finally
            {
                _twinLinksLock.Release();
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, timeout, $"{nameof(EnsureTwinLinksAreOpenedAsync)}");
                }
            }
        }
Пример #9
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);
        }