public DefaultSubscriptionClientManager(IOptions <ServiceBusOptions> options, ISubscriptionClientFactory subscriptionClientFactory, ITopicMessageReceiver messageReceiver, IServiceBusManagementClient managementClient) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (subscriptionClientFactory == null) { throw new ArgumentNullException(nameof(subscriptionClientFactory)); } if (messageReceiver == null) { throw new ArgumentNullException(nameof(messageReceiver)); } if (managementClient == null) { throw new ArgumentNullException(nameof(managementClient)); } _options = options; _subscriptionClientFactory = subscriptionClientFactory; _messageReceiver = messageReceiver; _managementClient = managementClient; _clients = new List <ISubscriptionClient>(); }
/// <summary> /// Rotate either the primary or secondary connection string key of the Azure Service Bus resource. /// </summary> /// <param name="keyType">The type of the key to rotate.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="keyType"/> is outside the bounds of the enumeration.</exception> public async Task <string> RotateConnectionStringKeyAsync(KeyType keyType) { Guard.For <ArgumentOutOfRangeException>( () => !Enum.IsDefined(typeof(KeyType), keyType), $"Requires the KeyType value to be either '{nameof(KeyType.PrimaryKey)}' or '{nameof(KeyType.SecondaryKey)}'"); try { using IServiceBusManagementClient client = await _authentication.AuthenticateAsync(); _logger.LogTrace( "Start rotating {KeyType} connection string of Azure Service Bus {EntityType} '{EntityName}'...", keyType, Namespace.Entity, Namespace.EntityName); AccessKeys keys = await RegenerateAzureServiceBusKeysAsync(Namespace.Entity, Namespace.EntityName, keyType, client); _logger.LogWarning( "Rotated {KeyType} connection string of Azure Service Bus {EntityType} '{EntityName}'", keyType, Namespace.Entity, Namespace.EntityName); return(keyType switch { KeyType.PrimaryKey => keys.PrimaryConnectionString, KeyType.SecondaryKey => keys.SecondaryConnectionString, _ => throw new ArgumentOutOfRangeException(nameof(keyType), keyType, "Unknown key type") }); }
/// <summary> /// The Get Operation Status operation returns the status of /// thespecified operation. After calling an asynchronous operation, /// you can call Get Operation Status to determine whether the /// operation has succeeded, failed, or is still in progress. (see /// http://msdn.microsoft.com/en-us/library/windowsazure/ee460783.aspx /// for more information) /// </summary> /// <param name='operations'> /// Reference to the /// Microsoft.WindowsAzure.Management.ServiceBus.IServiceBusManagementClient. /// </param> /// <param name='requestId'> /// Required. The request ID for the request you wish to track. The /// request ID is returned in the x-ms-request-id response header for /// every request. /// </param> /// <returns> /// The response body contains the status of the specified asynchronous /// operation, indicating whether it has succeeded, is inprogress, or /// has failed. Note that this status is distinct from the HTTP status /// code returned for the Get Operation Status operation itself. If /// the asynchronous operation succeeded, the response body includes /// the HTTP status code for the successful request. If the /// asynchronous operation failed, the response body includes the HTTP /// status code for the failed request, and also includes error /// information regarding the failure. /// </returns> public static OperationStatusResponse GetOperationStatus(this IServiceBusManagementClient operations, string requestId) { return(Task.Factory.StartNew((object s) => { return ((IServiceBusManagementClient)s).GetOperationStatusAsync(requestId); } , operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult()); }
public ReceivingEndpoint(AzureServiceBusConfiguration configuration, IServiceBusManagementClient sbManagementClient, string topicName, IEnumerable <string> eventMessageTypeNames) { this.configuration = configuration; this.sbManagementClient = sbManagementClient; this.topicName = topicName; this.eventMessageTypeNames = eventMessageTypeNames; }
/// <summary> /// Gets the connection string keys for the Azure Service Bus Topic tested in the integration test suite. /// </summary> public async Task <AccessKeys> GetConnectionStringKeysForTopicAsync() { using IServiceBusManagementClient client = await CreateServiceManagementClientAsync(); AccessKeys accessKeys = await client.Topics.ListKeysAsync( _configuration.ServiceBusNamespace.ResourceGroup, _configuration.ServiceBusNamespace.Namespace, _configuration.ServiceBusNamespace.TopicName, _configuration.ServiceBusNamespace.AuthorizationRuleName); return(accessKeys); }
public ServiceBusMessageSubscriber( IServiceProvider serviceProvider, IServiceBusManagementClient serviceBusManagementClient, IMessageSerializer messageSerializer, IConfigurationManager configurationManager, ILogger logger) { this.serviceProvider = serviceProvider ?? throw new ArgumentNullException("config"); this.serviceBusManagementClient = serviceBusManagementClient ?? throw new ArgumentNullException("serviceBusManagementClient"); this.messageSerializer = messageSerializer ?? throw new ArgumentNullException("messageSerializer"); this.configurationManager = configurationManager ?? throw new ArgumentNullException("settingsManager"); this.logger = logger ?? throw new ArgumentNullException("logger"); }
private async Task EnsureAuthenticatedAsync() { if (_client is null) { var tm = new AzureAdTokenManager(); TokenCredentials token = await tm.RequestTokenAsync(_azureCredentials); _client = new ServiceBusManagementClient(token) { SubscriptionId = _identifier.SubscriptionId, }; } }
public DefaultTopicClientFactory(IServiceBusManagementClient managementClient, ServiceBusConnectionStringBuilder connectionStringBuilder) { if (managementClient == null) { throw new ArgumentNullException(nameof(managementClient)); } if (connectionStringBuilder == null) { throw new ArgumentNullException(nameof(connectionStringBuilder)); } _managementClient = managementClient; _connectionStringBuilder = connectionStringBuilder; }
/// <summary> /// Rotates the connection string key of the Azure Service Bus Queue, returning the new connection string as result. /// </summary> /// <param name="keyType">The type of key to rotate.</param> /// <returns> /// The new connection string according to the <paramref name="keyType"/>. /// </returns> /// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="keyType"/> is not within the bounds of the enumration.</exception> public async Task <string> RotateConnectionStringKeysForQueueAsync(KeyType keyType) { Guard.For <ArgumentOutOfRangeException>( () => !Enum.IsDefined(typeof(KeyType), keyType), $"Requires a KeyType that is either '{nameof(KeyType.PrimaryKey)}' or '{nameof(KeyType.SecondaryKey)}'"); var parameters = new RegenerateAccessKeyParameters(keyType); string queueName = _configuration.ServiceBusNamespace.QueueName; const ServiceBusEntityType entity = ServiceBusEntityType.Queue; try { using IServiceBusManagementClient client = await CreateServiceManagementClientAsync(); _logger.LogTrace( "Start rotating {KeyType} connection string of Azure Service Bus {EntityType} '{EntityName}'...", keyType, entity, queueName); AccessKeys accessKeys = await client.Queues.RegenerateKeysAsync( _configuration.ServiceBusNamespace.ResourceGroup, _configuration.ServiceBusNamespace.Namespace, queueName, _configuration.ServiceBusNamespace.AuthorizationRuleName, parameters); _logger.LogInformation( "Rotated {KeyType} connection string of Azure Service Bus {EntityType} '{EntityName}'", keyType, entity, queueName); switch (keyType) { case KeyType.PrimaryKey: return(accessKeys.PrimaryConnectionString); case KeyType.SecondaryKey: return(accessKeys.SecondaryConnectionString); default: throw new ArgumentOutOfRangeException(nameof(keyType), keyType, "Unknown key type"); } } catch (Exception exception) { _logger.LogError( exception, "Failed to rotate the {KeyType} connection string of the Azure Service Bus {EntityType} '{EntityName}'", keyType, entity, queueName); throw; } }
/// <summary> /// The Get Operation Status operation returns the status of /// thespecified operation. After calling an asynchronous operation, /// you can call Get Operation Status to determine whether the /// operation has succeeded, failed, or is still in progress. (see /// http://msdn.microsoft.com/en-us/library/windowsazure/ee460783.aspx /// for more information) /// </summary> /// <param name='operations'> /// Reference to the /// Microsoft.WindowsAzure.Management.ServiceBus.IServiceBusManagementClient. /// </param> /// <param name='requestId'> /// The request ID for the request you wish to track. The request ID is /// returned in the x-ms-request-id response header for every request. /// </param> /// <returns> /// The response body contains the status of the specified asynchronous /// operation, indicating whether it has succeeded, is inprogress, or /// has failed. Note that this status is distinct from the HTTP status /// code returned for the Get Operation Status operation itself. If /// the asynchronous operation succeeded, the response body includes /// the HTTP status code for the successful request. If the /// asynchronous operation failed, the response body includes the HTTP /// status code for the failed request, and also includes error /// information regarding the failure. /// </returns> public static ServiceBusOperationStatusResponse GetOperationStatus(this IServiceBusManagementClient operations, string requestId) { try { return(operations.GetOperationStatusAsync(requestId).Result); } catch (AggregateException ex) { if (ex.InnerExceptions.Count > 1) { throw; } else { throw ex.InnerException; } } }
/// <summary> /// Retrieves the list of regions that support the creation and /// management of Service Bus service namespaces. (see /// http://msdn.microsoft.com/en-us/library/windowsazure/jj860465.aspx /// for more information) /// </summary> /// <param name='operations'> /// Reference to the /// Microsoft.WindowsAzure.Management.ServiceBus.IServiceBusManagementClient. /// </param> /// <returns> /// A response to a request for a list of regions. /// </returns> public static ServiceBusRegionsResponse GetServiceBusRegions(this IServiceBusManagementClient operations) { try { return(operations.GetServiceBusRegionsAsync().Result); } catch (AggregateException ex) { if (ex.InnerExceptions.Count > 1) { throw; } else { throw ex.InnerException; } } }
/// <summary> /// Deletes a Service Bus namespace. Can handle transitioning states by recursing itself /// on exception. /// </summary> /// <param name="client">The <see cref="ServiceBusManagementClient"/> that is performing the operation.</param> /// <param name="nsName">The name of the namespace that we want to delete.</param> /// <param name="retries">Number of retries for "Active" state before giving up on deletion.</param> private static void DeleteNamespace(IServiceBusManagementClient client, string nsName, int retries) { if (retries-- < 0) throw new InvalidOperationException( string.Format( "Reached the maximum number of retries before I could delete the namespace. The namespace {0} needs to be deleted manually", nsName)); try { client.Namespaces.Delete(nsName); } catch (Exception) { Thread.Sleep(10000); DeleteNamespace(client, nsName, retries); } }
/// <summary> /// Deletes a Service Bus namespace. Can handle transitioning states by recursing itself /// on exception. /// </summary> /// <param name="client">The <see cref="ServiceBusManagementClient"/> that is performing the operation.</param> /// <param name="nsName">The name of the namespace that we want to delete.</param> /// <param name="retries">Number of retries for "Active" state before giving up on deletion.</param> private static void DeleteNamespace(IServiceBusManagementClient client, string nsName, int retries) { if (retries-- < 0) { throw new InvalidOperationException( string.Format( "Reached the maximum number of retries before I could delete the namespace. The namespace {0} needs to be deleted manually", nsName)); } try { client.Namespaces.Delete(nsName); } catch (Exception) { Thread.Sleep(10000); DeleteNamespace(client, nsName, retries); } }
public async Task <IServiceBusManagementClient> GetServiceBusManagementClient() { if (serviceBusManagementClient != null) { return(serviceBusManagementClient); } var context = new AuthenticationContext($"https://login.microsoftonline.com/{configuration.TenantId}"); var result = await context.AcquireTokenAsync( "https://management.core.windows.net/", new ClientCredential(configuration.ClientId, configuration.ClientSecret) ); var creds = new TokenCredentials(result.AccessToken); return(serviceBusManagementClient = new ServiceBusManagementClient(creds) { SubscriptionId = configuration.SubscriptionId }); }
internal static ITopicClient GetEventsTopicClient(IConfigurationManager configurationManager, IServiceBusManagementClient serviceBusManagementClient) { var connectionString = configurationManager.GetSetting("EasyCQRS.Infrastructure.ServiceBus.ConnectionString"); var resourceGroup = configurationManager.GetSetting("EasyCQRS.Infrastructure.ServiceBus.ResourceGroup"); var ns = configurationManager.GetSetting("EasyCQRS.Infrastructure.ServiceBus.Namespace"); var topicName = configurationManager.GetSetting("EasyCQRS.Infrastructure.ServiceBus.EventsTopic"); serviceBusManagementClient.Topics.CreateOrUpdate( resourceGroup, ns, topicName, new Microsoft.Azure.Management.ServiceBus.Fluent.Models.TopicInner { Location = "East US" }); return(new TopicClient(connectionString, topicName, RetryPolicy.Default)); }
/// <summary> /// Retrieves the list of regions that support the creation and /// management of Service Bus service namespaces. (see /// http://msdn.microsoft.com/en-us/library/windowsazure/jj860465.aspx /// for more information) /// </summary> /// <param name='operations'> /// Reference to the /// Microsoft.WindowsAzure.Management.ServiceBus.IServiceBusManagementClient. /// </param> /// <returns> /// A response to a request for a list of regions. /// </returns> public static Task <ServiceBusRegionsResponse> GetServiceBusRegionsAsync(this IServiceBusManagementClient operations) { return(operations.GetServiceBusRegionsAsync(CancellationToken.None)); }
/// <summary> /// The Get Operation Status operation returns the status of /// thespecified operation. After calling an asynchronous operation, /// you can call Get Operation Status to determine whether the /// operation has succeeded, failed, or is still in progress. (see /// http://msdn.microsoft.com/en-us/library/windowsazure/ee460783.aspx /// for more information) /// </summary> /// <param name='operations'> /// Reference to the /// Microsoft.WindowsAzure.Management.ServiceBus.IServiceBusManagementClient. /// </param> /// <param name='requestId'> /// Required. The request ID for the request you wish to track. The /// request ID is returned in the x-ms-request-id response header for /// every request. /// </param> /// <returns> /// The response body contains the status of the specified asynchronous /// operation, indicating whether it has succeeded, is inprogress, or /// has failed. Note that this status is distinct from the HTTP status /// code returned for the Get Operation Status operation itself. If /// the asynchronous operation succeeded, the response body includes /// the HTTP status code for the successful request. If the /// asynchronous operation failed, the response body includes the HTTP /// status code for the failed request, and also includes error /// information regarding the failure. /// </returns> public static Task <OperationStatusResponse> GetOperationStatusAsync(this IServiceBusManagementClient operations, string requestId) { return(operations.GetOperationStatusAsync(requestId, CancellationToken.None)); }
internal static ISubscriptionClient GetEventsSubscriptionClient(IConfigurationManager configurationManager, IServiceBusManagementClient serviceBusManagementClient, string subscriptionName) { var connectionString = configurationManager.GetSetting("EasyCQRS.Infrastructure.ServiceBus.ConnectionString"); var resourceGroup = configurationManager.GetSetting("EasyCQRS.Infrastructure.ServiceBus.ResourceGroup"); var ns = configurationManager.GetSetting("EasyCQRS.Infrastructure.ServiceBus.Namespace"); var topicName = configurationManager.GetSetting("EasyCQRS.Infrastructure.ServiceBus.EventsTopic"); serviceBusManagementClient.Subscriptions.CreateOrUpdate( resourceGroup, ns, topicName, subscriptionName, new Microsoft.Azure.Management.ServiceBus.Fluent.Models.SubscriptionInner { Location = "East US" }); return(new SubscriptionClient(connectionString, topicName, subscriptionName)); }