/// <summary> /// Creates the Subscription based on the SalesOrderType value /// </summary> /// <param name="StrSalesOrderType"></param> /// <returns></returns> private bool CreateSubscription(string StrSalesOrderType) { bool blnRet = false; NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(strServiceBusConnect); IEnumerable <SubscriptionDescription> lstSubcription = namespaceManager.GetSubscriptions(strTopic); foreach (SubscriptionDescription sub in lstSubcription) { IEnumerable <RuleDescription> lstRules = namespaceManager.GetRules(strTopic, sub.Name); foreach (RuleDescription rule in lstRules) { string strFilter = rule.Filter.ToString(); if (strFilter.Contains("Type='" + StrSalesOrderType + "'")) { blnRet = true; } } } if (blnRet == false) { try { SubscriptionDescription sub = new SubscriptionDescription(strTopic, "sub_" + StrSalesOrderType); sub.MaxDeliveryCount = 100; SqlFilter filter = new SqlFilter("Type='" + StrSalesOrderType + "'"); namespaceManager.CreateSubscription(sub, filter); blnRet = true; } catch (Exception ex) { throw ex; } } return(blnRet); }
private void AddRule(string[] rules) { NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(this.connectionString); var namespaceRules = namespaceManager.GetRules(this.topicName, this.subbscriptionName); foreach (var rule in namespaceRules) { subscriptionClient.RemoveRule(rule.Name); } if (namespaceRules.Where(f => f.Name == "$Default").SingleOrDefault() != null) { subscriptionClient.RemoveRule("$Default"); } foreach (string rule in rules) { subscriptionClient.AddRule(new RuleDescription() { Filter = new CorrelationFilter { Label = rule }, Name = rule }); } }
static void Main(string[] args) { string connectionStr = ConfigurationManager.AppSettings["Microsoft.ServiceBus.ConnectionString"]; NamespaceManager nsm = NamespaceManager.CreateFromConnectionString(connectionStr); string topicName = "yolitopic"; TopicDescription topic = null; if (!nsm.TopicExists(topicName)) { nsm.CreateTopic(new TopicDescription(topicName) { EnablePartitioning = false }); } topic = nsm.GetTopic(topicName); if (topic.SubscriptionCount == 0) { SqlFilter filter1 = new SqlFilter("(index % 2) = 0"); nsm.CreateSubscription(topic.Path, "YoliSubscription1", filter1); SqlFilter filter2 = new SqlFilter("(index % 2) > 0"); nsm.CreateSubscription(topic.Path, "YoliSubscription2", filter2); } // //sadfsdf foreach (var s in nsm.GetSubscriptions(topicName)) { Console.WriteLine(s.Name); foreach (var r in nsm.GetRules(topic.Path, s.Name)) { Console.WriteLine("{0}-{1}", r.Name, r.Filter.ToString()); } } Console.WriteLine("Sending message to topic"); TopicClient topicClient = TopicClient.CreateFromConnectionString(connectionStr, topicName); for (int i = 0; i < 5000; i++) { BrokeredMessage message = new BrokeredMessage(); message.Properties["index"] = i; message.Properties["value"] = (i * 10 + 5) % 11; topicClient.Send(message); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }
public void CheckFilter(string topicName, string subscriptionName, string ruleName, Filter filter) { var rules = _namespaceManager.GetRules(topicName, subscriptionName); var result = rules.FirstOrDefault(x => x.Name == ruleName); if (result != null) { return; // there is a subscription with the requested filter } // if not, make it simple: just create the correct one (it won't be possible if similar subscription already exist) var rule = new RuleDescription(ruleName, filter); _namespaceManager.CreateSubscription(topicName, subscriptionName, rule); }
/// <summary> /// Calls <see cref="AzureServiceBus{TAuthenticationToken}.InstantiateReceiving()"/> /// then uses a <see cref="Task"/> to apply the <see cref="FilterKey"/> as a <see cref="RuleDescription"/> /// to the <see cref="SubscriptionClient"/> instances in <paramref name="serviceBusReceivers"/>. /// </summary> /// <param name="namespaceManager">The <see cref="NamespaceManager"/>.</param> /// <param name="serviceBusReceivers">The receivers collection to place <see cref="SubscriptionClient"/> instances into.</param> /// <param name="topicName">The topic name.</param> /// <param name="topicSubscriptionName">The topic subscription name.</param> protected override void InstantiateReceiving(NamespaceManager namespaceManager, IDictionary <int, SubscriptionClient> serviceBusReceivers, string topicName, string topicSubscriptionName) { base.InstantiateReceiving(namespaceManager, serviceBusReceivers, topicName, topicSubscriptionName); Task.Factory.StartNewSafely (() => { // Because refreshing the rule can take a while, we only want to do this when the value changes string filter; if (!ConfigurationManager.TryGetSetting(FilterKeyConfigurationKey, out filter)) { return; } if (FilterKey.ContainsKey(topicName) && FilterKey[topicName] == filter) { return; } FilterKey[topicName] = filter; // https://docs.microsoft.com/en-us/azure/application-insights/app-insights-analytics-reference#summarize-operator // http://www.summa.com/blog/business-blog/everything-you-need-to-know-about-azure-service-bus-brokered-messaging-part-2#rulesfiltersactions // https://github.com/Azure-Samples/azure-servicebus-messaging-samples/tree/master/TopicFilters SubscriptionClient client = serviceBusReceivers[0]; bool reAddRule = false; try { IEnumerable <RuleDescription> rules = namespaceManager.GetRules(client.TopicPath, client.Name).ToList(); RuleDescription ruleDescription = rules.SingleOrDefault(rule => rule.Name == "CqrsConfiguredFilter"); if (ruleDescription != null) { var sqlFilter = ruleDescription.Filter as SqlFilter; if (sqlFilter == null && !string.IsNullOrWhiteSpace(filter)) { reAddRule = true; } else if (sqlFilter != null && sqlFilter.SqlExpression != filter) { reAddRule = true; } if (sqlFilter != null && reAddRule) { client.RemoveRule("CqrsConfiguredFilter"); } } else if (!string.IsNullOrWhiteSpace(filter)) { reAddRule = true; } ruleDescription = rules.SingleOrDefault(rule => rule.Name == "$Default"); // If there is a default rule and we have a rule, it will cause issues if (!string.IsNullOrWhiteSpace(filter) && ruleDescription != null) { client.RemoveRule("$Default"); } // If we don't have a rule and there is no longer a default rule, it will cause issues else if (string.IsNullOrWhiteSpace(filter) && !rules.Any()) { ruleDescription = new RuleDescription ( "$Default", new SqlFilter("1=1") ); client.AddRule(ruleDescription); } } catch (MessagingEntityNotFoundException) { } if (!reAddRule) { return; } int loopCounter = 0; while (loopCounter < 10) { try { RuleDescription ruleDescription = new RuleDescription ( "CqrsConfiguredFilter", new SqlFilter(filter) ); client.AddRule(ruleDescription); break; } catch (MessagingEntityAlreadyExistsException exception) { loopCounter++; // Still waiting for the delete to complete Thread.Sleep(1000); if (loopCounter == 9) { Logger.LogError("Setting the filter failed as it already exists.", exception: exception); TelemetryHelper.TrackException(exception); } } catch (Exception exception) { Logger.LogError("Setting the filter failed.", exception: exception); TelemetryHelper.TrackException(exception); break; } } }); }
private static void UpdateSqlFilter(NamespaceManager namespaceManager, string servicebusConnectionString, string sqlExpression, string subscriptionName, string topicPath) { bool needsReset = false; List <RuleDescription> existingRules; try { existingRules = namespaceManager.GetRules(topicPath, subscriptionName).ToList(); } catch (MessagingEntityNotFoundException) { // the subscription does not exist, no need to update rules. return; } if (existingRules.Count != 1) { needsReset = true; } else { var existingRule = existingRules.First(); if (sqlExpression != null && existingRule.Name == RuleDescription.DefaultRuleName) { needsReset = true; } else if (sqlExpression == null && existingRule.Name != RuleDescription.DefaultRuleName) { needsReset = true; } else if (sqlExpression != null && existingRule.Name != RuleName) { needsReset = true; } else if (sqlExpression != null && existingRule.Name == RuleName) { var filter = existingRule.Filter as SqlFilter; if (filter == null || filter.SqlExpression != sqlExpression) { needsReset = true; } } } if (needsReset) { MessagingFactory factory = null; try { factory = MessagingFactory.CreateFromConnectionString(servicebusConnectionString); SubscriptionClient client = null; try { client = factory.CreateSubscriptionClient(topicPath, subscriptionName); // first add the default rule, so no new messages are lost while we are updating the subscription TryAddRule(client, new RuleDescription(RuleDescription.DefaultRuleName, new TrueFilter())); // then delete every rule but the Default one foreach (var existing in existingRules.Where(x => x.Name != RuleDescription.DefaultRuleName)) { TryRemoveRule(client, existing.Name); } if (sqlExpression != null) { // Add the desired rule. TryAddRule(client, new RuleDescription(RuleName, new SqlFilter(sqlExpression))); // once the desired rule was added, delete the default rule. TryRemoveRule(client, RuleDescription.DefaultRuleName); } } finally { if (client != null) { client.Close(); } } } finally { if (factory != null) { factory.Close(); } } } }
static void GuardAgainstSubscriptionReuseAcrossLogicalEndpoints(string subscriptionname, NamespaceManager namespaceClient, string topicPath, string filter) { var rules = namespaceClient.GetRules(topicPath, subscriptionname); foreach (var rule in rules) { var sqlFilter = rule.Filter as SqlFilter; if (sqlFilter != null && sqlFilter.SqlExpression != filter) { throw new SubscriptionAlreadyInUseException( "Looks like this subscriptionname is already taken by another logical endpoint as the sql filter does not match the subscribed eventtype, please choose a different subscription name!"); } } }
private static void UpdateSqlFilter(NamespaceManager namespaceManager, string sqlExpression, string subscriptionName, string topicPath) { bool needsReset = false; List<RuleDescription> existingRules; try { existingRules = namespaceManager.GetRules(topicPath, subscriptionName).ToList(); } catch (MessagingEntityNotFoundException) { // the subscription does not exist, no need to update rules. return; } if (existingRules.Count != 1) { needsReset = true; } else { var existingRule = existingRules.First(); if (sqlExpression != null && existingRule.Name == RuleDescription.DefaultRuleName) { needsReset = true; } else if (sqlExpression == null && existingRule.Name != RuleDescription.DefaultRuleName) { needsReset = true; } else if (sqlExpression != null && existingRule.Name != RuleName) { needsReset = true; } else if (sqlExpression != null && existingRule.Name == RuleName) { var filter = existingRule.Filter as SqlFilter; if (filter == null || filter.SqlExpression != sqlExpression) { needsReset = true; } } } if (needsReset) { MessagingFactory factory = null; try { factory = MessagingFactory.Create(namespaceManager.Address, namespaceManager.Settings.TokenProvider); SubscriptionClient client = null; try { client = factory.CreateSubscriptionClient(topicPath, subscriptionName); // first add the default rule, so no new messages are lost while we are updating the subscription TryAddRule(client, new RuleDescription(RuleDescription.DefaultRuleName, new TrueFilter())); // then delete every rule but the Default one foreach (var existing in existingRules.Where(x => x.Name != RuleDescription.DefaultRuleName)) { TryRemoveRule(client, existing.Name); } if (sqlExpression != null) { // Add the desired rule. TryAddRule(client, new RuleDescription(RuleName, new SqlFilter(sqlExpression))); // once the desired rule was added, delete the default rule. TryRemoveRule(client, RuleDescription.DefaultRuleName); } } finally { if (client != null) client.Close(); } } finally { if (factory != null) factory.Close(); } } }