/// <summary> /// Initializes a new instance of the <see cref="EventHubConnection"/> class. /// </summary> /// /// <param name="fullyQualifiedNamespace">The fully qualified Event Hubs namespace to connect to. This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param> /// <param name="eventHubName">The name of the specific Event Hub to associate the connection with.</param> /// <param name="credential">The Azure managed identity credential to use for authorization. Access controls may be specified by the Event Hubs namespace or the requested Event Hub, depending on Azure configuration.</param> /// <param name="connectionOptions">A set of options to apply when configuring the connection.</param> /// public EventHubConnection(string fullyQualifiedNamespace, string eventHubName, TokenCredential credential, EventHubConnectionOptions connectionOptions = default) { Argument.AssertWellFormedEventHubsNamespace(fullyQualifiedNamespace, nameof(fullyQualifiedNamespace)); Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNull(credential, nameof(credential)); connectionOptions = connectionOptions?.Clone() ?? new EventHubConnectionOptions(); ValidateConnectionOptions(connectionOptions); var tokenCredential = new EventHubTokenCredential(credential); FullyQualifiedNamespace = fullyQualifiedNamespace; EventHubName = eventHubName; Options = connectionOptions; #pragma warning disable CA2214 // Do not call overridable methods in constructors. This internal method is virtual for testing purposes. InnerClient = CreateTransportClient(fullyQualifiedNamespace, eventHubName, tokenCredential, connectionOptions); #pragma warning restore CA2214 // Do not call overridable methods in constructors. }
/// <summary> /// Initializes a new instance of the <see cref="EventHubConnection"/> class. /// </summary> /// /// <param name="connectionString">The connection string to use for connecting to the Event Hubs namespace; it is expected that the shared key properties are contained in this connection string, but not the Event Hub name.</param> /// <param name="eventHubName">The name of the specific Event Hub to associate the connection with.</param> /// <param name="connectionOptions">A set of options to apply when configuring the connection.</param> /// /// <remarks> /// If the connection string is copied from the Event Hub itself, it will contain the name of the desired Event Hub, /// and can be used directly without passing the <paramref name="eventHubName" />. The name of the Event Hub should be /// passed only once, either as part of the connection string or separately. /// </remarks> /// public EventHubConnection(string connectionString, string eventHubName, EventHubConnectionOptions connectionOptions) { Argument.AssertNotNullOrEmpty(connectionString, nameof(connectionString)); connectionOptions = connectionOptions?.Clone() ?? new EventHubConnectionOptions(); ValidateConnectionOptions(connectionOptions); ConnectionStringProperties connectionStringProperties = ConnectionStringParser.Parse(connectionString); ValidateConnectionProperties(connectionStringProperties, eventHubName, nameof(connectionString)); var fullyQualifiedNamespace = connectionStringProperties.Endpoint.Host; if (string.IsNullOrEmpty(eventHubName)) { eventHubName = connectionStringProperties.EventHubName; } var sharedAccessSignature = new SharedAccessSignature ( BuildAudienceResource(connectionOptions.TransportType, fullyQualifiedNamespace, eventHubName), connectionStringProperties.SharedAccessKeyName, connectionStringProperties.SharedAccessKey ); var sharedCredentials = new SharedAccessSignatureCredential(sharedAccessSignature); var tokenCredentials = new EventHubTokenCredential(sharedCredentials, BuildAudienceResource(connectionOptions.TransportType, fullyQualifiedNamespace, eventHubName)); FullyQualifiedNamespace = fullyQualifiedNamespace; EventHubName = eventHubName; Options = connectionOptions; #pragma warning disable CA2214 // Do not call overridable methods in constructors. This internal method is virtual for testing purposes. InnerClient = CreateTransportClient(fullyQualifiedNamespace, eventHubName, tokenCredentials, connectionOptions); #pragma warning restore CA2214 // Do not call overridable methods in constructors. }
/// <summary> /// Initializes a new instance of the <see cref="AmqpConnectionScope"/> class. /// </summary> /// /// <param name="serviceEndpoint">Endpoint for the Event Hubs service to which the scope is associated.</param> /// <param name="eventHubName"> The name of the Event Hub to which the scope is associated</param> /// <param name="credential">The credential to use for authorization with the Event Hubs service.</param> /// <param name="transport">The transport to use for communication.</param> /// <param name="proxy">The proxy, if any, to use for communication.</param> /// <param name="identifier">The identifier to assign this scope; if not provided, one will be generated.</param> /// public AmqpConnectionScope(Uri serviceEndpoint, string eventHubName, EventHubTokenCredential credential, EventHubsTransportType transport, IWebProxy proxy, string identifier = default) { Argument.AssertNotNull(serviceEndpoint, nameof(serviceEndpoint)); Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNull(credential, nameof(credential)); ValidateTransport(transport); ServiceEndpoint = serviceEndpoint; EventHubName = eventHubName; Transport = transport; Proxy = proxy; TokenProvider = new CbsTokenProvider(new EventHubTokenCredential(credential, serviceEndpoint.ToString()), OperationCancellationSource.Token); Id = identifier ?? $"{ eventHubName }-{ Guid.NewGuid().ToString("D").Substring(0, 8) }"; Task <AmqpConnection> connectionFactory(TimeSpan timeout) => CreateAndOpenConnectionAsync(AmqpVersion, ServiceEndpoint, Transport, Proxy, Id, timeout); ActiveConnection = new FaultTolerantAmqpObject <AmqpConnection>(connectionFactory, CloseConnection); }
/// <summary> /// Initializes a new instance of the <see cref="CbsTokenProvider"/> class. /// </summary> /// /// <param name="credential">The credential to use for access token generation.</param> /// <param name="tokenExpirationBuffer">The amount of time to buffer expiration</param> /// <param name="cancellationToken">The cancellation token to consider when making requests.</param> /// public CbsTokenProvider(EventHubTokenCredential credential, TimeSpan tokenExpirationBuffer, CancellationToken cancellationToken) { Argument.AssertNotNull(credential, nameof(credential)); Argument.AssertNotNegative(tokenExpirationBuffer, nameof(tokenExpirationBuffer)); Credential = credential; TokenExpirationBuffer = tokenExpirationBuffer; CancellationToken = cancellationToken; TokenType = (credential.IsSharedAccessCredential) ? SharedAccessTokenType : JsonWebTokenType; // Tokens are only cached for JWT-based credentials; no need // to instantiate the semaphore if no caching is taking place. if (!credential.IsSharedAccessCredential) { TokenAcquireGuard = new SemaphoreSlim(1, 1); } }
/// <summary> /// Initializes a new instance of the <see cref="AmqpClient"/> class. /// </summary> /// /// <param name="host">The fully qualified host name for the Event Hubs namespace. This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param> /// <param name="eventHubName">The name of the specific Event Hub to connect the client to.</param> /// <param name="operationTimeout">The amount of time to allow for an AMQP operation using the link to complete before attempting to cancel it.</param> /// <param name="credential">The Azure managed identity credential to use for authorization. Access controls may be specified by the Event Hubs namespace or the requested Event Hub, depending on Azure configuration.</param> /// <param name="clientOptions">A set of options to apply when configuring the client.</param> /// <param name="connectionScope">The optional scope to use for AMQP connection management. If <c>null</c>, a new scope will be created.</param> /// <param name="messageConverter">The optional converter to use for transforming AMQP message-related types. If <c>null</c>, a new converter will be created.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// protected AmqpClient(string host, string eventHubName, TimeSpan operationTimeout, EventHubTokenCredential credential, EventHubConnectionOptions clientOptions, AmqpConnectionScope connectionScope, AmqpMessageConverter messageConverter) { Argument.AssertNotNullOrEmpty(host, nameof(host)); Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNegative(operationTimeout, nameof(operationTimeout)); Argument.AssertNotNull(credential, nameof(credential)); Argument.AssertNotNull(clientOptions, nameof(clientOptions)); try { EventHubsEventSource.Log.EventHubClientCreateStart(host, eventHubName); ServiceEndpoint = new UriBuilder { Scheme = clientOptions.TransportType.GetUriScheme(), Host = host }.Uri; ConnectionEndpoint = clientOptions.CustomEndpointAddress switch { null => ServiceEndpoint, _ => new UriBuilder { Scheme = ServiceEndpoint.Scheme, Host = clientOptions.CustomEndpointAddress.Host }.Uri }; EventHubName = eventHubName; Credential = credential; MessageConverter = messageConverter ?? new AmqpMessageConverter(); ConnectionScope = connectionScope ?? new AmqpConnectionScope( ServiceEndpoint, ConnectionEndpoint, eventHubName, credential, clientOptions.TransportType, clientOptions.Proxy, clientOptions.ConnectionIdleTimeout, null, clientOptions.SendBufferSizeInBytes, clientOptions.ReceiveBufferSizeInBytes, clientOptions.CertificateValidationCallback); ManagementLink = new FaultTolerantAmqpObject <RequestResponseAmqpLink>( linkTimeout => ConnectionScope.OpenManagementLinkAsync(operationTimeout, linkTimeout, CancellationToken.None), link => { link.Session?.SafeClose(); link.SafeClose(); EventHubsEventSource.Log.FaultTolerantAmqpObjectClose(nameof(RequestResponseAmqpLink), "", EventHubName, "", "", link.TerminalException?.Message); }); } finally { EventHubsEventSource.Log.EventHubClientCreateComplete(host, eventHubName); } }
internal override TransportClient CreateTransportClient(string fullyQualifiedNamespace, string eventHubName, EventHubTokenCredential credential, EventHubConnectionOptions options) => Mock.Of <TransportClient>();
/// <summary> /// Initializes a new instance of the <see cref="AmqpClient"/> class. /// </summary> /// /// <param name="host">The fully qualified host name for the Event Hubs namespace. This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param> /// <param name="eventHubName">The name of the specific Event Hub to connect the client to.</param> /// <param name="credential">The Azure managed identity credential to use for authorization. Access controls may be specified by the Event Hubs namespace or the requested Event Hub, depending on Azure configuration.</param> /// <param name="clientOptions">A set of options to apply when configuring the client.</param> /// /// <remarks> /// As an internal type, this class performs only basic sanity checks against its arguments. It /// is assumed that callers are trusted and have performed deep validation. /// /// Any parameters passed are assumed to be owned by this instance and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the /// caller. /// </remarks> /// public AmqpClient(string host, string eventHubName, EventHubTokenCredential credential, EventHubConnectionOptions clientOptions) : this(host, eventHubName, credential, clientOptions, null, null) { }
internal override TransportClient CreateTransportClient(string fullyQualifiedNamespace, string eventHubName, EventHubTokenCredential credential, EventHubConnectionOptions options) { var client = new Mock <TransportClient>(); client .Setup(client => client.ServiceEndpoint) .Returns(new Uri($"amgp://{ fullyQualifiedNamespace }.com/{ eventHubName }")); return(client.Object); }
internal override TransportClient CreateTransportClient(string fullyQualifiedNamespace, string eventHubName, EventHubTokenCredential credential, EventHubConnectionOptions options) { TransportClientOptions = options; _transportClient = new ObservableTransportClientMock(); return(_transportClient); }