Пример #1
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());
            }
        }
Пример #2
0
 internal void SafeClose()
 {
     _amqpSession.SafeClose();
 }
Пример #3
0
        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;

            AmqpLinkSettings 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
                }
            };

            amqpLinkSettings.SndSettleMode = senderSettleMode;
            amqpLinkSettings.RcvSettleMode = receiverSettleMode;
            amqpLinkSettings.AddProperty(AmqpIoTErrorAdapter.TimeoutName, timeout.TotalMilliseconds);
            amqpLinkSettings.AddProperty(AmqpIoTErrorAdapter.ClientVersion, deviceIdentity.ProductInfo.ToString());
            amqpLinkSettings.AddProperty(AmqpIoTErrorAdapter.ApiVersion, ClientApiVersionHelper.ApiVersionString);

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

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

            try
            {
                ReceivingAmqpLink 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)}");
                }
            }
        }
Пример #4
0
        async Task <SendingAmqpLink> CreateLinkAsync(TimeSpan timeout)
        {
            var amqpEventHubClient = ((AmqpEventHubClient)this.EventHubClient);

            var            timeoutHelper = new TimeoutHelper(timeout);
            AmqpConnection connection    = await amqpEventHubClient.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

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

            ICbsTokenProvider cbsTokenProvider = amqpEventHubClient.CbsTokenProvider;
            Uri    address   = new Uri(amqpEventHubClient.ConnectionStringBuilder.Endpoint, this.Path);
            string audience  = address.AbsoluteUri;
            string resource  = address.AbsoluteUri;
            var    expiresAt = await cbsLink.SendTokenAsync(
                cbsTokenProvider,
                address,
                audience,
                resource,
                new[] { ClaimConstants.Send },
                timeoutHelper.RemainingTime()).ConfigureAwait(false);

            AmqpSession session = null;

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

                // Create our Link
                var linkSettings = new AmqpLinkSettings();
                linkSettings.AddProperty(AmqpClientConstants.TimeoutName, (uint)timeoutHelper.RemainingTime().TotalMilliseconds);
                linkSettings.AddProperty(AmqpClientConstants.EntityTypeName, (int)MessagingEntityType.EventHub);
                linkSettings.Role = false;
                linkSettings.InitialDeliveryCount = 0;
                linkSettings.Target = new Target {
                    Address = address.AbsolutePath
                };
                linkSettings.Source = new Source {
                    Address = this.ClientId
                };

                var link = new SendingAmqpLink(linkSettings);
                linkSettings.LinkName = $"{amqpEventHubClient.ContainerId};{connection.Identifier}:{session.Identifier}:{link.Identifier}";
                link.AttachTo(session);

                await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                var activeClientLink = new ActiveClientLink(
                    link,
                    audience,                                                         // audience
                    this.EventHubClient.ConnectionStringBuilder.Endpoint.AbsoluteUri, // endpointUri
                    new[] { ClaimConstants.Send },
                    true,
                    expiresAt);

                this.MaxMessageSize = (long)activeClientLink.Link.Settings.MaxMessageSize();
                this.clientLinkManager.SetActiveLink(activeClientLink);
                return(link);
            }
            catch
            {
                // Cleanup any session (and thus link) in case of exception.
                session?.SafeClose();
                throw;
            }
        }
Пример #5
0
        async Task <ReceivingAmqpLink> CreateLinkAsync(TimeSpan timeout)
        {
            var amqpEventHubClient = ((AmqpEventHubClient)this.EventHubClient);

            var            timeoutHelper = new TimeoutHelper(timeout);
            AmqpConnection connection    = await amqpEventHubClient.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

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

            ICbsTokenProvider cbsTokenProvider = amqpEventHubClient.CbsTokenProvider;
            Uri    address   = new Uri(amqpEventHubClient.ConnectionStringBuilder.Endpoint, this.Path);
            string audience  = address.AbsoluteUri;
            string resource  = address.AbsoluteUri;
            var    expiresAt = await cbsLink.SendTokenAsync(cbsTokenProvider, address, audience, resource, new[] { ClaimConstants.Listen }, timeoutHelper.RemainingTime()).ConfigureAwait(false);

            AmqpSession session = null;

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

                FilterSet filterMap = null;
                var       filters   = this.CreateFilters();
                if (filters != null && filters.Count > 0)
                {
                    filterMap = new FilterSet();
                    foreach (var filter in filters)
                    {
                        filterMap.Add(filter.DescriptorName, filter);
                    }
                }

                // Create our Link
                var linkSettings = new AmqpLinkSettings
                {
                    Role            = true,
                    TotalLinkCredit = (uint)this.PrefetchCount,
                    AutoSendFlow    = this.PrefetchCount > 0
                };
                linkSettings.AddProperty(AmqpClientConstants.EntityTypeName, (int)MessagingEntityType.ConsumerGroup);
                linkSettings.Source = new Source {
                    Address = address.AbsolutePath, FilterSet = filterMap
                };
                linkSettings.Target = new Target {
                    Address = this.ClientId
                };
                linkSettings.SettleType = SettleMode.SettleOnSend;

                // Receiver metrics enabled?
                if (this.ReceiverRuntimeMetricEnabled)
                {
                    linkSettings.DesiredCapabilities = new Multiple <AmqpSymbol>(new List <AmqpSymbol>
                    {
                        AmqpClientConstants.EnableReceiverRuntimeMetricName
                    });
                }

                if (this.Epoch.HasValue)
                {
                    linkSettings.AddProperty(AmqpClientConstants.AttachEpoch, this.Epoch.Value);
                }

                if (!string.IsNullOrWhiteSpace(this.Identifier))
                {
                    linkSettings.AddProperty(AmqpClientConstants.ReceiverIdentifierName, this.Identifier);
                }

                var link = new ReceivingAmqpLink(linkSettings);
                linkSettings.LinkName = $"{amqpEventHubClient.ContainerId};{connection.Identifier}:{session.Identifier}:{link.Identifier}";
                link.AttachTo(session);

                await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                var activeClientLink = new ActiveClientLink(
                    link,
                    audience,                                                         // audience
                    this.EventHubClient.ConnectionStringBuilder.Endpoint.AbsoluteUri, // endpointUri
                    new[] { ClaimConstants.Listen },
                    true,
                    expiresAt);

                this.clientLinkManager.SetActiveLink(activeClientLink);

                return(link);
            }
            catch
            {
                // Cleanup any session (and thus link) in case of exception.
                session?.SafeClose();
                throw;
            }
        }
Пример #6
0
        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
                }
            };

            amqpLinkSettings.SndSettleMode = senderSettleMode;
            amqpLinkSettings.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)}");
                }
            }
        }
Пример #7
0
        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
                }
            };

            amqpLinkSettings.SndSettleMode = senderSettleMode;
            amqpLinkSettings.RcvSettleMode = receiverSettleMode;
            amqpLinkSettings.AddProperty(AmqpIoTErrorAdapter.TimeoutName, timeout.TotalMilliseconds);
            amqpLinkSettings.AddProperty(AmqpIoTErrorAdapter.ClientVersion, deviceIdentity.ProductInfo.ToString());
            amqpLinkSettings.AddProperty(AmqpIoTErrorAdapter.ApiVersion, ClientApiVersionHelper.ApiVersionString);
            if (CorrelationId != null)
            {
                amqpLinkSettings.AddProperty(AmqpIoTErrorAdapter.ChannelCorrelationId, CorrelationId);
            }

            try
            {
                SendingAmqpLink 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);
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(typeof(AmqpIoTSession), deviceIdentity, $"{nameof(OpenSendingAmqpLinkAsync)}");
                }
            }
        }
        public async Task <Tuple <AmqpObject, DateTime> > CreateAndOpenAmqpLinkAsync()
        {
            var timeoutHelper = new TimeoutHelper(this.serviceBusConnection.OperationTimeout, true);

            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>();
            DateTime cbsTokenExpiresAtUtc = DateTime.MaxValue;

            foreach (var resource in this.audience)
            {
                MessagingEventSource.Log.AmqpSendAuthenticationTokenStart(this.endpointAddress, resource, resource, this.requiredClaims);
                cbsTokenExpiresAtUtc = TimeoutHelper.Min(
                    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()
                };
                if (this.amqpLinkSettings.IsReceiver())
                {
                    // This is the maximum number of unsettled transfers across all receive links on this session.
                    // This will allow the session to accept unlimited number of transfers, even if the recevier(s)
                    // are not settling any of the deliveries.
                    amqpSessionSettings.IncomingWindow = uint.MaxValue;
                }

                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(), amqpConnection.IsClosing());
            }

            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(), amqpConnection.IsClosing());
            }
        }