async Task <AmqpConnection> CreateConnectionAsync(TimeSpan timeout) { string hostName = this.ConnectionStringBuilder.Endpoint.Host; string networkHost = this.ConnectionStringBuilder.Endpoint.Host; int port = this.ConnectionStringBuilder.Endpoint.Port; var timeoutHelper = new TimeoutHelper(timeout); var amqpSettings = CreateAmqpSettings( amqpVersion: this.AmqpVersion, useSslStreamSecurity: true, hasTokenProvider: true); TransportSettings tpSettings = CreateTcpTransportSettings( networkHost: networkHost, hostName: hostName, port: port, useSslStreamSecurity: true); 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); }
public async Task OpenAsync(TimeSpan timeout, bool useWebSocket, X509Certificate2 clientCert) { var hostName = _uri.Host; var tcpSettings = new TcpTransportSettings { Host = hostName, Port = _uri.Port != -1 ? _uri.Port : AmqpConstants.DefaultSecurePort }; TransportSettings = new TlsTransportSettings(tcpSettings) { TargetHost = hostName, CertificateValidationCallback = (sender, cert, chain, errors) => true, Certificate = clientCert }; TransportBase transport; if (useWebSocket) { transport = await CreateClientWebSocketTransportAsync(timeout).ConfigureAwait(false); } else { var tcpInitiator = new AmqpTransportInitiator(_amqpSettings, TransportSettings); transport = await tcpInitiator.ConnectTaskAsync(timeout).ConfigureAwait(false); } AmqpConnection = new AmqpConnection(transport, _amqpSettings, AmqpConnectionSettings); await AmqpConnection.OpenAsync(timeout).ConfigureAwait(false); _isConnectionClosed = false; AmqpConnection.Closed += OnConnectionClosed; }
async Task <AmqpConnection> CreateConnectionAsync(TimeSpan timeout) { var hostName = this.Endpoint.Host; var timeoutHelper = new TimeoutHelper(timeout); 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); 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); }
private async Task <AmqpConnection> CreateConnectionAsync(TimeSpan timeout) { string hostName = ConnectionStringBuilder.Endpoint.Host; int port = ConnectionStringBuilder.Endpoint.Port; bool useWebSockets = ConnectionStringBuilder.TransportType == TrackOne.TransportType.AmqpWebSockets; var timeoutHelper = new TimeoutHelper(timeout); AmqpSettings amqpSettings = CreateAmqpSettings( amqpVersion: AmqpVersion, useSslStreamSecurity: true, hasTokenProvider: true, useWebSockets: useWebSockets); TransportSettings tpSettings = useWebSockets ? CreateWebSocketsTransportSettings(hostName, WebProxy) : CreateTcpTlsTransportSettings(hostName, port); var initiator = new AmqpTransportInitiator(amqpSettings, tpSettings); TransportBase transport = await initiator.ConnectTaskAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); AmqpConnectionSettings connectionSettings = CreateAmqpConnectionSettings(MaxFrameSize, 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); }
internal async Task <AmqpIoTConnection> OpenConnectionAsync(TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, $"{nameof(OpenConnectionAsync)}"); } TransportBase transportBase = await _amqpIoTTransport.Initialize(timeout).ConfigureAwait(false); try { _amqpConnection = new AmqpConnection(transportBase, _amqpSettings, _amqpConnectionSettings); _amqpConnection.Closed += _amqpConnectionClosed; await _amqpConnection.OpenAsync(timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Exit(this, timeout, $"{nameof(OpenConnectionAsync)}"); } return(this); } catch (Exception) { transportBase?.Close(); throw; } finally { if (Logging.IsEnabled) { Logging.Exit(this, $"{nameof(OpenConnectionAsync)}"); } } }
public async Task <AmqpConnection> OpenConnectionAsync(TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, timeout, $"{nameof(OpenConnectionAsync)}"); } TransportBase transportBase = null; try { transportBase = await InitializeTransport(timeout).ConfigureAwait(false); AmqpConnection amqpConnection = new AmqpConnection(transportBase, AmqpSettings, AmqpConnectionSettings); await amqpConnection.OpenAsync(timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Exit(this, timeout, $"{nameof(OpenConnectionAsync)}"); } return(amqpConnection); } catch (Exception) { transportBase?.Close(); throw; } }
public async Task <AmqpIoTConnection> OpenConnectionAsync(TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, timeout, $"{nameof(OpenConnectionAsync)}"); } var amqpSettings = new AmqpSettings(); var amqpTransportProvider = new AmqpTransportProvider(); amqpTransportProvider.Versions.Add(s_amqpVersion_1_0_0); amqpSettings.TransportProviders.Add(amqpTransportProvider); var amqpConnectionSettings = new AmqpConnectionSettings() { MaxFrameSize = AmqpConstants.DefaultMaxFrameSize, ContainerId = CommonResources.GetNewStringGuid(), HostName = _hostName }; TimeSpan idleTimeout = _amqpTransportSettings.IdleTimeout; if (idleTimeout != null) { amqpConnectionSettings.IdleTimeOut = Convert.ToUInt32(idleTimeout.TotalMilliseconds); } var amqpIoTTransport = new AmqpIoTTransport(amqpSettings, _amqpTransportSettings, _hostName, s_disableServerCertificateValidation); TransportBase transportBase = await amqpIoTTransport.InitializeAsync(timeout).ConfigureAwait(false); try { var amqpConnection = new AmqpConnection(transportBase, amqpSettings, amqpConnectionSettings); AmqpIoTConnection amqpIoTConnection = new AmqpIoTConnection(amqpConnection); amqpConnection.Closed += amqpIoTConnection.AmqpConnectionClosed; await amqpConnection.OpenAsync(timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Exit(this, timeout, $"{nameof(OpenConnectionAsync)}"); } return(amqpIoTConnection); } catch (Exception e) when(!e.IsFatal()) { transportBase?.Close(); throw; } finally { if (Logging.IsEnabled) { Logging.Exit(this, $"{nameof(OpenConnectionAsync)}"); } } }
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); }
public async Task OpenAsync(TimeSpan timeout, bool useWebSocket, X509Certificate2 clientCert) { var hostName = _uri.Host; var tcpSettings = new TcpTransportSettings { Host = hostName, Port = _uri.Port != -1 ? _uri.Port : AmqpConstants.DefaultSecurePort }; TransportSettings = new TlsTransportSettings(tcpSettings) { TargetHost = hostName, Certificate = clientCert }; TransportBase transport; if (useWebSocket) { transport = await CreateClientWebSocketTransportAsync(timeout).ConfigureAwait(false); SaslTransportProvider provider = _amqpSettings.GetTransportProvider <SaslTransportProvider>(); if (provider != null) { _sentHeader = new ProtocolHeader(provider.ProtocolId, provider.DefaultVersion); ByteBuffer buffer = new ByteBuffer(new byte[AmqpConstants.ProtocolHeaderSize]); _sentHeader.Encode(buffer); var args = new TransportAsyncCallbackArgs(); args.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Length); args.CompletedCallback = OnWriteHeaderComplete; args.Transport = transport; transport.WriteAsync(args); _tcs = new TaskCompletionSource <TransportBase>(); transport = await _tcs.Task.ConfigureAwait(false); await transport.OpenAsync(timeout).ConfigureAwait(false); } } else { var tcpInitiator = new AmqpTransportInitiator(_amqpSettings, TransportSettings); transport = await tcpInitiator.ConnectTaskAsync(timeout).ConfigureAwait(false); } AmqpConnection = new AmqpConnection(transport, _amqpSettings, AmqpConnectionSettings); AmqpConnection.Closed += OnConnectionClosed; await AmqpConnection.OpenAsync(timeout).ConfigureAwait(false); _isConnectionClosed = false; }
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); }
/// <summary> /// Creates an AMQP connection for a given scope. /// </summary> /// /// <param name="amqpVersion">The version of AMQP to use for the connection.</param> /// <param name="serviceEndpoint">The endpoint for the Event Hubs service to which the scope is associated.</param> /// <param name="transportType">The type of transport to use for communication.</param> /// <param name="proxy">The proxy, if any, to use for communication.</param> /// <param name="scopeIdentifier">The unique identifier for the associated scope.</param> /// <param name="timeout">The timeout to consider when creating the connection.</param> /// /// <returns>An AMQP connection that may be used for communicating with the Event Hubs service.</returns> /// protected virtual async Task <AmqpConnection> CreateConnectionAsync(Version amqpVersion, Uri serviceEndpoint, TransportType transportType, IWebProxy proxy, string scopeIdentifier, TimeSpan timeout) { var hostName = serviceEndpoint.Host; var amqpSettings = CreateAmpqSettings(AmqpVersion); var connectionSetings = CreateAmqpConnectionSettings(hostName, scopeIdentifier); var transportSettings = transportType.IsWebSocketTransport() ? CreateTransportSettingsForWebSockets(hostName, proxy) : CreateTransportSettingsforTcp(hostName, serviceEndpoint.Port); // Create and open the connection, respecting the timeout constraint // that was received. var stopWatch = Stopwatch.StartNew(); var initiator = new AmqpTransportInitiator(amqpSettings, transportSettings); var transport = await initiator.ConnectTaskAsync(timeout).ConfigureAwait(false); var connection = new AmqpConnection(transport, amqpSettings, connectionSetings); await connection.OpenAsync(timeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false); stopWatch.Stop(); // Create the CBS link that will be used for authorization and ensure that it is associated // with the connection. var cbsLink = new AmqpCbsLink(connection); // TODO (pri2 // squire): // The act of creating the link should ensure that it is added to the connection. Unsure // of why this additional check was in the track one code. Investigate and either // document or remove. if (!connection.Extensions.Contains(typeof(AmqpCbsLink))) { connection.Extensions.Add(cbsLink); } 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); }
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); }
async Task <AmqpConnection> CreateConnectionAsync(TimeSpan timeout) { var hostName = this.Endpoint.Host; var timeoutHelper = new TimeoutHelper(timeout); var amqpSettings = AmqpConnectionHelper.CreateAmqpSettings( amqpVersion: AmqpVersion, useSslStreamSecurity: true, networkCredential: NetCredential, 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); var connection = new AmqpConnection(transport, amqpSettings, amqpConnectionSettings); await connection.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); MessagingEventSource.Log.AmqpConnectionCreated(hostName, connection); return(connection); }
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); }
protected virtual async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout, CancellationToken token) { this.OnCreateSession(); var timeoutHelper = new TimeoutHelper(timeout); AmqpSettings amqpSettings = CreateAmqpSettings(); TransportBase transport; token.ThrowIfCancellationRequested(); switch (this.AmqpTransportSettings.GetTransportType()) { #if !WINDOWS_UWP && !PCL 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 { token.ThrowIfCancellationRequested(); await amqpConnection.OpenAsync(timeoutHelper.RemainingTime()); var sessionSettings = new AmqpSessionSettings() { Properties = new Fields() }; AmqpSession amqpSession = amqpConnection.CreateSession(sessionSettings); token.ThrowIfCancellationRequested(); 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; } }
public async Task OpenAsync(TimeSpan timeout, bool useWebSocket, X509Certificate2 clientCert, IWebProxy proxy, RemoteCertificateValidationCallback remoteCerificateValidationCallback) { if (Logging.IsEnabled) { Logging.Enter(this, $"{nameof(AmqpClientConnection)}.{nameof(OpenAsync)}"); } var hostName = _uri.Host; var tcpSettings = new TcpTransportSettings { Host = hostName, Port = _uri.Port != -1 ? _uri.Port : AmqpConstants.DefaultSecurePort }; TransportSettings = new TlsTransportSettings(tcpSettings) { TargetHost = hostName, Certificate = clientCert, CertificateValidationCallback = remoteCerificateValidationCallback, }; TransportBase transport; if (useWebSocket) { transport = await CreateClientWebSocketTransportAsync(timeout, proxy).ConfigureAwait(false); SaslTransportProvider provider = _amqpSettings.GetTransportProvider <SaslTransportProvider>(); if (provider != null) { if (Logging.IsEnabled) { Logging.Info(this, $"{nameof(AmqpClientConnection)}.{nameof(OpenAsync)}: Using SaslTransport"); } _sentHeader = new ProtocolHeader(provider.ProtocolId, provider.DefaultVersion); ByteBuffer buffer = new ByteBuffer(new byte[AmqpConstants.ProtocolHeaderSize]); _sentHeader.Encode(buffer); _tcs = new TaskCompletionSource <TransportBase>(); var args = new TransportAsyncCallbackArgs(); args.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Length); args.CompletedCallback = OnWriteHeaderComplete; args.Transport = transport; bool operationPending = transport.WriteAsync(args); if (Logging.IsEnabled) { Logging.Info(this, $"{nameof(AmqpClientConnection)}.{nameof(OpenAsync)}: Sent Protocol Header: {_sentHeader.ToString()} operationPending: {operationPending} completedSynchronously: {args.CompletedSynchronously}"); } if (!operationPending) { args.CompletedCallback(args); } transport = await _tcs.Task.ConfigureAwait(false); await transport.OpenAsync(timeout).ConfigureAwait(false); } } else { var tcpInitiator = new AmqpTransportInitiator(_amqpSettings, TransportSettings); transport = await tcpInitiator.ConnectTaskAsync(timeout).ConfigureAwait(false); } AmqpConnection = new AmqpConnection(transport, _amqpSettings, AmqpConnectionSettings); AmqpConnection.Closed += OnConnectionClosed; await AmqpConnection.OpenAsync(timeout).ConfigureAwait(false); _isConnectionClosed = false; }
/// <summary> /// Performs the tasks needed to build and open a connection to the IoT Hub /// service. /// </summary> /// <param name="serviceEndpoint">The endpoint of the IoT Hub service to connect to.</param> /// <param name="iotHubName">The name of the IoT Hub to connect to.</param> /// <param name="sharedAccessKeyName">The name of the shared access key being used for authentication.</param> /// <param name="sharedAccessKey">The shared access key being used for authentication.</param> /// <param name="timeout">The maximum amount of time that establishing the connection should be allowed to take.</param> /// <returns>An <see cref="AmqpConnection" /> to the requested IoT Hub.</returns> /// <seealso href="https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-amqp-support"/> private static async Task <AmqpConnection> CreateAndOpenConnectionAsync( Uri serviceEndpoint, string iotHubName, string sharedAccessKeyName, string sharedAccessKey, TimeSpan timeout) { var hostName = serviceEndpoint.Host; var userName = $"{ sharedAccessKeyName }@sas.root.{ iotHubName }"; var signature = BuildSignature($"{ hostName }{ serviceEndpoint.AbsolutePath }", sharedAccessKeyName, sharedAccessKey, TimeSpan.FromMinutes(5)); var port = 5671; // Create the layers of settings needed to establish the connection. var amqpVersion = new Version(1, 0, 0, 0); var tcpSettings = new TcpTransportSettings { Host = hostName, Port = port, ReceiveBufferSize = AmqpConstants.TransportBufferSize, SendBufferSize = AmqpConstants.TransportBufferSize }; var transportSettings = new TlsTransportSettings(tcpSettings) { TargetHost = hostName, }; var connectionSettings = new AmqpConnectionSettings { IdleTimeOut = (uint)TimeSpan.FromMinutes(1).TotalMilliseconds, MaxFrameSize = AmqpConstants.DefaultMaxFrameSize, ContainerId = Guid.NewGuid().ToString(), HostName = hostName }; var saslProvider = new SaslTransportProvider(); saslProvider.Versions.Add(new AmqpVersion(amqpVersion)); saslProvider.AddHandler(new SaslPlainHandler { AuthenticationIdentity = userName, Password = signature }); var amqpProvider = new AmqpTransportProvider(); amqpProvider.Versions.Add(new AmqpVersion(amqpVersion)); var amqpSettings = new AmqpSettings(); amqpSettings.TransportProviders.Add(saslProvider); amqpSettings.TransportProviders.Add(amqpProvider); // Create and open the connection, respecting the timeout constraint // that was received. var stopWatch = Stopwatch.StartNew(); var initiator = new AmqpTransportInitiator(amqpSettings, transportSettings); var transport = await initiator.ConnectTaskAsync(timeout).ConfigureAwait(false); try { var connection = new AmqpConnection(transport, amqpSettings, connectionSettings); await connection.OpenAsync(timeout.Subtract(stopWatch.Elapsed)).ConfigureAwait(false); return(connection); } catch { transport.Abort(); throw; } finally { stopWatch.Stop(); } }
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; } }
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)); } }
async Task OpenAmqpConnectionAsync(AmqpConnection amqpConnection, TimeSpan defaultTimeout) { if (await SafeOpenConnectionAsync()) { try { if (this.incomingConnectionMap.TryAdd(amqpConnection.Identifier.Value, amqpConnection)) { amqpConnection.SafeAddClosed((s, e) => this.incomingConnectionMap.TryRemove(amqpConnection.Identifier.Value, out AmqpConnection _)); } else { Events.ConnectionContextAddFailed(amqpConnection.Identifier.Value); } } catch (Exception e) when(!e.IsFatal()) { Events.OpenConnectionError(e); amqpConnection.SafeClose(e); } } async Task <bool> SafeOpenConnectionAsync() { try { await amqpConnection.OpenAsync(defaultTimeout); return(true); } catch (Exception e) when(!e.IsFatal()) { Events.AmqpConnectionOpenAsyncFailed(e); switch (e) { case OperationCanceledException _: amqpConnection.SafeClose(new EdgeHubConnectionException("Operation Canceled Exception")); break; case TimeoutException _: amqpConnection.SafeClose(new EdgeHubConnectionException("Timeout Exception")); break; case IOException _: amqpConnection.SafeClose(new EdgeHubConnectionException("IO Exception")); break; case SocketException _: amqpConnection.SafeClose(new EdgeHubConnectionException("Socket Exception")); break; case AmqpException ae when ae.Error.Condition.Equals(AmqpErrorCode.ConnectionForced): amqpConnection.SafeClose(new EdgeHubConnectionException("AMQP connection forced exception")); break; default: amqpConnection.SafeClose(e); break; } return(false); } } }