diff --git a/framework/Volo.Abp.slnx b/framework/Volo.Abp.slnx index b5d1f87166..1e36f1d212 100644 --- a/framework/Volo.Abp.slnx +++ b/framework/Volo.Abp.slnx @@ -169,7 +169,7 @@ - + @@ -257,6 +257,6 @@ - + diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitResource.cs b/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitResource.cs deleted file mode 100644 index d180b89838..0000000000 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitResource.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Volo.Abp.Localization; - -namespace Volo.Abp.OperationRateLimit; - -[LocalizationResourceName("AbpOperationRateLimit")] -public class AbpOperationRateLimitResource -{ -} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitChecker.cs b/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitChecker.cs deleted file mode 100644 index 8cccb0d51f..0000000000 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitChecker.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.OperationRateLimit; - -public interface IOperationRateLimitChecker -{ - Task CheckAsync(string policyName, OperationRateLimitContext? context = null); - - Task IsAllowedAsync(string policyName, OperationRateLimitContext? context = null); - - Task GetStatusAsync(string policyName, OperationRateLimitContext? context = null); - - Task ResetAsync(string policyName, OperationRateLimitContext? context = null); -} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitFormatter.cs b/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitFormatter.cs deleted file mode 100644 index 8fd61d3925..0000000000 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitFormatter.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace Volo.Abp.OperationRateLimit; - -public interface IOperationRateLimitFormatter -{ - string Format(TimeSpan duration); -} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitPolicyProvider.cs b/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitPolicyProvider.cs deleted file mode 100644 index 504b8da745..0000000000 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitPolicyProvider.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Volo.Abp.OperationRateLimit; - -public interface IOperationRateLimitPolicyProvider -{ - Task GetAsync(string policyName); - - Task> GetListAsync(); -} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitRule.cs b/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitRule.cs deleted file mode 100644 index b7c83265f2..0000000000 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitRule.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.OperationRateLimit; - -public interface IOperationRateLimitRule -{ - Task AcquireAsync(OperationRateLimitContext context); - - Task CheckAsync(OperationRateLimitContext context); - - Task ResetAsync(OperationRateLimitContext context); -} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitStore.cs b/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitStore.cs deleted file mode 100644 index c6c736b45c..0000000000 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/IOperationRateLimitStore.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Volo.Abp.OperationRateLimit; - -public interface IOperationRateLimitStore -{ - Task IncrementAsync(string key, TimeSpan duration, int maxCount); - - Task GetAsync(string key, TimeSpan duration, int maxCount); - - Task ResetAsync(string key); -} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleDefinition.cs b/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleDefinition.cs deleted file mode 100644 index 856fb299fa..0000000000 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleDefinition.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Volo.Abp.OperationRateLimit; - -public class OperationRateLimitRuleDefinition -{ - public TimeSpan Duration { get; set; } - - public int MaxCount { get; set; } - - public OperationRateLimitPartitionType PartitionType { get; set; } - - public Func? CustomPartitionKeyResolver { get; set; } - - public bool IsMultiTenant { get; set; } -} diff --git a/framework/src/Volo.Abp.OperationRateLimit/FodyWeavers.xml b/framework/src/Volo.Abp.OperationRateLimiting/FodyWeavers.xml similarity index 100% rename from framework/src/Volo.Abp.OperationRateLimit/FodyWeavers.xml rename to framework/src/Volo.Abp.OperationRateLimiting/FodyWeavers.xml diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo.Abp.OperationRateLimit.csproj b/framework/src/Volo.Abp.OperationRateLimiting/Volo.Abp.OperationRateLimiting.csproj similarity index 81% rename from framework/src/Volo.Abp.OperationRateLimit/Volo.Abp.OperationRateLimit.csproj rename to framework/src/Volo.Abp.OperationRateLimiting/Volo.Abp.OperationRateLimiting.csproj index f550b7c7cf..ffac7ef34e 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo.Abp.OperationRateLimit.csproj +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo.Abp.OperationRateLimiting.csproj @@ -7,8 +7,8 @@ netstandard2.0;netstandard2.1;net8.0;net9.0;net10.0 enable Nullable - Volo.Abp.OperationRateLimit - Volo.Abp.OperationRateLimit + Volo.Abp.OperationRateLimiting + Volo.Abp.OperationRateLimiting $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; false false @@ -17,8 +17,8 @@ - - + + diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitErrorCodes.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingErrorCodes.cs similarity index 58% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitErrorCodes.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingErrorCodes.cs index 783b52e3f2..5ff8d88b5a 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitErrorCodes.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingErrorCodes.cs @@ -1,9 +1,9 @@ -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public static class AbpOperationRateLimitErrorCodes +public static class AbpOperationRateLimitingErrorCodes { /// /// Default error code for rate limit exceeded. /// - public const string ExceedLimit = "Volo.Abp.OperationRateLimit:010001"; + public const string ExceedLimit = "Volo.Abp.OperationRateLimiting:010001"; } diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitModule.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingModule.cs similarity index 67% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitModule.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingModule.cs index ac74e4c80c..0462a285a5 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitModule.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingModule.cs @@ -7,7 +7,7 @@ using Volo.Abp.Modularity; using Volo.Abp.Security; using Volo.Abp.VirtualFileSystem; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; [DependsOn( typeof(AbpCachingModule), @@ -16,27 +16,27 @@ namespace Volo.Abp.OperationRateLimit; typeof(AbpAspNetCoreAbstractionsModule), typeof(AbpDistributedLockingAbstractionsModule) )] -public class AbpOperationRateLimitModule : AbpModule +public class AbpOperationRateLimitingModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => { - options.FileSets.AddEmbedded(); + options.FileSets.AddEmbedded(); }); Configure(options => { options.Resources - .Add("en") - .AddVirtualJson("/Volo/Abp/OperationRateLimit/Localization"); + .Add("en") + .AddVirtualJson("/Volo/Abp/OperationRateLimiting/Localization"); }); Configure(options => { options.MapCodeNamespace( - "Volo.Abp.OperationRateLimit", - typeof(AbpOperationRateLimitResource)); + "Volo.Abp.OperationRateLimiting", + typeof(AbpOperationRateLimitingResource)); }); } } diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitOptions.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingOptions.cs similarity index 54% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitOptions.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingOptions.cs index 5ed35d4de7..711f2b17d0 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitOptions.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingOptions.cs @@ -1,19 +1,19 @@ using System; using System.Collections.Generic; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class AbpOperationRateLimitOptions +public class AbpOperationRateLimitingOptions { public bool IsEnabled { get; set; } = true; public TimeSpan LockTimeout { get; set; } = TimeSpan.FromSeconds(5); - public Dictionary Policies { get; } = new(); + public Dictionary Policies { get; } = new(); - public void AddPolicy(string name, Action configure) + public void AddPolicy(string name, Action configure) { - var builder = new OperationRateLimitPolicyBuilder(name); + var builder = new OperationRateLimitingPolicyBuilder(name); configure(builder); Policies[name] = builder.Build(); } diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingResource.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingResource.cs new file mode 100644 index 0000000000..e4f93d97d0 --- /dev/null +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingResource.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Localization; + +namespace Volo.Abp.OperationRateLimiting; + +[LocalizationResourceName("AbpOperationRateLimiting")] +public class AbpOperationRateLimitingResource +{ +} diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/IOperationRateLimitingChecker.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/IOperationRateLimitingChecker.cs new file mode 100644 index 0000000000..2220c241e8 --- /dev/null +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/IOperationRateLimitingChecker.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.OperationRateLimiting; + +public interface IOperationRateLimitingChecker +{ + Task CheckAsync(string policyName, OperationRateLimitingContext? context = null); + + Task IsAllowedAsync(string policyName, OperationRateLimitingContext? context = null); + + Task GetStatusAsync(string policyName, OperationRateLimitingContext? context = null); + + Task ResetAsync(string policyName, OperationRateLimitingContext? context = null); +} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitChecker.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingChecker.cs similarity index 78% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitChecker.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingChecker.cs index 9240d096b7..3b3006b248 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitChecker.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingChecker.cs @@ -9,23 +9,23 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; using Volo.Abp.Users; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientDependency +public class OperationRateLimitingChecker : IOperationRateLimitingChecker, ITransientDependency { - protected AbpOperationRateLimitOptions Options { get; } - protected IOperationRateLimitPolicyProvider PolicyProvider { get; } + protected AbpOperationRateLimitingOptions Options { get; } + protected IOperationRateLimitingPolicyProvider PolicyProvider { get; } protected IServiceProvider ServiceProvider { get; } - protected IOperationRateLimitStore Store { get; } + protected IOperationRateLimitingStore Store { get; } protected ICurrentUser CurrentUser { get; } protected ICurrentTenant CurrentTenant { get; } protected IWebClientInfoProvider WebClientInfoProvider { get; } - public OperationRateLimitChecker( - IOptions options, - IOperationRateLimitPolicyProvider policyProvider, + public OperationRateLimitingChecker( + IOptions options, + IOperationRateLimitingPolicyProvider policyProvider, IServiceProvider serviceProvider, - IOperationRateLimitStore store, + IOperationRateLimitingStore store, ICurrentUser currentUser, ICurrentTenant currentTenant, IWebClientInfoProvider webClientInfoProvider) @@ -39,7 +39,7 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD WebClientInfoProvider = webClientInfoProvider; } - public virtual async Task CheckAsync(string policyName, OperationRateLimitContext? context = null) + public virtual async Task CheckAsync(string policyName, OperationRateLimitingContext? context = null) { if (!Options.IsEnabled) { @@ -52,7 +52,7 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD // Phase 1: Check ALL rules without incrementing to get complete status. // Do not exit early: a later rule may have a larger RetryAfter that the caller needs to know about. - var checkResults = new List(); + var checkResults = new List(); foreach (var rule in rules) { checkResults.Add(await rule.CheckAsync(context)); @@ -68,7 +68,7 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD // Phase 2: All rules pass - now increment all counters. // Also guard against a concurrent race where another request consumed the last quota // between Phase 1 and Phase 2. - var incrementResults = new List(); + var incrementResults = new List(); foreach (var rule in rules) { incrementResults.Add(await rule.AcquireAsync(context)); @@ -81,7 +81,7 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD } } - public virtual async Task IsAllowedAsync(string policyName, OperationRateLimitContext? context = null) + public virtual async Task IsAllowedAsync(string policyName, OperationRateLimitingContext? context = null) { if (!Options.IsEnabled) { @@ -104,11 +104,11 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD return true; } - public virtual async Task GetStatusAsync(string policyName, OperationRateLimitContext? context = null) + public virtual async Task GetStatusAsync(string policyName, OperationRateLimitingContext? context = null) { if (!Options.IsEnabled) { - return new OperationRateLimitResult + return new OperationRateLimitingResult { IsAllowed = true, RemainingCount = int.MaxValue, @@ -120,7 +120,7 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD context = EnsureContext(context); var policy = await PolicyProvider.GetAsync(policyName); var rules = CreateRules(policy); - var ruleResults = new List(); + var ruleResults = new List(); foreach (var rule in rules) { @@ -130,7 +130,7 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD return AggregateResults(ruleResults, policy); } - public virtual async Task ResetAsync(string policyName, OperationRateLimitContext? context = null) + public virtual async Task ResetAsync(string policyName, OperationRateLimitingContext? context = null) { context = EnsureContext(context); var policy = await PolicyProvider.GetAsync(policyName); @@ -142,20 +142,20 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD } } - protected virtual OperationRateLimitContext EnsureContext(OperationRateLimitContext? context) + protected virtual OperationRateLimitingContext EnsureContext(OperationRateLimitingContext? context) { - context ??= new OperationRateLimitContext(); + context ??= new OperationRateLimitingContext(); context.ServiceProvider = ServiceProvider; return context; } - protected virtual List CreateRules(OperationRateLimitPolicy policy) + protected virtual List CreateRules(OperationRateLimitingPolicy policy) { - var rules = new List(); + var rules = new List(); for (var i = 0; i < policy.Rules.Count; i++) { - rules.Add(new FixedWindowOperationRateLimitRule( + rules.Add(new FixedWindowOperationRateLimitingRule( policy.Name, i, policy.Rules[i], @@ -167,15 +167,15 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD foreach (var customRuleType in policy.CustomRuleTypes) { - rules.Add((IOperationRateLimitRule)ServiceProvider.GetRequiredService(customRuleType)); + rules.Add((IOperationRateLimitingRule)ServiceProvider.GetRequiredService(customRuleType)); } return rules; } - protected virtual OperationRateLimitResult AggregateResults( - List ruleResults, - OperationRateLimitPolicy policy) + protected virtual OperationRateLimitingResult AggregateResults( + List ruleResults, + OperationRateLimitingPolicy policy) { var isAllowed = ruleResults.All(r => r.IsAllowed); var mostRestrictive = ruleResults @@ -183,7 +183,7 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD .ThenByDescending(r => r.RetryAfter ?? TimeSpan.Zero) .First(); - return new OperationRateLimitResult + return new OperationRateLimitingResult { IsAllowed = isAllowed, RemainingCount = mostRestrictive.RemainingCount, @@ -201,13 +201,13 @@ public class OperationRateLimitChecker : IOperationRateLimitChecker, ITransientD } protected virtual void ThrowRateLimitException( - OperationRateLimitPolicy policy, - OperationRateLimitResult result, - OperationRateLimitContext context) + OperationRateLimitingPolicy policy, + OperationRateLimitingResult result, + OperationRateLimitingContext context) { - var formatter = context.ServiceProvider.GetRequiredService(); + var formatter = context.ServiceProvider.GetRequiredService(); - var exception = new AbpOperationRateLimitException( + var exception = new AbpOperationRateLimitingException( policy.Name, result, policy.ErrorCode); diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitContext.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingContext.cs similarity index 88% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitContext.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingContext.cs index d3e706a9ff..3f408b8240 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitContext.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingContext.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitContext +public class OperationRateLimitingContext { /// /// Optional parameter passed by the caller. @@ -14,7 +14,7 @@ public class OperationRateLimitContext public string? Parameter { get; set; } /// - /// Additional properties that can be read by custom implementations + /// Additional properties that can be read by custom implementations /// and are forwarded to the exception's Data dictionary when the rate limit is exceeded. /// public Dictionary ExtraProperties { get; set; } = new(); diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitResult.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingResult.cs similarity index 72% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitResult.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingResult.cs index 83d77d21af..6659947099 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitResult.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingResult.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitResult +public class OperationRateLimitingResult { public bool IsAllowed { get; set; } @@ -20,5 +20,5 @@ public class OperationRateLimitResult /// /// Detailed results per rule (for composite policies). /// - public List? RuleResults { get; set; } + public List? RuleResults { get; set; } } diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleResult.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingRuleResult.cs similarity index 77% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleResult.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingRuleResult.cs index efc0fd8548..e05e6bf4fb 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleResult.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Checker/OperationRateLimitingRuleResult.cs @@ -1,8 +1,8 @@ using System; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitRuleResult +public class OperationRateLimitingRuleResult { public string RuleName { get; set; } = default!; diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitException.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Exceptions/AbpOperationRateLimitingException.cs similarity index 74% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitException.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Exceptions/AbpOperationRateLimitingException.cs index 852b506e46..9872d26e76 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/AbpOperationRateLimitException.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Exceptions/AbpOperationRateLimitingException.cs @@ -1,21 +1,21 @@ using System; using Volo.Abp.ExceptionHandling; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class AbpOperationRateLimitException : BusinessException, IHasHttpStatusCode +public class AbpOperationRateLimitingException : BusinessException, IHasHttpStatusCode { public string PolicyName { get; } - public OperationRateLimitResult Result { get; } + public OperationRateLimitingResult Result { get; } public int HttpStatusCode => 429; - public AbpOperationRateLimitException( + public AbpOperationRateLimitingException( string policyName, - OperationRateLimitResult result, + OperationRateLimitingResult result, string? errorCode = null) - : base(code: errorCode ?? AbpOperationRateLimitErrorCodes.ExceedLimit) + : base(code: errorCode ?? AbpOperationRateLimitingErrorCodes.ExceedLimit) { PolicyName = policyName; Result = result; diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DefaultOperationRateLimitFormatter.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Formatting/DefaultOperationRateLimitingFormatter.cs similarity index 84% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DefaultOperationRateLimitFormatter.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Formatting/DefaultOperationRateLimitingFormatter.cs index 7a506e5d5e..e69dd7082b 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DefaultOperationRateLimitFormatter.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Formatting/DefaultOperationRateLimitingFormatter.cs @@ -2,15 +2,15 @@ using System; using Microsoft.Extensions.Localization; using Volo.Abp.DependencyInjection; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class DefaultOperationRateLimitFormatter - : IOperationRateLimitFormatter, ITransientDependency +public class DefaultOperationRateLimitingFormatter + : IOperationRateLimitingFormatter, ITransientDependency { - protected IStringLocalizer Localizer { get; } + protected IStringLocalizer Localizer { get; } - public DefaultOperationRateLimitFormatter( - IStringLocalizer localizer) + public DefaultOperationRateLimitingFormatter( + IStringLocalizer localizer) { Localizer = localizer; } diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Formatting/IOperationRateLimitingFormatter.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Formatting/IOperationRateLimitingFormatter.cs new file mode 100644 index 0000000000..7e6370e215 --- /dev/null +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Formatting/IOperationRateLimitingFormatter.cs @@ -0,0 +1,8 @@ +using System; + +namespace Volo.Abp.OperationRateLimiting; + +public interface IOperationRateLimitingFormatter +{ + string Format(TimeSpan duration); +} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ar.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ar.json similarity index 82% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ar.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ar.json index 8e2cf120cd..46b937bb99 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ar.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ar.json @@ -1,7 +1,7 @@ { "culture": "ar", "texts": { - "Volo.Abp.OperationRateLimit:010001": "تم تجاوز حد معدل العملية. يمكنك المحاولة مرة أخرى بعد {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "تم تجاوز حد معدل العملية. يمكنك المحاولة مرة أخرى بعد {RetryAfter}.", "RetryAfter:Years": "{0} سنة/سنوات", "RetryAfter:YearsAndMonths": "{0} سنة/سنوات و {1} شهر/أشهر", "RetryAfter:Months": "{0} شهر/أشهر", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/cs.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/cs.json similarity index 85% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/cs.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/cs.json index d1db9eb671..205d229c10 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/cs.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/cs.json @@ -1,7 +1,7 @@ { "culture": "cs", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Překročen limit rychlosti operace. Můžete to zkusit znovu za {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Překročen limit rychlosti operace. Můžete to zkusit znovu za {RetryAfter}.", "RetryAfter:Years": "{0} rok(y/let)", "RetryAfter:YearsAndMonths": "{0} rok(y/let) a {1} měsíc(e/ů)", "RetryAfter:Months": "{0} měsíc(e/ů)", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/de.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/de.json similarity index 82% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/de.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/de.json index 5fcca27604..3313e0156d 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/de.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/de.json @@ -1,7 +1,7 @@ { "culture": "de", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Betriebsratenlimit überschritten. Sie können es nach {RetryAfter} erneut versuchen.", + "Volo.Abp.OperationRateLimiting:010001": "Betriebsratenlimit überschritten. Sie können es nach {RetryAfter} erneut versuchen.", "RetryAfter:Years": "{0} Jahr(e)", "RetryAfter:YearsAndMonths": "{0} Jahr(e) und {1} Monat(e)", "RetryAfter:Months": "{0} Monat(e)", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/el.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/el.json similarity index 79% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/el.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/el.json index f5d5ba20b7..53359d6fa8 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/el.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/el.json @@ -1,7 +1,7 @@ { "culture": "el", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Υπέρβαση ορίου ρυθμού λειτουργίας. Μπορείτε να δοκιμάσετε ξανά μετά από {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Υπέρβαση ορίου ρυθμού λειτουργίας. Μπορείτε να δοκιμάσετε ξανά μετά από {RetryAfter}.", "RetryAfter:Years": "{0} έτος/η", "RetryAfter:YearsAndMonths": "{0} έτος/η και {1} μήνας/ες", "RetryAfter:Months": "{0} μήνας/ες", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/en-GB.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en-GB.json similarity index 83% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/en-GB.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en-GB.json index 4dad40dd1a..de3b1de3a3 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/en-GB.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en-GB.json @@ -1,7 +1,7 @@ { "culture": "en-GB", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Operation rate limit exceeded. You can try again after {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Operation rate limit exceeded. You can try again after {RetryAfter}.", "RetryAfter:Years": "{0} year(s)", "RetryAfter:YearsAndMonths": "{0} year(s) and {1} month(s)", "RetryAfter:Months": "{0} month(s)", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/en.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en.json similarity index 83% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/en.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en.json index a962e3d9c9..0abcff4386 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/en.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/en.json @@ -1,7 +1,7 @@ { "culture": "en", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Operation rate limit exceeded. You can try again after {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Operation rate limit exceeded. You can try again after {RetryAfter}.", "RetryAfter:Years": "{0} year(s)", "RetryAfter:YearsAndMonths": "{0} year(s) and {1} month(s)", "RetryAfter:Months": "{0} month(s)", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/es.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/es.json similarity index 80% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/es.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/es.json index fa5ce16176..299ccd0fa2 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/es.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/es.json @@ -1,7 +1,7 @@ { "culture": "es", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Se ha excedido el límite de tasa de operación. Puede intentarlo de nuevo después de {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Se ha excedido el límite de tasa de operación. Puede intentarlo de nuevo después de {RetryAfter}.", "RetryAfter:Years": "{0} año(s)", "RetryAfter:YearsAndMonths": "{0} año(s) y {1} mes(es)", "RetryAfter:Months": "{0} mes(es)", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fa.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fa.json similarity index 76% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fa.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fa.json index 9bd5fa51c5..09c7f21376 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fa.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fa.json @@ -1,7 +1,7 @@ { "culture": "fa", "texts": { - "Volo.Abp.OperationRateLimit:010001": "محدودیت نرخ عملیات فراتر رفته است. می‌توانید بعد از {RetryAfter} دوباره تلاش کنید.", + "Volo.Abp.OperationRateLimiting:010001": "محدودیت نرخ عملیات فراتر رفته است. می‌توانید بعد از {RetryAfter} دوباره تلاش کنید.", "RetryAfter:Years": "{0} سال", "RetryAfter:YearsAndMonths": "{0} سال و {1} ماه", "RetryAfter:Months": "{0} ماه", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fi.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fi.json similarity index 85% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fi.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fi.json index 91d5a799e2..de379d5989 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fi.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fi.json @@ -1,7 +1,7 @@ { "culture": "fi", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Toiminnon nopeusraja ylitetty. Voit yrittää uudelleen {RetryAfter} kuluttua.", + "Volo.Abp.OperationRateLimiting:010001": "Toiminnon nopeusraja ylitetty. Voit yrittää uudelleen {RetryAfter} kuluttua.", "RetryAfter:Years": "{0} vuosi/vuotta", "RetryAfter:YearsAndMonths": "{0} vuosi/vuotta ja {1} kuukausi/kuukautta", "RetryAfter:Months": "{0} kuukausi/kuukautta", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fr.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fr.json similarity index 81% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fr.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fr.json index ce1b2a5da5..b531b036f0 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/fr.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/fr.json @@ -1,7 +1,7 @@ { "culture": "fr", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Limite de taux d'opération dépassée. Vous pouvez réessayer après {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Limite de taux d'opération dépassée. Vous pouvez réessayer après {RetryAfter}.", "RetryAfter:Years": "{0} an(s)", "RetryAfter:YearsAndMonths": "{0} an(s) et {1} mois", "RetryAfter:Months": "{0} mois", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hi.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hi.json similarity index 78% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hi.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hi.json index c23d01b4e1..6a53a5106e 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hi.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hi.json @@ -1,7 +1,7 @@ { "culture": "hi", "texts": { - "Volo.Abp.OperationRateLimit:010001": "ऑपरेशन दर सीमा पार हो गई। आप {RetryAfter} के बाद पुनः प्रयास कर सकते हैं।", + "Volo.Abp.OperationRateLimiting:010001": "ऑपरेशन दर सीमा पार हो गई। आप {RetryAfter} के बाद पुनः प्रयास कर सकते हैं।", "RetryAfter:Years": "{0} वर्ष", "RetryAfter:YearsAndMonths": "{0} वर्ष और {1} महीना/महीने", "RetryAfter:Months": "{0} महीना/महीने", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hr.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hr.json similarity index 81% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hr.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hr.json index 77a253b33e..d8a0ce4a18 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hr.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hr.json @@ -1,7 +1,7 @@ { "culture": "hr", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Prekoračeno ograničenje brzine operacije. Možete pokušati ponovo nakon {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Prekoračeno ograničenje brzine operacije. Možete pokušati ponovo nakon {RetryAfter}.", "RetryAfter:Years": "{0} godina/e", "RetryAfter:YearsAndMonths": "{0} godina/e i {1} mjesec/i", "RetryAfter:Months": "{0} mjesec/i", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hu.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hu.json similarity index 81% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hu.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hu.json index 30ca0a59a0..b1ece6246a 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/hu.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/hu.json @@ -1,7 +1,7 @@ { "culture": "hu", "texts": { - "Volo.Abp.OperationRateLimit:010001": "A műveleti sebességkorlát túllépve. Újra próbálkozhat {RetryAfter} múlva.", + "Volo.Abp.OperationRateLimiting:010001": "A műveleti sebességkorlát túllépve. Újra próbálkozhat {RetryAfter} múlva.", "RetryAfter:Years": "{0} év", "RetryAfter:YearsAndMonths": "{0} év és {1} hónap", "RetryAfter:Months": "{0} hónap", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/is.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/is.json similarity index 84% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/is.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/is.json index 1331cc4bef..45c6255ee1 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/is.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/is.json @@ -1,7 +1,7 @@ { "culture": "is", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Aðgerðarhraðatakmörk náð. Þú getur reynt aftur eftir {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Aðgerðarhraðatakmörk náð. Þú getur reynt aftur eftir {RetryAfter}.", "RetryAfter:Years": "{0} ár", "RetryAfter:YearsAndMonths": "{0} ár og {1} mánuð(ir)", "RetryAfter:Months": "{0} mánuð(ur/ir)", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/it.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/it.json similarity index 82% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/it.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/it.json index fb550655f2..f93fb278bf 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/it.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/it.json @@ -1,7 +1,7 @@ { "culture": "it", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Limite di frequenza operazione superato. Puoi riprovare dopo {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Limite di frequenza operazione superato. Puoi riprovare dopo {RetryAfter}.", "RetryAfter:Years": "{0} anno/i", "RetryAfter:YearsAndMonths": "{0} anno/i e {1} mese/i", "RetryAfter:Months": "{0} mese/i", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/nl.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/nl.json similarity index 82% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/nl.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/nl.json index 68646ea677..a733537123 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/nl.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/nl.json @@ -1,7 +1,7 @@ { "culture": "nl", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Bewerkingssnelheidslimiet overschreden. U kunt het opnieuw proberen na {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Bewerkingssnelheidslimiet overschreden. U kunt het opnieuw proberen na {RetryAfter}.", "RetryAfter:Years": "{0} jaar", "RetryAfter:YearsAndMonths": "{0} jaar en {1} maand(en)", "RetryAfter:Months": "{0} maand(en)", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/pl-PL.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pl-PL.json similarity index 82% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/pl-PL.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pl-PL.json index 085a20af9d..72d6c905a5 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/pl-PL.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pl-PL.json @@ -1,7 +1,7 @@ { "culture": "pl-PL", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Przekroczono limit częstotliwości operacji. Możesz spróbować ponownie po {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Przekroczono limit częstotliwości operacji. Możesz spróbować ponownie po {RetryAfter}.", "RetryAfter:Years": "{0} rok/lat", "RetryAfter:YearsAndMonths": "{0} rok/lat i {1} miesiąc/miesięcy", "RetryAfter:Months": "{0} miesiąc/miesięcy", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/pt-BR.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pt-BR.json similarity index 81% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/pt-BR.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pt-BR.json index f1d7cd1dfe..412f7f2389 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/pt-BR.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/pt-BR.json @@ -1,7 +1,7 @@ { "culture": "pt-BR", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Limite de taxa de operação excedido. Você pode tentar novamente após {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Limite de taxa de operação excedido. Você pode tentar novamente após {RetryAfter}.", "RetryAfter:Years": "{0} ano(s)", "RetryAfter:YearsAndMonths": "{0} ano(s) e {1} mês/meses", "RetryAfter:Months": "{0} mês/meses", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ro-RO.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ro-RO.json similarity index 82% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ro-RO.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ro-RO.json index 51a7446b4f..cef165fa42 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ro-RO.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ro-RO.json @@ -1,7 +1,7 @@ { "culture": "ro-RO", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Limita ratei de operare a fost depășită. Puteți încerca din nou după {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Limita ratei de operare a fost depășită. Puteți încerca din nou după {RetryAfter}.", "RetryAfter:Years": "{0} an/ani", "RetryAfter:YearsAndMonths": "{0} an/ani și {1} lună/luni", "RetryAfter:Months": "{0} lună/luni", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ru.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ru.json similarity index 81% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ru.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ru.json index fbee7ea360..dc4ddf6db6 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/ru.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/ru.json @@ -1,7 +1,7 @@ { "culture": "ru", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Превышен лимит частоты операций. Вы можете повторить попытку через {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Превышен лимит частоты операций. Вы можете повторить попытку через {RetryAfter}.", "RetryAfter:Years": "{0} год/лет", "RetryAfter:YearsAndMonths": "{0} год/лет и {1} месяц/месяцев", "RetryAfter:Months": "{0} месяц/месяцев", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sk.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sk.json similarity index 83% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sk.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sk.json index 16e1a32403..bd849adb48 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sk.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sk.json @@ -1,7 +1,7 @@ { "culture": "sk", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Prekročený limit rýchlosti operácie. Môžete to skúsiť znova po {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Prekročený limit rýchlosti operácie. Môžete to skúsiť znova po {RetryAfter}.", "RetryAfter:Years": "{0} rok/rokov", "RetryAfter:YearsAndMonths": "{0} rok/rokov a {1} mesiac/mesiacov", "RetryAfter:Months": "{0} mesiac/mesiacov", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sl.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sl.json similarity index 83% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sl.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sl.json index 22bbbf58c2..eb6c54980e 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sl.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sl.json @@ -1,7 +1,7 @@ { "culture": "sl", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Presežena omejitev hitrosti operacije. Poskusite lahko znova čez {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Presežena omejitev hitrosti operacije. Poskusite lahko znova čez {RetryAfter}.", "RetryAfter:Years": "{0} leto/let", "RetryAfter:YearsAndMonths": "{0} leto/let in {1} mesec/mesecev", "RetryAfter:Months": "{0} mesec/mesecev", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sv.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sv.json similarity index 81% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sv.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sv.json index 1aa6d1f6ed..562ba3d586 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/sv.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/sv.json @@ -1,7 +1,7 @@ { "culture": "sv", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Hastighetsgränsen för operationen har överskridits. Du kan försöka igen efter {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Hastighetsgränsen för operationen har överskridits. Du kan försöka igen efter {RetryAfter}.", "RetryAfter:Years": "{0} år", "RetryAfter:YearsAndMonths": "{0} år och {1} månad(er)", "RetryAfter:Months": "{0} månad(er)", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/tr.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/tr.json similarity index 81% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/tr.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/tr.json index 9dfc82dc7b..3ce04aa915 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/tr.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/tr.json @@ -1,7 +1,7 @@ { "culture": "tr", "texts": { - "Volo.Abp.OperationRateLimit:010001": "İşlem hız sınırı aşıldı. {RetryAfter} sonra tekrar deneyebilirsiniz.", + "Volo.Abp.OperationRateLimiting:010001": "İşlem hız sınırı aşıldı. {RetryAfter} sonra tekrar deneyebilirsiniz.", "RetryAfter:Years": "{0} yıl", "RetryAfter:YearsAndMonths": "{0} yıl ve {1} ay", "RetryAfter:Months": "{0} ay", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/vi.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/vi.json similarity index 79% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/vi.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/vi.json index 4744a6c5ce..6b0ee47927 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/vi.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/vi.json @@ -1,7 +1,7 @@ { "culture": "vi", "texts": { - "Volo.Abp.OperationRateLimit:010001": "Đã vượt quá giới hạn tốc độ thao tác. Bạn có thể thử lại sau {RetryAfter}.", + "Volo.Abp.OperationRateLimiting:010001": "Đã vượt quá giới hạn tốc độ thao tác. Bạn có thể thử lại sau {RetryAfter}.", "RetryAfter:Years": "{0} năm", "RetryAfter:YearsAndMonths": "{0} năm và {1} tháng", "RetryAfter:Months": "{0} tháng", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/zh-Hans.json b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/zh-Hans.json similarity index 83% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/zh-Hans.json rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/zh-Hans.json index 1db03def8c..6472587357 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Localization/zh-Hans.json @@ -1,7 +1,7 @@ { "culture": "zh-Hans", "texts": { - "Volo.Abp.OperationRateLimit:010001": "操作频率超出限制。请在 {RetryAfter} 后重试。", + "Volo.Abp.OperationRateLimiting:010001": "操作频率超出限制。请在 {RetryAfter} 后重试。", "RetryAfter:Years": "{0} 年", "RetryAfter:YearsAndMonths": "{0} 年 {1} 个月", "RetryAfter:Months": "{0} 个月", diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DefaultOperationRateLimitPolicyProvider.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/DefaultOperationRateLimitingPolicyProvider.cs similarity index 54% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DefaultOperationRateLimitPolicyProvider.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/DefaultOperationRateLimitingPolicyProvider.cs index 86cec343eb..305863381a 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DefaultOperationRateLimitPolicyProvider.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/DefaultOperationRateLimitingPolicyProvider.cs @@ -4,30 +4,30 @@ using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class DefaultOperationRateLimitPolicyProvider : IOperationRateLimitPolicyProvider, ITransientDependency +public class DefaultOperationRateLimitingPolicyProvider : IOperationRateLimitingPolicyProvider, ITransientDependency { - protected AbpOperationRateLimitOptions Options { get; } + protected AbpOperationRateLimitingOptions Options { get; } - public DefaultOperationRateLimitPolicyProvider(IOptions options) + public DefaultOperationRateLimitingPolicyProvider(IOptions options) { Options = options.Value; } - public virtual Task GetAsync(string policyName) + public virtual Task GetAsync(string policyName) { if (!Options.Policies.TryGetValue(policyName, out var policy)) { throw new AbpException( $"Operation rate limit policy '{policyName}' was not found. " + - $"Make sure to configure it using AbpOperationRateLimitOptions.AddPolicy()."); + $"Make sure to configure it using AbpOperationRateLimitingOptions.AddPolicy()."); } return Task.FromResult(policy); } - public virtual Task> GetListAsync() + public virtual Task> GetListAsync() { return Task.FromResult(Options.Policies.Values.ToList()); } diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/IOperationRateLimitingPolicyProvider.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/IOperationRateLimitingPolicyProvider.cs new file mode 100644 index 0000000000..1f87137a68 --- /dev/null +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/IOperationRateLimitingPolicyProvider.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Volo.Abp.OperationRateLimiting; + +public interface IOperationRateLimitingPolicyProvider +{ + Task GetAsync(string policyName); + + Task> GetListAsync(); +} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPartitionType.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPartitionType.cs similarity index 55% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPartitionType.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPartitionType.cs index 3435f07bd0..e330bd8e46 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPartitionType.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPartitionType.cs @@ -1,6 +1,6 @@ -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public enum OperationRateLimitPartitionType +public enum OperationRateLimitingPartitionType { Parameter, CurrentUser, diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPolicy.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPolicy.cs similarity index 56% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPolicy.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPolicy.cs index cf720ba112..45634e5de1 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPolicy.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPolicy.cs @@ -1,15 +1,15 @@ using System; using System.Collections.Generic; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitPolicy +public class OperationRateLimitingPolicy { public string Name { get; set; } = default!; public string? ErrorCode { get; set; } - public List Rules { get; set; } = new(); + public List Rules { get; set; } = new(); public List CustomRuleTypes { get; set; } = new(); } diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPolicyBuilder.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPolicyBuilder.cs similarity index 68% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPolicyBuilder.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPolicyBuilder.cs index a420b088fb..72cb247614 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitPolicyBuilder.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingPolicyBuilder.cs @@ -2,16 +2,16 @@ using System; using System.Collections.Generic; using System.Linq; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitPolicyBuilder +public class OperationRateLimitingPolicyBuilder { private readonly string _name; private string? _errorCode; - private readonly List _rules = new(); + private readonly List _rules = new(); private readonly List _customRuleTypes = new(); - public OperationRateLimitPolicyBuilder(string name) + public OperationRateLimitingPolicyBuilder(string name) { _name = Check.NotNullOrWhiteSpace(name, nameof(name)); } @@ -19,10 +19,10 @@ public class OperationRateLimitPolicyBuilder /// /// Add a built-in rule. Multiple rules are AND-combined. /// - public OperationRateLimitPolicyBuilder AddRule( - Action configure) + public OperationRateLimitingPolicyBuilder AddRule( + Action configure) { - var builder = new OperationRateLimitRuleBuilder(this); + var builder = new OperationRateLimitingRuleBuilder(this); configure(builder); if (!builder.IsCommitted) { @@ -34,8 +34,8 @@ public class OperationRateLimitPolicyBuilder /// /// Add a custom rule type (resolved from DI). /// - public OperationRateLimitPolicyBuilder AddRule() - where TRule : class, IOperationRateLimitRule + public OperationRateLimitingPolicyBuilder AddRule() + where TRule : class, IOperationRateLimitingRule { _customRuleTypes.Add(typeof(TRule)); return this; @@ -45,10 +45,10 @@ public class OperationRateLimitPolicyBuilder /// Shortcut: single-rule policy with fixed window. /// Returns the rule builder for partition configuration. /// - public OperationRateLimitRuleBuilder WithFixedWindow( + public OperationRateLimitingRuleBuilder WithFixedWindow( TimeSpan duration, int maxCount) { - var builder = new OperationRateLimitRuleBuilder(this); + var builder = new OperationRateLimitingRuleBuilder(this); builder.WithFixedWindow(duration, maxCount); return builder; } @@ -56,18 +56,18 @@ public class OperationRateLimitPolicyBuilder /// /// Set a custom ErrorCode for this policy's exception. /// - public OperationRateLimitPolicyBuilder WithErrorCode(string errorCode) + public OperationRateLimitingPolicyBuilder WithErrorCode(string errorCode) { _errorCode = Check.NotNullOrWhiteSpace(errorCode, nameof(errorCode)); return this; } - internal void AddRuleDefinition(OperationRateLimitRuleDefinition definition) + internal void AddRuleDefinition(OperationRateLimitingRuleDefinition definition) { _rules.Add(definition); } - internal OperationRateLimitPolicy Build() + internal OperationRateLimitingPolicy Build() { if (_rules.Count == 0 && _customRuleTypes.Count == 0) { @@ -77,7 +77,7 @@ public class OperationRateLimitPolicyBuilder } var duplicate = _rules - .Where(r => r.PartitionType != OperationRateLimitPartitionType.Custom) + .Where(r => r.PartitionType != OperationRateLimitingPartitionType.Custom) .GroupBy(r => (r.Duration, r.MaxCount, r.PartitionType, r.IsMultiTenant)) .FirstOrDefault(g => g.Count() > 1); @@ -91,11 +91,11 @@ public class OperationRateLimitPolicyBuilder "Each rule in a policy must have a unique combination of these properties."); } - return new OperationRateLimitPolicy + return new OperationRateLimitingPolicy { Name = _name, ErrorCode = _errorCode, - Rules = new List(_rules), + Rules = new List(_rules), CustomRuleTypes = new List(_customRuleTypes) }; } diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleBuilder.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingRuleBuilder.cs similarity index 64% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleBuilder.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingRuleBuilder.cs index 2908f9a538..82ed356f01 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitRuleBuilder.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingRuleBuilder.cs @@ -1,24 +1,24 @@ using System; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitRuleBuilder +public class OperationRateLimitingRuleBuilder { - private readonly OperationRateLimitPolicyBuilder _policyBuilder; + private readonly OperationRateLimitingPolicyBuilder _policyBuilder; private TimeSpan _duration; private int _maxCount; - private OperationRateLimitPartitionType? _partitionType; - private Func? _customPartitionKeyResolver; + private OperationRateLimitingPartitionType? _partitionType; + private Func? _customPartitionKeyResolver; private bool _isMultiTenant; internal bool IsCommitted { get; private set; } - internal OperationRateLimitRuleBuilder(OperationRateLimitPolicyBuilder policyBuilder) + internal OperationRateLimitingRuleBuilder(OperationRateLimitingPolicyBuilder policyBuilder) { _policyBuilder = policyBuilder; } - public OperationRateLimitRuleBuilder WithFixedWindow( + public OperationRateLimitingRuleBuilder WithFixedWindow( TimeSpan duration, int maxCount) { _duration = duration; @@ -26,7 +26,7 @@ public class OperationRateLimitRuleBuilder return this; } - public OperationRateLimitRuleBuilder WithMultiTenancy() + public OperationRateLimitingRuleBuilder WithMultiTenancy() { _isMultiTenant = true; return this; @@ -35,9 +35,9 @@ public class OperationRateLimitRuleBuilder /// /// Use context.Parameter as partition key. /// - public OperationRateLimitPolicyBuilder PartitionByParameter() + public OperationRateLimitingPolicyBuilder PartitionByParameter() { - _partitionType = OperationRateLimitPartitionType.Parameter; + _partitionType = OperationRateLimitingPartitionType.Parameter; CommitToPolicyBuilder(); return _policyBuilder; } @@ -45,9 +45,9 @@ public class OperationRateLimitRuleBuilder /// /// Auto resolve from ICurrentUser.Id. /// - public OperationRateLimitPolicyBuilder PartitionByCurrentUser() + public OperationRateLimitingPolicyBuilder PartitionByCurrentUser() { - _partitionType = OperationRateLimitPartitionType.CurrentUser; + _partitionType = OperationRateLimitingPartitionType.CurrentUser; CommitToPolicyBuilder(); return _policyBuilder; } @@ -55,9 +55,9 @@ public class OperationRateLimitRuleBuilder /// /// Auto resolve from ICurrentTenant.Id. /// - public OperationRateLimitPolicyBuilder PartitionByCurrentTenant() + public OperationRateLimitingPolicyBuilder PartitionByCurrentTenant() { - _partitionType = OperationRateLimitPartitionType.CurrentTenant; + _partitionType = OperationRateLimitingPartitionType.CurrentTenant; CommitToPolicyBuilder(); return _policyBuilder; } @@ -65,9 +65,9 @@ public class OperationRateLimitRuleBuilder /// /// Auto resolve from IWebClientInfoProvider.ClientIpAddress. /// - public OperationRateLimitPolicyBuilder PartitionByClientIp() + public OperationRateLimitingPolicyBuilder PartitionByClientIp() { - _partitionType = OperationRateLimitPartitionType.ClientIp; + _partitionType = OperationRateLimitingPartitionType.ClientIp; CommitToPolicyBuilder(); return _policyBuilder; } @@ -76,9 +76,9 @@ public class OperationRateLimitRuleBuilder /// Partition by email address. /// Resolves from context.Parameter, falls back to ICurrentUser.Email. /// - public OperationRateLimitPolicyBuilder PartitionByEmail() + public OperationRateLimitingPolicyBuilder PartitionByEmail() { - _partitionType = OperationRateLimitPartitionType.Email; + _partitionType = OperationRateLimitingPartitionType.Email; CommitToPolicyBuilder(); return _policyBuilder; } @@ -87,9 +87,9 @@ public class OperationRateLimitRuleBuilder /// Partition by phone number. /// Resolves from context.Parameter, falls back to ICurrentUser.PhoneNumber. /// - public OperationRateLimitPolicyBuilder PartitionByPhoneNumber() + public OperationRateLimitingPolicyBuilder PartitionByPhoneNumber() { - _partitionType = OperationRateLimitPartitionType.PhoneNumber; + _partitionType = OperationRateLimitingPartitionType.PhoneNumber; CommitToPolicyBuilder(); return _policyBuilder; } @@ -97,10 +97,10 @@ public class OperationRateLimitRuleBuilder /// /// Custom partition key resolver from context. /// - public OperationRateLimitPolicyBuilder PartitionBy( - Func keyResolver) + public OperationRateLimitingPolicyBuilder PartitionBy( + Func keyResolver) { - _partitionType = OperationRateLimitPartitionType.Custom; + _partitionType = OperationRateLimitingPartitionType.Custom; _customPartitionKeyResolver = Check.NotNull(keyResolver, nameof(keyResolver)); CommitToPolicyBuilder(); return _policyBuilder; @@ -112,7 +112,7 @@ public class OperationRateLimitRuleBuilder IsCommitted = true; } - internal OperationRateLimitRuleDefinition Build() + internal OperationRateLimitingRuleDefinition Build() { if (_duration <= TimeSpan.Zero) { @@ -135,14 +135,14 @@ public class OperationRateLimitRuleBuilder "Call PartitionByParameter(), PartitionByCurrentUser(), PartitionByClientIp(), or another PartitionBy*() method."); } - if (_partitionType == OperationRateLimitPartitionType.Custom && _customPartitionKeyResolver == null) + if (_partitionType == OperationRateLimitingPartitionType.Custom && _customPartitionKeyResolver == null) { throw new AbpException( "Custom partition type requires a key resolver. " + "Call PartitionBy(keyResolver) instead of setting partition type directly."); } - return new OperationRateLimitRuleDefinition + return new OperationRateLimitingRuleDefinition { Duration = _duration, MaxCount = _maxCount, diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingRuleDefinition.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingRuleDefinition.cs new file mode 100644 index 0000000000..a3415105d9 --- /dev/null +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Policies/OperationRateLimitingRuleDefinition.cs @@ -0,0 +1,16 @@ +using System; + +namespace Volo.Abp.OperationRateLimiting; + +public class OperationRateLimitingRuleDefinition +{ + public TimeSpan Duration { get; set; } + + public int MaxCount { get; set; } + + public OperationRateLimitingPartitionType PartitionType { get; set; } + + public Func? CustomPartitionKeyResolver { get; set; } + + public bool IsMultiTenant { get; set; } +} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/FixedWindowOperationRateLimitRule.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Rules/FixedWindowOperationRateLimitingRule.cs similarity index 74% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/FixedWindowOperationRateLimitRule.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Rules/FixedWindowOperationRateLimitingRule.cs index 3b46cf3c7b..af072bc8c4 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/FixedWindowOperationRateLimitRule.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Rules/FixedWindowOperationRateLimitingRule.cs @@ -3,25 +3,25 @@ using Volo.Abp.AspNetCore.WebClientInfo; using Volo.Abp.MultiTenancy; using Volo.Abp.Users; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class FixedWindowOperationRateLimitRule : IOperationRateLimitRule +public class FixedWindowOperationRateLimitingRule : IOperationRateLimitingRule { private const string HostTenantKey = "host"; protected string PolicyName { get; } protected int RuleIndex { get; } - protected OperationRateLimitRuleDefinition Definition { get; } - protected IOperationRateLimitStore Store { get; } + protected OperationRateLimitingRuleDefinition Definition { get; } + protected IOperationRateLimitingStore Store { get; } protected ICurrentUser CurrentUser { get; } protected ICurrentTenant CurrentTenant { get; } protected IWebClientInfoProvider WebClientInfoProvider { get; } - public FixedWindowOperationRateLimitRule( + public FixedWindowOperationRateLimitingRule( string policyName, int ruleIndex, - OperationRateLimitRuleDefinition definition, - IOperationRateLimitStore store, + OperationRateLimitingRuleDefinition definition, + IOperationRateLimitingStore store, ICurrentUser currentUser, ICurrentTenant currentTenant, IWebClientInfoProvider webClientInfoProvider) @@ -35,8 +35,8 @@ public class FixedWindowOperationRateLimitRule : IOperationRateLimitRule WebClientInfoProvider = webClientInfoProvider; } - public virtual async Task AcquireAsync( - OperationRateLimitContext context) + public virtual async Task AcquireAsync( + OperationRateLimitingContext context) { var partitionKey = ResolvePartitionKey(context); var storeKey = BuildStoreKey(partitionKey); @@ -45,8 +45,8 @@ public class FixedWindowOperationRateLimitRule : IOperationRateLimitRule return ToRuleResult(storeResult); } - public virtual async Task CheckAsync( - OperationRateLimitContext context) + public virtual async Task CheckAsync( + OperationRateLimitingContext context) { var partitionKey = ResolvePartitionKey(context); var storeKey = BuildStoreKey(partitionKey); @@ -55,47 +55,47 @@ public class FixedWindowOperationRateLimitRule : IOperationRateLimitRule return ToRuleResult(storeResult); } - public virtual async Task ResetAsync(OperationRateLimitContext context) + public virtual async Task ResetAsync(OperationRateLimitingContext context) { var partitionKey = ResolvePartitionKey(context); var storeKey = BuildStoreKey(partitionKey); await Store.ResetAsync(storeKey); } - protected virtual string ResolvePartitionKey(OperationRateLimitContext context) + protected virtual string ResolvePartitionKey(OperationRateLimitingContext context) { return Definition.PartitionType switch { - OperationRateLimitPartitionType.Parameter => + OperationRateLimitingPartitionType.Parameter => context.Parameter ?? throw new AbpException( - $"OperationRateLimitContext.Parameter is required for policy '{PolicyName}' (PartitionByParameter)."), + $"OperationRateLimitingContext.Parameter is required for policy '{PolicyName}' (PartitionByParameter)."), - OperationRateLimitPartitionType.CurrentUser => + OperationRateLimitingPartitionType.CurrentUser => CurrentUser.Id?.ToString() ?? throw new AbpException( $"Current user is not authenticated. Policy '{PolicyName}' requires PartitionByCurrentUser."), - OperationRateLimitPartitionType.CurrentTenant => + OperationRateLimitingPartitionType.CurrentTenant => CurrentTenant.Id?.ToString() ?? HostTenantKey, - OperationRateLimitPartitionType.ClientIp => + OperationRateLimitingPartitionType.ClientIp => WebClientInfoProvider.ClientIpAddress ?? throw new AbpException( $"Client IP address could not be determined. Policy '{PolicyName}' requires PartitionByClientIp. " + "Ensure IWebClientInfoProvider is properly configured."), - OperationRateLimitPartitionType.Email => + OperationRateLimitingPartitionType.Email => context.Parameter ?? CurrentUser.Email ?? throw new AbpException( $"Email is required for policy '{PolicyName}' (PartitionByEmail). Provide it via context.Parameter or ensure the user has an email."), - OperationRateLimitPartitionType.PhoneNumber => + OperationRateLimitingPartitionType.PhoneNumber => context.Parameter ?? CurrentUser.PhoneNumber ?? throw new AbpException( $"Phone number is required for policy '{PolicyName}' (PartitionByPhoneNumber). Provide it via context.Parameter or ensure the user has a phone number."), - OperationRateLimitPartitionType.Custom => + OperationRateLimitingPartitionType.Custom => Definition.CustomPartitionKeyResolver!(context), _ => throw new AbpException($"Unknown partition type: {Definition.PartitionType}") @@ -119,9 +119,9 @@ public class FixedWindowOperationRateLimitRule : IOperationRateLimitRule return $"orl:t:{tenantId}:{PolicyName}:{ruleKey}:{partitionKey}"; } - protected virtual OperationRateLimitRuleResult ToRuleResult(OperationRateLimitStoreResult storeResult) + protected virtual OperationRateLimitingRuleResult ToRuleResult(OperationRateLimitingStoreResult storeResult) { - return new OperationRateLimitRuleResult + return new OperationRateLimitingRuleResult { RuleName = $"{PolicyName}:Rule[{(long)Definition.Duration.TotalSeconds}s,{Definition.MaxCount},{Definition.PartitionType}]", IsAllowed = storeResult.IsAllowed, diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Rules/IOperationRateLimitingRule.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Rules/IOperationRateLimitingRule.cs new file mode 100644 index 0000000000..1bb42a1727 --- /dev/null +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Rules/IOperationRateLimitingRule.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.OperationRateLimiting; + +public interface IOperationRateLimitingRule +{ + Task AcquireAsync(OperationRateLimitingContext context); + + Task CheckAsync(OperationRateLimitingContext context); + + Task ResetAsync(OperationRateLimitingContext context); +} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DistributedCacheOperationRateLimitStore.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/DistributedCacheOperationRateLimitingStore.cs similarity index 75% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DistributedCacheOperationRateLimitStore.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/DistributedCacheOperationRateLimitingStore.cs index 0e86fc31a1..ca64981e3b 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/DistributedCacheOperationRateLimitStore.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/DistributedCacheOperationRateLimitingStore.cs @@ -7,20 +7,20 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.DistributedLocking; using Volo.Abp.Timing; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, ITransientDependency +public class DistributedCacheOperationRateLimitingStore : IOperationRateLimitingStore, ITransientDependency { - protected IDistributedCache Cache { get; } + protected IDistributedCache Cache { get; } protected IClock Clock { get; } protected IAbpDistributedLock DistributedLock { get; } - protected AbpOperationRateLimitOptions Options { get; } + protected AbpOperationRateLimitingOptions Options { get; } - public DistributedCacheOperationRateLimitStore( - IDistributedCache cache, + public DistributedCacheOperationRateLimitingStore( + IDistributedCache cache, IClock clock, IAbpDistributedLock distributedLock, - IOptions options) + IOptions options) { Cache = cache; Clock = clock; @@ -28,12 +28,12 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, Options = options.Value; } - public virtual async Task IncrementAsync( + public virtual async Task IncrementAsync( string key, TimeSpan duration, int maxCount) { if (maxCount <= 0) { - return new OperationRateLimitStoreResult + return new OperationRateLimitingStoreResult { IsAllowed = false, CurrentCount = 0, @@ -43,7 +43,7 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, } await using (var handle = await DistributedLock.TryAcquireAsync( - $"OperationRateLimit:{key}", Options.LockTimeout)) + $"OperationRateLimiting:{key}", Options.LockTimeout)) { if (handle == null) { @@ -57,14 +57,14 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, if (cacheItem == null || now >= cacheItem.WindowStart.Add(duration)) { - cacheItem = new OperationRateLimitCacheItem { Count = 1, WindowStart = now }; + cacheItem = new OperationRateLimitingCacheItem { Count = 1, WindowStart = now }; await Cache.SetAsync(key, cacheItem, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = duration }); - return new OperationRateLimitStoreResult + return new OperationRateLimitingStoreResult { IsAllowed = true, CurrentCount = 1, @@ -75,7 +75,7 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, if (cacheItem.Count >= maxCount) { var retryAfter = cacheItem.WindowStart.Add(duration) - now; - return new OperationRateLimitStoreResult + return new OperationRateLimitingStoreResult { IsAllowed = false, CurrentCount = cacheItem.Count, @@ -92,7 +92,7 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, AbsoluteExpirationRelativeToNow = expiration > TimeSpan.Zero ? expiration : duration }); - return new OperationRateLimitStoreResult + return new OperationRateLimitingStoreResult { IsAllowed = true, CurrentCount = cacheItem.Count, @@ -101,12 +101,12 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, } } - public virtual async Task GetAsync( + public virtual async Task GetAsync( string key, TimeSpan duration, int maxCount) { if (maxCount <= 0) { - return new OperationRateLimitStoreResult + return new OperationRateLimitingStoreResult { IsAllowed = false, CurrentCount = 0, @@ -120,7 +120,7 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, if (cacheItem == null || now >= cacheItem.WindowStart.Add(duration)) { - return new OperationRateLimitStoreResult + return new OperationRateLimitingStoreResult { IsAllowed = true, CurrentCount = 0, @@ -131,7 +131,7 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, if (cacheItem.Count >= maxCount) { var retryAfter = cacheItem.WindowStart.Add(duration) - now; - return new OperationRateLimitStoreResult + return new OperationRateLimitingStoreResult { IsAllowed = false, CurrentCount = cacheItem.Count, @@ -140,7 +140,7 @@ public class DistributedCacheOperationRateLimitStore : IOperationRateLimitStore, }; } - return new OperationRateLimitStoreResult + return new OperationRateLimitingStoreResult { IsAllowed = true, CurrentCount = cacheItem.Count, diff --git a/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/IOperationRateLimitingStore.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/IOperationRateLimitingStore.cs new file mode 100644 index 0000000000..049fa35b0c --- /dev/null +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/IOperationRateLimitingStore.cs @@ -0,0 +1,13 @@ +using System; +using System.Threading.Tasks; + +namespace Volo.Abp.OperationRateLimiting; + +public interface IOperationRateLimitingStore +{ + Task IncrementAsync(string key, TimeSpan duration, int maxCount); + + Task GetAsync(string key, TimeSpan duration, int maxCount); + + Task ResetAsync(string key); +} diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitCacheItem.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/OperationRateLimitingCacheItem.cs similarity index 59% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitCacheItem.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/OperationRateLimitingCacheItem.cs index f2ed13b7b1..2d92d8578e 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitCacheItem.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/OperationRateLimitingCacheItem.cs @@ -2,11 +2,11 @@ using System; using Volo.Abp.Caching; using Volo.Abp.MultiTenancy; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -[CacheName("OperationRateLimit")] +[CacheName("OperationRateLimiting")] [IgnoreMultiTenancy] -public class OperationRateLimitCacheItem +public class OperationRateLimitingCacheItem { public int Count { get; set; } diff --git a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitStoreResult.cs b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/OperationRateLimitingStoreResult.cs similarity index 68% rename from framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitStoreResult.cs rename to framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/OperationRateLimitingStoreResult.cs index d67d650298..caa2bd640d 100644 --- a/framework/src/Volo.Abp.OperationRateLimit/Volo/Abp/OperationRateLimit/OperationRateLimitStoreResult.cs +++ b/framework/src/Volo.Abp.OperationRateLimiting/Volo/Abp/OperationRateLimiting/Store/OperationRateLimitingStoreResult.cs @@ -1,8 +1,8 @@ using System; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitStoreResult +public class OperationRateLimitingStoreResult { public bool IsAllowed { get; set; } diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo.Abp.OperationRateLimit.Tests.csproj b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo.Abp.OperationRateLimiting.Tests.csproj similarity index 92% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo.Abp.OperationRateLimit.Tests.csproj rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo.Abp.OperationRateLimiting.Tests.csproj index 5f284a7c3b..a9d2d9ee36 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo.Abp.OperationRateLimit.Tests.csproj +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo.Abp.OperationRateLimiting.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitException_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingException_Tests.cs similarity index 68% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitException_Tests.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingException_Tests.cs index bcbf6a2300..bf20e1f6a4 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitException_Tests.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingException_Tests.cs @@ -2,14 +2,14 @@ using System; using Shouldly; using Xunit; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class AbpOperationRateLimitException_Tests +public class AbpOperationRateLimitingException_Tests { [Fact] public void Should_Set_HttpStatusCode_To_429() { - var result = new OperationRateLimitResult + var result = new OperationRateLimitingResult { IsAllowed = false, MaxCount = 3, @@ -18,7 +18,7 @@ public class AbpOperationRateLimitException_Tests RetryAfter = TimeSpan.FromMinutes(15) }; - var exception = new AbpOperationRateLimitException("TestPolicy", result); + var exception = new AbpOperationRateLimitingException("TestPolicy", result); exception.HttpStatusCode.ShouldBe(429); } @@ -26,7 +26,7 @@ public class AbpOperationRateLimitException_Tests [Fact] public void Should_Set_Default_ErrorCode() { - var result = new OperationRateLimitResult + var result = new OperationRateLimitingResult { IsAllowed = false, MaxCount = 3, @@ -34,15 +34,15 @@ public class AbpOperationRateLimitException_Tests RemainingCount = 0 }; - var exception = new AbpOperationRateLimitException("TestPolicy", result); + var exception = new AbpOperationRateLimitingException("TestPolicy", result); - exception.Code.ShouldBe(AbpOperationRateLimitErrorCodes.ExceedLimit); + exception.Code.ShouldBe(AbpOperationRateLimitingErrorCodes.ExceedLimit); } [Fact] public void Should_Set_Custom_ErrorCode() { - var result = new OperationRateLimitResult + var result = new OperationRateLimitingResult { IsAllowed = false, MaxCount = 3, @@ -50,7 +50,7 @@ public class AbpOperationRateLimitException_Tests RemainingCount = 0 }; - var exception = new AbpOperationRateLimitException("TestPolicy", result, "App:Custom:Error"); + var exception = new AbpOperationRateLimitingException("TestPolicy", result, "App:Custom:Error"); exception.Code.ShouldBe("App:Custom:Error"); } @@ -58,7 +58,7 @@ public class AbpOperationRateLimitException_Tests [Fact] public void Should_Include_Data_Properties() { - var result = new OperationRateLimitResult + var result = new OperationRateLimitingResult { IsAllowed = false, MaxCount = 3, @@ -68,7 +68,7 @@ public class AbpOperationRateLimitException_Tests WindowDuration = TimeSpan.FromHours(1) }; - var exception = new AbpOperationRateLimitException("TestPolicy", result); + var exception = new AbpOperationRateLimitingException("TestPolicy", result); exception.Data["PolicyName"].ShouldBe("TestPolicy"); exception.Data["MaxCount"].ShouldBe(3); @@ -82,7 +82,7 @@ public class AbpOperationRateLimitException_Tests [Fact] public void Should_Store_PolicyName_And_Result() { - var result = new OperationRateLimitResult + var result = new OperationRateLimitingResult { IsAllowed = false, MaxCount = 5, @@ -91,7 +91,7 @@ public class AbpOperationRateLimitException_Tests RetryAfter = TimeSpan.FromHours(1) }; - var exception = new AbpOperationRateLimitException("MyPolicy", result); + var exception = new AbpOperationRateLimitingException("MyPolicy", result); exception.PolicyName.ShouldBe("MyPolicy"); exception.Result.ShouldBeSameAs(result); diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitPhase2RaceTestModule.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingPhase2RaceTestModule.cs similarity index 69% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitPhase2RaceTestModule.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingPhase2RaceTestModule.cs index f390d6d0e9..c60381c774 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitPhase2RaceTestModule.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingPhase2RaceTestModule.cs @@ -6,18 +6,18 @@ using Volo.Abp.Autofac; using Volo.Abp.ExceptionHandling; using Volo.Abp.Modularity; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; /// /// A mock store that simulates a concurrent race condition: /// - GetAsync always says the quota is available (Phase 1 checks pass). /// - IncrementAsync always says the quota is exhausted (Phase 2 finds another request consumed it). /// -internal class RaceConditionSimulatorStore : IOperationRateLimitStore +internal class RaceConditionSimulatorStore : IOperationRateLimitingStore { - public Task GetAsync(string key, TimeSpan duration, int maxCount) + public Task GetAsync(string key, TimeSpan duration, int maxCount) { - return Task.FromResult(new OperationRateLimitStoreResult + return Task.FromResult(new OperationRateLimitingStoreResult { IsAllowed = true, CurrentCount = 0, @@ -25,10 +25,10 @@ internal class RaceConditionSimulatorStore : IOperationRateLimitStore }); } - public Task IncrementAsync(string key, TimeSpan duration, int maxCount) + public Task IncrementAsync(string key, TimeSpan duration, int maxCount) { // Simulate: between Phase 1 and Phase 2 another concurrent request consumed the last slot. - return Task.FromResult(new OperationRateLimitStoreResult + return Task.FromResult(new OperationRateLimitingStoreResult { IsAllowed = false, CurrentCount = maxCount, @@ -44,19 +44,19 @@ internal class RaceConditionSimulatorStore : IOperationRateLimitStore } [DependsOn( - typeof(AbpOperationRateLimitModule), + typeof(AbpOperationRateLimitingModule), typeof(AbpExceptionHandlingModule), typeof(AbpTestBaseModule), typeof(AbpAutofacModule) )] -public class AbpOperationRateLimitPhase2RaceTestModule : AbpModule +public class AbpOperationRateLimitingPhase2RaceTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.Replace( - ServiceDescriptor.Transient()); + ServiceDescriptor.Transient()); - Configure(options => + Configure(options => { options.AddPolicy("TestRacePolicy", policy => { diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitTestModule.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingTestModule.cs similarity index 97% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitTestModule.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingTestModule.cs index 45cf7320e1..6bee2b7d83 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/AbpOperationRateLimitTestModule.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/AbpOperationRateLimitingTestModule.cs @@ -6,15 +6,15 @@ using Volo.Abp.Autofac; using Volo.Abp.ExceptionHandling; using Volo.Abp.Modularity; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; [DependsOn( - typeof(AbpOperationRateLimitModule), + typeof(AbpOperationRateLimitingModule), typeof(AbpExceptionHandlingModule), typeof(AbpTestBaseModule), typeof(AbpAutofacModule) )] -public class AbpOperationRateLimitTestModule : AbpModule +public class AbpOperationRateLimitingTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { @@ -22,7 +22,7 @@ public class AbpOperationRateLimitTestModule : AbpModule mockWebClientInfoProvider.ClientIpAddress.Returns("127.0.0.1"); context.Services.AddSingleton(mockWebClientInfoProvider); - Configure(options => + Configure(options => { options.AddPolicy("TestSimple", policy => { diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/DistributedCacheOperationRateLimitStore_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/DistributedCacheOperationRateLimitingStore_Tests.cs similarity index 92% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/DistributedCacheOperationRateLimitStore_Tests.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/DistributedCacheOperationRateLimitingStore_Tests.cs index d4748b60e3..aa21159613 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/DistributedCacheOperationRateLimitStore_Tests.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/DistributedCacheOperationRateLimitingStore_Tests.cs @@ -3,15 +3,15 @@ using System.Threading.Tasks; using Shouldly; using Xunit; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class DistributedCacheOperationRateLimitStore_Tests : OperationRateLimitTestBase +public class DistributedCacheOperationRateLimitingStore_Tests : OperationRateLimitingTestBase { - private readonly IOperationRateLimitStore _store; + private readonly IOperationRateLimitingStore _store; - public DistributedCacheOperationRateLimitStore_Tests() + public DistributedCacheOperationRateLimitingStore_Tests() { - _store = GetRequiredService(); + _store = GetRequiredService(); } [Fact] diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitCheckerFixes_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingCheckerFixes_Tests.cs similarity index 82% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitCheckerFixes_Tests.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingCheckerFixes_Tests.cs index 6254ada97f..8d15d2a2b9 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitCheckerFixes_Tests.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingCheckerFixes_Tests.cs @@ -4,19 +4,19 @@ using Shouldly; using Volo.Abp.Testing; using Xunit; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; /// /// Tests for Fix #6: Phase 1 in CheckAsync now checks ALL rules before throwing, /// so RetryAfter is the maximum across all blocking rules and RuleResults is complete. /// -public class OperationRateLimitCheckerPhase1_Tests : OperationRateLimitTestBase +public class OperationRateLimitingCheckerPhase1_Tests : OperationRateLimitingTestBase { - private readonly IOperationRateLimitChecker _checker; + private readonly IOperationRateLimitingChecker _checker; - public OperationRateLimitCheckerPhase1_Tests() + public OperationRateLimitingCheckerPhase1_Tests() { - _checker = GetRequiredService(); + _checker = GetRequiredService(); } [Fact] @@ -25,14 +25,14 @@ public class OperationRateLimitCheckerPhase1_Tests : OperationRateLimitTestBase // TestCompositeMaxRetryAfter: Rule0 (5-min window, max=1), Rule1 (2-hr window, max=1) // Both rules use PartitionByParameter with the same key, so one request exhausts both. var param = $"max-retry-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // First request: both rules go from 0 to 1 (exhausted, since maxCount=1) await _checker.CheckAsync("TestCompositeMaxRetryAfter", context); // Second request: both Rule0 and Rule1 are blocking. // Phase 1 checks all rules → RetryAfter must be the larger one (~2 hours). - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestCompositeMaxRetryAfter", context); }); @@ -46,12 +46,12 @@ public class OperationRateLimitCheckerPhase1_Tests : OperationRateLimitTestBase public async Task Should_Include_All_Rules_In_RuleResults_When_Multiple_Rules_Block() { var param = $"all-rules-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // Exhaust both rules await _checker.CheckAsync("TestCompositeMaxRetryAfter", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestCompositeMaxRetryAfter", context); }); @@ -69,12 +69,12 @@ public class OperationRateLimitCheckerPhase1_Tests : OperationRateLimitTestBase // TestCompositePartialBlock: Rule0 (max=1) blocks, Rule1 (max=100) is still within limit. // RuleResults must contain BOTH rules so callers get the full picture. var param = $"partial-block-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // Exhaust only Rule0 (max=1) await _checker.CheckAsync("TestCompositePartialBlock", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestCompositePartialBlock", context); }); @@ -102,8 +102,8 @@ public class OperationRateLimitCheckerPhase1_Tests : OperationRateLimitTestBase /// Uses a mock store that simulates a concurrent race condition: /// GetAsync (Phase 1) always reports quota available, but IncrementAsync (Phase 2) returns denied. /// -public class OperationRateLimitCheckerPhase2Race_Tests - : AbpIntegratedTest +public class OperationRateLimitingCheckerPhase2Race_Tests + : AbpIntegratedTest { protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) { @@ -116,10 +116,10 @@ public class OperationRateLimitCheckerPhase2Race_Tests // The mock store always returns IsAllowed=true in GetAsync (Phase 1 passes) // but always returns IsAllowed=false in IncrementAsync (simulates concurrent exhaustion). // Before Fix #1, CheckAsync would silently succeed. After the fix it must throw. - var checker = GetRequiredService(); - var context = new OperationRateLimitContext { Parameter = "race-test" }; + var checker = GetRequiredService(); + var context = new OperationRateLimitingContext { Parameter = "race-test" }; - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await checker.CheckAsync("TestRacePolicy", context); }); @@ -134,8 +134,8 @@ public class OperationRateLimitCheckerPhase2Race_Tests { // IsAllowedAsync is read-only and does not call IncrementAsync, // so it should not be affected by the mock store's deny-on-increment behavior. - var checker = GetRequiredService(); - var context = new OperationRateLimitContext { Parameter = "is-allowed-race" }; + var checker = GetRequiredService(); + var context = new OperationRateLimitingContext { Parameter = "is-allowed-race" }; // Should return true because GetAsync always returns allowed in the mock store var allowed = await checker.IsAllowedAsync("TestRacePolicy", context); diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitChecker_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingChecker_Tests.cs similarity index 84% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitChecker_Tests.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingChecker_Tests.cs index 347aea5f37..23dcfb6799 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitChecker_Tests.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingChecker_Tests.cs @@ -6,21 +6,21 @@ using Shouldly; using Volo.Abp.Security.Claims; using Xunit; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase +public class OperationRateLimitingChecker_Tests : OperationRateLimitingTestBase { - private readonly IOperationRateLimitChecker _checker; + private readonly IOperationRateLimitingChecker _checker; - public OperationRateLimitChecker_Tests() + public OperationRateLimitingChecker_Tests() { - _checker = GetRequiredService(); + _checker = GetRequiredService(); } [Fact] public async Task Should_Allow_Within_Limit() { - var context = new OperationRateLimitContext { Parameter = "test@example.com" }; + var context = new OperationRateLimitingContext { Parameter = "test@example.com" }; // Should not throw for 3 requests (max is 3) await _checker.CheckAsync("TestSimple", context); @@ -32,13 +32,13 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Reject_When_Exceeded() { var param = $"exceed-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestSimple", context); }); @@ -46,14 +46,14 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase exception.PolicyName.ShouldBe("TestSimple"); exception.Result.IsAllowed.ShouldBeFalse(); exception.HttpStatusCode.ShouldBe(429); - exception.Code.ShouldBe(AbpOperationRateLimitErrorCodes.ExceedLimit); + exception.Code.ShouldBe(AbpOperationRateLimitingErrorCodes.ExceedLimit); } [Fact] public async Task Should_Return_Correct_RemainingCount() { var param = $"remaining-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; var status = await _checker.GetStatusAsync("TestSimple", context); status.IsAllowed.ShouldBeTrue(); @@ -73,13 +73,13 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Return_Correct_RetryAfter() { var param = $"retry-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestSimple", context); }); @@ -100,8 +100,8 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase using (principalAccessor.Change(claimsPrincipal)) { - var checker = scope.ServiceProvider.GetRequiredService(); - var context = new OperationRateLimitContext { Parameter = $"composite-{Guid.NewGuid()}" }; + var checker = scope.ServiceProvider.GetRequiredService(); + var context = new OperationRateLimitingContext { Parameter = $"composite-{Guid.NewGuid()}" }; // Should pass: both rules within limits await checker.CheckAsync("TestComposite", context); @@ -123,16 +123,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase using (principalAccessor.Change(claimsPrincipal)) { - var checker = scope.ServiceProvider.GetRequiredService(); + var checker = scope.ServiceProvider.GetRequiredService(); var param = $"composite-reject-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; await checker.CheckAsync("TestComposite", context); await checker.CheckAsync("TestComposite", context); await checker.CheckAsync("TestComposite", context); // 4th request: Rule1 (max 3 per hour by parameter) should fail - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await checker.CheckAsync("TestComposite", context); }); @@ -146,14 +146,14 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Reset_Counter() { var param = $"reset-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); // Should be at limit - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestSimple", context); }); @@ -169,12 +169,12 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Use_Custom_ErrorCode() { var param = $"custom-error-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestCustomErrorCode", context); await _checker.CheckAsync("TestCustomErrorCode", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestCustomErrorCode", context); }); @@ -194,7 +194,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase [Fact] public async Task Should_Skip_When_Disabled() { - var options = GetRequiredService>(); + var options = GetRequiredService>(); var originalValue = options.Value.IsEnabled; try @@ -202,7 +202,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase options.Value.IsEnabled = false; var param = $"disabled-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // Should pass unlimited times for (var i = 0; i < 100; i++) @@ -220,7 +220,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Work_With_IsAllowedAsync() { var param = $"is-allowed-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // IsAllowedAsync does not consume quota (await _checker.IsAllowedAsync("TestSimple", context)).ShouldBeTrue(); @@ -245,8 +245,8 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase var param1 = $"param1-{Guid.NewGuid()}"; var param2 = $"param2-{Guid.NewGuid()}"; - var context1 = new OperationRateLimitContext { Parameter = param1 }; - var context2 = new OperationRateLimitContext { Parameter = param2 }; + var context1 = new OperationRateLimitingContext { Parameter = param1 }; + var context2 = new OperationRateLimitingContext { Parameter = param2 }; // Consume all for param1 await _checker.CheckAsync("TestSimple", context1); @@ -262,7 +262,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Support_ExtraProperties_In_Exception_Data() { var param = $"extra-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext + var context = new OperationRateLimitingContext { Parameter = param, ExtraProperties = @@ -276,7 +276,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestSimple", context); }); @@ -291,13 +291,13 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Partition_By_Email_Via_Parameter() { var email = $"email-param-{Guid.NewGuid()}@example.com"; - var context = new OperationRateLimitContext { Parameter = email }; + var context = new OperationRateLimitingContext { Parameter = email }; await _checker.CheckAsync("TestEmailBased", context); await _checker.CheckAsync("TestEmailBased", context); await _checker.CheckAsync("TestEmailBased", context); - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestEmailBased", context); }); @@ -315,16 +315,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase using (principalAccessor.Change(claimsPrincipal)) { - var checker = scope.ServiceProvider.GetRequiredService(); + var checker = scope.ServiceProvider.GetRequiredService(); // No Parameter set, should fall back to ICurrentUser.Email - var context = new OperationRateLimitContext(); + var context = new OperationRateLimitingContext(); await checker.CheckAsync("TestEmailBased", context); await checker.CheckAsync("TestEmailBased", context); await checker.CheckAsync("TestEmailBased", context); - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await checker.CheckAsync("TestEmailBased", context); }); @@ -336,13 +336,13 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Partition_By_PhoneNumber_Via_Parameter() { var phone = $"phone-param-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = phone }; + var context = new OperationRateLimitingContext { Parameter = phone }; await _checker.CheckAsync("TestPhoneNumberBased", context); await _checker.CheckAsync("TestPhoneNumberBased", context); await _checker.CheckAsync("TestPhoneNumberBased", context); - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestPhoneNumberBased", context); }); @@ -360,16 +360,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase using (principalAccessor.Change(claimsPrincipal)) { - var checker = scope.ServiceProvider.GetRequiredService(); + var checker = scope.ServiceProvider.GetRequiredService(); // No Parameter set, should fall back to ICurrentUser.PhoneNumber - var context = new OperationRateLimitContext(); + var context = new OperationRateLimitingContext(); await checker.CheckAsync("TestPhoneNumberBased", context); await checker.CheckAsync("TestPhoneNumberBased", context); await checker.CheckAsync("TestPhoneNumberBased", context); - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await checker.CheckAsync("TestPhoneNumberBased", context); }); @@ -381,7 +381,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Throw_When_Email_Not_Available() { // No Parameter and no authenticated user - var context = new OperationRateLimitContext(); + var context = new OperationRateLimitingContext(); await Assert.ThrowsAsync(async () => { @@ -403,16 +403,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase using (principalAccessor.Change(claimsPrincipal)) { - var checker = scope.ServiceProvider.GetRequiredService(); + var checker = scope.ServiceProvider.GetRequiredService(); var param = $"no-waste-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // 2 successful requests (Rule1: 2/5, Rule2: 2/2) await checker.CheckAsync("TestCompositeRule2First", context); await checker.CheckAsync("TestCompositeRule2First", context); // 3rd request: Rule2 blocks (2/2 at max) - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await checker.CheckAsync("TestCompositeRule2First", context); }); @@ -442,7 +442,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase // TestCompositeParamIp: Rule1 (Parameter, 5/hour), Rule2 (ClientIp, 3/hour) // IP limit (3) is lower, should trigger first var param = $"param-ip-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // 3 successful requests await _checker.CheckAsync("TestCompositeParamIp", context); @@ -450,7 +450,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase await _checker.CheckAsync("TestCompositeParamIp", context); // 4th: IP rule blocks (3/3) - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestCompositeParamIp", context); }); @@ -475,8 +475,8 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase // but share the same Rule2 (IP) counter var param1 = $"share-ip-1-{Guid.NewGuid()}"; var param2 = $"share-ip-2-{Guid.NewGuid()}"; - var context1 = new OperationRateLimitContext { Parameter = param1 }; - var context2 = new OperationRateLimitContext { Parameter = param2 }; + var context1 = new OperationRateLimitingContext { Parameter = param1 }; + var context2 = new OperationRateLimitingContext { Parameter = param2 }; // 2 requests with param1 await _checker.CheckAsync("TestCompositeParamIp", context1); @@ -486,7 +486,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase await _checker.CheckAsync("TestCompositeParamIp", context2); // 4th request with param2: IP rule blocks (3/3 from combined) - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestCompositeParamIp", context2); }); @@ -516,9 +516,9 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase using (principalAccessor.Change(claimsPrincipal)) { - var checker = scope.ServiceProvider.GetRequiredService(); + var checker = scope.ServiceProvider.GetRequiredService(); var param = $"triple-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // 3 successful requests await checker.CheckAsync("TestCompositeTriple", context); @@ -526,7 +526,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase await checker.CheckAsync("TestCompositeTriple", context); // 4th: IP rule blocks (3/3) - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await checker.CheckAsync("TestCompositeTriple", context); }); @@ -559,9 +559,9 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase using (principalAccessor.Change(claimsPrincipal)) { - var checker = scope.ServiceProvider.GetRequiredService(); + var checker = scope.ServiceProvider.GetRequiredService(); var param = $"triple-nowaste-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // 3 successful requests (all rules increment to 3) await checker.CheckAsync("TestCompositeTriple", context); @@ -571,7 +571,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase // Attempt 3 more blocked requests for (var i = 0; i < 3; i++) { - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await checker.CheckAsync("TestCompositeTriple", context); }); @@ -599,16 +599,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase using (principalAccessor.Change(claimsPrincipal)) { - var checker = scope.ServiceProvider.GetRequiredService(); + var checker = scope.ServiceProvider.GetRequiredService(); var param = $"triple-reset-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // Exhaust IP limit await checker.CheckAsync("TestCompositeTriple", context); await checker.CheckAsync("TestCompositeTriple", context); await checker.CheckAsync("TestCompositeTriple", context); - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await checker.CheckAsync("TestCompositeTriple", context); }); @@ -633,7 +633,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase public async Task Should_Throw_When_PhoneNumber_Not_Available() { // No Parameter and no authenticated user - var context = new OperationRateLimitContext(); + var context = new OperationRateLimitingContext(); await Assert.ThrowsAsync(async () => { @@ -644,9 +644,9 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase [Fact] public async Task Should_Deny_First_Request_When_MaxCount_Is_Zero() { - var context = new OperationRateLimitContext { Parameter = $"ban-{Guid.NewGuid()}" }; + var context = new OperationRateLimitingContext { Parameter = $"ban-{Guid.NewGuid()}" }; - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestBanPolicy", context); }); @@ -659,7 +659,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase [Fact] public async Task Should_IsAllowed_Return_False_When_MaxCount_Is_Zero() { - var context = new OperationRateLimitContext { Parameter = $"ban-allowed-{Guid.NewGuid()}" }; + var context = new OperationRateLimitingContext { Parameter = $"ban-allowed-{Guid.NewGuid()}" }; var allowed = await _checker.IsAllowedAsync("TestBanPolicy", context); allowed.ShouldBeFalse(); @@ -668,7 +668,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase [Fact] public async Task Should_GetStatus_Show_Not_Allowed_When_MaxCount_Is_Zero() { - var context = new OperationRateLimitContext { Parameter = $"ban-status-{Guid.NewGuid()}" }; + var context = new OperationRateLimitingContext { Parameter = $"ban-status-{Guid.NewGuid()}" }; var status = await _checker.GetStatusAsync("TestBanPolicy", context); status.IsAllowed.ShouldBeFalse(); @@ -684,14 +684,14 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase var param1 = $"op1-{Guid.NewGuid()}"; var param2 = $"op2-{Guid.NewGuid()}"; - var ctx1 = new OperationRateLimitContext { Parameter = param1 }; - var ctx2 = new OperationRateLimitContext { Parameter = param2 }; + var ctx1 = new OperationRateLimitingContext { Parameter = param1 }; + var ctx2 = new OperationRateLimitingContext { Parameter = param2 }; // Exhaust param1's quota (max=2) await _checker.CheckAsync("TestCustomResolver", ctx1); await _checker.CheckAsync("TestCustomResolver", ctx1); - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestCustomResolver", ctx1); }); @@ -704,7 +704,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase [Fact] public void Should_Throw_When_Policy_Has_Duplicate_Rules() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); Assert.Throws(() => { diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitFrontendIntegration_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingFrontendIntegration_Tests.cs similarity index 91% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitFrontendIntegration_Tests.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingFrontendIntegration_Tests.cs index 48a68b876e..6566bbccdb 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitFrontendIntegration_Tests.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingFrontendIntegration_Tests.cs @@ -6,19 +6,19 @@ using Volo.Abp.AspNetCore.ExceptionHandling; using Volo.Abp.Localization; using Xunit; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTestBase +public class OperationRateLimitingFrontendIntegration_Tests : OperationRateLimitingTestBase { - private readonly IOperationRateLimitChecker _checker; + private readonly IOperationRateLimitingChecker _checker; private readonly IExceptionToErrorInfoConverter _errorInfoConverter; - private readonly IOperationRateLimitFormatter _formatter; + private readonly IOperationRateLimitingFormatter _formatter; - public OperationRateLimitFrontendIntegration_Tests() + public OperationRateLimitingFrontendIntegration_Tests() { - _checker = GetRequiredService(); + _checker = GetRequiredService(); _errorInfoConverter = GetRequiredService(); - _formatter = GetRequiredService(); + _formatter = GetRequiredService(); } [Fact] @@ -27,13 +27,13 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes using (CultureHelper.Use("en")) { var param = $"frontend-en-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestSimple", context); }); @@ -52,13 +52,13 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes using (CultureHelper.Use("zh-Hans")) { var param = $"frontend-zh-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestSimple", context); }); @@ -75,7 +75,7 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes public async Task ErrorInfo_Should_Include_Structured_Data_For_Frontend() { var param = $"frontend-data-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext + var context = new OperationRateLimitingContext { Parameter = param, ExtraProperties = @@ -88,7 +88,7 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes await _checker.CheckAsync("TestSimple", context); await _checker.CheckAsync("TestSimple", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestSimple", context); }); @@ -96,7 +96,7 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes var errorInfo = _errorInfoConverter.Convert(exception); // Frontend receives error.code - errorInfo.Code.ShouldBe(AbpOperationRateLimitErrorCodes.ExceedLimit); + errorInfo.Code.ShouldBe(AbpOperationRateLimitingErrorCodes.ExceedLimit); // Frontend receives error.data for countdown timer and UI display exception.Data["PolicyName"].ShouldBe("TestSimple"); @@ -144,7 +144,7 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes public async Task GetStatusAsync_Should_Provide_Countdown_Data_For_Frontend() { var param = $"frontend-status-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // Before any requests: frontend can show "3 remaining" var status = await _checker.GetStatusAsync("TestSimple", context); @@ -180,12 +180,12 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes public async Task Custom_ErrorCode_Should_Appear_In_ErrorInfo() { var param = $"frontend-custom-code-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestCustomErrorCode", context); await _checker.CheckAsync("TestCustomErrorCode", context); - var exception = await Assert.ThrowsAsync(async () => + var exception = await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestCustomErrorCode", context); }); @@ -364,7 +364,7 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes public async Task Reset_Should_Allow_Frontend_To_Resume() { var param = $"frontend-reset-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // Exhaust limit await _checker.CheckAsync("TestSimple", context); @@ -389,7 +389,7 @@ public class OperationRateLimitFrontendIntegration_Tests : OperationRateLimitTes public async Task IsAllowedAsync_Can_Be_Used_For_Frontend_PreCheck() { var param = $"frontend-precheck-{Guid.NewGuid()}"; - var context = new OperationRateLimitContext { Parameter = param }; + var context = new OperationRateLimitingContext { Parameter = param }; // Frontend precheck: button should be enabled (await _checker.IsAllowedAsync("TestSimple", context)).ShouldBeTrue(); diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitMultiTenant_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingMultiTenant_Tests.cs similarity index 75% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitMultiTenant_Tests.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingMultiTenant_Tests.cs index 5ec3ad2ae3..fbd1a17059 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitMultiTenant_Tests.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingMultiTenant_Tests.cs @@ -5,24 +5,24 @@ using Shouldly; using Volo.Abp.MultiTenancy; using Xunit; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; /// /// Verifies per-tenant isolation for tenant-scoped partition types and /// global (cross-tenant) sharing for ClientIp partition type. /// -public class OperationRateLimitMultiTenant_Tests : OperationRateLimitTestBase +public class OperationRateLimitingMultiTenant_Tests : OperationRateLimitingTestBase { private readonly ICurrentTenant _currentTenant; - private readonly IOperationRateLimitChecker _checker; + private readonly IOperationRateLimitingChecker _checker; private static readonly Guid TenantA = Guid.NewGuid(); private static readonly Guid TenantB = Guid.NewGuid(); - public OperationRateLimitMultiTenant_Tests() + public OperationRateLimitingMultiTenant_Tests() { _currentTenant = GetRequiredService(); - _checker = GetRequiredService(); + _checker = GetRequiredService(); } [Fact] @@ -33,12 +33,12 @@ public class OperationRateLimitMultiTenant_Tests : OperationRateLimitTestBase using (_currentTenant.Change(TenantA)) { - var ctx = new OperationRateLimitContext { Parameter = param }; + var ctx = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestMultiTenantByParameter", ctx); await _checker.CheckAsync("TestMultiTenantByParameter", ctx); // Tenant A exhausted (max=2) - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestMultiTenantByParameter", ctx); }); @@ -46,7 +46,7 @@ public class OperationRateLimitMultiTenant_Tests : OperationRateLimitTestBase using (_currentTenant.Change(TenantB)) { - var ctx = new OperationRateLimitContext { Parameter = param }; + var ctx = new OperationRateLimitingContext { Parameter = param }; // Tenant B has its own counter and should still be allowed await _checker.CheckAsync("TestMultiTenantByParameter", ctx); @@ -63,17 +63,17 @@ public class OperationRateLimitMultiTenant_Tests : OperationRateLimitTestBase using (_currentTenant.Change(TenantA)) { - var ctx = new OperationRateLimitContext(); + var ctx = new OperationRateLimitingContext(); await _checker.CheckAsync("TestMultiTenantByClientIp", ctx); await _checker.CheckAsync("TestMultiTenantByClientIp", ctx); } using (_currentTenant.Change(TenantB)) { - var ctx = new OperationRateLimitContext(); + var ctx = new OperationRateLimitingContext(); // Tenant B shares the same IP counter; should be at limit now - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestMultiTenantByClientIp", ctx); }); @@ -87,10 +87,10 @@ public class OperationRateLimitMultiTenant_Tests : OperationRateLimitTestBase var param = $"host-vs-tenant-{Guid.NewGuid()}"; // Host context: exhaust quota - var hostCtx = new OperationRateLimitContext { Parameter = param }; + var hostCtx = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestMultiTenantByParameter", hostCtx); await _checker.CheckAsync("TestMultiTenantByParameter", hostCtx); - await Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await _checker.CheckAsync("TestMultiTenantByParameter", hostCtx); }); @@ -98,7 +98,7 @@ public class OperationRateLimitMultiTenant_Tests : OperationRateLimitTestBase // Tenant A should have its own counter, unaffected by host using (_currentTenant.Change(TenantA)) { - var tenantCtx = new OperationRateLimitContext { Parameter = param }; + var tenantCtx = new OperationRateLimitingContext { Parameter = param }; await _checker.CheckAsync("TestMultiTenantByParameter", tenantCtx); (await _checker.IsAllowedAsync("TestMultiTenantByParameter", tenantCtx)).ShouldBeTrue(); } diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitPolicyBuilder_Tests.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingPolicyBuilder_Tests.cs similarity index 85% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitPolicyBuilder_Tests.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingPolicyBuilder_Tests.cs index 76dac315ae..56347cf53b 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitPolicyBuilder_Tests.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingPolicyBuilder_Tests.cs @@ -2,14 +2,14 @@ using System; using Shouldly; using Xunit; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitPolicyBuilder_Tests +public class OperationRateLimitingPolicyBuilder_Tests { [Fact] public void Should_Build_Simple_Policy() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); options.AddPolicy("TestPolicy", policy => { policy.WithFixedWindow(TimeSpan.FromHours(1), maxCount: 5) @@ -22,14 +22,14 @@ public class OperationRateLimitPolicyBuilder_Tests policy.Rules.Count.ShouldBe(1); policy.Rules[0].Duration.ShouldBe(TimeSpan.FromHours(1)); policy.Rules[0].MaxCount.ShouldBe(5); - policy.Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.Parameter); + policy.Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.Parameter); policy.ErrorCode.ShouldBeNull(); } [Fact] public void Should_Build_Composite_Policy() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); options.AddPolicy("CompositePolicy", policy => { policy.AddRule(rule => rule @@ -45,16 +45,16 @@ public class OperationRateLimitPolicyBuilder_Tests policy.Name.ShouldBe("CompositePolicy"); policy.Rules.Count.ShouldBe(2); - policy.Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.Parameter); + policy.Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.Parameter); policy.Rules[0].MaxCount.ShouldBe(3); - policy.Rules[1].PartitionType.ShouldBe(OperationRateLimitPartitionType.CurrentUser); + policy.Rules[1].PartitionType.ShouldBe(OperationRateLimitingPartitionType.CurrentUser); policy.Rules[1].MaxCount.ShouldBe(10); } [Fact] public void Should_Set_ErrorCode() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); options.AddPolicy("ErrorPolicy", policy => { policy.WithFixedWindow(TimeSpan.FromHours(1), maxCount: 2) @@ -69,7 +69,7 @@ public class OperationRateLimitPolicyBuilder_Tests [Fact] public void Should_Build_Custom_Partition() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); options.AddPolicy("CustomPolicy", policy => { policy.AddRule(rule => rule @@ -80,14 +80,14 @@ public class OperationRateLimitPolicyBuilder_Tests var policy = options.Policies["CustomPolicy"]; policy.Rules.Count.ShouldBe(1); - policy.Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.Custom); + policy.Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.Custom); policy.Rules[0].CustomPartitionKeyResolver.ShouldNotBeNull(); } [Fact] public void Should_Support_All_Partition_Types() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); options.AddPolicy("P1", p => p.WithFixedWindow(TimeSpan.FromHours(1), 1).PartitionByParameter()); options.AddPolicy("P2", p => p.WithFixedWindow(TimeSpan.FromHours(1), 1).PartitionByCurrentUser()); @@ -96,18 +96,18 @@ public class OperationRateLimitPolicyBuilder_Tests options.AddPolicy("P5", p => p.WithFixedWindow(TimeSpan.FromHours(1), 1).PartitionByEmail()); options.AddPolicy("P6", p => p.WithFixedWindow(TimeSpan.FromHours(1), 1).PartitionByPhoneNumber()); - options.Policies["P1"].Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.Parameter); - options.Policies["P2"].Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.CurrentUser); - options.Policies["P3"].Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.CurrentTenant); - options.Policies["P4"].Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.ClientIp); - options.Policies["P5"].Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.Email); - options.Policies["P6"].Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.PhoneNumber); + options.Policies["P1"].Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.Parameter); + options.Policies["P2"].Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.CurrentUser); + options.Policies["P3"].Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.CurrentTenant); + options.Policies["P4"].Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.ClientIp); + options.Policies["P5"].Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.Email); + options.Policies["P6"].Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.PhoneNumber); } [Fact] public void Should_Throw_When_Policy_Has_No_Rules() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); var exception = Assert.Throws(() => { @@ -123,7 +123,7 @@ public class OperationRateLimitPolicyBuilder_Tests [Fact] public void Should_Throw_When_WithFixedWindow_Without_PartitionBy() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); var exception = Assert.Throws(() => { @@ -140,7 +140,7 @@ public class OperationRateLimitPolicyBuilder_Tests [Fact] public void Should_Throw_When_AddRule_Without_WithFixedWindow() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); var exception = Assert.Throws(() => { @@ -159,7 +159,7 @@ public class OperationRateLimitPolicyBuilder_Tests [Fact] public void Should_Allow_MaxCount_Zero_For_Ban_Policy() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); // maxCount=0 is a valid "ban" policy - always deny options.AddPolicy("BanPolicy", policy => @@ -175,7 +175,7 @@ public class OperationRateLimitPolicyBuilder_Tests [Fact] public void Should_Throw_When_AddRule_Without_PartitionBy() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); var exception = Assert.Throws(() => { @@ -193,7 +193,7 @@ public class OperationRateLimitPolicyBuilder_Tests [Fact] public void Should_Throw_When_MaxCount_Is_Negative() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); var exception = Assert.Throws(() => { @@ -210,7 +210,7 @@ public class OperationRateLimitPolicyBuilder_Tests [Fact] public void Should_Allow_Same_Rule_With_Different_MultiTenancy() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); // Same Duration/MaxCount/PartitionType but different IsMultiTenant should be allowed options.AddPolicy("MultiTenancyPolicy", policy => @@ -234,7 +234,7 @@ public class OperationRateLimitPolicyBuilder_Tests [Fact] public void Should_Allow_Multiple_Custom_Partition_Rules() { - var options = new AbpOperationRateLimitOptions(); + var options = new AbpOperationRateLimitingOptions(); // Multiple custom partition rules with same Duration/MaxCount should be allowed // because they may use different key resolvers @@ -251,7 +251,7 @@ public class OperationRateLimitPolicyBuilder_Tests var policy = options.Policies["MultiCustomPolicy"]; policy.Rules.Count.ShouldBe(2); - policy.Rules[0].PartitionType.ShouldBe(OperationRateLimitPartitionType.Custom); - policy.Rules[1].PartitionType.ShouldBe(OperationRateLimitPartitionType.Custom); + policy.Rules[0].PartitionType.ShouldBe(OperationRateLimitingPartitionType.Custom); + policy.Rules[1].PartitionType.ShouldBe(OperationRateLimitingPartitionType.Custom); } } diff --git a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitTestBase.cs b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingTestBase.cs similarity index 54% rename from framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitTestBase.cs rename to framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingTestBase.cs index 3139024e9d..4316437e57 100644 --- a/framework/test/Volo.Abp.OperationRateLimit.Tests/Volo/Abp/OperationRateLimit/OperationRateLimitTestBase.cs +++ b/framework/test/Volo.Abp.OperationRateLimiting.Tests/Volo/Abp/OperationRateLimiting/OperationRateLimitingTestBase.cs @@ -1,8 +1,8 @@ using Volo.Abp.Testing; -namespace Volo.Abp.OperationRateLimit; +namespace Volo.Abp.OperationRateLimiting; -public class OperationRateLimitTestBase : AbpIntegratedTest +public class OperationRateLimitingTestBase : AbpIntegratedTest { protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) {