/// <summary> /// Adds a new rule. /// </summary> /// <param name="rule">The rule.</param> /// <param name="ruleAddPriorityOption">The rule add priority option.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">rule or rule</exception> /// <exception cref="NotSupportedException"> /// The placement option '{ruleAddPriorityOption.PriorityOption}' is not supported. /// </exception> public Task <RuleOperationResult> AddRuleAsync(Rule <TContentType, TConditionType> rule, RuleAddPriorityOption ruleAddPriorityOption) { if (rule is null) { throw new ArgumentNullException(nameof(rule)); } if (ruleAddPriorityOption is null) { throw new ArgumentNullException(nameof(rule)); } return(this.AddRuleInternalAsync(rule, ruleAddPriorityOption)); }
private async Task <RuleOperationResult> AddRuleInternalAsync(Rule <TContentType, TConditionType> rule, RuleAddPriorityOption ruleAddPriorityOption) { List <string> errors = new List <string>(); RulesFilterArgs <TContentType> rulesFilterArgs = new RulesFilterArgs <TContentType> { ContentType = rule.ContentContainer.ContentType }; IEnumerable <Rule <TContentType, TConditionType> > existentRules = await this.rulesDataSource.GetRulesByAsync(rulesFilterArgs).ConfigureAwait(false); if (ruleAddPriorityOption.PriorityOption == PriorityOptions.AtRuleName && !existentRules.Any(r => string.Equals(r.Name, ruleAddPriorityOption.AtRuleNameOptionValue, StringComparison.OrdinalIgnoreCase))) { errors.Add($"Rule name '{ruleAddPriorityOption.AtRuleNameOptionValue}' specified for priority placement does not exist."); } if (existentRules.Any(r => string.Equals(r.Name, rule.Name, StringComparison.OrdinalIgnoreCase))) { errors.Add($"A rule with name '{rule.Name}' already exists."); } if (errors.Any()) { return(RuleOperationResult.Error(errors)); } switch (ruleAddPriorityOption.PriorityOption) { case PriorityOptions.AtTop: rule.Priority = 1; await ManagementOperations.Manage(existentRules) .UsingDataSource(this.rulesDataSource) .IncreasePriority() .UpdateRules() .AddRule(rule) .ExecuteOperationsAsync() .ConfigureAwait(false); break; case PriorityOptions.AtBottom: rule.Priority = existentRules.Max(r => r.Priority) + 1; await ManagementOperations.Manage(existentRules) .UsingDataSource(this.rulesDataSource) .AddRule(rule) .ExecuteOperationsAsync() .ConfigureAwait(false); break; case PriorityOptions.AtPriorityNumber: int priorityMin = existentRules.MinOrDefault(r => r.Priority); int priorityMax = existentRules.MaxOrDefault(r => r.Priority); int rulePriority = ruleAddPriorityOption.AtPriorityNumberOptionValue; rulePriority = Math.Min(rulePriority, priorityMax + 1); rulePriority = Math.Max(rulePriority, priorityMin); rule.Priority = rulePriority; await ManagementOperations.Manage(existentRules) .UsingDataSource(this.rulesDataSource) .FilterFromThresholdPriorityToBottom(rulePriority) .IncreasePriority() .UpdateRules() .AddRule(rule) .ExecuteOperationsAsync() .ConfigureAwait(false); break; case PriorityOptions.AtRuleName: int firstPriorityToIncrement = existentRules .FirstOrDefault(r => string.Equals(r.Name, ruleAddPriorityOption.AtRuleNameOptionValue, StringComparison.OrdinalIgnoreCase)) .Priority; rule.Priority = firstPriorityToIncrement; await ManagementOperations.Manage(existentRules) .UsingDataSource(this.rulesDataSource) .FilterFromThresholdPriorityToBottom(firstPriorityToIncrement) .IncreasePriority() .UpdateRules() .AddRule(rule) .ExecuteOperationsAsync() .ConfigureAwait(false); break; default: throw new NotSupportedException($"The placement option '{ruleAddPriorityOption.PriorityOption}' is not supported."); } return(RuleOperationResult.Success()); }