public void LimitRuleFilter() { _resourceRepository.Setup(x => x.Get("order")) .Returns(new Resource { Key = "order", RateLimitRules = new List <LimitRule> { new LimitRule { GeoLocation = "US", Threshold = 5, TimeSpan = 10 }, new LimitRule { GeoLocation = "AU", Threshold = 3, TimeSpan = 30 }, new LimitRule { GeoLocation = "AU", Threshold = 1, TimeSpan = 8 }, new LimitRule { Threshold = 1, TimeSpan = 5 } } }); var resource = _resourceRepository.Object.Get("order"); var context = new RequestContext { ClientContext = new ClientContext { GeoLocation = "US" } }; var appliedLimits = _limitRuleFilter.FilterByRequest(resource, context); Assert.IsTrue(appliedLimits.Count() == 1 && appliedLimits.Any(r => r.GeoLocation == "US")); context = new RequestContext { ClientContext = new ClientContext { GeoLocation = "AU" } }; appliedLimits = _limitRuleFilter.FilterByRequest(resource, context); Assert.IsTrue(appliedLimits.Count() == 2 && appliedLimits.All(r => r.GeoLocation == "AU")); context = new RequestContext { ClientContext = new ClientContext { GeoLocation = "EU" } }; appliedLimits = _limitRuleFilter.FilterByRequest(resource, context); Assert.IsNull(appliedLimits.FirstOrDefault().GeoLocation); }
/// <summary> /// Process shouldn't have cpu bound operation however method can be converted to be async to implement cancellation token. /// </summary> /// <param name="context"></param> public void Evaluate(RequestContext context) { var resource = _resourceRepository.Get(context.Resource); if (resource.HasNoLimitation()) { return; // No limit defined. } var evaluationContext = new EvaluationContext { RequestContext = context, RuleSet = _limitRuleFilter.FilterByRequest(resource, context) }; _tokenBucket.EvaluateAndUpdate(evaluationContext); }