async Task <bool> ExistsAsync(INamespaceManagerInternal namespaceClient, string queuePath, bool removeCacheEntry = false) { var key = queuePath + namespaceClient.Address; logger.InfoFormat("Checking existence cache for '{0}'", queuePath); if (removeCacheEntry) { rememberExistence.TryRemove(key, out Task <bool> dummy); } var exists = await rememberExistence.GetOrAdd(key, s => { logger.InfoFormat("Checking namespace for existence of the queue '{0}'", queuePath); return(namespaceClient.QueueExists(queuePath)); }).ConfigureAwait(false); logger.InfoFormat("Determined, from cache, that the queue '{0}' {1}", queuePath, exists ? "exists" : "does not exist"); return(exists); }
async Task <bool> ExistsAsync(string topicPath, INamespaceManagerInternal namespaceClient, bool removeCacheEntry = false) { var key = topicPath + namespaceClient.Address; logger.InfoFormat("Checking existence cache for '{0}'", topicPath); if (removeCacheEntry) { Task <bool> dummy; rememberExistence.TryRemove(key, out dummy); } var exists = await rememberExistence.GetOrAdd(key, notFoundTopicPath => { logger.InfoFormat("Checking namespace for existence of the topic '{0}'", topicPath); return(namespaceClient.TopicExists(topicPath)); }).ConfigureAwait(false); logger.InfoFormat("Determined, from cache, that the topic '{0}' {1}", topicPath, exists ? "exists" : "does not exist"); return(exists); }
public async Task <QueueDescription> Create(string queuePath, INamespaceManagerInternal namespaceManager) { var description = new QueueDescription(queuePath) { LockDuration = queueSettings.LockDuration, MaxSizeInMegabytes = queueSettings.MaxSizeInMegabytes, RequiresDuplicateDetection = queueSettings.RequiresDuplicateDetection, DefaultMessageTimeToLive = queueSettings.DefaultMessageTimeToLive, EnableDeadLetteringOnMessageExpiration = queueSettings.EnableDeadLetteringOnMessageExpiration, DuplicateDetectionHistoryTimeWindow = queueSettings.DuplicateDetectionHistoryTimeWindow, MaxDeliveryCount = DefaultMaxDeliveryCountForNoImmediateRetries, EnableBatchedOperations = queueSettings.EnableBatchedOperations, EnablePartitioning = queueSettings.EnablePartitioning, SupportOrdering = queueSettings.SupportOrdering, AutoDeleteOnIdle = queueSettings.AutoDeleteOnIdle, }; if (queueSettings.ForwardDeadLetteredMessagesToCondition(queuePath)) { description.ForwardDeadLetteredMessagesTo = queueSettings.ForwardDeadLetteredMessagesTo; } queueSettings.DescriptionCustomizer(description); try { if (!await ExistsAsync(namespaceManager, description.Path).ConfigureAwait(false)) { await namespaceManager.CreateQueue(description).ConfigureAwait(false); logger.InfoFormat("Queue '{0}' created", description.Path); await rememberExistence.AddOrUpdate(description.Path, s => TaskEx.CompletedTrue, (s, b) => TaskEx.CompletedTrue).ConfigureAwait(false); } else { logger.InfoFormat("Queue '{0}' already exists, skipping creation", description.Path); logger.InfoFormat("Checking if queue '{0}' needs to be updated", description.Path); if (IsSystemQueue(description.Path)) { logger.InfoFormat("Queue '{0}' is a shared queue and should not be updated", description.Path); return(description); } var existingDescription = await namespaceManager.GetQueue(description.Path).ConfigureAwait(false); if (MembersAreNotEqual(existingDescription, description)) { OverrideImmutableMembers(existingDescription, description); logger.InfoFormat("Updating queue '{0}' with new description", description.Path); await namespaceManager.UpdateQueue(description).ConfigureAwait(false); } } } catch (MessagingEntityAlreadyExistsException) { // the queue already exists or another node beat us to it, which is ok logger.InfoFormat("Queue '{0}' already exists, another node probably beat us to it", description.Path); } catch (TimeoutException) { logger.InfoFormat("Timeout occurred on queue creation for '{0}' going to validate if it doesn't exist", description.Path); // there is a chance that the timeout occurred, but the topic was still created, check again if (!await ExistsAsync(namespaceManager, description.Path, removeCacheEntry: true).ConfigureAwait(false)) { throw; } logger.InfoFormat("Looks like queue '{0}' exists anyway", description.Path); } catch (MessagingException ex) { if (!ex.IsTransient) { logger.Fatal(string.Format("{1} {2} occurred on queue creation {0}", description.Path, ex.IsTransient ? "Transient" : "Non transient", ex.GetType().Name), ex); throw; } logger.Info(string.Format("{1} {2} occurred on queue creation {0}", description.Path, ex.IsTransient ? "Transient" : "Non transient", ex.GetType().Name), ex); } return(description); }
public async Task <SubscriptionDescription> Create(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo = null) { var subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName) { EnableBatchedOperations = subscriptionSettings.EnableBatchedOperations, AutoDeleteOnIdle = subscriptionSettings.AutoDeleteOnIdle, DefaultMessageTimeToLive = subscriptionSettings.DefaultMessageTimeToLive, EnableDeadLetteringOnFilterEvaluationExceptions = subscriptionSettings.EnableDeadLetteringOnFilterEvaluationExceptions, EnableDeadLetteringOnMessageExpiration = subscriptionSettings.EnableDeadLetteringOnMessageExpiration, LockDuration = subscriptionSettings.LockDuration, MaxDeliveryCount = DefaultMaxDeliveryCountForNoImmediateRetries }; if (subscriptionSettings.ForwardDeadLetteredMessagesToCondition(SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName))) { subscriptionDescription.ForwardDeadLetteredMessagesTo = subscriptionSettings.ForwardDeadLetteredMessagesTo; } subscriptionSettings.DescriptionCustomizer(subscriptionDescription); if (!string.IsNullOrWhiteSpace(forwardTo)) { subscriptionDescription.ForwardTo = forwardTo; } subscriptionDescription.UserMetadata = metadata.Description; try { if (!await ExistsAsync(topicPath, subscriptionName, metadata.Description, namespaceManager).ConfigureAwait(false)) { await namespaceManager.CreateSubscription(subscriptionDescription, sqlFilter).ConfigureAwait(false); logger.Info($"Subscription '{subscriptionDescription.UserMetadata}' in namespace '{namespaceManager.Address.Host}' created as '{subscriptionDescription.Name}'."); var key = GenerateSubscriptionKey(namespaceManager.Address, subscriptionDescription.TopicPath, subscriptionDescription.Name); await rememberExistence.AddOrUpdate(key, keyNotFound => TaskEx.CompletedTrue, (updateTopicPath, previousValue) => TaskEx.CompletedTrue).ConfigureAwait(false); } else { logger.Info($"Subscription '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' aka '{subscriptionDescription.UserMetadata}' already exists, skipping creation."); logger.InfoFormat("Checking if subscription '{0}' in namespace '{1}' needs to be updated.", subscriptionDescription.Name, namespaceManager.Address.Host); var existingSubscriptionDescription = await namespaceManager.GetSubscription(subscriptionDescription.TopicPath, subscriptionDescription.Name).ConfigureAwait(false); if (MembersAreNotEqual(existingSubscriptionDescription, subscriptionDescription)) { OverrideImmutableMembers(existingSubscriptionDescription, subscriptionDescription); logger.InfoFormat("Updating subscription '{0}' in namespace '{1}' with new description.", subscriptionDescription.Name, namespaceManager.Address.Host); await namespaceManager.UpdateSubscription(subscriptionDescription).ConfigureAwait(false); } } } catch (MessagingEntityAlreadyExistsException) { // the subscription already exists or another node beat us to it, which is ok logger.InfoFormat("Subscription '{0}' in namespace '{1}' already exists, another node probably beat us to it.", subscriptionDescription.Name, namespaceManager.Address.Host); } catch (TimeoutException) { logger.InfoFormat("Timeout occurred on subscription creation for topic '{0}' subscription name '{1}' in namespace '{2}' going to validate if it doesn't exist.", subscriptionDescription.TopicPath, subscriptionDescription.Name, namespaceManager.Address.Host); // there is a chance that the timeout occurred, but the topic was still created, check again if (!await ExistsAsync(subscriptionDescription.TopicPath, subscriptionDescription.Name, metadata.Description, namespaceManager, removeCacheEntry: true).ConfigureAwait(false)) { throw; } logger.InfoFormat("Looks like subscription '{0}' in namespace '{1}' exists anyway.", subscriptionDescription.Name, namespaceManager.Address.Host); } catch (MessagingException ex) { var loggedMessage = $"{(ex.IsTransient ? "Transient" : "Non transient")} {ex.GetType().Name} occurred on subscription '{subscriptionDescription.Name}' creation for topic '{subscriptionDescription.TopicPath}' in namespace '{namespaceManager.Address.Host}'."; if (!ex.IsTransient) { logger.Fatal(loggedMessage, ex); throw; } logger.Info(loggedMessage, ex); } return(subscriptionDescription); }
async Task <bool> ExistsAsync(string topicPath, string subscriptionName, string metadata, INamespaceManagerInternal namespaceClient, bool removeCacheEntry = false) { logger.Info($"Checking existence cache for subscription '{subscriptionName}' in namespace '{namespaceClient.Address.Host}' aka '{metadata}'."); var key = GenerateSubscriptionKey(namespaceClient.Address, topicPath, subscriptionName); if (removeCacheEntry) { Task <bool> dummy; rememberExistence.TryRemove(key, out dummy); } var exists = await rememberExistence.GetOrAdd(key, notFoundKey => { logger.InfoFormat("Checking namespace for existence of subscription '{0}' for the topic '{1}' in namespace '{2}'.", subscriptionName, topicPath, namespaceClient.Address.Host); return(namespaceClient.SubscriptionExists(topicPath, subscriptionName)); }).ConfigureAwait(false); logger.InfoFormat("Determined, from cache, that the subscription '{0}' in namespace '{2}' {1}.", subscriptionName, exists ? "exists" : "does not exist", namespaceClient.Address.Host); return(exists); }
public async Task DeleteSubscription(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo) { var subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName); try { if (await ExistsAsync(topicPath, subscriptionName, metadata.Description, namespaceManager, true).ConfigureAwait(false)) { await namespaceManager.DeleteSubscription(subscriptionDescription).ConfigureAwait(false); } } catch (MessagingException ex) { var loggedMessage = $"{(ex.IsTransient ? "Transient" : "Non transient")} {ex.GetType().Name} occurred on subscription '{subscriptionDescription.Name}' creation for topic '{subscriptionDescription.TopicPath}' in namespace '{namespaceManager.Address.Host}'."; if (!ex.IsTransient) { logger.Fatal(loggedMessage, ex); throw; } logger.Info(loggedMessage, ex); } }
async Task <bool> SubscriptionIsReusedAcrossDifferentNamespaces(SubscriptionDescription subscriptionDescription, string sqlFilter, INamespaceManagerInternal namespaceManager) { var rules = await namespaceManager.GetRules(subscriptionDescription).ConfigureAwait(false); var filter = rules.First().Filter as SqlFilter; if (filter != null && filter.SqlExpression != sqlFilter) { logger.Debug("Looks like this subscription name is already taken as the sql filter does not match the subscribed event name."); return(true); } return(false); }
public async Task DeleteSubscription(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo) { var subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName); // Check subscription with event name only is the one we should delete. If it's reused, then we need to use event full name. if (await SubscriptionIsReusedAcrossDifferentNamespaces(subscriptionDescription, sqlFilter, namespaceManager).ConfigureAwait(false)) { logger.Debug("Deleting subscription using event type full name"); subscriptionDescription = new SubscriptionDescription(topicPath, metadata.SubscriptionNameBasedOnEventWithNamespace); } // delete subscription based on event name only await creator.DeleteSubscription(subscriptionDescription.TopicPath, subscriptionDescription.Name, metadata, sqlFilter, namespaceManager, forwardTo).ConfigureAwait(false); }
public async Task <SubscriptionDescription> Create(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo = null) { var subscriptionDescription = await creator.Create(topicPath, subscriptionName, metadata, sqlFilter, namespaceManager, forwardTo).ConfigureAwait(false); if (await SubscriptionIsReusedAcrossDifferentNamespaces(subscriptionDescription, sqlFilter, namespaceManager).ConfigureAwait(false)) { logger.Debug("Creating subscription using event type full name"); subscriptionDescription = await creator.Create(topicPath, metadata.SubscriptionNameBasedOnEventWithNamespace, metadata, sqlFilter, namespaceManager, forwardTo).ConfigureAwait(false); } return(subscriptionDescription); }
public Task UpdateFilter(string topicPath, string subscriptionName, string sqlFilter, INamespaceManagerInternal namespaceManager) => namespaceManager.UpdateRule(topicPath, subscriptionName, new RuleDescription("$Default", new SqlFilter(sqlFilter)));
public async Task <TopicDescription> Create(string topicPath, INamespaceManagerInternal namespaceManager) { var topicDescription = new TopicDescription(topicPath) { SupportOrdering = topicSettings.SupportOrdering, MaxSizeInMegabytes = topicSettings.MaxSizeInMegabytes, DefaultMessageTimeToLive = topicSettings.DefaultMessageTimeToLive, RequiresDuplicateDetection = topicSettings.RequiresDuplicateDetection, DuplicateDetectionHistoryTimeWindow = topicSettings.DuplicateDetectionHistoryTimeWindow, EnableBatchedOperations = topicSettings.EnableBatchedOperations, EnablePartitioning = topicSettings.EnablePartitioning, AutoDeleteOnIdle = topicSettings.AutoDeleteOnIdle, EnableFilteringMessagesBeforePublishing = topicSettings.EnableFilteringMessagesBeforePublishing }; topicSettings.DescriptionCustomizer(topicDescription); try { if (!await ExistsAsync(topicPath, namespaceManager).ConfigureAwait(false)) { await namespaceManager.CreateTopic(topicDescription).ConfigureAwait(false); logger.InfoFormat("Topic '{0}' created", topicDescription.Path); await rememberExistence.AddOrUpdate(topicDescription.Path, notFoundTopicPath => TaskEx.CompletedTrue, (updateTopicPath, previousValue) => TaskEx.CompletedTrue).ConfigureAwait(false); } else { logger.InfoFormat("Topic '{0}' already exists, skipping creation", topicDescription.Path); logger.InfoFormat("Checking if topic '{0}' needs to be updated", topicDescription.Path); var existingTopicDescription = await namespaceManager.GetTopic(topicDescription.Path).ConfigureAwait(false); if (MembersAreNotEqual(existingTopicDescription, topicDescription)) { OverrideImmutableMembers(existingTopicDescription, topicDescription); logger.InfoFormat("Updating topic '{0}' with new description", topicDescription.Path); await namespaceManager.UpdateTopic(topicDescription).ConfigureAwait(false); } } } catch (MessagingEntityAlreadyExistsException) { // the topic already exists or another node beat us to it, which is ok logger.InfoFormat("Topic '{0}' already exists, another node probably beat us to it", topicDescription.Path); } catch (TimeoutException) { logger.InfoFormat("Timeout occurred on topic creation for '{0}' going to validate if it doesn't exist", topicDescription.Path); // there is a chance that the timeout occurred, but the topic was still created, check again if (!await ExistsAsync(topicDescription.Path, namespaceManager, removeCacheEntry: true).ConfigureAwait(false)) { throw; } logger.InfoFormat("Looks like topic '{0}' exists anyway", topicDescription.Path); } catch (MessagingException ex) { var loggedMessage = string.Format("{1} {2} occurred on topic creation {0}", topicDescription.Path, ex.IsTransient ? "Transient" : "Non transient", ex.GetType().Name); if (!ex.IsTransient) { logger.Fatal(loggedMessage, ex); throw; } logger.Info(loggedMessage, ex); } return(topicDescription); }
public async Task <SubscriptionDescription> Create(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo) { if (!(metadata is ForwardingTopologySubscriptionMetadata meta)) { throw new InvalidOperationException($"Cannot create subscription `{subscriptionName}` for topic `{topicPath}` without namespace information required."); } var subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName) { EnableBatchedOperations = subscriptionSettings.EnableBatchedOperations, AutoDeleteOnIdle = subscriptionSettings.AutoDeleteOnIdle, DefaultMessageTimeToLive = subscriptionSettings.DefaultMessageTimeToLive, EnableDeadLetteringOnFilterEvaluationExceptions = subscriptionSettings.EnableDeadLetteringOnFilterEvaluationExceptions, EnableDeadLetteringOnMessageExpiration = subscriptionSettings.EnableDeadLetteringOnMessageExpiration, LockDuration = subscriptionSettings.LockDuration, MaxDeliveryCount = DefaultMaxDeliveryCountForNoImmediateRetries }; if (subscriptionSettings.ForwardDeadLetteredMessagesToCondition(SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName))) { subscriptionDescription.ForwardDeadLetteredMessagesTo = subscriptionSettings.ForwardDeadLetteredMessagesTo; } subscriptionSettings.DescriptionCustomizer(subscriptionDescription); subscriptionDescription.ForwardTo = forwardTo; subscriptionDescription.UserMetadata = metadata.Description; try { var exists = await ExistsAsync(topicPath, subscriptionName, metadata.Description, namespaceManager).ConfigureAwait(false); if (!exists) { var ruleDescription = new RuleDescription { Filter = new SqlFilter(sqlFilter), Name = metadata.SubscriptionNameBasedOnEventWithNamespace }; try { await namespaceManager.CreateSubscription(subscriptionDescription, ruleDescription).ConfigureAwait(false); logger.Info($"Subscription '{subscriptionDescription.UserMetadata}' created as '{subscriptionDescription.Name}' with rule '{ruleDescription.Name}' for event '{meta.SubscribedEventFullName}' in namespace '{namespaceManager.Address.Host}'."); var key = GenerateSubscriptionKey(namespaceManager.Address, subscriptionDescription.TopicPath, subscriptionDescription.Name); await rememberExistence.AddOrUpdate(key, keyNotFound => TaskEx.CompletedTrue, (updateTopicPath, previousValue) => TaskEx.CompletedTrue).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException) { // the subscription already exists or another node beat us to it, which is ok logger.Info($"Subscription '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' already exists, another node probably beat us to it."); exists = true; } } if (exists) { logger.Info($"Subscription '{subscriptionDescription.Name}' aka '{subscriptionDescription.UserMetadata}' already exists, skipping creation."); logger.InfoFormat("Checking if subscription '{0}' in namespace '{1}' needs to be updated.", subscriptionDescription.Name, namespaceManager.Address.Host); var existingSubscriptionDescription = await namespaceManager.GetSubscription(subscriptionDescription.TopicPath, subscriptionDescription.Name).ConfigureAwait(false); if (MembersAreNotEqual(existingSubscriptionDescription, subscriptionDescription)) { logger.Info($"Updating subscription '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' with new description."); await namespaceManager.UpdateSubscription(subscriptionDescription).ConfigureAwait(false); } // Rules can't be queried, so try to add var ruleDescription = new RuleDescription { Filter = new SqlFilter(sqlFilter), Name = metadata.SubscriptionNameBasedOnEventWithNamespace }; logger.Info($"Adding subscription rule '{ruleDescription.Name}' for event '{meta.SubscribedEventFullName}' in namespace '{namespaceManager.Address.Host}'."); try { var subscriptionClient = SubscriptionClient.CreateFromConnectionString(meta.NamespaceInfo.ConnectionString, topicPath, subscriptionName); await subscriptionClient.AddRuleAsync(ruleDescription).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException exception) { logger.Debug($"Rule '{ruleDescription.Name}' already exists. Response from the server: '{exception.Message}'."); } } } catch (TimeoutException) { logger.Info($"Timeout occurred on subscription creation for topic '{subscriptionDescription.TopicPath}' subscription name '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' going to validate if it doesn't exist."); // there is a chance that the timeout occurred, but the topic was still created, check again if (!await ExistsAsync(subscriptionDescription.TopicPath, subscriptionDescription.Name, metadata.Description, namespaceManager, removeCacheEntry: true).ConfigureAwait(false)) { throw; } logger.Info($"Looks like subscription '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' exists anyway."); } catch (MessagingException ex) { var loggedMessage = $"{(ex.IsTransient ? "Transient" : "Non transient")} {ex.GetType().Name} occurred on subscription '{subscriptionDescription.Name}' creation for topic '{subscriptionDescription.TopicPath}' in namespace '{namespaceManager.Address.Host}'."; if (!ex.IsTransient) { logger.Fatal(loggedMessage, ex); throw; } logger.Info(loggedMessage, ex); } return(subscriptionDescription); }
public async Task DeleteSubscription(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo) { var meta = metadata as ForwardingTopologySubscriptionMetadata; // var subscriptionDescription = subscriptionDescriptionFactory(topicPath, subscriptionName, settings); var subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName); try { if (await ExistsAsync(topicPath, subscriptionName, metadata.Description, namespaceManager, removeCacheEntry: true).ConfigureAwait(false)) { var ruleDescription = new RuleDescription { Filter = new SqlFilter(sqlFilter), Name = metadata.SubscriptionNameBasedOnEventWithNamespace }; logger.Info($"Removing subscription rule '{ruleDescription.Name}' for event '{meta.SubscribedEventFullName}'."); var subscriptionClient = SubscriptionClient.CreateFromConnectionString(meta.NamespaceInfo.ConnectionString, topicPath, subscriptionName); await subscriptionClient.RemoveRuleAsync(ruleDescription.Name).ConfigureAwait(false); var remainingRules = await namespaceManager.GetRules(subscriptionDescription).ConfigureAwait(false); if (!remainingRules.Any()) { await namespaceManager.DeleteSubscription(subscriptionDescription).ConfigureAwait(false); logger.Debug($"Subscription '{metadata.Description}' created as '{subscriptionDescription.Name}' was removed as part of unsubscribe since events are subscribed to."); } } } catch (MessagingException ex) { var loggedMessage = $"{(ex.IsTransient ? "Transient" : "Non transient")} {ex.GetType().Name} occurred on subscription '{subscriptionDescription.Name}' deletion for topic '{subscriptionDescription.TopicPath}' in namespace '{namespaceManager.Address.Host}'."; if (!ex.IsTransient) { logger.Fatal(loggedMessage, ex); throw; } logger.Info(loggedMessage, ex); } }
async Task <bool> SubscriptionIsReusedAcrossDifferentNamespaces(SubscriptionDescription subscriptionDescription, string sqlFilter, INamespaceManagerInternal namespaceManager) { var foundRules = await namespaceManager.GetRules(subscriptionDescription).ConfigureAwait(false); var rules = foundRules as RuleDescription[] ?? foundRules.ToArray(); if (rules.First().Filter is SqlFilter filter) { if (!filter.SqlExpression.Contains(sqlFilter)) { logger.Debug("Looks like this subscription name is already taken as the sql filter does not match the subscribed event name."); return(true); } if (sqlFilter.Length != filter.SqlExpression.Length && rules.Length == 1) { logger.Info($"SQL filter of the existing subscription '{subscriptionDescription.Name}' should be optimized.\nUpdate Rule filter from \"{filter.SqlExpression}\" to \"{sqlFilter}\"."); } } return(false); }
public async Task <SubscriptionDescription> Create(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo = null) { var subscriptionDescription = await creator.Create(topicPath, subscriptionName, metadata, sqlFilter, namespaceManager, forwardTo).ConfigureAwait(false); if (await SubscriptionIsReusedAcrossDifferentNamespaces(subscriptionDescription, sqlFilter, namespaceManager).ConfigureAwait(false)) { // Instead of adding new subscription, we're going to update the subscription filter instead, // since if there are 2 messages with same and different namespace, we provide merged filter capturing both of them. // subscriptionDescription = await creator.Create(topicPath, metadata.SubscriptionNameBasedOnEventWithNamespace, metadata, sqlFilter, namespaceManager, forwardTo).ConfigureAwait(false); logger.Debug("Updating the subscription filter."); await creator.UpdateFilter(topicPath, subscriptionName, sqlFilter, namespaceManager).ConfigureAwait(false); } return(subscriptionDescription); }
public Task DeleteSubscription(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo) { if (metadata is ForwardingTopologySubscriptionMetadata) { return(azureServiceBusForwardingSubscriptionCreator.DeleteSubscription(topicPath, subscriptionName, metadata, sqlFilter, namespaceManager, forwardTo)); } return(azureServiceBusSubscriptionCreatorV6.DeleteSubscription(topicPath, subscriptionName, metadata, sqlFilter, namespaceManager, forwardTo)); }