/// <summary> /// The schedule rule runs. /// </summary> /// <param name="execution"> /// The execution. /// </param> /// <param name="identifiableRules"> /// The identifiable rules. /// </param> /// <param name="rule"> /// The rule. /// </param> /// <param name="ruleContext"> /// The rule context. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> private async Task ScheduleRuleRuns( ScheduledExecution execution, IReadOnlyCollection <IIdentifiableRule> identifiableRules, RuleIdentifier rule, ISystemProcessOperationDistributeRuleContext ruleContext) { if (identifiableRules == null || !identifiableRules.Any()) { this.logger.LogWarning($"did not have any identifiable rules for rule {rule.Rule}"); return; } if (rule.Ids == null || !rule.Ids.Any()) { foreach (var ruleSet in identifiableRules) { var ruleInstance = new RuleIdentifier { Rule = rule.Rule, Ids = new[] { ruleSet.Id } }; await this.ScheduleRule(ruleInstance, execution, ruleSet.WindowSize, ruleContext.Id); } } else { foreach (var id in rule.Ids) { var identifiableRule = identifiableRules?.FirstOrDefault(_ => string.Equals(_.Id, id, StringComparison.InvariantCultureIgnoreCase)); if (identifiableRule == null) { this.logger.LogError( $"asked to schedule an execution for rule {rule.Rule.GetDescription()} with id of {id} which was not found when querying the rule parameter API on the client service."); ruleContext.EventError( $"asked to schedule an execution for rule {rule.Rule.GetDescription()} with id of {id} which was not found when querying the rule parameter API on the client service."); continue; } var ruleInstance = new RuleIdentifier { Rule = rule.Rule, Ids = new[] { id } }; await this.ScheduleRule(ruleInstance, execution, identifiableRule.WindowSize, ruleContext.Id); } } }
/// <summary> /// The schedule rule. /// </summary> /// <param name="ruleIdentifier"> /// The rule identifier. /// </param> /// <param name="execution"> /// The execution. /// </param> /// <param name="timespan"> /// The timespan. /// </param> /// <param name="correlationId"> /// The correlation id. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> private async Task ScheduleRule( RuleIdentifier ruleIdentifier, ScheduledExecution execution, TimeSpan?timespan, string correlationId) { var ruleTimespan = execution.TimeSeriesTermination - execution.TimeSeriesInitiation; var ruleParameterTimeWindow = timespan; if (ruleParameterTimeWindow == null || ruleTimespan.TotalDays < 7) { this.logger.LogInformation("had a rule time span below 7 days. Scheduling single execution."); await this.ScheduleSingleExecution(ruleIdentifier, execution, correlationId); return; } if (ruleParameterTimeWindow.GetValueOrDefault().TotalDays >= ruleTimespan.TotalDays) { this.logger.LogInformation( "had a rule parameter time window that exceeded the rule time span. Scheduling single execution."); await this.ScheduleSingleExecution(ruleIdentifier, execution, correlationId); return; } var daysToRunRuleFor = Math.Max(6, ruleParameterTimeWindow.GetValueOrDefault().TotalDays * 3); if (daysToRunRuleFor >= ruleTimespan.TotalDays) { this.logger.LogInformation( $"had days to run rule for {daysToRunRuleFor} greater than or equal to rule time span total days {ruleTimespan.TotalDays} . Scheduling single execution."); await this.ScheduleSingleExecution(ruleIdentifier, execution, correlationId); return; } this.logger.LogInformation( "had a time span too excessive for the time window. Utilising time splitter to divide and conquer the requested rule run."); await this .TimeSplitter( ruleIdentifier, execution, ruleParameterTimeWindow, daysToRunRuleFor, correlationId) ; }
public void GetFailureMessageAsyncShouldCallWrappedServiceWithOneGenericType([Frozen] IGetsFailureMessage <string> wrapped, FailureMessageProviderAdapter <string> sut, [RuleResult] RuleResult ruleResult, [ManifestModel] ManifestRule rule, Type ruleInterface, RuleIdentifier id, string actualValue, string expectedResult, IValidationLogic validationLogic) { var context = new RuleContext(rule, id, actualValue, Enumerable.Empty <ValueContext>(), ruleInterface); var validationRuleResult = new ValidationRuleResult(ruleResult, context, validationLogic); Mock.Get(wrapped).Setup(x => x.GetFailureMessageAsync(actualValue, validationRuleResult, default)).Returns(Task.FromResult(expectedResult)); Assert.That(async() => await sut.GetFailureMessageAsync(validationRuleResult), Is.EqualTo(expectedResult)); }
/// <summary> /// The time splitter. /// </summary> /// <param name="rule"> /// The rule. /// </param> /// <param name="execution"> /// The execution. /// </param> /// <param name="ruleParameterTimeWindow"> /// The rule parameter time window. /// </param> /// <param name="daysToRunRuleFor"> /// The days to run rule for. /// </param> /// <param name="correlationId"> /// The correlation id. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> private async Task TimeSplitter( RuleIdentifier rule, ScheduledExecution execution, TimeSpan?ruleParameterTimeWindow, double daysToRunRuleFor, string correlationId) { var continueSplit = true; var executions = new List <ScheduledExecution>(); var currentInitiationPoint = execution.TimeSeriesInitiation; while (continueSplit) { var currentEndPoint = currentInitiationPoint.AddDays(daysToRunRuleFor); if (currentEndPoint > execution.TimeSeriesTermination) { currentEndPoint = execution.TimeSeriesTermination; } var distributedExecution = new ScheduledExecution { Rules = new List <RuleIdentifier> { rule }, TimeSeriesInitiation = currentInitiationPoint, TimeSeriesTermination = currentEndPoint, CorrelationId = correlationId, IsBackTest = execution.IsBackTest }; executions.Add(distributedExecution); currentInitiationPoint = currentEndPoint.AddDays(1); if (currentInitiationPoint > execution.TimeSeriesTermination) { continueSplit = false; } currentInitiationPoint = currentInitiationPoint.AddDays(-ruleParameterTimeWindow.GetValueOrDefault().TotalDays); } foreach (var executionSplit in executions) { await this.rulePublisher.ScheduleExecution(executionSplit); } }
public void IsMatchShouldReturnFalseIfActualValidatedTypeIsNotASubclassOfAttributeType([RuleResult] RuleResult result, [ManifestModel] ManifestRule rule, Type ruleType, object objectId, object actualValue, IValidationLogic validationLogic) { var id = new RuleIdentifier(ruleType, typeof(Employee), objectId); var context = new RuleContext(rule, id, actualValue, Enumerable.Empty <ValueContext>(), typeof(string)); var ruleResult = new ValidationRuleResult(result, context, validationLogic); var sut = new FailureMessageStrategyAttribute { ValidatedType = typeof(string), }; Assert.That(() => sut.IsMatch(ruleResult), Is.False); }
/// <summary> /// The schedule single execution. /// </summary> /// <param name="rule"> /// The rule. /// </param> /// <param name="execution"> /// The execution. /// </param> /// <param name="correlationId"> /// The correlation id. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> private async Task ScheduleSingleExecution( RuleIdentifier rule, ScheduledExecution execution, string correlationId) { var distributedExecution = new ScheduledExecution { Rules = new List <RuleIdentifier> { rule }, TimeSeriesInitiation = execution.TimeSeriesInitiation, TimeSeriesTermination = execution.TimeSeriesTermination, CorrelationId = correlationId, IsBackTest = execution.IsBackTest }; await this.rulePublisher.ScheduleExecution(distributedExecution); }
public void IsMatchShouldReturnTrueIfActualParentValidatedTypeIsASubclassOfAttributeParentType([RuleResult] RuleResult result, [ManifestModel] ManifestRule rule, Type type, object objectId, object actualValue, IValidationLogic validationLogic) { var id = new RuleIdentifier(type, type, objectId); var context = new RuleContext(rule, id, actualValue, new [] { new ValueContext(objectId, actualValue, new ManifestValue { ValidatedType = typeof(Employee) }) }, typeof(string)); var ruleResult = new ValidationRuleResult(result, context, validationLogic); var sut = new FailureMessageStrategyAttribute { ParentValidatedType = typeof(Person), }; Assert.That(() => sut.IsMatch(ruleResult), Is.True); }
public void CanGetFailureMessageShouldCallWrappedServiceWithOneGenericType([Frozen] IHasFailureMessageUsageCriteria <string> wrapped, FailureMessageCriteriaAdapter <string> sut, [RuleResult] RuleResult ruleResult, [ManifestModel] ManifestRule rule, Type ruleInterface, RuleIdentifier id, string actualValue, bool expectedResult, IValidationLogic validationLogic) { var context = new RuleContext(rule, id, actualValue, Enumerable.Empty <ValueContext>(), ruleInterface); var validationRuleResult = new ValidationRuleResult(ruleResult, context, validationLogic); Mock.Get(wrapped).Setup(x => x.CanGetFailureMessage(actualValue, validationRuleResult)).Returns(expectedResult); var actualResult = sut.CanGetFailureMessage(validationRuleResult); Assert.Multiple(() => { Assert.That(actualResult, Is.EqualTo(expectedResult), "Actual result matches expected"); Mock.Get(wrapped).Verify(x => x.CanGetFailureMessage(actualValue, validationRuleResult), Times.Once, "Wrapped service was called"); }); }
public void GetExpressionShouldReturnAnExpressionWhichReturnsTrueForAResultWhichMatchesTheCurrentContextWithAValue([ManifestModel] ManifestRule rule, [RuleId] RuleIdentifier ruleIdentifier, object actualValue, Type ruleInterface, [RuleResult] RuleResult ruleResult, IValidationLogic logic) { ((ManifestValueBase)rule.ManifestValue).IdentityAccessor = null; var context = new RuleContext(rule, ruleIdentifier, actualValue, Enumerable.Empty <ValueContext>(), ruleInterface); var validationRuleResult = new ValidationRuleResult(ruleResult, context, logic); var sut = new RuleResultIsForDescendentOfValue(rule.ManifestValue, actualValue); Assert.That(() => sut.Matches(validationRuleResult), Is.True); }
public void GetExpressionShouldReturnAnExpressionWhichReturnsFalseForAResultWhichMatchesAnAncestorContextWhenAllowAncestorsIsFalse([ManifestModel] ManifestValue value, [ManifestModel] ManifestValue otherValue, [ManifestModel] ManifestRule rule, [RuleId] RuleIdentifier ruleIdentifier, object identity, object actualValue, Type ruleInterface, [RuleResult] RuleResult ruleResult, IValidationLogic logic) { value.IdentityAccessor = null; var context = new RuleContext(rule, ruleIdentifier, actualValue, new [] { new ValueContext(identity, actualValue, value) }, ruleInterface); var validationRuleResult = new ValidationRuleResult(ruleResult, context, logic); var sut = new RuleResultIsForDescendentOfValue(value, false); Assert.That(() => sut.Matches(validationRuleResult), Is.False); }
public RuleIdentifierToken(RuleIdentifier ruleIdentifier) { this.Identifier = ruleIdentifier; }
public RuleHeadPrefix(RuleIdentifier id) { this.Id = id; }
public RuleHead(RuleIdentifier ruleIdentifier, ClassIdentifier classIdentifier) { this.RuleIdentifier = ruleIdentifier; this.ClassIdentifier = classIdentifier; }
RuleHeadPrefix IParsnipRuleFactory.RuleHeadPrefix1(RuleIdentifier t0) => new RuleHeadPrefix(t0);
IToken IParsnipRuleFactory.Token3(RuleIdentifier t0) => new RuleIdentifierToken(t0);
public void IsMatchShouldReturnFalseIfTheRuleInterfaceIsSpecifiedButDoesNotMatch([RuleResult] RuleResult result, [ManifestModel] ManifestRule rule, RuleIdentifier id, object actualValue, IValidationLogic validationLogic) { var context = new RuleContext(rule, id, actualValue, Enumerable.Empty <ValueContext>(), typeof(string)); var ruleResult = new ValidationRuleResult(result, context, validationLogic); var sut = new FailureMessageStrategyAttribute { RuleInterface = typeof(int), }; Assert.That(() => sut.IsMatch(ruleResult), Is.False); }