internal async Task <IAmqpAuthenticationRefresher> CreateRefresherAsync(DeviceIdentity deviceIdentity, TimeSpan timeout)
        {
            if (_amqpConnection.IsClosing())
            {
                throw new IotHubCommunicationException("Amqp connection is disconnected.");
            }
            try
            {
                IAmqpAuthenticationRefresher amqpAuthenticator = new AmqpAuthenticationRefresher(deviceIdentity, _amqpIotCbsLink);
                await amqpAuthenticator.InitLoopAsync(timeout).ConfigureAwait(false);

                return(amqpAuthenticator);
            }
            catch (Exception e) when(!e.IsFatal())
            {
                Exception ex = AmqpIotExceptionAdapter.ConvertToIotHubException(e, _amqpConnection);

                if (ReferenceEquals(e, ex))
                {
                    throw;
                }
                else
                {
                    throw ex;
                }
            }
        }
        internal async Task <Message> ReceiveAmqpMessageAsync(CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(ReceiveAmqpMessageAsync));
            }

            try
            {
                AmqpMessage amqpMessage = await _receivingAmqpLink.ReceiveMessageAsync(cancellationToken).ConfigureAwait(false);

                Message message = null;
                if (amqpMessage != null)
                {
                    message           = AmqpIotMessageConverter.AmqpMessageToMessage(amqpMessage);
                    message.LockToken = new Guid(amqpMessage.DeliveryTag.Array).ToString();
                }
                return(message);
            }
            catch (Exception e) when(!e.IsFatal())
            {
                Exception ex = AmqpIotExceptionAdapter.ConvertToIotHubException(e, _receivingAmqpLink);

                if (ReferenceEquals(e, ex))
                {
                    throw;
                }
                else
                {
                    if (ex is AmqpIotResourceException)
                    {
                        _receivingAmqpLink.SafeClose();
                        throw new IotHubCommunicationException(ex.Message, ex);
                    }
                    throw ex;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(ReceiveAmqpMessageAsync));
                }
            }
        }
        private async Task <Outcome> SendAmqpMessageAsync(AmqpMessage amqpMessage, CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(SendAmqpMessageAsync));
            }

            try
            {
                return(await _sendingAmqpLink
                       .SendMessageAsync(
                           amqpMessage,
                           new ArraySegment <byte>(Guid.NewGuid().ToByteArray()),
                           AmqpConstants.NullBinary,
                           cancellationToken)
                       .ConfigureAwait(false));
            }
            catch (Exception e) when(!e.IsFatal())
            {
                Exception ex = AmqpIotExceptionAdapter.ConvertToIotHubException(e, _sendingAmqpLink);

                if (ReferenceEquals(e, ex))
                {
                    throw;
                }
                else
                {
                    if (ex is AmqpIotResourceException)
                    {
                        _sendingAmqpLink.SafeClose();
                        throw new IotHubCommunicationException(ex.Message, ex);
                    }
                    throw ex;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(SendAmqpMessageAsync));
                }
            }
        }
Пример #4
0
        public async Task <DateTime> SendTokenAsync(
            ICbsTokenProvider tokenProvider,
            Uri namespaceAddress,
            string audience,
            string resource,
            string[] requiredClaims,
            CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(SendTokenAsync));
            }

            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                return(await _amqpCbsLink
                       .SendTokenAsync(tokenProvider, namespaceAddress, audience, resource, requiredClaims, cancellationToken)
                       .ConfigureAwait(false));
            }
            catch (AmqpException e) when(!e.IsFatal())
            {
                Exception ex = AmqpIotExceptionAdapter.ConvertToIotHubException(e);

                if (ReferenceEquals(e, ex))
                {
                    throw;
                }
                else
                {
                    throw ex;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(SendTokenAsync));
                }
            }
        }
        internal async Task <AmqpIotSession> OpenSessionAsync(TimeSpan timeout)
        {
            if (_amqpConnection.IsClosing())
            {
                throw new IotHubCommunicationException("Amqp connection is disconnected.");
            }

            var amqpSessionSettings = new AmqpSessionSettings
            {
                Properties = new Fields(),
            };

            try
            {
                var amqpSession = new AmqpSession(_amqpConnection, amqpSessionSettings, AmqpIotLinkFactory.GetInstance());
                _amqpConnection.AddSession(amqpSession, new ushort?());
                await amqpSession.OpenAsync(timeout).ConfigureAwait(false);

                return(new AmqpIotSession(amqpSession));
            }
            catch (Exception e) when(!e.IsFatal())
            {
                Exception ex = AmqpIotExceptionAdapter.ConvertToIotHubException(e, _amqpConnection);

                if (ReferenceEquals(e, ex))
                {
                    throw;
                }
                else
                {
                    if (ex is AmqpIotResourceException)
                    {
                        _amqpConnection.SafeClose();
                        throw new IotHubCommunicationException(ex.Message, ex);
                    }
                    throw ex;
                }
            }
        }
        private static async Task <AmqpIotReceivingLink> OpenReceivingAmqpLinkAsync(
            DeviceIdentity deviceIdentity,
            AmqpSession amqpSession,
            byte?senderSettleMode,
            byte?receiverSettleMode,
            string deviceTemplate,
            string moduleTemplate,
            string linkSuffix,
            string correlationId,
            TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(typeof(AmqpIotSession), deviceIdentity, $"{nameof(OpenReceivingAmqpLinkAsync)}");
            }

            uint prefetchCount = deviceIdentity.AmqpTransportSettings.PrefetchCount;

            var amqpLinkSettings = new AmqpLinkSettings
            {
                LinkName        = linkSuffix,
                Role            = true,
                TotalLinkCredit = prefetchCount,
                AutoSendFlow    = prefetchCount > 0,
                Source          = new Source {
                    Address = BuildLinkAddress(deviceIdentity, deviceTemplate, moduleTemplate)
                },
                Target = new Target {
                    Address = deviceIdentity.IotHubConnectionString.DeviceId
                },
                SndSettleMode = senderSettleMode,
                RcvSettleMode = receiverSettleMode,
            };

            amqpLinkSettings.AddProperty(AmqpIotErrorAdapter.TimeoutName, timeout.TotalMilliseconds);
            amqpLinkSettings.AddProperty(AmqpIotConstants.ClientVersion, deviceIdentity.ProductInfo.ToString());
            amqpLinkSettings.AddProperty(AmqpIotConstants.ApiVersion, ClientApiVersionHelper.ApiVersionString);

            if (!deviceIdentity.AmqpTransportSettings.AuthenticationChain.IsNullOrWhiteSpace())
            {
                amqpLinkSettings.AddProperty(AmqpIotConstants.AuthChain, deviceIdentity.AmqpTransportSettings.AuthenticationChain);
            }

            if (correlationId != null)
            {
                amqpLinkSettings.AddProperty(AmqpIotConstants.ChannelCorrelationId, correlationId);
            }

            try
            {
                var receivingLink = new ReceivingAmqpLink(amqpLinkSettings);
                receivingLink.AttachTo(amqpSession);
                await receivingLink.OpenAsync(timeout).ConfigureAwait(false);

                return(new AmqpIotReceivingLink(receivingLink));
            }
            catch (Exception e) when(!e.IsFatal())
            {
                Exception ex = AmqpIotExceptionAdapter.ConvertToIotHubException(e, amqpSession);

                if (ReferenceEquals(e, ex))
                {
                    throw;
                }
                else
                {
                    if (ex is AmqpIotResourceException)
                    {
                        amqpSession.SafeClose();
                        throw new IotHubCommunicationException(ex.Message, ex);
                    }
                    throw ex;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(typeof(AmqpIotSession), deviceIdentity, $"{nameof(OpenReceivingAmqpLinkAsync)}");
                }
            }
        }
        private static async Task <AmqpIotSendingLink> OpenSendingAmqpLinkAsync(
            DeviceIdentity deviceIdentity,
            AmqpSession amqpSession,
            byte?senderSettleMode,
            byte?receiverSettleMode,
            string deviceTemplate,
            string moduleTemplate,
            string linkSuffix,
            string correlationId,
            TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(typeof(AmqpIotSession), deviceIdentity, nameof(OpenSendingAmqpLinkAsync));
            }

            AmqpLinkSettings amqpLinkSettings = new AmqpLinkSettings
            {
                LinkName             = linkSuffix,
                Role                 = false,
                InitialDeliveryCount = 0,
                Target               = new Target {
                    Address = BuildLinkAddress(deviceIdentity, deviceTemplate, moduleTemplate)
                },
                Source = new Source {
                    Address = deviceIdentity.IotHubConnectionString.DeviceId
                },
                SndSettleMode = senderSettleMode,
                RcvSettleMode = receiverSettleMode,
            };

            amqpLinkSettings.AddProperty(AmqpIotErrorAdapter.TimeoutName, timeout.TotalMilliseconds);
            amqpLinkSettings.AddProperty(AmqpIotConstants.ClientVersion, deviceIdentity.ProductInfo.ToString());

            if (correlationId != null)
            {
                amqpLinkSettings.AddProperty(AmqpIotConstants.ChannelCorrelationId, correlationId);
            }

            if (!deviceIdentity.AmqpTransportSettings.AuthenticationChain.IsNullOrWhiteSpace())
            {
                amqpLinkSettings.AddProperty(AmqpIotConstants.AuthChain, deviceIdentity.AmqpTransportSettings.AuthenticationChain);
            }

            // This check is added to enable the device or module client to available plug and play features. For devices or modules that pass in the model Id,
            // the SDK will enable plug and play features by setting the modelId to Amqp link settings.
            if (!string.IsNullOrWhiteSpace(deviceIdentity.Options?.ModelId))
            {
                amqpLinkSettings.AddProperty(AmqpIotConstants.ModelId, deviceIdentity.Options.ModelId);
            }

            amqpLinkSettings.AddProperty(AmqpIotConstants.ApiVersion, ClientApiVersionHelper.ApiVersionString);

            try
            {
                var sendingLink = new SendingAmqpLink(amqpLinkSettings);
                sendingLink.AttachTo(amqpSession);
                await sendingLink.OpenAsync(timeout).ConfigureAwait(false);

                return(new AmqpIotSendingLink(sendingLink));
            }
            catch (Exception e) when(!e.IsFatal())
            {
                Exception ex = AmqpIotExceptionAdapter.ConvertToIotHubException(e, amqpSession);

                if (ReferenceEquals(e, ex))
                {
                    throw;
                }
                else
                {
                    if (ex is AmqpIotResourceException)
                    {
                        amqpSession.SafeClose();
                        throw new IotHubCommunicationException(ex.Message, ex);
                    }
                    throw ex;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(typeof(AmqpIotSession), deviceIdentity, nameof(OpenSendingAmqpLinkAsync));
                }
            }
        }