public AmqpSession CreateSession(AmqpSessionSettings sessionSettings) { if (this.IsClosing()) { throw new InvalidOperationException(CommonResources.CreateSessionOnClosingConnection); } AmqpSession session = this.SessionFactory.CreateSession(this, sessionSettings); this.AddSession(session, null); return session; }
protected AmqpSession(string type, AmqpConnection connection, AmqpSessionSettings settings, ILinkFactory linkFactory) : base(type) { Fx.Assert(connection != null, "connection must not be null"); Fx.Assert(settings != null, "settings must not be null"); this.connection = connection; this.settings = settings; this.linkFactory = linkFactory; this.State = AmqpObjectState.Start; this.links = new Dictionary<string, AmqpLink>(); this.linksByLocalHandle = new HandleTable<AmqpLink>(settings.HandleMax ?? AmqpConstants.DefaultMaxLinkHandles - 1); this.linksByRemoteHandle = new HandleTable<AmqpLink>(settings.HandleMax ?? AmqpConstants.DefaultMaxLinkHandles - 1); this.outgoingChannel = new OutgoingSessionChannel(this); this.incomingChannel = new IncomingSessionChannel(this); }
/// <summary> /// Creates an AMQP link for use with management operations. /// </summary> /// <param name="entityPath"></param> /// /// <param name="connection">The active and opened AMQP connection to use for this link.</param> /// <param name="timeout">The timeout to apply when creating the link.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>A link for use with management operations.</returns> protected virtual async Task <RequestResponseAmqpLink> CreateManagementLinkAsync( string entityPath, AmqpConnection connection, TimeSpan timeout, CancellationToken cancellationToken) { Argument.AssertNotDisposed(IsDisposed, nameof(AmqpConnectionScope)); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var session = default(AmqpSession); var stopWatch = ValueStopwatch.StartNew(); try { // Create and open the AMQP session associated with the link. var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = connection.CreateSession(sessionSettings); await OpenAmqpObjectAsync(session, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the link. var linkSettings = new AmqpLinkSettings(); linkSettings.AddProperty(AmqpClientConstants.TimeoutName, (uint)timeout.CalculateRemaining(stopWatch.GetElapsedTime()).TotalMilliseconds); linkSettings.AddProperty(AmqpClientConstants.EntityTypeName, AmqpClientConstants.EntityTypeManagement); entityPath += '/' + AmqpClientConstants.ManagementAddress; // Perform the initial authorization for the link. string[] claims = { ServiceBusClaim.Manage, ServiceBusClaim.Listen, ServiceBusClaim.Send }; var endpoint = new Uri(ServiceEndpoint, entityPath); var audience = new[] { endpoint.AbsoluteUri }; DateTime authExpirationUtc = await RequestAuthorizationUsingCbsAsync( connection, TokenProvider, ServiceEndpoint, audience, claims, timeout.CalculateRemaining(stopWatch.GetElapsedTime())) .ConfigureAwait(false); var link = new RequestResponseAmqpLink( AmqpClientConstants.EntityTypeManagement, session, entityPath, linkSettings.Properties); linkSettings.LinkName = $"{connection.Settings.ContainerId};{connection.Identifier}:{session.Identifier}:{link.Identifier}"; // Track the link before returning it, so that it can be managed with the scope. var refreshTimer = default(Timer); TimerCallback refreshHandler = CreateAuthorizationRefreshHandler ( entityPath, connection, link, TokenProvider, ServiceEndpoint, audience, claims, AuthorizationRefreshTimeout, () => (ActiveLinks.ContainsKey(link) ? refreshTimer : null) ); refreshTimer = new Timer(refreshHandler, null, CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan); // Track the link before returning it, so that it can be managed with the scope. BeginTrackingLinkAsActive(entityPath, link, refreshTimer); return(link); } catch (Exception exception) { // Aborting the session will perform any necessary cleanup of // the associated link as well. session?.Abort(); ExceptionDispatchInfo.Capture(AmqpExceptionHelper.TranslateException( exception, null, session.GetInnerException(), connection.IsClosing())) .Throw(); throw; // will never be reached } }
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; } }
async Task <AmqpSession> CreateSessionAsync(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); this.refreshTokenTimer.Cancel(); var amqpSettings = 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 <SendingAmqpLink> CreateLinkAsync(TimeSpan timeout) { var amqpEventHubClient = ((AmqpEventHubClient)this.EventHubClient); var csb = amqpEventHubClient.ConnectionStringBuilder; var timeoutHelper = new TimeoutHelper(csb.OperationTimeout); AmqpConnection connection = await amqpEventHubClient.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()); // Authenticate over CBS var cbsLink = connection.Extensions.Find <AmqpCbsLink>(); ICbsTokenProvider cbsTokenProvider = amqpEventHubClient.CbsTokenProvider; Uri address = new Uri(csb.Endpoint, this.Path); string audience = address.AbsoluteUri; string resource = address.AbsoluteUri; var expiresAt = await cbsLink.SendTokenAsync(cbsTokenProvider, address, audience, resource, new[] { ClaimConstants.Send }, timeoutHelper.RemainingTime()); AmqpSession session = null; try { // Create our Session var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = connection.CreateSession(sessionSettings); await session.OpenAsync(timeoutHelper.RemainingTime()); // Create our Link var linkSettings = new AmqpLinkSettings(); linkSettings.AddProperty(AmqpClientConstants.TimeoutName, (uint)timeoutHelper.RemainingTime().TotalMilliseconds); linkSettings.AddProperty(AmqpClientConstants.EntityTypeName, (int)MessagingEntityType.EventHub); linkSettings.Role = false; linkSettings.InitialDeliveryCount = 0; linkSettings.Target = new Target { Address = address.AbsolutePath }; linkSettings.Source = new Source { Address = this.ClientId }; var link = new SendingAmqpLink(linkSettings); linkSettings.LinkName = $"{amqpEventHubClient.ContainerId};{connection.Identifier}:{session.Identifier}:{link.Identifier}"; link.AttachTo(session); await link.OpenAsync(timeoutHelper.RemainingTime()); var activeClientLink = new ActiveClientLink( link, this.EventHubClient.ConnectionStringBuilder.Endpoint.AbsoluteUri, // audience this.EventHubClient.ConnectionStringBuilder.Endpoint.AbsoluteUri, // endpointUri new[] { ClaimConstants.Send }, true, expiresAt); this.clientLinkManager.SetActiveLink(activeClientLink); return(link); } catch { // Cleanup any session (and thus link) in case of exception. session?.Abort(); 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 <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)); } }
public AmqpSession CreateSession(AmqpConnection connection, AmqpSessionSettings settings) { throw new InvalidOperationException(); }
public AmqpSession CreateSession(AmqpConnection connection, AmqpSessionSettings settings) { return(new AmqpSession(connection, settings, this)); }
/// <summary> /// Creates an AMQP link for use with receiving operations. /// </summary> /// <param name="entityName"></param> /// /// <param name="connection">The active and opened AMQP connection to use for this link.</param> /// <param name="endpoint">The fully qualified endpoint to open the link for.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested.</param> /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</param> /// <param name="sessionId"></param> /// <param name="isSessionReceiver"></param> /// <param name="timeout">The timeout to apply when creating the link.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>A link for use for operations related to receiving events.</returns> /// protected virtual async Task <ReceivingAmqpLink> CreateReceivingLinkAsync( string entityName, AmqpConnection connection, Uri endpoint, TimeSpan timeout, uint prefetchCount, ReceiveMode receiveMode, string sessionId, bool isSessionReceiver, CancellationToken cancellationToken) { Argument.AssertNotDisposed(IsDisposed, nameof(AmqpConnectionScope)); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var session = default(AmqpSession); var stopWatch = Stopwatch.StartNew(); try { // Perform the initial authorization for the link. var authClaims = new[] { ServiceBusClaim.Listen }; var authExpirationUtc = await RequestAuthorizationUsingCbsAsync(connection, TokenProvider, endpoint, endpoint.AbsoluteUri, endpoint.AbsoluteUri, authClaims, timeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the AMQP session associated with the link. var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = connection.CreateSession(sessionSettings); await OpenAmqpObjectAsync(session, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var filters = new FilterSet(); // even if supplied sessionId is null, we need to add the Session filter if it is a session receiver if (isSessionReceiver) { filters.Add(AmqpClientConstants.SessionFilterName, sessionId); } var linkSettings = new AmqpLinkSettings { Role = true, TotalLinkCredit = (uint)prefetchCount, AutoSendFlow = prefetchCount > 0, SettleType = (receiveMode == ReceiveMode.PeekLock) ? SettleMode.SettleOnDispose : SettleMode.SettleOnSend, Source = new Source { Address = endpoint.AbsolutePath, FilterSet = filters }, Target = new Target { Address = Guid.NewGuid().ToString() } }; var link = new ReceivingAmqpLink(linkSettings); linkSettings.LinkName = $"{connection.Settings.ContainerId};{connection.Identifier}:{session.Identifier}:{link.Identifier}:{linkSettings.Source.ToString()}"; link.AttachTo(session); stopWatch.Stop(); // Configure refresh for authorization of the link. var refreshTimer = default(Timer); var refreshHandler = CreateAuthorizationRefreshHandler ( entityName, connection, link, TokenProvider, endpoint, endpoint.AbsoluteUri, endpoint.AbsoluteUri, authClaims, AuthorizationRefreshTimeout, () => (ActiveLinks.ContainsKey(link) ? refreshTimer : null) ); refreshTimer = new Timer(refreshHandler, null, CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan); // Track the link before returning it, so that it can be managed with the scope. BeginTrackingLinkAsActive(entityName, link, refreshTimer); return(link); } catch { // Aborting the session will perform any necessary cleanup of // the associated link as well. session?.Abort(); throw; } }
AmqpSession ISessionFactory.CreateSession(AmqpConnection connection, AmqpSessionSettings sessionSettings) { return new AmqpSession(this, sessionSettings, this.amqpSettings.RuntimeProvider); }
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; } }
protected override IEnumerator <IteratorTask <object> .TaskStep> GetTasks() { ConnectivityMode connectivityMode; object obj = null; bool flag = false; try { object thisLock = this.relay.ThisLock; object obj1 = thisLock; obj = thisLock; Monitor.Enter(obj1, ref flag); if (this.relay.State != AmqpObjectState.OpenReceived && this.relay.State != AmqpObjectState.Opened) { goto Label0; } } finally { if (flag) { Monitor.Exit(obj); } } Microsoft.ServiceBus.Common.TimeoutHelper timeoutHelper = new Microsoft.ServiceBus.Common.TimeoutHelper(this.timeout); string host = this.relay.serviceBusUri.Host; AmqpSettings amqpSetting = AmqpRelay.ConnectTask.CreateAmqpSettings(); connectivityMode = (this.relay.connectivitySettings != null ? this.relay.connectivitySettings.Mode : ServiceBusEnvironment.SystemConnectivity.Mode); ConnectivityMode connectivityMode1 = connectivityMode; if (connectivityMode1 == ConnectivityMode.Tcp) { TcpTransportSettings tcpTransportSetting = new TcpTransportSettings() { Host = host, Port = 5671 }; TlsTransportSettings tlsTransportSetting = new TlsTransportSettings(tcpTransportSetting) { TargetHost = host }; AmqpTransportInitiator amqpTransportInitiator = new AmqpTransportInitiator(amqpSetting, tlsTransportSetting); yield return(base.CallTask(amqpTransportInitiator.ConnectTaskAsync(timeoutHelper.RemainingTime()), IteratorTask <TResult> .ExceptionPolicy.Transfer)); } else if (connectivityMode1 == ConnectivityMode.Http || this.relay.httpConnectivitySettings != null) { WebSocketTransportSettings webSocketTransportSetting = new WebSocketTransportSettings(this.relay.serviceBusUri); AmqpTransportInitiator amqpTransportInitiator1 = new AmqpTransportInitiator(amqpSetting, webSocketTransportSetting); yield return(base.CallTask(amqpTransportInitiator1.ConnectTaskAsync(timeoutHelper.RemainingTime()), IteratorTask <TResult> .ExceptionPolicy.Transfer)); } else { TcpTransportSettings tcpTransportSetting1 = new TcpTransportSettings() { Host = host, Port = 5671 }; TlsTransportSettings tlsTransportSetting1 = new TlsTransportSettings(tcpTransportSetting1) { TargetHost = host }; AmqpTransportInitiator amqpTransportInitiator2 = new AmqpTransportInitiator(amqpSetting, tlsTransportSetting1); yield return(base.CallTask(amqpTransportInitiator2.ConnectTaskAsync(Microsoft.ServiceBus.Common.TimeoutHelper.Divide(timeoutHelper.RemainingTime(), 2)), IteratorTask <TResult> .ExceptionPolicy.Continue)); if (base.LastTask.Exception != null) { if (timeoutHelper.RemainingTime() == TimeSpan.Zero) { throw base.LastTask.Exception; } WebSocketTransportSettings webSocketTransportSetting1 = new WebSocketTransportSettings(this.relay.serviceBusUri); AmqpTransportInitiator amqpTransportInitiator3 = new AmqpTransportInitiator(amqpSetting, webSocketTransportSetting1); yield return(base.CallTask(amqpTransportInitiator3.ConnectTaskAsync(timeoutHelper.RemainingTime()), IteratorTask <TResult> .ExceptionPolicy.Transfer)); } } TransportBase transportBase = base.LastTaskResult <TransportBase>(); string[] strArrays = host.Split(new char[] { '.' }); strArrays[0] = string.Concat(strArrays[0], "-relay"); AmqpConnectionSettings amqpConnectionSetting = new AmqpConnectionSettings() { ContainerId = Guid.NewGuid().ToString(), HostName = string.Join(".", strArrays) }; this.relay.connection = new AmqpConnection(transportBase, amqpSetting, amqpConnectionSetting); yield return(base.CallTask(this.relay.connection.OpenAsync(timeoutHelper.RemainingTime()), IteratorTask <TResult> .ExceptionPolicy.Transfer)); AmqpSessionSettings amqpSessionSetting = new AmqpSessionSettings(); AmqpSession amqpSession = this.relay.connection.CreateSession(amqpSessionSetting); yield return(base.CallTask(amqpSession.OpenAsync(timeoutHelper.RemainingTime()), IteratorTask <TResult> .ExceptionPolicy.Transfer)); AmqpLinkSettings amqpLinkSetting = new AmqpLinkSettings() { Role = new bool?(false), InitialDeliveryCount = new uint?(0), LinkName = string.Concat("HttpRelayServer_Link_", Guid.NewGuid()), Target = new Target(this.relay.serviceBusUri), Source = new Source(this.relay.serviceBusUri), TotalLinkCredit = 1000, AutoSendFlow = true }; AmqpLinkSettings amqpLinkSetting1 = amqpLinkSetting; if (this.relay.tokenRenewer != null) { amqpLinkSetting1.AddProperty(AmqpConstants.SimpleWebTokenPropertyName, this.relay.tokenRenewer.CurrentToken.Token); } if (!this.relay.TransportSecurityRequired) { amqpLinkSetting1.AddProperty(ClientConstants.TransportSecurityRequiredName, false); } if (!this.relay.RelayClientAuthorizationRequired) { amqpLinkSetting1.AddProperty(ClientConstants.ClientAuthenticationRequiredName, false); } if (this.relay.PublishToRegistry) { amqpLinkSetting1.AddProperty(ClientConstants.RequiresPublicRegistry, true); } if (!string.IsNullOrEmpty(this.relay.ClientAgent)) { amqpLinkSetting1.AddProperty(ClientConstants.ClientAgent, this.relay.ClientAgent); } if (!string.IsNullOrEmpty(this.relay.DisplayName)) { amqpLinkSetting1.AddProperty(ClientConstants.DisplayName, this.relay.DisplayName); } amqpLinkSetting1.AddProperty(ClientConstants.DynamicRelay, this.relay.IsDynamic); amqpLinkSetting1.AddProperty(ClientConstants.ListenerTypeName, this.relay.ListenerType.ToString()); this.relay.link = new DuplexAmqpLink(amqpSession, amqpLinkSetting1); yield return(base.CallTask(this.relay.link.OpenAsync(timeoutHelper.RemainingTime()), IteratorTask <TResult> .ExceptionPolicy.Transfer)); this.relay.link.SafeAddClosed(this.relay.onAmqpObjectClosed); this.relay.link.RegisterMessageListener((AmqpMessage msg) => this.relay.messageListener(this.relay.link, msg)); this.relay.OnOnline(); Label0: yield break; }
private async Task <AmqpSession> AmqpSessionCreator(DeviceIdentity deviceIdentity, ILinkFactory linkFactory, AmqpSessionSettings amqpSessionSettings, TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, timeout, $"{nameof(AmqpSessionCreator)}"); } AmqpConnection amqpConnection = await EnsureConnection(timeout).ConfigureAwait(false); AmqpSession amqpSession = new AmqpSession(amqpConnection, amqpSessionSettings, linkFactory); amqpConnection.AddSession(amqpSession, new ushort?()); if (Logging.IsEnabled) { Logging.Associate(amqpConnection, amqpSession, $"{nameof(AmqpSessionCreator)}"); } if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, timeout, $"{nameof(AmqpSessionCreator)}"); } return(amqpSession); }
public AmqpClientSession(AmqpClientConnection amqpTestConnection) { _amqpConnection = amqpTestConnection; AmqpSessionSettings = new AmqpSessionSettings(); }
/// <summary> /// Creates an AMQP link for use with publishing operations. /// </summary> /// /// <param name="connection">The active and opened AMQP connection to use for this link.</param> /// <param name="endpoint">The fully qualified endpoint to open the link for.</param> /// <param name="timeout">The timeout to apply when creating the link.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>A link for use for operations related to receiving events.</returns> /// protected virtual async Task <SendingAmqpLink> CreateSendingLinkAsync(AmqpConnection connection, Uri endpoint, TimeSpan timeout, CancellationToken cancellationToken) { Argument.AssertNotDisposed(IsDisposed, nameof(AmqpConnectionScope)); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var session = default(AmqpSession); var stopWatch = Stopwatch.StartNew(); try { // Perform the initial authorization for the link. var authClaims = new[] { EventHubsClaim.Send }; var authExpirationUtc = await RequestAuthorizationUsingCbsAsync(connection, TokenProvider, endpoint, endpoint.AbsoluteUri, endpoint.AbsoluteUri, authClaims, timeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the AMQP session associated with the link. var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = connection.CreateSession(sessionSettings); await OpenAmqpObjectAsync(session, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the link. var linkSettings = new AmqpLinkSettings { Role = false, InitialDeliveryCount = 0, Source = new Source { Address = Guid.NewGuid().ToString() }, Target = new Target { Address = endpoint.AbsolutePath } }; linkSettings.AddProperty(AmqpProperty.Timeout, (uint)timeout.CalculateRemaining(stopWatch.Elapsed).TotalMilliseconds); linkSettings.AddProperty(AmqpProperty.EntityType, (int)AmqpProperty.Entity.EventHub); var link = new SendingAmqpLink(linkSettings); linkSettings.LinkName = $"{ Id };{ connection.Identifier }:{ session.Identifier }:{ link.Identifier }"; link.AttachTo(session); stopWatch.Stop(); // Configure refresh for authorization of the link. var refreshTimer = default(Timer); var refreshHandler = CreateAuthorizationRefreshHandler ( connection, link, TokenProvider, endpoint, endpoint.AbsoluteUri, endpoint.AbsoluteUri, authClaims, AuthorizationRefreshTimeout, () => refreshTimer ); refreshTimer = new Timer(refreshHandler, null, CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan); // Track the link before returning it, so that it can be managed with the scope. BeginTrackingLinkAsActive(link, refreshTimer); return(link); } catch { // Aborting the session will perform any necessary cleanup of // the associated link as well. session?.Abort(); throw; } }
/// <summary> /// Creates an AMQP link for use with management operations. /// </summary> /// /// <param name="connection">The active and opened AMQP connection to use for this link.</param> /// <param name="timeout">The timeout to apply when creating the link.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>A link for use with management operations.</returns> /// protected virtual async Task <RequestResponseAmqpLink> CreateManagementLinkAsync(AmqpConnection connection, TimeSpan timeout, CancellationToken cancellationToken) { Argument.AssertNotDisposed(IsDisposed, nameof(AmqpConnectionScope)); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var session = default(AmqpSession); var stopWatch = Stopwatch.StartNew(); try { // Create and open the AMQP session associated with the link. var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = connection.CreateSession(sessionSettings); await OpenAmqpObjectAsync(session, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the link. var linkSettings = new AmqpLinkSettings(); linkSettings.AddProperty(AmqpProperty.Timeout, (uint)timeout.CalculateRemaining(stopWatch.Elapsed).TotalMilliseconds); linkSettings.AddProperty(AmqpClientConstants.EntityTypeName, AmqpClientConstants.EntityTypeManagement); var entityPath = EntityName + '/' + AmqpClientConstants.ManagementAddress; string[] claims = { ClaimConstants.Manage, ClaimConstants.Listen }; var endpointUri = new Uri(ServiceEndpoint, entityPath); var authExpirationUtc = await RequestAuthorizationUsingCbsAsync(connection, TokenProvider, ServiceEndpoint, endpointUri.AbsoluteUri, endpointUri.AbsoluteUri, claims, timeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false); var link = new RequestResponseAmqpLink(/*AmqpManagement.LinkType*/ "entity-mgmt", session, entityPath, linkSettings.Properties); linkSettings.LinkName = $"{connection.Settings.ContainerId};{connection.Identifier}:{session.Identifier}:{link.Identifier}"; stopWatch.Stop(); // Track the link before returning it, so that it can be managed with the scope. var refreshTimer = default(Timer); var refreshHandler = CreateAuthorizationRefreshHandler ( connection, link, TokenProvider, ServiceEndpoint, ServiceEndpoint.AbsoluteUri, ServiceEndpoint.AbsoluteUri, claims, AuthorizationRefreshTimeout, () => (ActiveLinks.ContainsKey(link) ? refreshTimer : null) ); refreshTimer = new Timer(refreshHandler, null, CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan); // Track the link before returning it, so that it can be managed with the scope. BeginTrackingLinkAsActive(link, refreshTimer); return(link); } catch { // Aborting the session will perform any necessary cleanup of // the associated link as well. session?.Abort(); throw; } }
public async Task <Tuple <AmqpObject, DateTime> > CreateAndOpenAmqpLinkAsync() { var timeoutHelper = new TimeoutHelper(this.serviceBusConnection.OperationTimeout, true); MessagingEventSource.Log.AmqpGetOrCreateConnectionStart(); var amqpConnection = await this.serviceBusConnection.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); MessagingEventSource.Log.AmqpGetOrCreateConnectionStop(this.entityPath, amqpConnection.ToString(), amqpConnection.State.ToString()); // Authenticate over CBS var cbsLink = amqpConnection.Extensions.Find <AmqpCbsLink>(); DateTime cbsTokenExpiresAtUtc = DateTime.MaxValue; foreach (var resource in this.audience) { MessagingEventSource.Log.AmqpSendAuthenticationTokenStart(this.endpointAddress, resource, resource, this.requiredClaims); cbsTokenExpiresAtUtc = TimeoutHelper.Min( cbsTokenExpiresAtUtc, await cbsLink.SendTokenAsync(this.cbsTokenProvider, this.endpointAddress, resource, resource, this.requiredClaims, timeoutHelper.RemainingTime()).ConfigureAwait(false)); MessagingEventSource.Log.AmqpSendAuthenticationTokenStop(); } AmqpSession session = null; try { // Create Session var amqpSessionSettings = new AmqpSessionSettings { Properties = new Fields() }; if (this.amqpLinkSettings.IsReceiver()) { // This is the maximum number of unsettled transfers across all receive links on this session. // This will allow the session to accept unlimited number of transfers, even if the recevier(s) // are not settling any of the deliveries. amqpSessionSettings.IncomingWindow = uint.MaxValue; } session = amqpConnection.CreateSession(amqpSessionSettings); await session.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); } catch (Exception exception) { MessagingEventSource.Log.AmqpSessionCreationException(this.entityPath, amqpConnection, exception); session?.Abort(); throw AmqpExceptionHelper.GetClientException(exception, null, session.GetInnerException(), amqpConnection.IsClosing()); } AmqpObject link = null; try { // Create Link link = this.OnCreateAmqpLink(amqpConnection, this.amqpLinkSettings, session); await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); return(new Tuple <AmqpObject, DateTime>(link, cbsTokenExpiresAtUtc)); } catch (Exception exception) { MessagingEventSource.Log.AmqpLinkCreationException( this.entityPath, session, amqpConnection, exception); session.SafeClose(exception); throw AmqpExceptionHelper.GetClientException(exception, null, link?.GetInnerException(), amqpConnection.IsClosing()); } }
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; }
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; }
AmqpSession ISessionFactory.CreateSession(AmqpConnection connection, AmqpSessionSettings settings) => new AmqpSession(connection, settings, this);
public AmqpSession(AmqpConnection connection, AmqpSessionSettings settings, ILinkFactory linkFactory) : this("session", connection, settings, linkFactory) { }
async Task <ReceivingAmqpLink> CreateLinkAsync(TimeSpan timeout) { var amqpEventHubClient = ((AmqpEventHubClient)this.EventHubClient); var timeoutHelper = new TimeoutHelper(timeout); AmqpConnection connection = await amqpEventHubClient.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); // Authenticate over CBS var cbsLink = connection.Extensions.Find <AmqpCbsLink>(); ICbsTokenProvider cbsTokenProvider = amqpEventHubClient.CbsTokenProvider; Uri address = new Uri(amqpEventHubClient.ConnectionStringBuilder.Endpoint, this.Path); string audience = address.AbsoluteUri; string resource = address.AbsoluteUri; var expiresAt = await cbsLink.SendTokenAsync(cbsTokenProvider, address, audience, resource, new[] { ClaimConstants.Listen }, timeoutHelper.RemainingTime()).ConfigureAwait(false); AmqpSession session = null; try { // Create our Session var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = connection.CreateSession(sessionSettings); await session.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); FilterSet filterMap = null; var filters = this.CreateFilters(); if (filters != null && filters.Count > 0) { filterMap = new FilterSet(); foreach (var filter in filters) { filterMap.Add(filter.DescriptorName, filter); } } // Create our Link var linkSettings = new AmqpLinkSettings { Role = true, TotalLinkCredit = (uint)this.PrefetchCount, AutoSendFlow = this.PrefetchCount > 0 }; linkSettings.AddProperty(AmqpClientConstants.EntityTypeName, (int)MessagingEntityType.ConsumerGroup); linkSettings.Source = new Source { Address = address.AbsolutePath, FilterSet = filterMap }; linkSettings.Target = new Target { Address = this.ClientId }; linkSettings.SettleType = SettleMode.SettleOnSend; // Receiver metrics enabled? if (this.ReceiverRuntimeMetricEnabled) { linkSettings.DesiredCapabilities = new Multiple <AmqpSymbol>(new List <AmqpSymbol> { AmqpClientConstants.EnableReceiverRuntimeMetricName }); } if (this.Epoch.HasValue) { linkSettings.AddProperty(AmqpClientConstants.AttachEpoch, this.Epoch.Value); } if (!string.IsNullOrWhiteSpace(this.Identifier)) { linkSettings.AddProperty(AmqpClientConstants.ReceiverIdentifierName, this.Identifier); } var link = new ReceivingAmqpLink(linkSettings); linkSettings.LinkName = $"{amqpEventHubClient.ContainerId};{connection.Identifier}:{session.Identifier}:{link.Identifier}"; link.AttachTo(session); await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); var activeClientLink = new ActiveClientLink( link, audience, // audience this.EventHubClient.ConnectionStringBuilder.Endpoint.AbsoluteUri, // endpointUri new[] { ClaimConstants.Listen }, true, expiresAt); this.clientLinkManager.SetActiveLink(activeClientLink); return(link); } catch { // Cleanup any session (and thus link) in case of exception. session?.SafeClose(); throw; } }
static void Main(string[] args) { try { var connection = AmqpConnection.Factory.OpenConnectionAsync("amqp://localhost:5672").Result; var sessionSettings = new AmqpSessionSettings { }; //AmqpSessionSettings.Create(new Begin()) var session = connection.CreateSession(sessionSettings); var linkSettings = new AmqpLinkSettings { LinkName = "theExchange", Handle = 1234, Role = false, Target = new Target { Address = "theQueue", Durable = 1 } }; var sender = new SendingAmqpLink(session, linkSettings); session.Open(); sender.Open(); var key = ConsoleKey.A; var i = 0; do { Console.WriteLine("Press any key to send message"); var body = "Hello, AMQP1.0!"; var message = AmqpMessage.Create(new AmqpValue() { Value = body }); var tag = new ArraySegment <byte>(BitConverter.GetBytes(i++)); var outcome = sender.SendMessageAsync(message, tag, AmqpConstants.NullBinary, TimeSpan.FromSeconds(3)).Result; if (outcome.DescriptorCode == Accepted.Code) { Console.WriteLine(" [x] Sent {0}", body); } else { Console.WriteLine("Error sending message!"); } } while (key != ConsoleKey.Q); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); throw; } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); }
/// <summary> /// Creates an AMQP link for use with publishing operations. /// </summary> /// <param name="entityPath"></param> /// <param name="viaEntityPath">The entity path to route the message through. Useful when using transactions.</param> /// <param name="connection">The active and opened AMQP connection to use for this link.</param> /// <param name="timeout">The timeout to apply when creating the link.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>A link for use for operations related to receiving events.</returns> /// protected virtual async Task <SendingAmqpLink> CreateSendingLinkAsync( string entityPath, string viaEntityPath, AmqpConnection connection, TimeSpan timeout, CancellationToken cancellationToken) { Argument.AssertNotDisposed(IsDisposed, nameof(AmqpConnectionScope)); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var session = default(AmqpSession); var stopWatch = ValueStopwatch.StartNew(); try { string[] audience; Uri destinationEndpoint = null; // if there is a via entityPath, include that in the audience if (!string.IsNullOrEmpty(viaEntityPath)) { destinationEndpoint = new Uri(ServiceEndpoint, viaEntityPath); var finalDestinationEndpoint = new Uri(ServiceEndpoint, entityPath); audience = new string[] { finalDestinationEndpoint.AbsoluteUri, destinationEndpoint.AbsoluteUri }; } else { destinationEndpoint = new Uri(ServiceEndpoint, entityPath); audience = new string[] { destinationEndpoint.AbsoluteUri }; } // Perform the initial authorization for the link. var authClaims = new[] { ServiceBusClaim.Send }; DateTime authExpirationUtc = await RequestAuthorizationUsingCbsAsync( connection, TokenProvider, destinationEndpoint, audience, authClaims, timeout.CalculateRemaining(stopWatch.GetElapsedTime())) .ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the AMQP session associated with the link. var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = connection.CreateSession(sessionSettings); await OpenAmqpObjectAsync(session, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the link. var linkSettings = new AmqpLinkSettings { Role = false, InitialDeliveryCount = 0, Source = new Source { Address = Guid.NewGuid().ToString() }, Target = new Target { Address = destinationEndpoint.AbsolutePath } }; if (!string.IsNullOrEmpty(viaEntityPath)) { linkSettings.AddProperty(AmqpClientConstants.TransferDestinationAddress, entityPath); } linkSettings.AddProperty(AmqpClientConstants.TimeoutName, (uint)timeout.CalculateRemaining(stopWatch.GetElapsedTime()).TotalMilliseconds); var link = new SendingAmqpLink(linkSettings); linkSettings.LinkName = $"{ Id };{ connection.Identifier }:{ session.Identifier }:{ link.Identifier }"; link.AttachTo(session); // Configure refresh for authorization of the link. var refreshTimer = default(Timer); TimerCallback refreshHandler = CreateAuthorizationRefreshHandler ( entityPath, connection, link, TokenProvider, destinationEndpoint, audience, authClaims, AuthorizationRefreshTimeout, () => refreshTimer ); refreshTimer = new Timer(refreshHandler, null, CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan); // Track the link before returning it, so that it can be managed with the scope. BeginTrackingLinkAsActive(entityPath, link, refreshTimer); return(link); } catch (Exception exception) { // Aborting the session will perform any necessary cleanup of // the associated link as well. session?.Abort(); ExceptionDispatchInfo.Capture(AmqpExceptionHelper.TranslateException( exception, null, session.GetInnerException(), connection.IsClosing())) .Throw(); throw; // will never be reached } }
protected override IEnumerator <IteratorAsyncResult <AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult> .AsyncStep> GetAsyncSteps() { string str = "$management"; if (base.RemainingTime() > TimeSpan.Zero) { try { AmqpSessionSettings amqpSessionSetting = new AmqpSessionSettings() { Properties = new Fields() }; this.session = new AmqpSession(this.connection, amqpSessionSetting, this); this.connection.AddSession(this.session, null); } catch (InvalidOperationException invalidOperationException1) { InvalidOperationException invalidOperationException = invalidOperationException1; base.Complete(new MessagingException(invalidOperationException.Message, true, invalidOperationException)); goto Label0; } AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult openManagementRequestResponseLinkAsyncResult = this; IteratorAsyncResult <AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult> .BeginCall beginCall = (AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult thisPtr, TimeSpan t, AsyncCallback c, object s) => thisPtr.session.BeginOpen(t, c, s); yield return(openManagementRequestResponseLinkAsyncResult.CallAsync(beginCall, (AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult thisPtr, IAsyncResult r) => thisPtr.session.EndOpen(r), IteratorAsyncResult <TIteratorAsyncResult> .ExceptionPolicy.Continue)); Exception lastAsyncStepException = base.LastAsyncStepException; if (lastAsyncStepException == null) { AmqpLinkSettings amqpLinkSetting = new AmqpLinkSettings(); AmqpLinkSettings amqpLinkSetting1 = amqpLinkSetting; AmqpSymbol timeoutName = ClientConstants.TimeoutName; TimeSpan timeSpan = base.RemainingTime(); amqpLinkSetting1.AddProperty(timeoutName, (uint)timeSpan.TotalMilliseconds); amqpLinkSetting.Target = new Target() { Address = str }; amqpLinkSetting.Source = new Source() { Address = str }; amqpLinkSetting.InitialDeliveryCount = new uint?(0); amqpLinkSetting.TotalLinkCredit = 50; amqpLinkSetting.AutoSendFlow = true; amqpLinkSetting.SettleType = SettleMode.SettleOnSend; this.Link = new RequestResponseAmqpLink(this.session, amqpLinkSetting); AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult openManagementRequestResponseLinkAsyncResult1 = this; IteratorAsyncResult <AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult> .BeginCall beginCall1 = (AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult thisPtr, TimeSpan t, AsyncCallback c, object s) => thisPtr.Link.BeginOpen(t, c, s); yield return(openManagementRequestResponseLinkAsyncResult1.CallAsync(beginCall1, (AmqpManagementLink.OpenManagementRequestResponseLinkAsyncResult thisPtr, IAsyncResult r) => thisPtr.Link.EndOpen(r), IteratorAsyncResult <TIteratorAsyncResult> .ExceptionPolicy.Continue)); lastAsyncStepException = base.LastAsyncStepException; if (lastAsyncStepException == null) { MessagingClientEtwProvider.Provider.EventWriteAmqpOpenEntitySucceeded(this.connection, this.Link, this.Link.Name, str); } else { this.Link = null; MessagingClientEtwProvider.Provider.EventWriteAmqpOpenEntityFailed(this.connection, this.Link, this.Link.Name, str, lastAsyncStepException.Message); this.session.SafeClose(); base.Complete(Microsoft.ServiceBus.Messaging.Amqp.ExceptionHelper.ToMessagingContract(lastAsyncStepException, this.connection.RemoteEndpoint.ToString())); } } else { MessagingClientEtwProvider.Provider.EventWriteAmqpOpenEntityFailed(this.connection, this.session, string.Empty, str, lastAsyncStepException.Message); this.session.Abort(); base.Complete(Microsoft.ServiceBus.Messaging.Amqp.ExceptionHelper.ToMessagingContract(lastAsyncStepException, this.connection.RemoteEndpoint.ToString())); } } else { if (this.session != null) { this.session.SafeClose(); } base.Complete(new TimeoutException(SRAmqp.AmqpTimeout(base.OriginalTimeout, str))); } Label0: yield break; }
public async Task <Tuple <AmqpObject, DateTime> > CreateAndOpenAmqpLinkAsync() { var timeoutHelper = new TimeoutHelper(this.serviceBusConnection.OperationTimeout); MessagingEventSource.Log.AmqpGetOrCreateConnectionStart(); var amqpConnection = await this.serviceBusConnection.ConnectionManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); MessagingEventSource.Log.AmqpGetOrCreateConnectionStop(this.entityPath, amqpConnection.ToString(), amqpConnection.State.ToString()); // Authenticate over CBS var cbsLink = amqpConnection.Extensions.Find <AmqpCbsLink>(); DateTime cbsTokenExpiresAtUtc = DateTime.MaxValue; foreach (var resource in this.audience) { MessagingEventSource.Log.AmqpSendAuthenticationTokenStart(this.endpointAddress, resource, resource, this.requiredClaims); cbsTokenExpiresAtUtc = TimeoutHelper.Min( cbsTokenExpiresAtUtc, await cbsLink.SendTokenAsync(this.cbsTokenProvider, this.endpointAddress, resource, resource, this.requiredClaims, timeoutHelper.RemainingTime()).ConfigureAwait(false)); MessagingEventSource.Log.AmqpSendAuthenticationTokenStop(); } AmqpSession session = null; try { // Create Session var amqpSessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = amqpConnection.CreateSession(amqpSessionSettings); await session.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); } catch (Exception exception) { MessagingEventSource.Log.AmqpSessionCreationException(this.entityPath, amqpConnection, exception); session?.Abort(); throw AmqpExceptionHelper.GetClientException(exception, null, session.GetInnerException()); } AmqpObject link = null; try { // Create Link link = this.OnCreateAmqpLink(amqpConnection, this.amqpLinkSettings, session); await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); return(new Tuple <AmqpObject, DateTime>(link, cbsTokenExpiresAtUtc)); } catch (Exception exception) { MessagingEventSource.Log.AmqpLinkCreationException( this.entityPath, session, amqpConnection, exception); session.SafeClose(exception); throw AmqpExceptionHelper.GetClientException(exception, null, link?.GetInnerException(), session.IsClosing()); } }
/// <summary> /// Creates an AMQP link for use with receiving operations. /// </summary> /// /// <param name="connection">The active and opened AMQP connection to use for this link.</param> /// <param name="endpoint">The fully qualified endpoint to open the link for.</param> /// <param name="eventPosition">The position of the event in the partition where the link should be filtered to.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested.</param> /// <param name="ownerLevel">The relative priority to associate with the link; for a non-exclusive link, this value should be <c>null</c>.</param> /// <param name="trackLastEnqueuedEventProperties">Indicates whether information on the last enqueued event on the partition is sent as events are received.</param> /// <param name="timeout">The timeout to apply when creating the link.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>A link for use for operations related to receiving events.</returns> /// protected virtual async Task <ReceivingAmqpLink> CreateReceivingLinkAsync(AmqpConnection connection, Uri endpoint, EventPosition eventPosition, TimeSpan timeout, uint prefetchCount, long?ownerLevel, bool trackLastEnqueuedEventProperties, CancellationToken cancellationToken) { Argument.AssertNotDisposed(IsDisposed, nameof(AmqpConnectionScope)); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var session = default(AmqpSession); var stopWatch = Stopwatch.StartNew(); try { // Perform the initial authorization for the link. var authClaims = new[] { EventHubsClaim.Listen }; var authExpirationUtc = await RequestAuthorizationUsingCbsAsync(connection, TokenProvider, endpoint, endpoint.AbsoluteUri, endpoint.AbsoluteUri, authClaims, timeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the AMQP session associated with the link. var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; session = connection.CreateSession(sessionSettings); await OpenAmqpObjectAsync(session, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the link. var filters = new FilterSet(); filters.Add(AmqpFilter.ConsumerFilterName, AmqpFilter.CreateConsumerFilter(AmqpFilter.BuildFilterExpression(eventPosition))); var linkSettings = new AmqpLinkSettings { Role = true, TotalLinkCredit = prefetchCount, AutoSendFlow = prefetchCount > 0, SettleType = SettleMode.SettleOnSend, Source = new Source { Address = endpoint.AbsolutePath, FilterSet = filters }, Target = new Target { Address = Guid.NewGuid().ToString() } }; linkSettings.AddProperty(AmqpProperty.EntityType, (int)AmqpProperty.Entity.ConsumerGroup); if (ownerLevel.HasValue) { linkSettings.AddProperty(AmqpProperty.OwnerLevel, ownerLevel.Value); } if (trackLastEnqueuedEventProperties) { linkSettings.DesiredCapabilities = new Multiple <AmqpSymbol>(new List <AmqpSymbol> { AmqpProperty.TrackLastEnqueuedEventProperties }); } var link = new ReceivingAmqpLink(linkSettings); linkSettings.LinkName = $"{ Id };{ connection.Identifier }:{ session.Identifier }:{ link.Identifier }"; link.AttachTo(session); stopWatch.Stop(); // Configure refresh for authorization of the link. var refreshTimer = default(Timer); var refreshHandler = CreateAuthorizationRefreshHandler ( connection, link, TokenProvider, endpoint, endpoint.AbsoluteUri, endpoint.AbsoluteUri, authClaims, AuthorizationRefreshTimeout, () => (ActiveLinks.ContainsKey(link) ? refreshTimer : null) ); refreshTimer = new Timer(refreshHandler, null, CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan); // Track the link before returning it, so that it can be managed with the scope. BeginTrackingLinkAsActive(link, refreshTimer); return(link); } catch { // Aborting the session will perform any necessary cleanup of // the associated link as well. session?.Abort(); throw; } }
/// <summary> /// Creates an AMQP link for use with receiving operations. /// </summary> /// <param name="entityPath">The entity path to receive from.</param> /// <param name="connection">The active and opened AMQP connection to use for this link.</param> /// <param name="endpoint">The fully qualified endpoint to open the link for.</param> /// <param name="prefetchCount">Controls the number of events received and queued locally without regard to whether an operation was requested.</param> /// <param name="receiveMode">The <see cref="ReceiveMode"/> used to specify how messages are received. Defaults to PeekLock mode.</param> /// <param name="sessionId">The session to receive from.</param> /// <param name="isSessionReceiver">Whether or not this is a sessionful receiver.</param> /// <param name="timeout">The timeout to apply when creating the link.</param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// /// <returns>A link for use for operations related to receiving events.</returns> protected virtual async Task <ReceivingAmqpLink> CreateReceivingLinkAsync( string entityPath, AmqpConnection connection, Uri endpoint, TimeSpan timeout, uint prefetchCount, ReceiveMode receiveMode, string sessionId, bool isSessionReceiver, CancellationToken cancellationToken) { Argument.AssertNotDisposed(IsDisposed, nameof(AmqpConnectionScope)); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var session = default(AmqpSession); var stopWatch = ValueStopwatch.StartNew(); try { // Perform the initial authorization for the link. string[] authClaims = new string[] { ServiceBusClaim.Send }; var audience = new[] { endpoint.AbsoluteUri }; DateTime authExpirationUtc = await RequestAuthorizationUsingCbsAsync( connection, TokenProvider, endpoint, audience, authClaims, timeout.CalculateRemaining(stopWatch.GetElapsedTime())).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); // Create and open the AMQP session associated with the link. var sessionSettings = new AmqpSessionSettings { Properties = new Fields() }; // This is the maximum number of unsettled transfers across all receive links on this session. // This will allow the session to accept unlimited number of transfers, even if the receiver(s) // are not settling any of the deliveries. sessionSettings.IncomingWindow = uint.MaxValue; session = connection.CreateSession(sessionSettings); await OpenAmqpObjectAsync(session, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); var filters = new FilterSet(); // even if supplied sessionId is null, we need to add the Session filter if it is a session receiver if (isSessionReceiver) { filters.Add(AmqpClientConstants.SessionFilterName, sessionId); } var linkSettings = new AmqpLinkSettings { Role = true, TotalLinkCredit = prefetchCount, AutoSendFlow = prefetchCount > 0, SettleType = (receiveMode == ReceiveMode.PeekLock) ? SettleMode.SettleOnDispose : SettleMode.SettleOnSend, Source = new Source { Address = endpoint.AbsolutePath, FilterSet = filters }, Target = new Target { Address = Guid.NewGuid().ToString() } }; var link = new ReceivingAmqpLink(linkSettings); linkSettings.LinkName = $"{connection.Settings.ContainerId};{connection.Identifier}:{session.Identifier}:{link.Identifier}:{linkSettings.Source.ToString()}"; link.AttachTo(session); // Configure refresh for authorization of the link. var refreshTimer = default(Timer); TimerCallback refreshHandler = CreateAuthorizationRefreshHandler ( entityPath, connection, link, TokenProvider, endpoint, audience, authClaims, AuthorizationRefreshTimeout, () => (ActiveLinks.ContainsKey(link) ? refreshTimer : null) ); refreshTimer = new Timer(refreshHandler, null, CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan); // Track the link before returning it, so that it can be managed with the scope. BeginTrackingLinkAsActive(entityPath, link, refreshTimer); return(link); } catch (Exception exception) { // Aborting the session will perform any necessary cleanup of // the associated link as well. session?.Abort(); ExceptionDispatchInfo.Capture(AmqpExceptionHelper.TranslateException( exception, null, session.GetInnerException(), connection.IsClosing())) .Throw(); throw; // will never be reached } }
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; }