Пример #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));
                }
            }
        }
Пример #2
0
        internal async Task EnableTwinLinksAsync(TimeSpan timeout)
        {
            if (_closed)
            {
                throw new IotHubException("Device is now offline.", false);
            }

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

            AmqpIotSession amqpIotSession = await EnsureSessionIsOpenAsync(timeout).ConfigureAwait(false);

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

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

                await Task
                .WhenAll(
                    OpenTwinReceiverLinkAsync(amqpIotSession, correlationIdSuffix, timeout),
                    OpenTwinSenderLinkAsync(amqpIotSession, correlationIdSuffix, timeout))
                .ConfigureAwait(false);
            }
            finally
            {
                _twinLinksSemaphore.Release();
                Logging.Exit(this, timeout, nameof(EnableTwinLinksAsync));
            }
        }
Пример #3
0
        private async Task OpenTwinReceiverLinkAsync(AmqpIotSession amqpIotSession, string correlationIdSuffix, CancellationToken cancellationToken)
        {
            if (_twinReceivingLink == null ||
                _twinReceivingLink.IsClosing())
            {
                _twinReceivingLink?.SafeClose();

                _twinReceivingLink = await amqpIotSession
                                     .OpenTwinReceiverLinkAsync(_deviceIdentity, correlationIdSuffix, cancellationToken)
                                     .ConfigureAwait(false);

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

                _twinReceivingLink.Closed += _twinReceiverLinkDisconnected;

                _twinReceivingLink.RegisterTwinListener(OnDesiredPropertyReceived);
                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, _twinReceivingLink, nameof(_twinReceivingLink));
                }
            }
        }
Пример #4
0
        public async Task EnableEventReceiveAsync(CancellationToken cancellationToken)
        {
            if (_closed)
            {
                throw new IotHubException("Device is now offline.", false);
            }

            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(EnableEventReceiveAsync));
            }

            AmqpIotSession amqpIotSession = await EnsureSessionIsOpenAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                await _eventReceivingLinkSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP event receiver links are open.");
            }

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

                    _eventReceivingLink = await amqpIotSession
                                          .OpenEventsReceiverLinkAsync(_deviceIdentity, cancellationToken)
                                          .ConfigureAwait(false);

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

                    _messageReceivingLink.Closed += _eventReceiverLinkDisconnected;
                    _eventReceivingLink.RegisterEventListener(OnEventsReceived);
                    if (Logging.IsEnabled)
                    {
                        Logging.Associate(this, this, _eventReceivingLink, nameof(EnableEventReceiveAsync));
                    }
                }
            }
            finally
            {
                _eventReceivingLinkSemaphore.Release();
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(EnableEventReceiveAsync));
                }
            }
        }
Пример #5
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));
            }
        }
Пример #6
0
        private async Task OpenTwinReceiverLinkAsync(AmqpIotSession amqpIotSession, string correlationIdSuffix, TimeSpan timeout)
        {
            if (_twinReceivingLink == null || _twinReceivingLink.IsClosing())
            {
                _twinReceivingLink?.SafeClose();

                _twinReceivingLink = await amqpIotSession
                                     .OpenTwinReceiverLinkAsync(_deviceIdentity, correlationIdSuffix, timeout)
                                     .ConfigureAwait(false);

                _twinReceivingLink.Closed += (obj, arg) =>
                {
                    amqpIotSession.SafeClose();
                };
                _twinReceivingLink.RegisterTwinListener(OnDesiredPropertyReceived);
                Logging.Associate(this, _twinReceivingLink, nameof(_twinReceivingLink));
            }
        }
Пример #7
0
        private async Task EnsureMessageReceivingLinkIsOpenAsync(TimeSpan timeout, bool enableCallback = false)
        {
            if (_closed)
            {
                throw new IotHubException("Device is now offline.", false);
            }

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

            AmqpIotSession amqpIotSession = await EnsureSessionIsOpenAsync(timeout).ConfigureAwait(false);

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

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

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

                    _messageReceivingLink = await amqpIotSession.OpenMessageReceiverLinkAsync(_deviceIdentity, timeout).ConfigureAwait(false);

                    _messageReceivingLink.Closed += (obj, arg) =>
                    {
                        amqpIotSession.SafeClose();
                    };
                    Logging.Associate(this, this, _messageReceivingLink, nameof(EnsureMessageReceivingLinkIsOpenAsync));
                }

                if (enableCallback)
                {
                    _messageReceivingLink.RegisterReceiveMessageListener(OnDeviceMessageReceived);
                }
            }
            finally
            {
                _messageReceivingLinkSemaphore.Release();
                Logging.Exit(this, timeout, nameof(EnsureMessageReceivingLinkIsOpenAsync));
            }
        }
Пример #8
0
        internal async Task EnableTwinLinksAsync(CancellationToken cancellationToken)
        {
            if (_closed)
            {
                throw new IotHubException("Device is now offline.", false);
            }

            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(EnableTwinLinksAsync));
            }

            AmqpIotSession amqpIotSession = await EnsureSessionIsOpenAsync(cancellationToken).ConfigureAwait(false);

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

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

                await Task
                .WhenAll(
                    OpenTwinReceiverLinkAsync(amqpIotSession, correlationIdSuffix, cancellationToken),
                    OpenTwinSenderLinkAsync(amqpIotSession, correlationIdSuffix, cancellationToken))
                .ConfigureAwait(false);
            }
            finally
            {
                _twinLinksSemaphore.Release();
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(EnableTwinLinksAsync));
                }
            }
        }
Пример #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);
        }