/// <summary> /// Initializes a new instance of the <see cref="ServiceBusConnection"/> class. /// </summary> /// /// <param name="connectionString">The connection string to use for connecting to the Service Bus namespace.</param> /// <param name="entityName">The name of the specific Service Bus entity to associate the connection with (if not contained in connectionString).</param> /// <param name="connectionOptions">A set of options to apply when configuring the connection.</param> /// /// <remarks> /// If the connection string is copied from the Service Bus entity itself, it will contain the name of the desired Service Bus entity, /// and can be used directly without passing the <paramref name="entityName" />. The name of the Service Bus entity should be /// passed only once, either as part of the connection string or separately. /// </remarks> /// public ServiceBusConnection( string connectionString, string entityName, ServiceBusConnectionOptions connectionOptions) { Argument.AssertNotNullOrEmpty(connectionString, nameof(connectionString)); connectionOptions = connectionOptions?.Clone() ?? new ServiceBusConnectionOptions(); ValidateConnectionOptions(connectionOptions); var builder = new ServiceBusConnectionStringBuilder(connectionString); var fullyQualifiedNamespace = builder.FullyQualifiedNamespace; if (string.IsNullOrEmpty(entityName)) { entityName = builder.EntityName; } var sharedAccessSignature = new SharedAccessSignature ( BuildAudienceResource(connectionOptions.TransportType, fullyQualifiedNamespace, entityName), builder.SasKeyName, builder.SasKey ); var sharedCredentials = new SharedAccessSignatureCredential(sharedAccessSignature); var tokenCredentials = new ServiceBusTokenCredential(sharedCredentials, BuildAudienceResource(connectionOptions.TransportType, fullyQualifiedNamespace, entityName)); FullyQualifiedNamespace = fullyQualifiedNamespace; EntityName = entityName; InnerClient = CreateTransportClient(fullyQualifiedNamespace, entityName, tokenCredentials, connectionOptions); TransportType = connectionOptions.TransportType; }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBusConnection"/> class. /// </summary> /// /// <param name="fullyQualifiedNamespace">The fully qualified Service Bus namespace to connect to. This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param> /// <param name="entityName">The name of the specific Service Bus entity 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 Service Bus namespace or the requested Service Bus entity, depending on Azure configuration.</param> /// <param name="connectionOptions">A set of options to apply when configuring the connection.</param> /// public ServiceBusConnection( string fullyQualifiedNamespace, string entityName, TokenCredential credential, ServiceBusConnectionOptions connectionOptions = default) { Argument.AssertNotNullOrEmpty(fullyQualifiedNamespace, nameof(fullyQualifiedNamespace)); Argument.AssertNotNullOrEmpty(entityName, nameof(entityName)); Argument.AssertNotNull(credential, nameof(credential)); connectionOptions = connectionOptions?.Clone() ?? new ServiceBusConnectionOptions(); ValidateConnectionOptions(connectionOptions); switch (credential) { case SharedAccessSignatureCredential _: break; case ServiceBusSharedKeyCredential sharedKeyCredential: credential = sharedKeyCredential.AsSharedAccessSignatureCredential(BuildAudienceResource(connectionOptions.TransportType, fullyQualifiedNamespace, entityName)); break; } var tokenCredential = new ServiceBusTokenCredential(credential, BuildAudienceResource(connectionOptions.TransportType, fullyQualifiedNamespace, entityName)); FullyQualifiedNamespace = fullyQualifiedNamespace; EntityName = entityName; TransportType = connectionOptions.TransportType; InnerClient = CreateTransportClient(fullyQualifiedNamespace, entityName, tokenCredential, connectionOptions); }
///// <summary> ///// Performs the actions needed to validate the set of properties for connecting to the ///// Service Bus service, as passed to this client during creation. ///// </summary> ///// ///// <param name="properties">The set of properties parsed from the connection string associated this client.</param> ///// <param name="connectionStringArgumentName">The name of the argument associated with the connection string; to be used when raising <see cref="ArgumentException" /> variants.</param> ///// ///// <remarks> ///// In the case that the properties violate an invariant or otherwise represent a combination that ///// is not permissible, an appropriate exception will be thrown. ///// </remarks> ///// //private static void ValidateConnectionProperties(ConnectionStringProperties properties, // string connectionStringArgumentName) //{ // // The Service Bus entity name may only be specified in one of the possible forms, either as part of the // // connection string or as a stand-alone parameter, but not both. If specified in both to the same // // value, then do not consider this a failure. // if ((!string.IsNullOrEmpty(properties.EntityName)) // && (!string.Equals(properties.EventHubName, StringComparison.InvariantCultureIgnoreCase))) // { // throw new ArgumentException(Resources1.OnlyOneEventHubNameMayBeSpecified, connectionStringArgumentName); // } // // Ensure that each of the needed components are present for connecting. // if ( // (string.IsNullOrEmpty(properties.Endpoint?.Host)) // || (string.IsNullOrEmpty(properties.SharedAccessKeyName)) // || (string.IsNullOrEmpty(properties.SharedAccessKey))) // { // throw new ArgumentException(Resources1.MissingConnectionInformation, connectionStringArgumentName); // } //} /// <summary> /// Performs the actions needed to validate the <see cref="ServiceBusConnectionOptions" /> 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(ServiceBusConnectionOptions 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, Resources1.ProxyMustUseWebSockets), nameof(connectionOptions)); } }
/// <summary> /// Builds a Service Bus 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 Service Bus namespace. This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>.</param> /// <param name="entityName">The name of a specific Service Bus entity.</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 entityName, ServiceBusTokenCredential credential, ServiceBusConnectionOptions options) { switch (options.TransportType) { case ServiceBusTransportType.AmqpTcp: case ServiceBusTransportType.AmqpWebSockets: return(new AmqpClient(fullyQualifiedNamespace, entityName, credential, options)); default: throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources1.InvalidTransportType, options.TransportType.ToString()), nameof(options.TransportType)); } }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBusConnection"/> class. /// </summary> /// /// <param name="connectionString">The connection string to use for connecting to the Service Bus namespace; it is expected that the entity 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 Service Bus namespace, it will likely not contain the name of the desired Service Bus entity, /// which is needed. In this case, the name can be added manually by adding ";EntityPath=[[ Service Bus entity NAME ]]" to the end of the /// connection string. For example, ";EntityPath=telemetry-hub". /// /// If you have defined a shared access policy directly on the Service Bus entity itself, then copying the connection string from that /// Service Bus entity will result in a connection string that contains the name. /// </remarks> /// public ServiceBusConnection( string connectionString, ServiceBusConnectionOptions connectionOptions) : this(connectionString, null, connectionOptions) { }