Ejemplo n.º 1
0
        public async Task <AmqpObject> CreateAndOpenAmqpLinkAsync()
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(this.serviceBusConnection.OperationTimeout);

            MessagingEventSource.Log.AmqpGetOrCreateConnectionStart();
            AmqpConnection connection = await this.serviceBusConnection.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            MessagingEventSource.Log.AmqpGetOrCreateConnectionStop();

            // Authenticate over CBS
            AmqpCbsLink cbsLink  = connection.Extensions.Find <AmqpCbsLink>();
            Uri         address  = new Uri(this.serviceBusConnection.Endpoint, this.entityPath);
            string      audience = address.AbsoluteUri;
            string      resource = address.AbsoluteUri;

            MessagingEventSource.Log.AmqpSendAuthenticanTokenStart(address, audience, resource, this.requiredClaims);
            await cbsLink.SendTokenAsync(this.cbsTokenProvider, address, audience, resource, this.requiredClaims, timeoutHelper.RemainingTime()).ConfigureAwait(false);

            MessagingEventSource.Log.AmqpSendAuthenticanTokenStop();

            AmqpSession session = null;

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

                // Create our Link
                AmqpObject link = this.OnCreateAmqpLink(connection, this.amqpLinkSettings, session);
                await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                return(link);
            }
            catch (Exception)
            {
                session?.Abort();
                throw;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///   Requests authorization for a connection or link using a connection via the CBS mechanism.
        /// </summary>
        ///
        /// <param name="connection">The AMQP connection for which the authorization is associated.</param>
        /// <param name="tokenProvider">The <see cref="CbsTokenProvider" /> to use for obtaining access tokens.</param>
        /// <param name="endpoint">The Service Bus service endpoint that the authorization is requested for.</param>
        /// <param name="audience">The audience associated with the authorization.  This is likely the <paramref name="endpoint"/> absolute URI.</param>
        /// <param name="requiredClaims">The set of claims required to support the operations of the AMQP link.</param>
        /// <param name="timeout">The timeout to apply when requesting authorization.</param>
        ///
        /// <returns>The date/time, in UTC, when the authorization expires.</returns>
        ///
        /// <remarks>
        ///   It is assumed that there is a valid <see cref="AmqpCbsLink" /> already associated
        ///   with the connection; this will be used as the transport for the authorization
        ///   credentials.
        /// </remarks>
        ///
        protected virtual async Task <DateTime> RequestAuthorizationUsingCbsAsync(
            AmqpConnection connection,
            CbsTokenProvider tokenProvider,
            Uri endpoint,
            string[] audience,
            string[] requiredClaims,
            TimeSpan timeout)
        {
            AmqpCbsLink authLink             = connection.Extensions.Find <AmqpCbsLink>();
            DateTime    cbsTokenExpiresAtUtc = DateTime.MaxValue;

            foreach (string resource in audience)
            {
                cbsTokenExpiresAtUtc = TimeoutHelper.Min(
                    cbsTokenExpiresAtUtc,
                    await authLink.SendTokenAsync(TokenProvider, endpoint, resource, resource, requiredClaims, timeout).ConfigureAwait(false));
            }
            return(cbsTokenExpiresAtUtc);
        }
Ejemplo n.º 3
0
        private async Task SendCbsTokenAsync(AmqpCbsLink cbsLink, TimeSpan timeout)
        {
            Logging.Enter(this, cbsLink, timeout, nameof(SendCbsTokenAsync));

            string   audience     = Credential.AmqpEndpoint.AbsoluteUri;
            string   resource     = Credential.AmqpEndpoint.AbsoluteUri;
            DateTime expiresAtUtc = await cbsLink
                                    .SendTokenAsync(
                Credential,
                Credential.AmqpEndpoint,
                audience,
                resource,
                Credential.AmqpAudience.ToArray(),
                timeout)
                                    .ConfigureAwait(false);

            ScheduleTokenRefresh(expiresAtUtc);

            Logging.Exit(this, cbsLink, timeout, nameof(SendCbsTokenAsync));
        }
        private async Task SendCbsTokenAsync(AmqpCbsLink cbsLink, TimeSpan timeout)
        {
            Logging.Enter(this, cbsLink, timeout, nameof(SendCbsTokenAsync));

            string   audience     = ConnectionString.AmqpEndpoint.AbsoluteUri;
            string   resource     = ConnectionString.AmqpEndpoint.AbsoluteUri;
            DateTime expiresAtUtc = await cbsLink
                                    .SendTokenAsync(
                ConnectionString,
                ConnectionString.AmqpEndpoint,
                audience,
                resource,
                AccessRightsHelper.AccessRightsToStringArray(_accessRights),
                timeout)
                                    .ConfigureAwait(false);

            ScheduleTokenRefresh(expiresAtUtc);

            Logging.Exit(this, cbsLink, timeout, nameof(SendCbsTokenAsync));
        }
        async Task <AmqpConnection> CreateConnectionAsync(TimeSpan timeout)
        {
            string hostName      = this.ConnectionStringBuilder.Endpoint.Host;
            int    port          = this.ConnectionStringBuilder.Endpoint.Port;
            bool   useWebSockets = this.ConnectionStringBuilder.TransportType == Microsoft.Azure.EventHubs.TransportType.AmqpWebSockets;

            var timeoutHelper = new TimeoutHelper(timeout);
            var amqpSettings  = CreateAmqpSettings(
                amqpVersion: this.AmqpVersion,
                useSslStreamSecurity: true,
                hasTokenProvider: true,
                useWebSockets: useWebSockets);

            TransportSettings tpSettings = null;

            if (useWebSockets)
            {
                tpSettings = CreateWebSocketsTransportSettings(hostName, this.WebProxy);
            }
            else
            {
                tpSettings = CreateTcpTlsTransportSettings(hostName, port);
            }

            var initiator = new AmqpTransportInitiator(amqpSettings, tpSettings);
            var transport = await initiator.ConnectTaskAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            var connectionSettings = CreateAmqpConnectionSettings(this.MaxFrameSize, this.ContainerId, hostName);
            var connection         = new AmqpConnection(transport, amqpSettings, connectionSettings);
            await connection.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            // Always create the CBS Link + Session
            var cbsLink = new AmqpCbsLink(connection);

            if (connection.Extensions.Find <AmqpCbsLink>() == null)
            {
                connection.Extensions.Add(cbsLink);
            }

            return(connection);
        }
Ejemplo n.º 6
0
        private async Task <IAmqpAuthenticationRefresher> AuthenticationRefresherCreator(DeviceIdentity deviceIdentity, TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, deviceIdentity, timeout, $"{nameof(AuthenticationRefresherCreator)}");
            }
            if (AmqpConnection == null)
            {
                throw new IotHubCommunicationException();
            }
            AmqpCbsLink = AmqpCbsLink ?? new AmqpCbsLink(AmqpConnection);

            IAmqpAuthenticationRefresher amqpAuthenticator = new AmqpAuthenticationRefresher(deviceIdentity, AmqpCbsLink);
            await amqpAuthenticator.InitLoopAsync(timeout).ConfigureAwait(false);

            if (Logging.IsEnabled)
            {
                Logging.Exit(this, deviceIdentity, timeout, $"{nameof(AuthenticationRefresherCreator)}");
            }
            return(amqpAuthenticator);
        }
        private static void OnLinkExpiration(object state)
        {
            ActiveClientLinkManager activeClientLinkManager = (ActiveClientLinkManager)state;

            try
            {
                MessagingClientEtwProvider.TraceClient(() => {
                });
                AmqpCbsLink amqpCbsLink = activeClientLinkManager.activeClientLink.Link.Session.Connection.Extensions.Find <AmqpCbsLink>() ?? new AmqpCbsLink(activeClientLinkManager.activeClientLink.Link.Session.Connection);
                amqpCbsLink.BeginSendToken(activeClientLinkManager.factory.ServiceBusSecuritySettings.TokenProvider, activeClientLinkManager.factory.Address, activeClientLinkManager.activeClientLink.Audience, activeClientLinkManager.activeClientLink.EndpointUri, activeClientLinkManager.activeClientLink.RequiredClaims, ActiveClientLinkManager.SendTokenTimeout, new AsyncCallback(ActiveClientLinkManager.OnSendTokenComplete), activeClientLinkManager);
            }
            catch (Exception exception1)
            {
                Exception exception = exception1;
                if (Fx.IsFatal(exception))
                {
                    throw;
                }
                MessagingClientEtwProvider.TraceClient(() => MessagingClientEtwProvider.Provider.EventWriteAmqpLogError(activeClientLinkManager.activeClientLink.Link, "BeginSendToken", exception.Message));
            }
        }
        async Task <AmqpConnection> CreateConnectionAsync(TimeSpan timeout)
        {
            var hostName = this.Endpoint.Host;

            var timeoutHelper = new TimeoutHelper(timeout, true);
            var amqpSettings  = AmqpConnectionHelper.CreateAmqpSettings(
                amqpVersion: AmqpVersion,
                useSslStreamSecurity: true,
                hasTokenProvider: true,
                useWebSockets: TransportType == TransportType.AmqpWebSockets);

            var transportSettings      = CreateTransportSettings();
            var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, transportSettings);
            var transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            var containerId            = Guid.NewGuid().ToString();
            var amqpConnectionSettings = AmqpConnectionHelper.CreateAmqpConnectionSettings(AmqpConstants.DefaultMaxFrameSize, containerId, hostName);

            if (this.ConnectionIdleTimeout.HasValue && this.ConnectionIdleTimeout.Value > TimeSpan.Zero)
            {
                uint timeOutInMillis = checked ((uint)this.ConnectionIdleTimeout.Value.TotalMilliseconds);
                amqpConnectionSettings.IdleTimeOut = timeOutInMillis;
            }

            var connection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await connection.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            // Always create the CBS Link + Session
            var cbsLink = new AmqpCbsLink(connection);

            if (connection.Extensions.Find <AmqpCbsLink>() == null)
            {
                connection.Extensions.Add(cbsLink);
            }

            MessagingEventSource.Log.AmqpConnectionCreated(hostName, connection);

            return(connection);
        }
        async Task <AmqpConnection> CreateConnectionAsync(TimeSpan timeout)
        {
            string hostName    = this.Endpoint.Host;
            string networkHost = this.Endpoint.Host;
            int    port        = this.Endpoint.Port;

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            AmqpSettings  amqpSettings  = AmqpConnectionHelper.CreateAmqpSettings(
                amqpVersion: AmqpVersion,
                useSslStreamSecurity: true,
                hasTokenProvider: true);

            TransportSettings tpSettings = AmqpConnectionHelper.CreateTcpTransportSettings(
                networkHost: networkHost,
                hostName: hostName,
                port: port,
                useSslStreamSecurity: true);

            AmqpTransportInitiator initiator = new AmqpTransportInitiator(amqpSettings, tpSettings);
            TransportBase          transport = await initiator.ConnectTaskAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            string containerId = Guid.NewGuid().ToString();
            AmqpConnectionSettings amqpConnectionSettings = AmqpConnectionHelper.CreateAmqpConnectionSettings(AmqpConstants.DefaultMaxFrameSize, containerId, hostName);
            AmqpConnection         connection             = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await connection.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

            // Always create the CBS Link + Session
            AmqpCbsLink cbsLink = new AmqpCbsLink(connection);

            if (connection.Extensions.Find <AmqpCbsLink>() == null)
            {
                connection.Extensions.Add(cbsLink);
            }

            MessagingEventSource.Log.AmqpConnectionCreated(hostName, connection);

            return(connection);
        }
        private async void OnRefreshToken()
        {
            if (_faultTolerantSession.TryGetOpenedObject(out AmqpSession amqpSession) && amqpSession != null && !amqpSession.IsClosing())
            {
                AmqpCbsLink cbsLink = amqpSession.Connection.Extensions.Find <AmqpCbsLink>();
                if (cbsLink != null)
                {
                    try
                    {
                        await SendCbsTokenAsync(cbsLink, DefaultOperationTimeout).ConfigureAwait(false);
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            throw;
                        }

                        _refreshTokenTimer.Set(s_refreshTokenRetryInterval);
                    }
                }
            }
        }
Ejemplo n.º 11
0
        async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            this.refreshTokenTimer.Cancel();

            var amqpSettings         = this.CreateAmqpSettings();
            var tlsTransportSettings = this.CreateTlsTransportSettings();

            var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
            var transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());

            AmqpConnectionSettings amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId  = Guid.NewGuid().ToString("N"),
                HostName     = this.connectionString.AmqpEndpoint.Host
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

            var sessionSettings = new AmqpSessionSettings()
            {
                Properties = new Fields()
            };

            var amqpSession = amqpConnection.CreateSession(sessionSettings);
            await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

            // This adds itself to amqpConnection.Extensions
            var cbsLink = new AmqpCbsLink(amqpConnection);

            await this.SendCbsTokenAsync(cbsLink, timeoutHelper.RemainingTime());

            return(amqpSession);
        }
        private async Task <ReceivingAmqpLink> CreateLinkAsync(TimeSpan timeout)
        {
            var amqpEventHubClient = ((AmqpEventHubClient)EventHubClient);

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

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

            ICbsTokenProvider cbsTokenProvider = amqpEventHubClient.CbsTokenProvider;
            Uri      address   = new Uri(amqpEventHubClient.ConnectionStringBuilder.Endpoint, Path);
            string   audience  = address.AbsoluteUri;
            string   resource  = address.AbsoluteUri;
            DateTime 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;
                IList <AmqpDescribed> filters   = CreateFilters();
                if (filters != null && filters.Count > 0)
                {
                    filterMap = new FilterSet();
                    foreach (AmqpDescribed filter in filters)
                    {
                        filterMap.Add(filter.DescriptorName, filter);
                    }
                }

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

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

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

                if (!string.IsNullOrWhiteSpace(Identifier))
                {
                    linkSettings.AddProperty(AmqpClientConstants.ReceiverIdentifierName, 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
                    EventHubClient.ConnectionStringBuilder.Endpoint.AbsoluteUri, // endpointUri
                    new[] { ClaimConstants.Listen },
                    true,
                    expiresAt);

                clientLinkManager.SetActiveLink(activeClientLink);

                return(link);
            }
            catch
            {
                // Cleanup any session (and thus link) in case of exception.
                session?.Abort();
                throw;
            }
        }
Ejemplo n.º 13
0
 internal AmqpIoTCbsLink(AmqpCbsLink amqpCbsLink)
 {
     _amqpCbsLink = amqpCbsLink;
 }
        protected virtual async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            this.OnCreateSession();

            var timeoutHelper = new TimeoutHelper(timeout);

            AmqpSettings  amqpSettings = CreateAmqpSettings();
            TransportBase transport;

            switch (this.AmqpTransportSettings.GetTransportType())
            {
#if !WINDOWS_UWP
            case TransportType.Amqp_WebSocket_Only:
                transport = await this.CreateClientWebSocketTransportAsync(timeoutHelper.RemainingTime());

                break;
#endif
            case TransportType.Amqp_Tcp_Only:
                TlsTransportSettings tlsTransportSettings = this.CreateTlsTransportSettings();
                var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
                transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());

                break;

            default:
                throw new InvalidOperationException("AmqpTransportSettings must specify WebSocketOnly or TcpOnly");
            }

            var amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId  = Guid.NewGuid().ToString("N"),
                HostName     = this.hostName
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            try
            {
                await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

                var sessionSettings = new AmqpSessionSettings()
                {
                    Properties = new Fields()
                };

                AmqpSession amqpSession = amqpConnection.CreateSession(sessionSettings);
                await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

                // This adds itself to amqpConnection.Extensions
                var cbsLink = new AmqpCbsLink(amqpConnection);
                return(amqpSession);
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                if (amqpConnection.TerminalException != null)
                {
                    throw AmqpClientHelper.ToIotHubClientContract(amqpConnection.TerminalException);
                }

                amqpConnection.SafeClose(ex);
                throw;
            }
        }
Ejemplo n.º 15
0
        async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            this.refreshTokenTimer.Cancel();

            var           amqpSettings = this.CreateAmqpSettings();
            TransportBase transport;

            if (this.useWebSocketOnly)
            {
                // Try only Amqp transport over WebSocket
                transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime());
            }
            else
            {
                var tlsTransportSettings   = this.CreateTlsTransportSettings();
                var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
                try
                {
                    transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }

                    // Amqp transport over TCP failed. Retry Amqp transport over WebSocket
                    if (timeoutHelper.RemainingTime() != TimeSpan.Zero)
                    {
                        transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime());
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            AmqpConnectionSettings amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId  = Guid.NewGuid().ToString("N"),
                HostName     = this.connectionString.AmqpEndpoint.Host
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

            var sessionSettings = new AmqpSessionSettings()
            {
                Properties = new Fields()
            };

            var amqpSession = amqpConnection.CreateSession(sessionSettings);
            await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

            // This adds itself to amqpConnection.Extensions
            var cbsLink = new AmqpCbsLink(amqpConnection);

            await this.SendCbsTokenAsync(cbsLink, timeoutHelper.RemainingTime());

            return(amqpSession);
        }
Ejemplo n.º 16
0
        private async Task <SendingAmqpLink> CreateLinkAsync(TimeSpan timeout)
        {
            var amqpEventHubClient = ((AmqpEventHubClient)EventHubClient);

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

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

            ICbsTokenProvider cbsTokenProvider = amqpEventHubClient.CbsTokenProvider;
            Uri      address   = new Uri(amqpEventHubClient.ConnectionStringBuilder.Endpoint, Path);
            string   audience  = address.AbsoluteUri;
            string   resource  = address.AbsoluteUri;
            DateTime 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 = 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
                    EventHubClient.ConnectionStringBuilder.Endpoint.AbsoluteUri, // endpointUri
                    new[] { ClaimConstants.Send },
                    true,
                    expiresAt);

                MaxMessageSize = (long)activeClientLink.Link.Settings.MaxMessageSize();
                _clientLinkManager.SetActiveLink(activeClientLink);
                _linkCreated = true;
                return(link);
            }
            catch
            {
                // Cleanup any session (and thus link) in case of exception.
                session?.Abort();
                throw;
            }
        }
Ejemplo n.º 17
0
        private async Task <AmqpConnection> EnsureConnection(TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, timeout, $"{nameof(EnsureConnection)}");
            }
            AmqpConnection amqpConnection = null;
            IAmqpAuthenticationRefresher amqpAuthenticationRefresher = null;
            AmqpCbsLink amqpCbsLink = null;
            bool        gain        = await Lock.WaitAsync(timeout).ConfigureAwait(false);

            if (!gain)
            {
                throw new TimeoutException();
            }
            try
            {
                if (AmqpConnection == null)
                {
                    if (Logging.IsEnabled)
                    {
                        Logging.Info(this, "Creating new AmqpConnection", $"{nameof(EnsureConnection)}");
                    }
                    // Create AmqpConnection
                    amqpConnection = await Connector.OpenConnectionAsync(timeout).ConfigureAwait(false);

                    if (DeviceIdentity.AuthenticationModel != AuthenticationModel.X509)
                    {
                        if (AmqpCbsLink == null)
                        {
                            if (Logging.IsEnabled)
                            {
                                Logging.Info(this, "Creating new AmqpCbsLink", $"{nameof(EnsureConnection)}");
                            }
                            amqpCbsLink = new AmqpCbsLink(amqpConnection);
                        }
                        else
                        {
                            amqpCbsLink = AmqpCbsLink;
                        }

                        if (DeviceIdentity.AuthenticationModel == AuthenticationModel.SasGrouped)
                        {
                            if (Logging.IsEnabled)
                            {
                                Logging.Info(this, "Creating connection width AmqpAuthenticationRefresher", $"{nameof(EnsureConnection)}");
                            }
                            amqpAuthenticationRefresher = new AmqpAuthenticationRefresher(DeviceIdentity, amqpCbsLink);
                            await amqpAuthenticationRefresher.InitLoopAsync(timeout).ConfigureAwait(false);
                        }
                    }
                    AmqpConnection = amqpConnection;
                    AmqpCbsLink    = amqpCbsLink;
                    AmqpAuthenticationRefresher = amqpAuthenticationRefresher;
                    AmqpConnection.Closed      += OnConnectionClosed;
                    if (Logging.IsEnabled)
                    {
                        Logging.Associate(this, AmqpConnection, $"{nameof(AmqpConnection)}");
                    }
                    if (Logging.IsEnabled)
                    {
                        Logging.Associate(this, AmqpCbsLink, $"{nameof(AmqpCbsLink)}");
                    }
                }
                else if (AmqpConnection.IsClosing())
                {
                    throw new IotHubCommunicationException("AMQP connection is closing.");
                }
                else
                {
                    amqpConnection = AmqpConnection;
                }
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                amqpCbsLink?.Close();
                amqpAuthenticationRefresher?.StopLoop();
                amqpConnection?.SafeClose();
                throw;
            }
            finally
            {
                Lock.Release();
            }
            if (Logging.IsEnabled)
            {
                Logging.Exit(this, timeout, $"{nameof(EnsureConnection)}");
            }
            return(amqpConnection);
        }
        private async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            var timeoutHelper = new TimeoutHelper(timeout);

            _refreshTokenTimer.Cancel();

            AmqpSettings  amqpSettings = CreateAmqpSettings();
            TransportBase transport;

            if (_useWebSocketOnly)
            {
                // Try only Amqp transport over WebSocket
                transport = await CreateClientWebSocketTransport(timeoutHelper.RemainingTime()).ConfigureAwait(false);
            }
            else
            {
                TlsTransportSettings tlsTransportSettings = CreateTlsTransportSettings();
                var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
                try
                {
                    transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);
                }
#if !NETSTANDARD1_3
                catch (AuthenticationException)
                {
                    throw;
                }
#endif
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }

                    // Amqp transport over TCP failed. Retry Amqp transport over WebSocket
                    if (timeoutHelper.RemainingTime() != TimeSpan.Zero)
                    {
                        transport = await CreateClientWebSocketTransport(timeoutHelper.RemainingTime()).ConfigureAwait(false);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            var amqpConnectionSettings = new AmqpConnectionSettings
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId  = Guid.NewGuid()
#if NETSTANDARD1_3
                               .ToString("N"),
#else
                               .ToString("N", CultureInfo.InvariantCulture), // Use a human readable link name to help with debugging
#endif
                HostName = ConnectionString.AmqpEndpoint.Host,
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await amqpConnection.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

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

            try
            {
                AmqpSession amqpSession = amqpConnection.CreateSession(sessionSettings);
                await amqpSession.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                // This adds itself to amqpConnection.Extensions
                var cbsLink = new AmqpCbsLink(amqpConnection);
                await SendCbsTokenAsync(cbsLink, timeoutHelper.RemainingTime()).ConfigureAwait(false);

                return(amqpSession);
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                if (amqpConnection.TerminalException != null)
                {
                    throw AmqpClientHelper.ToIotHubClientContract(amqpConnection.TerminalException);
                }

                amqpConnection.SafeClose(ex);
                throw;
            }
        }
Ejemplo n.º 19
0
 async Task SendCbsTokenAsync(AmqpCbsLink cbsLink, TimeSpan timeout)
 {
     string audience = this.ConnectionString.AmqpEndpoint.AbsoluteUri;
     string resource = this.ConnectionString.AmqpEndpoint.AbsoluteUri;
     var expiresAtUtc = await cbsLink.SendTokenAsync(
         this.ConnectionString,
         this.ConnectionString.AmqpEndpoint,
         audience,
         resource,
         AccessRightsHelper.AccessRightsToStringArray(this.accessRights),
         timeout);
     this.ScheduleTokenRefresh(expiresAtUtc);
 }
Ejemplo n.º 20
0
        async Task<AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            this.refreshTokenTimer.Cancel();

            var amqpSettings = this.CreateAmqpSettings();
            TransportBase transport;
            if (this.useWebSocketOnly)
            {
                // Try only Amqp transport over WebSocket
                transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime());
            }
            else
            {             
                var tlsTransportSettings = this.CreateTlsTransportSettings();
                var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
                try
                {
                    transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());
                }
                catch (Exception e)
                {
                    if (Fx.IsFatal(e))
                    {
                        throw;
                    }

                    // Amqp transport over TCP failed. Retry Amqp transport over WebSocket
                    if (timeoutHelper.RemainingTime() != TimeSpan.Zero)
                    {
                        transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime());
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            AmqpConnectionSettings amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId = Guid.NewGuid().ToString("N"),
                HostName = this.connectionString.AmqpEndpoint.Host
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

            var sessionSettings = new AmqpSessionSettings()
            {
                Properties = new Fields()
            };

            var amqpSession = amqpConnection.CreateSession(sessionSettings);
            await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

            // This adds itself to amqpConnection.Extensions
            var cbsLink = new AmqpCbsLink(amqpConnection);
            await this.SendCbsTokenAsync(cbsLink, timeoutHelper.RemainingTime());
            return amqpSession;
        }
        async Task<AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            this.refreshTokenTimer.Cancel();

            var amqpSettings = this.CreateAmqpSettings();
            var tlsTransportSettings = this.CreateTlsTransportSettings();

            var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
            var transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());

            AmqpConnectionSettings amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId = Guid.NewGuid().ToString("N"),
                HostName = this.connectionString.AmqpEndpoint.Host
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

            var sessionSettings = new AmqpSessionSettings()
            {
                Properties = new Fields()
            };

            var amqpSession = amqpConnection.CreateSession(sessionSettings);
            await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

            // This adds itself to amqpConnection.Extensions
            var cbsLink = new AmqpCbsLink(amqpConnection);
            await this.SendCbsTokenAsync(cbsLink, timeoutHelper.RemainingTime());
            return amqpSession;
        }
        private async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            Logging.Enter(this, timeout, nameof(CreateSessionAsync));

            TransportBase transport = null;

            try
            {
                var timeoutHelper = new TimeoutHelper(timeout);
                _refreshTokenTimer.Cancel();

                AmqpSettings amqpSettings = CreateAmqpSettings();
                if (_useWebSocketOnly)
                {
                    // Try only AMQP transport over WebSocket
                    transport = _clientWebSocketTransport = (ClientWebSocketTransport) await CreateClientWebSocketTransportAsync(timeoutHelper.RemainingTime())
                                                            .ConfigureAwait(false);
                }
                else
                {
                    TlsTransportSettings tlsTransportSettings = CreateTlsTransportSettings();
                    var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
                    try
                    {
                        transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);
                    }
                    catch (Exception e) when(!(e is AuthenticationException))
                    {
                        Logging.Error(this, e, nameof(CreateSessionAsync));

                        if (Fx.IsFatal(e))
                        {
                            throw;
                        }

                        // AMQP transport over TCP failed. Retry AMQP transport over WebSocket
                        if (timeoutHelper.RemainingTime() != TimeSpan.Zero)
                        {
                            transport = _clientWebSocketTransport = (ClientWebSocketTransport) await CreateClientWebSocketTransportAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }

                Logging.Info(this, $"Initialized {nameof(TransportBase)}, ws={_useWebSocketOnly}");

                var amqpConnectionSettings = new AmqpConnectionSettings
                {
                    MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                    ContainerId  = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture), // Use a human readable link name to help with debugging
                    HostName     = ConnectionString.AmqpEndpoint.Host,
                };

                var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
                await amqpConnection.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                Logging.Info(this, $"{nameof(AmqpConnection)} opened.");

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

                try
                {
                    AmqpSession amqpSession = amqpConnection.CreateSession(sessionSettings);
                    await amqpSession.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    Logging.Info(this, $"{nameof(AmqpSession)} opened.");

                    // This adds itself to amqpConnection.Extensions
                    var cbsLink = new AmqpCbsLink(amqpConnection);
                    await SendCbsTokenAsync(cbsLink, timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    return(amqpSession);
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    Logging.Error(this, ex, nameof(CreateSessionAsync));

                    _clientWebSocketTransport?.Dispose();
                    _clientWebSocketTransport = null;

                    if (amqpConnection.TerminalException != null)
                    {
                        throw AmqpClientHelper.ToIotHubClientContract(amqpConnection.TerminalException);
                    }

                    amqpConnection.SafeClose(ex);
                    throw;
                }
            }
            finally
            {
                Logging.Exit(this, timeout, nameof(CreateSessionAsync));
            }
        }
Ejemplo n.º 23
0
        protected virtual async Task<AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            this.OnCreateSession();

            var timeoutHelper = new TimeoutHelper(timeout);

            AmqpSettings amqpSettings = CreateAmqpSettings();
            TransportBase transport;

            switch (this.AmqpTransportSettings.GetTransportType())
            {
#if !WINDOWS_UWP
                case TransportType.Amqp_WebSocket_Only:
                    transport = await this.CreateClientWebSocketTransportAsync(timeoutHelper.RemainingTime());
                    break;
#endif
                case TransportType.Amqp_Tcp_Only:
                    TlsTransportSettings tlsTransportSettings = this.CreateTlsTransportSettings();
                    var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
                    transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());
                    break;
                default:
                    throw new InvalidOperationException("AmqpTransportSettings must specify WebSocketOnly or TcpOnly");
            }

            var amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId = Guid.NewGuid().ToString("N"),
                HostName = this.hostName
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

            var sessionSettings = new AmqpSessionSettings()
            {
                Properties = new Fields()
            };

            var amqpSession = amqpConnection.CreateSession(sessionSettings);
            await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

            // This adds itself to amqpConnection.Extensions
            var cbsLink = new AmqpCbsLink(amqpConnection);
            return amqpSession;
        }
        protected virtual async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout, CancellationToken token)
        {
            try
            {
                if (Logging.IsEnabled)
                {
                    Logging.Enter(this, timeout, token, $"{nameof(IotHubConnection)}.{nameof(CreateSessionAsync)}");
                }

                this.OnCreateSession();

                var timeoutHelper = new TimeoutHelper(timeout);

                AmqpSettings  amqpSettings = CreateAmqpSettings();
                TransportBase transport;

                token.ThrowIfCancellationRequested();

                switch (this.AmqpTransportSettings.GetTransportType())
                {
                case TransportType.Amqp_WebSocket_Only:
                    transport = await this.CreateClientWebSocketTransportAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    break;

                case TransportType.Amqp_Tcp_Only:
                    TlsTransportSettings tlsTransportSettings = this.CreateTlsTransportSettings();
                    var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
                    transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    break;

                default:
                    throw new InvalidOperationException("AmqpTransportSettings must specify WebSocketOnly or TcpOnly");
                }

                var amqpConnectionSettings = new AmqpConnectionSettings()
                {
                    MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                    ContainerId  = Guid.NewGuid().ToString("N"),
                    HostName     = this.hostName
                };

                var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
                try
                {
                    token.ThrowIfCancellationRequested();
                    await amqpConnection.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    var sessionSettings = new AmqpSessionSettings()
                    {
                        Properties = new Fields()
                    };

                    AmqpSession amqpSession = amqpConnection.CreateSession(sessionSettings);
                    token.ThrowIfCancellationRequested();
                    await amqpSession.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    // This adds itself to amqpConnection.Extensions
                    var cbsLink = new AmqpCbsLink(amqpConnection);
                    return(amqpSession);
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    if (amqpConnection.TerminalException != null)
                    {
                        throw AmqpClientHelper.ToIotHubClientContract(amqpConnection.TerminalException);
                    }

                    amqpConnection.SafeClose(ex);
                    throw;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, timeout, token, $"{nameof(IotHubConnection)}.{nameof(CreateSessionAsync)}");
                }
            }
        }
Ejemplo n.º 25
0
 internal AmqpIoTCbsLink(AmqpConnection amqpConnection)
 {
     _amqpCbsLink = _amqpCbsLink ?? new AmqpCbsLink(amqpConnection);
 }
Ejemplo n.º 26
0
        async Task<AmqpSession> CreateSessionAsync(TimeSpan timeout)
        {
            var timeoutHelper = new TimeoutHelper(timeout);
            this.refreshTokenTimer.Cancel();

            AmqpSettings amqpSettings = this.CreateAmqpSettings();
            TlsTransportSettings tlsTransportSettings = this.CreateTlsTransportSettings();

            var amqpTransportInitiator = new AmqpTransportInitiator(amqpSettings, tlsTransportSettings);
            TransportBase transport;

            switch (this.amqpTransportSettings.GetTransportType())
            {
                case TransportType.Amqp_WebSocket_Only:
                transport = await this.CreateClientWebSocketTransport(timeoutHelper.RemainingTime());
                    break;
                case TransportType.Amqp_Tcp_Only:
                    transport = await amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime());
                    break;
                default:
                    throw new InvalidOperationException("AmqpTransportSettings must specify WebSocketOnly or TcpOnly");
            }

            var amqpConnectionSettings = new AmqpConnectionSettings()
            {
                MaxFrameSize = AmqpConstants.DefaultMaxFrameSize,
                ContainerId = Guid.NewGuid().ToString("N"),
                HostName = this.connectionString.AmqpEndpoint.Host
            };

            var amqpConnection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings);
            await amqpConnection.OpenAsync(timeoutHelper.RemainingTime());

            var sessionSettings = new AmqpSessionSettings()
            {
                Properties = new Fields()
            };

            var amqpSession = amqpConnection.CreateSession(sessionSettings);
            await amqpSession.OpenAsync(timeoutHelper.RemainingTime());

            // This adds itself to amqpConnection.Extensions
            var cbsLink = new AmqpCbsLink(amqpConnection);
            await this.SendCbsTokenAsync(cbsLink, timeoutHelper.RemainingTime());
            return amqpSession;
        }