public async Task EnsureSubscriptionIsSetup(string subscriptionName) { try { // The hash lookup works only when this class is registered in DI as a singleton if (subscriptionsThatHaveBeenSetup.Contains(subscriptionName)) { return; } subscriptionsThatHaveBeenSetup.Add(subscriptionName); if (!await managementClient.SubscriptionExistsAsync(topicName, subscriptionName)) { await managementClient.CreateSubscriptionAsync(new SubscriptionDescription(topicName, subscriptionName), MakeRule(subscriptionName)); } else { // The default rule is to accept everything, so delete it and replace it with the subscriptionName filter await managementClient.DeleteRuleAsync(topicName, subscriptionName, "$Default"); await managementClient.CreateRuleAsync(topicName, subscriptionName, MakeRule(subscriptionName)); } } catch (Exception e) { logger.LogError(e, $"Error setting up subscription for subscriptionName: {subscriptionName}"); } }
/// <summary> /// Ensures the subscription filter exists. /// </summary> /// <param name="manager">The manager.</param> /// <param name="topicName">Name of the topic.</param> /// <param name="subscriptionName">Name of the subscription.</param> /// <param name="filter">The filter.</param> /// <returns>Task<RuleDescription>.</returns> private static async Task <RuleDescription> EnsureSubscriptionFilter(ManagementClient manager, string topicName, string subscriptionName, KeyValuePair <string, string> filter) { // Get the rule, if it doesn't exist then create it. RuleDescription rule; var ruleName = filter.Key; var ruleExpression = filter.Value; try { rule = await manager.GetRuleAsync(topicName, subscriptionName, ruleName); } catch (Exception) { // Has failed as the filter rule does not exist, therefore, create! // And go ahead, create the rule. rule = await manager.CreateRuleAsync(topicName, subscriptionName, new RuleDescription { Name = ruleName, Filter = new SqlFilter(ruleExpression) }); try { // If we're applying a rule it means we DON'T want the default rule to exist. Therefore, remove. await manager.DeleteRuleAsync(topicName, subscriptionName, "$Default"); } catch (Exception) { // Do nothing. } } return(rule); }
public async Task <SubscriptionDescriptionWithRuleDto> CreateSubscriptionWithRuleAsync(string topicName, string subsName, RuleDescription rule) { var subs = await _managementClient .CreateSubscriptionAsync(topicName, subsName); await _managementClient.DeleteRuleAsync(topicName, subsName, RuleDescription.DefaultRuleName); await _managementClient.CreateRuleAsync(topicName, subsName, rule); _logger.LogInformation($"Created Subscription {subsName} with a Rule named {rule.Name} for Topic {topicName}"); var correlationFilter = ((CorrelationFilter)rule.Filter); var ruleDescriptionDto = new RuleDescriptionDto() { Name = rule.Name, Filter = new CorrelationFilterDto() { Label = correlationFilter.Label, ContentType = correlationFilter.ContentType, CorrelationId = correlationFilter.CorrelationId, MessageId = correlationFilter.MessageId, ReplyTo = correlationFilter.ReplyTo, ReplyToSessionId = correlationFilter.ReplyToSessionId, SessionId = correlationFilter.SessionId, To = correlationFilter.To } }; return(new SubscriptionDescriptionWithRuleDto(subs, ruleDescriptionDto)); }
private static async Task UpdateSubscriptionRules <TPayload>( ManagementClient managementClient, string channelName, string subscriptionName, RuleDescription ruleDescription, IMessageFactory <TPayload> messageFactory) where TPayload : class, IReceivedServiceBusMessage { var currentRules = await managementClient.GetRulesAsync(channelName, subscriptionName); if (currentRules.All(rule => ParseRuleName(rule) < messageFactory.CurrentVersion)) { // First we add a rule so new messages can qualify await managementClient.CreateRuleAsync(channelName, subscriptionName, ruleDescription) .IgnoreRaceConditionException <MessagingEntityAlreadyExistsException>(); // Remove each rule that are older than the one we just added currentRules = await managementClient.GetRulesAsync(channelName, subscriptionName); foreach (var rule in currentRules) { if (ParseRuleName(rule) < messageFactory.CurrentVersion) { await managementClient.DeleteRuleAsync(channelName, subscriptionName, rule.Name) .IgnoreRaceConditionException <MessagingEntityNotFoundException>(); } } } }
public async Task Subscribe(Type eventType, ContextBag context) { await CheckForManagePermissions().ConfigureAwait(false); var ruleName = eventType.FullName.Length > maxNameLength?ruleShortener(eventType.FullName) : eventType.FullName; var sqlExpression = $"[{Headers.EnclosedMessageTypes}] LIKE '%{eventType.FullName}%'"; var rule = new RuleDescription(ruleName, new SqlFilter(sqlExpression)); var client = new ManagementClient(connectionStringBuilder, tokenProvider); try { var existingRule = await client.GetRuleAsync(topicPath, subscriptionName, rule.Name).ConfigureAwait(false); if (existingRule.Filter.ToString() != rule.Filter.ToString()) { rule.Action = existingRule.Action; await client.UpdateRuleAsync(topicPath, subscriptionName, rule).ConfigureAwait(false); } } catch (MessagingEntityNotFoundException) { try { await client.CreateRuleAsync(topicPath, subscriptionName, rule).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException) { } } await client.CloseAsync().ConfigureAwait(false); }
public static Task Create(ManagementClient client, CommandArgument endpointName, CommandOption topicName, CommandOption subscriptionName, CommandArgument eventType, CommandOption ruleName) { var topicNameToUse = topicName.HasValue() ? topicName.Value() : Topic.DefaultTopicName; var subscriptionNameToUse = subscriptionName.HasValue() ? subscriptionName.Value() : endpointName.Value; var eventToSubscribeTo = eventType.Value; var ruleNameToUse = ruleName.HasValue() ? ruleName.Value() : eventToSubscribeTo; var description = new RuleDescription(ruleNameToUse, new SqlFilter($"[NServiceBus.EnclosedMessageTypes] LIKE '%{eventToSubscribeTo}%'")); return(client.CreateRuleAsync(topicNameToUse, subscriptionNameToUse, description)); }
private async Task EnsureRulesUpToDate(SimpleSubscriptionDescription subscription, ManagementClient client, CancellationToken cancellationToken) { var newRules = BuildRules(subscription) .ToArray(); var existingRules = await client .GetRulesAsync(settings.SafeEffectiveTopicName, subscription.SafeSubscriptionName(), cancellationToken : cancellationToken) .ConfigureAwait(false); foreach (var newRule in newRules) { if (existingRules.Any(existingRule => existingRule.Name == newRule.Name)) { continue; } logger.LogInformation( $"Rule {newRule.Name} doesn't exist on the subscription; creating the rule."); try { await client .CreateRuleAsync(settings.SafeEffectiveTopicName, subscription.SafeSubscriptionName(), newRule, cancellationToken) .ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException) { logger.LogWarning( $"Rule {newRule.Name} has been created by another process that is competing with this process."); } } foreach (var existingRule in existingRules) { if (newRules.Any(newRule => newRule.Name == existingRule.Name)) { continue; } logger.LogInformation( $"Rule {existingRule.Name} is no longer neeed; deleting the rule."); try { await client .DeleteRuleAsync(settings.SafeEffectiveTopicName, subscription.SafeSubscriptionName(), existingRule.Name, cancellationToken) .ConfigureAwait(false); } catch (MessagingEntityNotFoundException) { logger.LogWarning( $"Rule {existingRule.Name} has already been removed by another process that is competing with this process."); } } }
private void CreateNewSubscriptionRule(Type type, string endpointName, CancellationToken cancellationToken) { var manageClient = new ManagementClient(connectionString); var ruleDescription = new RuleDescription { Filter = new SqlFilter($"[NServiceBus.EnclosedMessageTypes] LIKE '%{type.FullName}%'"), Name = type.Name }; manageClient.CreateRuleAsync(TopicPath, endpointName, ruleDescription, cancellationToken); }
private async Task CreateSubscriptionAsync(string connectionString, string topic, string subscription) { var client = new ManagementClient(connectionString); if (!await client.SubscriptionExistsAsync(topic, subscription)) { await client.CreateSubscriptionAsync(topic, subscription); await client.CreateRuleAsync(topic, subscription, _rule); await _topicBus.SendAsync(_option.ServiceBus.TopicLog, $"Create Subscription {topic}"); } }
public async Task SqlFilterParamsTest() { var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); var subscriptionName = Guid.NewGuid().ToString("D").Substring(0, 8); try { await client.CreateTopicAsync(topicName); await client.CreateSubscriptionAsync(topicName, subscriptionName); SqlFilter sqlFilter = new SqlFilter( "PROPERTY(@propertyName) = @stringPropertyValue " + "AND PROPERTY(intProperty) = @intPropertyValue " + "AND PROPERTY(longProperty) = @longPropertyValue " + "AND PROPERTY(boolProperty) = @boolPropertyValue " + "AND PROPERTY(doubleProperty) = @doublePropertyValue ") { Parameters = { { "@propertyName", "MyProperty" }, { "@stringPropertyValue", "string" }, { "@intPropertyValue", 3 }, { "@longPropertyValue", 3L }, { "@boolPropertyValue", true }, { "@doublePropertyValue", (double)3.0 }, } }; var rule = await client.CreateRuleAsync(topicName, subscriptionName, new RuleDescription("rule1", sqlFilter)); Assert.Equal(sqlFilter, rule.Filter); await client.DeleteTopicAsync(topicName); } catch { await SafeDeleteTopic(client, topicName); throw; } finally { await client.CloseAsync(); } }
public static async Task EnsureSubscriptionRuleExistsAsync(string topicName, string subscriptionName, RuleDescription ruleDescription) { var sbManagement = new ManagementClient(Configs.SbFailoverConnectionString); var rules = await sbManagement.GetRulesAsync(topicName, subscriptionName); var defaultRule = rules.SingleOrDefault(x => x.Name.Equals(RuleDescription.DefaultRuleName)); if (defaultRule != null) { Console.WriteLine($"Removing subscription rule: {defaultRule.Name}"); await sbManagement.DeleteRuleAsync(topicName, subscriptionName, defaultRule.Name); } if (!rules.Any(x => x.Name.Equals(ruleDescription.Name))) { Console.WriteLine($"Creating subscription rule: {ruleDescription.Name}"); await sbManagement.CreateRuleAsync(topicName, subscriptionName, ruleDescription); } }
private async Task UpdateSubscriptionRules <TMessageType>( string channelName, string subscriptionName, RuleDescription ruleDescription, IMessageHandler <TMessageType> messageHandler) where TMessageType : class, IMessageContract { var currentRules = await _managementClient.GetRulesAsync(channelName, subscriptionName); if (currentRules.All(rule => ParseRuleName(rule) < messageHandler.CurrentVersion)) { try { // First we add a rule so new messages can qualify await _managementClient.CreateRuleAsync(channelName, subscriptionName, ruleDescription); } catch (MessagingEntityAlreadyExistsException) { // noop } // Remove each rule that are older than the one we just added currentRules = await _managementClient.GetRulesAsync(channelName, subscriptionName); foreach (var rule in currentRules) { if (ParseRuleName(rule) < messageHandler.CurrentVersion) { try { await _managementClient.DeleteRuleAsync(channelName, subscriptionName, rule.Name); } catch (MessagingEntityNotFoundException) { // noop } } } } }
public async Task CreateRuleAsync(string ruleName, string subscriptionName, string topicName) { if (string.IsNullOrWhiteSpace(ruleName)) { throw new ArgumentException($"'{nameof(ruleName)}' cannot be null or empty.", nameof(ruleName)); } if (string.IsNullOrWhiteSpace(topicName)) { throw new ArgumentException($"'{nameof(topicName)}' cannot be null or empty.", nameof(topicName)); } if (string.IsNullOrWhiteSpace(subscriptionName)) { throw new ArgumentException($"'{nameof(subscriptionName)}' cannot be null or empty.", nameof(subscriptionName)); } var topicExists = await TopicExistsAsync(topicName); if (!topicExists) { throw new TopicNotFoundException(topicName); } var subscriptionExists = await SubscriptionExistsAsync(subscriptionName, topicName); if (!subscriptionExists) { throw new SubscriptionNotFoundException(subscriptionName); } var ruleExists = await RuleExistsAsync(ruleName, subscriptionName, topicName); if (ruleExists) { throw new RuleAlreadyExistsException(ruleName); } await _client.CreateRuleAsync(topicName, subscriptionName, new RuleDescription(filter : new CorrelationFilter { Label = ruleName }, name : ruleName)); }
public async Task CreateSubscription(string topicName, string subscriptionName, IList <Type> filters = null) { if (!await _managementClient.SubscriptionExistsAsync(topicName, subscriptionName)) { // Configure Topic Settings. SubscriptionDescription topicDescription = new SubscriptionDescription(topicName, subscriptionName) { EnableDeadLetteringOnMessageExpiration = true, DefaultMessageTimeToLive = TimeSpan.FromDays(10), AutoDeleteOnIdle = TimeSpan.FromDays(1) }; await _managementClient.CreateSubscriptionAsync(topicDescription); } if (filters != null && filters.Any()) { IList <RuleDescription> rules = await _managementClient.GetRulesAsync(topicName, subscriptionName); if (rules.Any(x => x.Name == RuleDescription.DefaultRuleName)) { await _managementClient.DeleteRuleAsync(topicName, subscriptionName, RuleDescription.DefaultRuleName); } foreach (Type filter in filters) { if (rules.Any(x => x.Name == filter.Name)) { continue; } await _managementClient.CreateRuleAsync(topicName, subscriptionName, new RuleDescription(filter.Name, new CorrelationFilter { Label = filter.FullName })); } } }
public async Task Subscribe(Type eventType, ContextBag context) { await CheckForManagePermissions().ConfigureAwait(false); var ruleName = ruleNameFactory(eventType); var sqlExpression = sqlExpressionFactory(eventType); var rule = new RuleDescription(ruleName, new SqlFilter(sqlExpression)); var client = new ManagementClient(connectionStringBuilder, tokenProvider); try { var existingRule = await client.GetRuleAsync(topicPath, subscriptionName, rule.Name).ConfigureAwait(false); if (existingRule.Filter.ToString() != rule.Filter.ToString()) { rule.Action = existingRule.Action; await client.UpdateRuleAsync(topicPath, subscriptionName, rule).ConfigureAwait(false); } } catch (MessagingEntityNotFoundException) { try { await client.CreateRuleAsync(topicPath, subscriptionName, rule).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException) { } } finally { await client.CloseAsync().ConfigureAwait(false); } }
public async Task CorrelationFilterPropertiesTest() { var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); var subscriptionName = Guid.NewGuid().ToString("D").Substring(0, 8); var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); try { await client.CreateTopicAsync(topicName); await client.CreateSubscriptionAsync(topicName, subscriptionName); var sClient = new SubscriptionClient(TestUtility.NamespaceConnectionString, topicName, subscriptionName); var filter = new CorrelationFilter(); filter.Properties.Add("stringKey", "stringVal"); filter.Properties.Add("intKey", 5); filter.Properties.Add("dateTimeKey", DateTime.UtcNow); var rule = await client.CreateRuleAsync(topicName, subscriptionName, new RuleDescription("rule1", filter)); Assert.True(filter.Properties.Count == 3); Assert.Equal(filter, rule.Filter); await client.DeleteTopicAsync(topicName); } catch { await SafeDeleteTopic(client, topicName); throw; } finally { await client.CloseAsync(); } }
public async Task BasicRulesCrudTest() { var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); var subscriptionName = Guid.NewGuid().ToString("D").Substring(0, 8); var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); try { await client.CreateTopicAsync(topicName); await client.CreateSubscriptionAsync( new SubscriptionDescription(topicName, subscriptionName), new RuleDescription("rule0", new FalseFilter())); var sqlFilter = new SqlFilter("stringValue = @stringParam AND intValue = @intParam AND longValue = @longParam AND dateValue = @dateParam AND timeSpanValue = @timeSpanParam"); sqlFilter.Parameters.Add("@stringParam", "string"); sqlFilter.Parameters.Add("@intParam", (int)1); sqlFilter.Parameters.Add("@longParam", (long)12); sqlFilter.Parameters.Add("@dateParam", DateTime.UtcNow); sqlFilter.Parameters.Add("@timeSpanParam", TimeSpan.FromDays(1)); var rule1 = new RuleDescription { Name = "rule1", Filter = sqlFilter, Action = new SqlRuleAction("SET a='b'") }; await client.CreateRuleAsync(topicName, subscriptionName, rule1); var correlationFilter = new CorrelationFilter() { ContentType = "contentType", CorrelationId = "correlationId", Label = "label", MessageId = "messageId", ReplyTo = "replyTo", ReplyToSessionId = "replyToSessionId", SessionId = "sessionId", To = "to" }; correlationFilter.Properties.Add("customKey", "customValue"); var rule2 = new RuleDescription() { Name = "rule2", Filter = correlationFilter, Action = null }; await client.CreateRuleAsync(topicName, subscriptionName, rule2); var rules = await client.GetRulesAsync(topicName, subscriptionName); Assert.True(rules.Count == 3); Assert.Equal("rule0", rules[0].Name); Assert.Equal(rule1, rules[1]); Assert.Equal(rule2, rules[2]); ((CorrelationFilter)rule2.Filter).CorrelationId = "correlationIdModified"; var updatedRule2 = await client.UpdateRuleAsync(topicName, subscriptionName, rule2); Assert.Equal(rule2, updatedRule2); var defaultRule = await client.GetRuleAsync(topicName, subscriptionName, "rule0"); Assert.NotNull(defaultRule); await client.DeleteRuleAsync(topicName, subscriptionName, "rule0"); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.GetRuleAsync(topicName, subscriptionName, "rule0"); }); await client.DeleteTopicAsync(topicName); } catch { await SafeDeleteTopic(client, topicName); throw; } finally { await client.CloseAsync(); } }