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; } }
/// <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); }
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); }
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); } } } }
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; } }
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; } }
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); }
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; } }
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; } }
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); }
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)); } }
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)}"); } } }
internal AmqpIoTCbsLink(AmqpConnection amqpConnection) { _amqpCbsLink = _amqpCbsLink ?? new AmqpCbsLink(amqpConnection); }
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; }