public static string ConnectionStringUri( string namespaceName, string entityName, ServiceBusEntityType entityType) { return string.Format("{0}/{1}s/{2}/ConnectionDetails/?api-version={3}", namespaceName, entityType.ToString(), entityName, ServiceBusLatestVersion); }
/// <summary> /// Removed shared access signature authorization for the service bus entity. /// </summary> /// <param name="namespaceName">The service bus namespace name</param> /// <param name="entityName">The fully qualified service bus entity name</param> /// <param name="entityType">The service bus entity type (e.g. Queue)</param> /// <param name="ruleName">The SAS authorization rule name</param> public virtual void RemoveAuthorizationRule( string namespaceName, string entityName, ServiceBusEntityType entityType, string ruleName) { bool removed = false; SharedAccessAuthorizationRule rule = (SharedAccessAuthorizationRule)GetAuthorizationRule( namespaceName, entityName, entityType, ruleName).Rule; // Create namespace manager NamespaceManager namespaceManager = CreateNamespaceManager(namespaceName); // Add the SAS rule and update the entity switch (entityType) { case ServiceBusEntityType.Queue: QueueDescription queue = namespaceManager.GetQueue(entityName); removed = queue.Authorization.Remove(rule); Debug.Assert(removed); namespaceManager.UpdateQueue(queue); break; case ServiceBusEntityType.Topic: TopicDescription topic = namespaceManager.GetTopic(entityName); removed = topic.Authorization.Remove(rule); Debug.Assert(removed); namespaceManager.UpdateTopic(topic); break; case ServiceBusEntityType.Relay: RelayDescription relay = namespaceManager.GetRelayAsync(entityName).Result; removed = relay.Authorization.Remove(rule); Debug.Assert(removed); namespaceManager.UpdateRelayAsync(relay).Wait(); break; case ServiceBusEntityType.NotificationHub: NotificationHubDescription notificationHub = namespaceManager.GetNotificationHub(entityName); removed = notificationHub.Authorization.Remove(rule); Debug.Assert(removed); namespaceManager.UpdateNotificationHub(notificationHub); break; default: throw new Exception(string.Format(Resources.ServiceBusEntityTypeNotFound, entityType.ToString())); } }
public void PublishMessage(string destination, ServiceBusEntityType entityType, Message message) { var connection = OpenConnection(destination, entityType); if (connection.client is IQueueClient) { var client = connection.client as IQueueClient; client.SendAsync(message).GetAwaiter().GetResult(); } if (connection.client is ITopicClient) { var client = connection.client as ITopicClient; client.SendAsync(message).GetAwaiter().GetResult(); } CloseConnection(connection.id); }
/// <summary> /// Gets the authorization rule with the specified name in the entity level. /// </summary> /// <param name="namespaceName">The namespace name</param> /// <param name="entityName">The entity name</param> /// <param name="entityType">The entity type</param> /// <param name="ruleName">The rule name</param> /// <returns>The authorization rule that matches the specified name</returns> public virtual ExtendedAuthorizationRule GetAuthorizationRule( string namespaceName, string entityName, ServiceBusEntityType entityType, string ruleName) { AuthorizationRuleFilterOption options = new AuthorizationRuleFilterOption() { Namespace = namespaceName, Name = ruleName, EntityName = entityName, EntityType = entityType }; return(FilterAuthorizationRules(options).FirstOrDefault()); }
/// <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; } }
private ExtendedAuthorizationRule CreateExtendedAuthorizationRule( AuthorizationRule rule, string namespaceName, string entityName, ServiceBusEntityType entityType) { return(new ExtendedAuthorizationRule() { Rule = rule, Name = rule.KeyName, Permission = rule.Rights.ToList(), ConnectionString = GetConnectionString(namespaceName, entityName, entityType, rule.KeyName), Namespace = namespaceName, EntityName = entityName, EntityType = entityType }); }
public async Task RotateServiceBusSecrets_WithValidArguments_RotatesPrimarySecondaryAlternatively() { // Arrange var config = TestConfig.Create(); KeyRotationConfig keyRotationConfig = config.GetKeyRotationConfig(); _logger.LogInformation("Using Service Principal [ClientID: '{ClientId}']", keyRotationConfig.ServicePrincipal.ClientId); const ServiceBusEntityType entity = ServiceBusEntityType.Topic; var keyVaultAuthentication = new ServicePrincipalAuthentication( keyRotationConfig.ServicePrincipal.ClientId, keyRotationConfig.ServicePrincipal.ClientSecret); var keyVaultConfiguration = new KeyVaultConfiguration(keyRotationConfig.KeyVault.VaultUri); var secretProvider = new KeyVaultSecretProvider(keyVaultAuthentication, keyVaultConfiguration); AzureServiceBusClient azureServiceBusClient = CreateAzureServiceBusClient(keyRotationConfig, secretProvider, entity); var rotation = new AzureServiceBusKeyRotation(azureServiceBusClient, keyVaultAuthentication, keyVaultConfiguration, _logger); var client = new ServiceBusConfiguration(keyRotationConfig, _logger); AccessKeys keysBefore1stRotation = await client.GetConnectionStringKeysForTopicAsync(); // Act await rotation.RotateServiceBusSecretAsync(keyRotationConfig.KeyVault.SecretName); // Assert string secondaryConnectionString = await secretProvider.GetRawSecretAsync(keyRotationConfig.KeyVault.SecretName); AccessKeys keysAfter1stRotation = await client.GetConnectionStringKeysForTopicAsync(); Assert.True(secondaryConnectionString == keysAfter1stRotation.SecondaryConnectionString, "Secondary connection string should be set in Azure Key Vault after first rotation"); Assert.NotEqual(keysBefore1stRotation.PrimaryConnectionString, keysAfter1stRotation.PrimaryConnectionString); Assert.NotEqual(keysBefore1stRotation.SecondaryConnectionString, keysAfter1stRotation.SecondaryConnectionString); await rotation.RotateServiceBusSecretAsync(keyRotationConfig.KeyVault.SecretName); string primaryConnectionString = await secretProvider.GetRawSecretAsync(keyRotationConfig.KeyVault.SecretName); AccessKeys keysAfter2ndRotation = await client.GetConnectionStringKeysForTopicAsync(); Assert.True(primaryConnectionString == keysAfter2ndRotation.PrimaryConnectionString, "Primary connection string should be set in Azure Key Vault after second rotation"); Assert.NotEqual(keysAfter1stRotation.PrimaryConnectionString, keysAfter2ndRotation.PrimaryConnectionString); Assert.NotEqual(keysAfter2ndRotation.SecondaryConnectionString, keysAfter1stRotation.SecondaryConnectionString); }
private async Task SetConnectionStringSecretAsync(IKeyVaultClient keyVaultClient, string secretName, string connectionString, KeyType keyType) { string vaultUri = _configuration.VaultUri.OriginalString; ServiceBusEntityType entity = _serviceBusClient.Namespace.Entity; string entityName = _serviceBusClient.Namespace.EntityName; try { _logger.LogTrace("Setting {KeyType} Azure Service Bus {EntityType} '{EntityName}' connection string key into Azure Key Vault...", keyType, entity, entityName); await keyVaultClient.SetSecretAsync(vaultUri, secretName, connectionString); _logger.LogInformation("{KeyType} Azure Service Bus {EntityType} '{EntityName}' connection string key set into Azure Key Vault", keyType, entity, entityName); } catch (Exception exception) { _logger.LogError( exception, "Unable to set the {KeyType} Azure Service Bus {EntityType} '{EntityName}' connection string key into Azure Key Vault", keyType, entity, entityName); throw; } }
public void LogServiceBusDependency_WithServiceBusDependency_CreatesDependencyTelemetry() { // Arrange var spySink = new InMemoryLogSink(); string operationId = $"operation-id-{Guid.NewGuid()}"; ILogger logger = CreateLogger(spySink, config => config.Enrich.WithProperty(ContextProperties.Correlation.OperationId, operationId)); string entityName = $"entity-name-{Guid.NewGuid()}"; const ServiceBusEntityType entityType = ServiceBusEntityType.Unknown; var startTime = DateTimeOffset.UtcNow; var duration = TimeSpan.FromSeconds(5); var telemetryContext = new Dictionary <string, object> { ["Namespace"] = "azure.servicebus.namespace" }; logger.LogServiceBusDependency(entityName, entityType: entityType, isSuccessful: true, startTime: startTime, duration: duration, context: telemetryContext); LogEvent logEvent = Assert.Single(spySink.CurrentLogEmits); Assert.NotNull(logEvent); var converter = ApplicationInsightsTelemetryConverter.Create(); // Act IEnumerable <ITelemetry> telemetries = converter.Convert(logEvent, formatProvider: null); // Assert AssertDoesNotContainLogProperty(logEvent, DependencyTracking.DependencyLogEntry); Assert.Collection(telemetries, telemetry => { var dependencyTelemetry = Assert.IsType <DependencyTelemetry>(telemetry); Assert.Equal("Azure Service Bus", dependencyTelemetry.Type); Assert.Equal(entityName, dependencyTelemetry.Target); Assert.Equal(startTime, dependencyTelemetry.Timestamp); Assert.Equal(duration, dependencyTelemetry.Duration); Assert.True(dependencyTelemetry.Success); AssertContainsTelemetryProperty(dependencyTelemetry, "Namespace", "azure.servicebus.namespace"); AssertContainsTelemetryProperty(dependencyTelemetry, "EntityType", entityType.ToString()); }); }
/// <summary> /// Initializes a new instance of the <see cref="AzureServiceBusNamespace"/> class. /// </summary> /// <param name="resourceGroup">The resource group where the Azure Service Bus resource is located.</param> /// <param name="namespace">The namespace where the Azure Service Bus is categorized.</param> /// <param name="entity">The entity type of the Azure Service Bus resource.</param> /// <param name="entityName">The entity name of the Azure Service Bus resource.</param> /// <param name="authorizationRuleName">The name of the authorization rule to use when authorizing with the Azure Service Bus.</param> /// <exception cref="ArgumentNullException"> /// Thrown when the <paramref name="resourceGroup"/>, <paramref name="namespace"/>, <paramref name="entityName"/>, or <paramref name="authorizationRuleName"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException">Thrown when the <paramref name="entity"/> is not defined within the bounds of the enumeration.</exception> public AzureServiceBusNamespace( string resourceGroup, string @namespace, ServiceBusEntityType entity, string entityName, string authorizationRuleName) { Guard.NotNullOrWhitespace(resourceGroup, nameof(resourceGroup)); Guard.NotNullOrWhitespace(@namespace, nameof(@namespace)); Guard.NotNullOrWhitespace(entityName, nameof(entityName)); Guard.NotNullOrWhitespace(authorizationRuleName, nameof(authorizationRuleName)); Guard.For <ArgumentException>( () => !Enum.IsDefined(typeof(ServiceBusEntityType), entity), $"Azure Service Bus entity '{entity}' is not defined in the '{nameof(ServiceBusEntityType)}' enumeration"); Guard.For <ArgumentOutOfRangeException>( () => entity is ServiceBusEntityType.Unknown, "Azure Service Bus entity type 'Unknown' is not supported here"); ResourceGroup = resourceGroup; Namespace = @namespace; Entity = entity; EntityName = entityName; AuthorizationRuleName = authorizationRuleName; }
private AzureServiceBusClient CreateAzureServiceBusClient( KeyRotationConfig keyRotationConfig, ISecretProvider secretProvider, ServiceBusEntityType entity) { var serviceBusAuthentication = new DefaultAzureServiceBusManagementAuthentication( keyRotationConfig.ServicePrincipal.ClientId, keyRotationConfig.ServicePrincipal.ClientSecretKey, keyRotationConfig.ServiceBusNamespace.SubscriptionId, keyRotationConfig.ServiceBusNamespace.TenantId, secretProvider); var serviceBusLocation = new AzureServiceBusNamespace( keyRotationConfig.ServiceBusNamespace.ResourceGroup, keyRotationConfig.ServiceBusNamespace.Namespace, entity, keyRotationConfig.ServiceBusNamespace.TopicName, keyRotationConfig.ServiceBusNamespace.AuthorizationRuleName); var azureServiceBusClient = new AzureServiceBusClient(serviceBusAuthentication, serviceBusLocation, _logger); return(azureServiceBusClient); }
private List <ExtendedAuthorizationRule> GetAuthorizationRuleCore( string namespaceName, string entityName, ServiceBusEntityType entityType, Predicate <AuthorizationRule> match) { NamespaceManager namespaceManager = CreateNamespaceManager(namespaceName); List <AuthorizationRule> rules = null; switch (entityType) { case ServiceBusEntityType.Queue: rules = namespaceManager.GetQueue(entityName).Authorization.GetRules(match); break; case ServiceBusEntityType.Topic: rules = namespaceManager.GetTopic(entityName).Authorization.GetRules(match); break; case ServiceBusEntityType.Relay: rules = namespaceManager.GetRelayAsync(entityName).Result.Authorization.GetRules(match); break; case ServiceBusEntityType.NotificationHub: rules = namespaceManager.GetNotificationHub(entityName).Authorization.GetRules(match); break; default: throw new InvalidOperationException(); } return(rules.Select(r => CreateExtendedAuthorizationRule( r, namespaceName, entityName, entityType)).ToList()); }
/// <summary> /// Initializes a new instance of the <see cref="AzureServiceBusMessagePumpSettings"/> class. /// </summary> /// <param name="entityName">The name of the entity to process.</param> /// <param name="subscriptionName">The name of the subscription to process.</param> /// <param name="serviceBusEntity">The entity type of the Azure Service Bus.</param> /// <param name="serviceBusNamespace"> /// The Service Bus namespace to connect to. This is likely to be similar to <c>{yournamespace}.servicebus.windows.net</c>. /// </param> /// <param name="tokenCredential">The client credentials to authenticate with the Azure Service Bus.</param> /// <param name="options">The options that influence the behavior of the <see cref="AzureServiceBusMessagePump"/>.</param> /// <param name="serviceProvider">The collection of services to use during the lifetime of the <see cref="AzureServiceBusMessagePump"/>.</param> /// <exception cref="ArgumentNullException"> /// Thrown when the <paramref name="options"/>, <paramref name="serviceProvider"/>, or <paramref name="tokenCredential"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// Thrown when the <paramref name="serviceBusNamespace"/> is blank or the <paramref name="serviceBusEntity"/> is outside the bounds of the enumeration. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown when the <paramref name="serviceBusEntity"/> represents the unsupported value <see cref="ServiceBusEntityType.Unknown"/>. /// </exception> public AzureServiceBusMessagePumpSettings( string entityName, string subscriptionName, ServiceBusEntityType serviceBusEntity, string serviceBusNamespace, TokenCredential tokenCredential, AzureServiceBusMessagePumpOptions options, IServiceProvider serviceProvider) { Guard.NotNull(options, nameof(options), "Requires message pump options that influence the behavior of the message pump"); Guard.NotNull(serviceProvider, nameof(serviceProvider), "Requires a service provider to get additional registered services during the lifetime of the message pump"); Guard.NotNull(tokenCredential, nameof(tokenCredential), "Requires a token credential instance to authenticate with the Azure Service Bus"); Guard.NotNullOrWhitespace(entityName, nameof(entityName), "Requires a non-blank entity name for the Azure Service Bus when using the token credentials"); Guard.NotNullOrWhitespace(serviceBusNamespace, nameof(serviceBusNamespace), "Requires a non-blank fully qualified Azure Service Bus namespace when using the token credentials"); Guard.For <ArgumentException>(() => !Enum.IsDefined(typeof(ServiceBusEntityType), serviceBusEntity), $"Azure Service Bus entity '{serviceBusEntity}' is not defined in the '{nameof(ServiceBusEntityType)}' enumeration"); Guard.For <ArgumentOutOfRangeException>(() => serviceBusEntity is ServiceBusEntityType.Unknown, "Azure Service Bus entity type 'Unknown' is not supported here"); _serviceProvider = serviceProvider; _tokenCredential = tokenCredential; EntityName = entityName; SubscriptionName = subscriptionName; ServiceBusEntity = serviceBusEntity; Options = options; if (serviceBusNamespace.EndsWith(".servicebus.windows.net")) { FullyQualifiedNamespace = serviceBusNamespace; } else { FullyQualifiedNamespace = serviceBusNamespace + ".servicebus.windows.net"; } }
/// <summary> /// Gets available connection strings for the specified entity. /// </summary> /// <param name="namespaceName">The namespace name</param> /// <param name="entityName">The entity name</param> /// <param name="entityType">The entity type</param> /// <returns>List of all available connection strings</returns> public virtual List<ServiceBusConnectionDetail> GetConnectionString( string namespaceName, string entityName, ServiceBusEntityType entityType) { switch (entityType) { case ServiceBusEntityType.Queue: return ServiceBusClient.Queues.GetConnectionDetails(namespaceName, entityName).ConnectionDetails .ToList(); case ServiceBusEntityType.Topic: return ServiceBusClient.Topics.GetConnectionDetails(namespaceName, entityName).ConnectionDetails .ToList(); case ServiceBusEntityType.Relay: return ServiceBusClient.Relays.GetConnectionDetails(namespaceName, entityName).ConnectionDetails .ToList(); case ServiceBusEntityType.NotificationHub: return ServiceBusClient.NotificationHubs.GetConnectionDetails(namespaceName, entityName) .ConnectionDetails .ToList(); default: throw new Exception(string.Format(Resources.ServiceBusEntityTypeNotFound, entityType.ToString())); } }
/// <summary> /// Gets the connection string with the given name for the entity. /// </summary> /// <param name="namespaceName">The namespace name</param> /// <param name="entityType"></param> /// <param name="keyName">The connection string key name</param> /// <param name="entityName"></param> /// <returns>The connection string value</returns> public virtual string GetConnectionString( string namespaceName, string entityName, ServiceBusEntityType entityType, string keyName) { List<ServiceBusConnectionDetail> connectionStrings = GetConnectionString(namespaceName, entityName, entityType); ServiceBusConnectionDetail connectionString = connectionStrings.Find(c => c.KeyName.Equals( keyName, StringComparison.OrdinalIgnoreCase)); return connectionString.ConnectionString; }
private List<ExtendedAuthorizationRule> GetAuthorizationRuleCore( string namespaceName, string entityName, ServiceBusEntityType entityType, Predicate<AuthorizationRule> match) { NamespaceManager namespaceManager = CreateNamespaceManager(namespaceName); List<AuthorizationRule> rules = null; switch (entityType) { case ServiceBusEntityType.Queue: rules = namespaceManager.GetQueue(entityName).Authorization.GetRules(match); break; case ServiceBusEntityType.Topic: rules = namespaceManager.GetTopic(entityName).Authorization.GetRules(match); break; case ServiceBusEntityType.Relay: rules = namespaceManager.GetRelayAsync(entityName).Result.Authorization.GetRules(match); break; case ServiceBusEntityType.NotificationHub: rules = namespaceManager.GetNotificationHub(entityName).Authorization.GetRules(match); break; default: throw new InvalidOperationException(); } return rules.Select(r => CreateExtendedAuthorizationRule( r, namespaceName, entityName, entityType)).ToList(); }
private ExtendedAuthorizationRule CreateExtendedAuthorizationRule( AuthorizationRule rule, string namespaceName, string entityName, ServiceBusEntityType entityType) { return new ExtendedAuthorizationRule() { Rule = rule, Name = rule.KeyName, Permission = rule.Rights.ToList(), ConnectionString = GetConnectionString(namespaceName, entityName, entityType, rule.KeyName), Namespace = namespaceName, EntityName = entityName, EntityType = entityType }; }
public async Task RotateServiceBusSecret_WithValidArguments_RotatesPrimarySecondaryAlternately(ServiceBusEntityType entity) { // Arrange string vaultUrl = BogusGenerator.Internet.UrlWithPath(protocol: "https"); string secretName = BogusGenerator.Random.Word(); AzureServiceBusNamespace @namespace = GenerateAzureServiceBusLocation(entity); var response = new AzureOperationResponse <AccessKeys> { Body = new AccessKeys( primaryConnectionString: BogusGenerator.Random.Words(), secondaryConnectionString: BogusGenerator.Random.Words()) }; Mock <ITopicsOperations> stubTopics = CreateStubTopicsOperations(@namespace, response); Mock <IQueuesOperations> stubQueues = CreateStubQueueOperations(@namespace, response); Mock <IAzureServiceBusManagementAuthentication> stubServiceBusAuthentication = CreateStubAuthentication(stubTopics.Object, stubQueues.Object); Mock <IKeyVaultAuthentication> stubKeyVaultAuthentication = CreateStubKeyVaultAuthentication(vaultUrl, secretName, response.Body); var rotation = new AzureServiceBusKeyRotation( new AzureServiceBusClient(stubServiceBusAuthentication.Object, @namespace, NullLogger.Instance), stubKeyVaultAuthentication.Object, new KeyVaultConfiguration(vaultUrl), NullLogger.Instance); // Act await rotation.RotateServiceBusSecretAsync(secretName); // Assert Assert.Empty(DetermineNonRelevantInvocations(entity, stubTopics.Invocations, stubQueues.Invocations)); Assert.Collection(DetermineRelevantInvocations(entity, stubTopics.Invocations, stubQueues.Invocations), invocation => AssertInvocationKeyRotation(invocation, KeyType.SecondaryKey), invocation => AssertInvocationKeyRotation(invocation, KeyType.PrimaryKey)); await rotation.RotateServiceBusSecretAsync(secretName); Assert.Empty(DetermineNonRelevantInvocations(entity, stubTopics.Invocations, stubQueues.Invocations)); Assert.Collection(DetermineRelevantInvocations(entity, stubTopics.Invocations, stubQueues.Invocations).Skip(2), invocation => AssertInvocationKeyRotation(invocation, KeyType.PrimaryKey), invocation => AssertInvocationKeyRotation(invocation, KeyType.SecondaryKey)); }
/// <summary> /// Updates shared access signature authorization for the service bus entity. This authorization works on /// public Microsoft Azure environments and Windows Azure Pack on prim as well. /// </summary> /// <param name="namespaceName">The service bus namespace name</param> /// <param name="entityName">The fully qualified service bus entity name</param> /// <param name="entityType">The service bus entity type (e.g. Queue)</param> /// <param name="ruleName">The SAS authorization rule name</param> /// <param name="primaryKey">The SAS primary key. It'll be generated if empty</param> /// <param name="secondaryKey">The SAS secondary key</param> /// <param name="permissions">Set of permissions given to the rule</param> /// <returns>The created Shared Access Signature authorization rule</returns> public virtual ExtendedAuthorizationRule UpdateSharedAccessAuthorization( string namespaceName, string entityName, ServiceBusEntityType entityType, string ruleName, string primaryKey, string secondaryKey, params AccessRights[] permissions) { bool removed = false; ExtendedAuthorizationRule rule = GetAuthorizationRule(namespaceName, entityName, entityType, ruleName); if (null == rule) { throw new ArgumentException(Resources.ServiceBusAuthorizationRuleNotFound); } SharedAccessAuthorizationRule oldRule = (SharedAccessAuthorizationRule)rule.Rule; SharedAccessAuthorizationRule newRule = new SharedAccessAuthorizationRule( ruleName, string.IsNullOrEmpty(primaryKey) ? SharedAccessAuthorizationRule.GenerateRandomKey() : primaryKey, secondaryKey, permissions ?? oldRule.Rights); // Create namespace manager NamespaceManager namespaceManager = CreateNamespaceManager(namespaceName); // Add the SAS rule and update the entity switch (entityType) { case ServiceBusEntityType.Queue: QueueDescription queue = namespaceManager.GetQueue(entityName); removed = queue.Authorization.Remove(oldRule); Debug.Assert(removed); queue.Authorization.Add(newRule); namespaceManager.UpdateQueue(queue); break; case ServiceBusEntityType.Topic: TopicDescription topic = namespaceManager.GetTopic(entityName); removed = topic.Authorization.Remove(oldRule); Debug.Assert(removed); topic.Authorization.Add(newRule); namespaceManager.UpdateTopic(topic); break; case ServiceBusEntityType.Relay: RelayDescription relay = namespaceManager.GetRelayAsync(entityName).Result; removed = relay.Authorization.Remove(oldRule); Debug.Assert(removed); relay.Authorization.Add(newRule); namespaceManager.UpdateRelayAsync(relay).Wait(); break; case ServiceBusEntityType.NotificationHub: NotificationHubDescription notificationHub = namespaceManager.GetNotificationHub(entityName); removed = notificationHub.Authorization.Remove(oldRule); Debug.Assert(removed); notificationHub.Authorization.Add(newRule); namespaceManager.UpdateNotificationHub(notificationHub); break; default: throw new Exception(string.Format(Resources.ServiceBusEntityTypeNotFound, entityType.ToString())); } return(CreateExtendedAuthorizationRule(newRule, namespaceName, entityName, entityType)); }
/// <summary> /// Logs an Azure Service Bus Dependency. /// </summary> /// <param name="logger">Logger to use</param> /// <param name="entityName">Name of the Service Bus entity</param> /// <param name="isSuccessful">Indication whether or not the operation was successful</param> /// <param name="measurement">Measuring the latency to call the Service Bus dependency</param> /// <param name="entityType">Type of the Service Bus entity</param> /// <param name="context">Context that provides more insights on the dependency that was measured</param> public static void LogServiceBusDependency(this ILogger logger, string entityName, bool isSuccessful, DependencyMeasurement measurement, ServiceBusEntityType entityType = ServiceBusEntityType.Unknown, Dictionary <string, object> context = null) { Guard.NotNull(logger, nameof(logger)); Guard.NotNull(measurement, nameof(measurement)); LogServiceBusDependency(logger, entityName, isSuccessful, measurement.StartTime, measurement.Elapsed, entityType, context); }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBusOutputAttribute"/> class. /// </summary> /// <param name="queueOrTopicName">The name of the queue or topic to bind to.</param> /// <param name="entityType">The type of the entity to bind to.</param> public ServiceBusOutputAttribute(string queueOrTopicName, ServiceBusEntityType entityType = ServiceBusEntityType.Queue) { QueueOrTopicName = queueOrTopicName; EntityType = entityType; }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBusAttribute"/> class. /// </summary> /// <param name="queueOrTopicName">The name of the queue or topic to bind to.</param> /// <param name="serviceBusEntityType">The type of the entity to bind to.</param> public ServiceBusAttribute(string queueOrTopicName, ServiceBusEntityType serviceBusEntityType = ServiceBusEntityType.Queue) { QueueOrTopicName = queueOrTopicName; ServiceBusEntityType = serviceBusEntityType; }
public void PublishMessage(string destination, ServiceBusEntityType entityType, Message message) { Connection.PublishMessage(destination, entityType, message); }
/// <summary> /// Gets the authorization rule with the specified name in the entity level. /// </summary> /// <param name="namespaceName">The namespace name</param> /// <param name="entityName">The entity name</param> /// <param name="entityType">The entity type</param> /// <param name="ruleName">The rule name</param> /// <returns>The authorization rule that matches the specified name</returns> public virtual ExtendedAuthorizationRule GetAuthorizationRule( string namespaceName, string entityName, ServiceBusEntityType entityType, string ruleName) { AuthorizationRuleFilterOption options = new AuthorizationRuleFilterOption() { Namespace = namespaceName, Name = ruleName, EntityName = entityName, EntityType = entityType }; return FilterAuthorizationRules(options).FirstOrDefault(); }
public void CreatesLocation_WithBlankOutOfBoundsEntity_Throws(ServiceBusEntityType entity) { Assert.Throws <ArgumentException>( () => new AzureServiceBusNamespace("resource group", "namespace", entity, "entity name", "authorization rule name")); }
/// <summary> /// Updates shared access signature authorization for the service bus entity. This authorization works on /// public Microsoft Azure environments and Windows Azure Pack on prim as well. /// </summary> /// <param name="namespaceName">The service bus namespace name</param> /// <param name="entityName">The fully qualified service bus entity name</param> /// <param name="entityType">The service bus entity type (e.g. Queue)</param> /// <param name="ruleName">The SAS authorization rule name</param> /// <param name="primaryKey">The SAS primary key. It'll be generated if empty</param> /// <param name="secondaryKey">The SAS secondary key</param> /// <param name="permissions">Set of permissions given to the rule</param> /// <returns>The created Shared Access Signature authorization rule</returns> public virtual ExtendedAuthorizationRule UpdateSharedAccessAuthorization( string namespaceName, string entityName, ServiceBusEntityType entityType, string ruleName, string primaryKey, string secondaryKey, params AccessRights[] permissions) { bool removed = false; ExtendedAuthorizationRule rule = GetAuthorizationRule( namespaceName, entityName, entityType, ruleName); if (null == rule) { throw new ArgumentException(Resources.ServiceBusAuthorizationRuleNotFound); } SharedAccessAuthorizationRule oldRule = (SharedAccessAuthorizationRule)rule.Rule; SharedAccessAuthorizationRule newRule = new SharedAccessAuthorizationRule( ruleName, string.IsNullOrEmpty(primaryKey) ? SharedAccessAuthorizationRule.GenerateRandomKey() : primaryKey, secondaryKey, permissions ?? oldRule.Rights); // Create namespace manager NamespaceManager namespaceManager = CreateNamespaceManager(namespaceName); // Add the SAS rule and update the entity switch (entityType) { case ServiceBusEntityType.Queue: QueueDescription queue = namespaceManager.GetQueue(entityName); removed = queue.Authorization.Remove(oldRule); Debug.Assert(removed); queue.Authorization.Add(newRule); namespaceManager.UpdateQueue(queue); break; case ServiceBusEntityType.Topic: TopicDescription topic = namespaceManager.GetTopic(entityName); removed = topic.Authorization.Remove(oldRule); Debug.Assert(removed); topic.Authorization.Add(newRule); namespaceManager.UpdateTopic(topic); break; case ServiceBusEntityType.Relay: RelayDescription relay = namespaceManager.GetRelayAsync(entityName).Result; removed = relay.Authorization.Remove(oldRule); Debug.Assert(removed); relay.Authorization.Add(newRule); namespaceManager.UpdateRelayAsync(relay).Wait(); break; case ServiceBusEntityType.NotificationHub: NotificationHubDescription notificationHub = namespaceManager.GetNotificationHub(entityName); removed = notificationHub.Authorization.Remove(oldRule); Debug.Assert(removed); notificationHub.Authorization.Add(newRule); namespaceManager.UpdateNotificationHub(notificationHub); break; default: throw new Exception(string.Format(Resources.ServiceBusEntityTypeNotFound, entityType.ToString())); } return CreateExtendedAuthorizationRule(newRule, namespaceName, entityName, entityType); }
/// <summary> /// Logs an Azure Service Bus Dependency. /// </summary> /// <param name="logger">Logger to use</param> /// <param name="entityName">Name of the Service Bus entity</param> /// <param name="isSuccessful">Indication whether or not the operation was successful</param> /// <param name="startTime">Point in time when the interaction with the dependency was started</param> /// <param name="duration">Duration of the operation</param> /// <param name="entityType">Type of the Service Bus entity</param> /// <param name="context">Context that provides more insights on the dependency that was measured</param> public static void LogServiceBusDependency(this ILogger logger, string entityName, bool isSuccessful, DateTimeOffset startTime, TimeSpan duration, ServiceBusEntityType entityType = ServiceBusEntityType.Unknown, Dictionary <string, object> context = null) { Guard.NotNull(logger, nameof(logger)); Guard.NotNullOrWhitespace(entityName, nameof(entityName)); context = context ?? new Dictionary <string, object>(); logger.LogWarning(ServiceBusDependencyFormat, "Azure Service Bus", entityType, entityName, duration, startTime.ToString(FormatSpecifiers.InvariantTimestampFormat), isSuccessful, context); }
public ServiceBusListener( string functionId, ServiceBusEntityType entityType, string entityPath, bool isSessionsEnabled, bool autoCompleteMessages, ITriggeredFunctionExecutor triggerExecutor, ServiceBusOptions options, string connection, MessagingProvider messagingProvider, ILoggerFactory loggerFactory, bool singleDispatch, ServiceBusClientFactory clientFactory, ConcurrencyManager concurrencyManager) { _entityPath = entityPath; _isSessionsEnabled = isSessionsEnabled; _autoCompleteMessages = autoCompleteMessages; _triggerExecutor = triggerExecutor; _cancellationTokenSource = new CancellationTokenSource(); _logger = loggerFactory.CreateLogger <ServiceBusListener>(); _functionId = functionId; _client = new Lazy <ServiceBusClient>( () => clientFactory.CreateClientFromSetting(connection)); _batchReceiver = new Lazy <ServiceBusReceiver>( () => messagingProvider.CreateBatchMessageReceiver( _client.Value, _entityPath, options.ToReceiverOptions())); _messageProcessor = new Lazy <MessageProcessor>( () => { var processorOptions = options.ToProcessorOptions(_autoCompleteMessages, concurrencyManager.Enabled); return(messagingProvider.CreateMessageProcessor(_client.Value, _entityPath, processorOptions)); }); _sessionMessageProcessor = new Lazy <SessionMessageProcessor>( () => { var sessionProcessorOptions = options.ToSessionProcessorOptions(_autoCompleteMessages, concurrencyManager.Enabled); return(messagingProvider.CreateSessionMessageProcessor(_client.Value, _entityPath, sessionProcessorOptions)); }); _scaleMonitor = new Lazy <ServiceBusScaleMonitor>( () => new ServiceBusScaleMonitor( functionId, entityType, _entityPath, connection, _batchReceiver, loggerFactory, clientFactory)); if (concurrencyManager.Enabled) { _concurrencyUpdateManager = new ConcurrencyUpdateManager(concurrencyManager, _messageProcessor, _sessionMessageProcessor, _isSessionsEnabled, _functionId, _logger); } _singleDispatch = singleDispatch; _serviceBusOptions = options; _details = new Lazy <string>(() => $"namespace='{_client.Value?.FullyQualifiedNamespace}', enityPath='{_entityPath}', singleDispatch='{_singleDispatch}', " + $"isSessionsEnabled='{_isSessionsEnabled}', functionId='{_functionId}'"); }
public async Task RotateConnectionStringKey_WithSpecifiedEntity_RotatesKeyForEntity(ServiceBusEntityType entity, KeyType keyType) { // Arrange var generator = new Faker(); string resourceGroup = generator.Random.Word(); string @namespace = generator.Random.Word(); string entityName = generator.Random.Word(); string authorizationRuleName = generator.Random.Word(); string primaryConnectionString = generator.Random.Words(); string secondaryConnectionString = generator.Random.Words(); var response = new AzureOperationResponse <AccessKeys> { Body = new AccessKeys( primaryConnectionString: primaryConnectionString, secondaryConnectionString: secondaryConnectionString) }; Mock <ITopicsOperations> stubTopics = CreateStubTopicsOperations(resourceGroup, @namespace, entityName, authorizationRuleName, response); Mock <IQueuesOperations> stubQueues = CreateStubQueueOperations(resourceGroup, @namespace, entityName, authorizationRuleName, response); Mock <IAzureServiceBusManagementAuthentication> stubAuthentication = CreateStubAuthentication(stubTopics.Object, stubQueues.Object); var client = new AzureServiceBusClient( stubAuthentication.Object, new AzureServiceBusNamespace(resourceGroup, @namespace, entity, entityName, authorizationRuleName), NullLogger.Instance); // Act string connectionString = await client.RotateConnectionStringKeyAsync(keyType); // Assert Assert.Equal(primaryConnectionString == connectionString, KeyType.PrimaryKey == keyType); Assert.Equal(secondaryConnectionString == connectionString, KeyType.SecondaryKey == keyType); Assert.Equal(stubTopics.Invocations.Count == 1 && stubQueues.Invocations.Count == 0, ServiceBusEntityType.Topic == entity); Assert.Equal(stubTopics.Invocations.Count == 0 && stubQueues.Invocations.Count == 1, ServiceBusEntityType.Queue == entity); }