/// <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.AssertNotNullOrEmpty(fullyQualifiedNamespace, nameof(fullyQualifiedNamespace)); Argument.AssertNotNullOrEmpty(eventHubName, nameof(eventHubName)); Argument.AssertNotNull(credential, nameof(credential)); connectionOptions = connectionOptions?.Clone() ?? new EventHubConnectionOptions(); ValidateConnectionOptions(connectionOptions); switch (credential) { case SharedAccessSignatureCredential _: break; case EventHubSharedKeyCredential sharedKeyCredential: credential = sharedKeyCredential.ConvertToSharedAccessSignatureCredential(BuildAudienceResource(connectionOptions.TransportType, fullyQualifiedNamespace, eventHubName)); break; default: credential = new EventHubTokenCredential(credential, BuildAudienceResource(connectionOptions.TransportType, fullyQualifiedNamespace, eventHubName)); break; } EventHubName = eventHubName; Options = connectionOptions; InnerClient = CreateTransportClient(fullyQualifiedNamespace, eventHubName, credential, connectionOptions); }
/// <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 Event Hub name and SAS token are contained in this connection string.</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 ); FullyQualifiedNamespace = fullyQualifiedNamespace; EventHubName = eventHubName; Options = connectionOptions; InnerClient = CreateTransportClient(fullyQualifiedNamespace, eventHubName, new SharedAccessSignatureCredential(sharedAccessSignature), connectionOptions); }
/// <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); switch (credential) { case SharedAccessSignatureCredential _: break; case EventHubSharedKeyCredential sharedKeyCredential: credential = sharedKeyCredential.AsSharedAccessSignatureCredential(BuildConnectionAudience(connectionOptions.TransportType, fullyQualifiedNamespace, eventHubName)); break; } var tokenCredential = new EventHubTokenCredential(credential, BuildConnectionAudience(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, 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="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 <see cref="AzureSasCredential"/> 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, AzureSasCredential credential, EventHubConnectionOptions connectionOptions = default) : this(fullyQualifiedNamespace, eventHubName, new SharedAccessCredential(credential), connectionOptions) { }
/// <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 <see cref="AzureNamedKeyCredential"/> 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, AzureNamedKeyCredential credential, EventHubConnectionOptions connectionOptions = default) : this(fullyQualifiedNamespace, eventHubName, TranslateNamedKeyCredential(credential, fullyQualifiedNamespace, eventHubName, connectionOptions?.TransportType), connectionOptions) { }
/// <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 <see cref="EventHubsSharedAccessKeyCredential"/> 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> /// internal EventHubConnection(string fullyQualifiedNamespace, string eventHubName, EventHubsSharedAccessKeyCredential credential, EventHubConnectionOptions connectionOptions = default) : this(fullyQualifiedNamespace, eventHubName, TranslateSharedKeyCredential(credential, fullyQualifiedNamespace, eventHubName, connectionOptions?.TransportType), connectionOptions) { }
/// <summary> /// Builds an Event Hub client specific to the protocol and transport specified by the /// requested connection type of the <paramref name="options" />. /// </summary> /// /// <param name="fullyQualifiedNamespace">The fully qualified Event Hubs namespace. This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param> /// <param name="eventHubName">The name of a specific Event Hub.</param> /// <param name="credential">The Azure managed identity credential to use for authorization.</param> /// <param name="options">The set of options to use for the client.</param> /// /// <returns>A client generalization specific to the specified protocol/transport to which operations may be delegated.</returns> /// /// <remarks> /// As an internal method, only basic sanity checks are performed against arguments. It is /// assumed that callers are trusted and have performed deep validation. /// /// Parameters passed are also assumed to be owned by thee transport client and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the caller. /// </remarks> /// internal virtual TransportClient CreateTransportClient(string fullyQualifiedNamespace, string eventHubName, EventHubTokenCredential credential, EventHubConnectionOptions options) { switch (options.TransportType) { case EventHubsTransportType.AmqpTcp: case EventHubsTransportType.AmqpWebSockets: return(new AmqpClient(fullyQualifiedNamespace, eventHubName, credential, options)); default: throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidTransportType, options.TransportType.ToString()), nameof(options.TransportType)); } }
/// <summary> /// Performs the actions needed to validate the <see cref="EventHubConnectionOptions" /> associated /// with this client. /// </summary> /// /// <param name="connectionOptions">The set of options to validate.</param> /// /// <remarks> /// In the case that the options violate an invariant or otherwise represent a combination that /// is not permissible, an appropriate exception will be thrown. /// </remarks> /// private static void ValidateConnectionOptions(EventHubConnectionOptions connectionOptions) { // If there were no options passed, they cannot be in an invalid state. if (connectionOptions == null) { return; } // A proxy is only valid when web sockets is used as the transport. if ((!connectionOptions.TransportType.IsWebSocketTransport()) && (connectionOptions.Proxy != null)) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.ProxyMustUseWebSockets), nameof(connectionOptions)); } }
/// <summary> /// Builds an Event Hub client specific to the protocol and transport specified by the /// requested connection type of the <paramref name="options" />. /// </summary> /// /// <param name="fullyQualifiedNamespace">The fully qualified Event Hubs namespace. This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param> /// <param name="eventHubName">The name of a specific Event Hub.</param> /// <param name="credential">The Azure managed identity credential to use for authorization.</param> /// <param name="options">The set of options to use for the client.</param> /// /// <returns>A client generalization specific to the specified protocol/transport to which operations may be delegated.</returns> /// /// <remarks> /// As an internal method, only basic sanity checks are performed against arguments. It is /// assumed that callers are trusted and have performed deep validation. /// /// Parameters passed are also assumed to be owned by thee transport client and safe to mutate or dispose; /// creation of clones or otherwise protecting the parameters is assumed to be the purview of the caller. /// </remarks> /// internal virtual TransportClient CreateTransportClient(string fullyQualifiedNamespace, string eventHubName, EventHubTokenCredential credential, EventHubConnectionOptions options) { switch (options.TransportType) { case EventHubsTransportType.AmqpTcp: case EventHubsTransportType.AmqpWebSockets: return(new AmqpClient(fullyQualifiedNamespace, eventHubName, credential, options)); default: #pragma warning disable CA2208 // Instantiate argument exceptions correctly. "TransportType" is a reasonable name. It's the property on the options argument which is invalid. throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidTransportType, options.TransportType.ToString()), nameof(options.TransportType)); #pragma warning restore CA2208 // Instantiate argument exceptions correctly } }
/// <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); var connectionStringProperties = ConnectionStringParser.Parse(connectionString); connectionStringProperties.Validate(eventHubName, nameof(connectionString)); var fullyQualifiedNamespace = connectionStringProperties.Endpoint.Host; if (string.IsNullOrEmpty(eventHubName)) { eventHubName = connectionStringProperties.EventHubName; } SharedAccessSignature sharedAccessSignature; if (string.IsNullOrEmpty(connectionStringProperties.SharedAccessSignature)) { sharedAccessSignature = new SharedAccessSignature( BuildConnectionAudience(connectionOptions.TransportType, fullyQualifiedNamespace, eventHubName), connectionStringProperties.SharedAccessKeyName, connectionStringProperties.SharedAccessKey); } else { sharedAccessSignature = new SharedAccessSignature(connectionStringProperties.SharedAccessSignature); } var sharedCredentials = new SharedAccessSignatureCredential(sharedAccessSignature); var tokenCredentials = new EventHubTokenCredential(sharedCredentials, BuildConnectionAudience(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="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, DefaultRetryPolicy.CalculateTryTimeout(0), 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 Event Hub name and the shared key properties are contained in this connection string.</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 Hubs namespace, it will likely not contain the name of the desired Event Hub, /// which is needed. In this case, the name can be added manually by adding ";EntityPath=[[ EVENT HUB NAME ]]" to the end of the /// connection string. For example, ";EntityPath=telemetry-hub". /// /// If you have defined a shared access policy directly on the Event Hub itself, then copying the connection string from that /// Event Hub will result in a connection string that contains the name. /// </remarks> /// public EventHubConnection(string connectionString, EventHubConnectionOptions connectionOptions) : this(connectionString, null, connectionOptions) { }
/// <summary> /// Creates an <see cref="EventHubConnection" /> based on the provided options and credential. /// </summary> /// /// <typeparam name="TCredential">The type of credential being used.</typeparam> /// /// <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 producer with.</param> /// <param name="credential">The credential to use for authorization. This may be of type <see cref="TokenCredential" />, <see cref="AzureSasCredential" />, or <see cref="AzureNamedKeyCredential" />.</param> /// <param name="options">A set of options to apply when configuring the connection.</param> /// /// <returns>The connection that was created.</returns> /// /// <remarks> /// Ownership of the connection is transferred to the caller. The caller holds responsibility /// for closing the connection and other cleanup activities. /// </remarks> /// internal static EventHubConnection CreateWithCredential <TCredential>(string fullyQualifiedNamespace, string eventHubName, TCredential credential, EventHubConnectionOptions options) => credential switch {