예제 #1
0
        /// <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;
                    }
                }
            });
        }
예제 #2
0
        /// <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="IMessageReceiver"/> instances in <paramref name="serviceBusReceivers"/>.
        /// </summary>
        /// <param name="manager">The <see cref="Manager"/>.</param>
        /// <param name="serviceBusReceivers">The receivers collection to place <see cref="IMessageReceiver"/> instances into.</param>
        /// <param name="topicName">The topic name.</param>
        /// <param name="topicSubscriptionName">The topic subscription name.</param>
        protected override void InstantiateReceiving(Manager manager, IDictionary <int, IMessageReceiver> serviceBusReceivers, string topicName, string topicSubscriptionName)
        {
            base.InstantiateReceiving(manager, 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
#if NET452
                SubscriptionClient client = serviceBusReceivers[0];
#endif
#if NETSTANDARD2_0
                // Since the IMessageReceiver and it's concrete implementation doesn't allow for the management of rules, we're creating a SubscriptionClient just to do the rules... it gets cleaned up somewhat below.
                SubscriptionClient client = new SubscriptionClient(ConnectionString, topicName, topicSubscriptionName);
#endif
                bool reAddRule = false;
                try
                {
#if NET452
                    IEnumerable <RuleDescription> rules = manager.GetRules(client.TopicPath, client.Name).ToList();
#endif
#if NETSTANDARD2_0
                    Task <IList <RuleDescription> > getRulesTask = manager.GetRulesAsync(client.TopicPath, client.SubscriptionName);
                    getRulesTask.Wait();
                    IEnumerable <RuleDescription> rules = getRulesTask.Result;
#endif
                    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)
                        {
#if NET452
                            client.RemoveRule("CqrsConfiguredFilter");
#endif
#if NETSTANDARD2_0
                            client.RemoveRuleAsync("CqrsConfiguredFilter").Wait();
#endif
                        }
                    }
                    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)
                    {
#if NET452
                        client.RemoveRule("$Default");
#endif
#if NETSTANDARD2_0
                        client.RemoveRuleAsync("$Default").Wait();
#endif
                    }
                    // 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")
                                          );
#if NET452
                        client.AddRule(ruleDescription);
#endif
#if NETSTANDARD2_0
                        client.AddRuleAsync(ruleDescription).Wait();
#endif
                    }
                }
                catch (AggregateException ex)
                {
                    if (!(ex.InnerException is MessagingEntityNotFoundException))
                    {
                        throw;
                    }
                }
                catch (MessagingEntityNotFoundException)
                {
                }

                if (!reAddRule)
                {
                    return;
                }

                int loopCounter = 0;
                while (loopCounter < 10)
                {
                    try
                    {
                        RuleDescription ruleDescription = new RuleDescription
                                                          (
                            "CqrsConfiguredFilter",
                            new SqlFilter(filter)
                                                          );
#if NET452
                        client.AddRule(ruleDescription);
#endif
#if NETSTANDARD2_0
                        client.AddRuleAsync(ruleDescription).Wait();
#endif
                        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;
                    }
                }

#if NETSTANDARD2_0
                client.CloseAsync();
#endif
            });
        }