diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index e1baa131a..cc0018760 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -428,7 +428,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.C EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Mvc.Localization", "modules\localization\LINGYUN.Abp.AspNetCore.Mvc.Localization\LINGYUN.Abp.AspNetCore.Mvc.Localization.csproj", "{995DB1CE-A2FC-4468-A521-4207FD587EC5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Account.Templates", "modules\account\LINGYUN.Abp.Account.Templates\LINGYUN.Abp.Account.Templates.csproj", "{AFFBE8EE-1B92-4CDF-8A4F-4000B78A0154}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.Templates", "modules\account\LINGYUN.Abp.Account.Templates\LINGYUN.Abp.Account.Templates.csproj", "{AFFBE8EE-1B92-4CDF-8A4F-4000B78A0154}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "caching", "caching", "{63FCC71F-1CEF-44D3-B95B-23EE58DE8C95}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.CachingManagement.Domain", "modules\caching\LINGYUN.Abp.CachingManagement.Domain\LINGYUN.Abp.CachingManagement.Domain.csproj", "{7D6AE2BB-7DBF-4FC8-A1F5-C004D139B278}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.CachingManagement.StackExchangeRedis", "modules\caching\LINGYUN.Abp.CachingManagement.StackExchangeRedis\LINGYUN.Abp.CachingManagement.StackExchangeRedis.csproj", "{920867B4-4740-4074-9B49-14002B272A63}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.CachingManagement.Application.Contracts", "modules\caching\LINGYUN.Abp.CachingManagement.Application.Contracts\LINGYUN.Abp.CachingManagement.Application.Contracts.csproj", "{3D422738-B111-4DEE-82E1-C3A90F1133B1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.CachingManagement.Application", "modules\caching\LINGYUN.Abp.CachingManagement.Application\LINGYUN.Abp.CachingManagement.Application.csproj", "{08CC528E-98D7-41D9-957D-9F9064645788}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.CachingManagement.HttpApi", "modules\caching\LINGYUN.Abp.CachingManagement.HttpApi\LINGYUN.Abp.CachingManagement.HttpApi.csproj", "{B507D18B-770E-4581-854B-15579AC7074F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1116,6 +1128,26 @@ Global {AFFBE8EE-1B92-4CDF-8A4F-4000B78A0154}.Debug|Any CPU.Build.0 = Debug|Any CPU {AFFBE8EE-1B92-4CDF-8A4F-4000B78A0154}.Release|Any CPU.ActiveCfg = Release|Any CPU {AFFBE8EE-1B92-4CDF-8A4F-4000B78A0154}.Release|Any CPU.Build.0 = Release|Any CPU + {7D6AE2BB-7DBF-4FC8-A1F5-C004D139B278}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D6AE2BB-7DBF-4FC8-A1F5-C004D139B278}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D6AE2BB-7DBF-4FC8-A1F5-C004D139B278}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D6AE2BB-7DBF-4FC8-A1F5-C004D139B278}.Release|Any CPU.Build.0 = Release|Any CPU + {920867B4-4740-4074-9B49-14002B272A63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {920867B4-4740-4074-9B49-14002B272A63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {920867B4-4740-4074-9B49-14002B272A63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {920867B4-4740-4074-9B49-14002B272A63}.Release|Any CPU.Build.0 = Release|Any CPU + {3D422738-B111-4DEE-82E1-C3A90F1133B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D422738-B111-4DEE-82E1-C3A90F1133B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D422738-B111-4DEE-82E1-C3A90F1133B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D422738-B111-4DEE-82E1-C3A90F1133B1}.Release|Any CPU.Build.0 = Release|Any CPU + {08CC528E-98D7-41D9-957D-9F9064645788}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08CC528E-98D7-41D9-957D-9F9064645788}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08CC528E-98D7-41D9-957D-9F9064645788}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08CC528E-98D7-41D9-957D-9F9064645788}.Release|Any CPU.Build.0 = Release|Any CPU + {B507D18B-770E-4581-854B-15579AC7074F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B507D18B-770E-4581-854B-15579AC7074F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B507D18B-770E-4581-854B-15579AC7074F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B507D18B-770E-4581-854B-15579AC7074F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1326,6 +1358,12 @@ Global {0CE035CF-2D8A-4559-93EC-ADBEC4237C61} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {995DB1CE-A2FC-4468-A521-4207FD587EC5} = {90E88EAC-4291-4406-8D88-EFDF61B11292} {AFFBE8EE-1B92-4CDF-8A4F-4000B78A0154} = {9E72FEB9-A626-4312-892B-CDD043879758} + {63FCC71F-1CEF-44D3-B95B-23EE58DE8C95} = {C5CAD011-DF84-4914-939C-0C029DCEF26F} + {7D6AE2BB-7DBF-4FC8-A1F5-C004D139B278} = {63FCC71F-1CEF-44D3-B95B-23EE58DE8C95} + {920867B4-4740-4074-9B49-14002B272A63} = {63FCC71F-1CEF-44D3-B95B-23EE58DE8C95} + {3D422738-B111-4DEE-82E1-C3A90F1133B1} = {63FCC71F-1CEF-44D3-B95B-23EE58DE8C95} + {08CC528E-98D7-41D9-957D-9F9064645788} = {63FCC71F-1CEF-44D3-B95B-23EE58DE8C95} + {B507D18B-770E-4581-854B-15579AC7074F} = {63FCC71F-1CEF-44D3-B95B-23EE58DE8C95} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/FodyWeavers.xml b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/FodyWeavers.xml new file mode 100644 index 000000000..c485a4548 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/FodyWeavers.xsd b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN.Abp.CachingManagement.Application.Contracts.csproj b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN.Abp.CachingManagement.Application.Contracts.csproj new file mode 100644 index 000000000..505c3b03b --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN.Abp.CachingManagement.Application.Contracts.csproj @@ -0,0 +1,24 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/AbpCachingManagementApplicationContractsModule.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/AbpCachingManagementApplicationContractsModule.cs new file mode 100644 index 000000000..f27b54ac8 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/AbpCachingManagementApplicationContractsModule.cs @@ -0,0 +1,29 @@ +using LINGYUN.Abp.CachingManagement.Localization; +using Volo.Abp.Application; +using Volo.Abp.Authorization; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.CachingManagement; + +[DependsOn( + typeof(AbpAuthorizationModule), + typeof(AbpDddApplicationContractsModule))] +public class AbpCachingManagementApplicationContractsModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add() + .AddVirtualJson("/LINGYUN/Abp/CachingManagement/Localization/Resources"); + }); + } +} \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/AbpCachingManagementRemoteServiceConsts.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/AbpCachingManagementRemoteServiceConsts.cs new file mode 100644 index 000000000..76f5849a9 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/AbpCachingManagementRemoteServiceConsts.cs @@ -0,0 +1,8 @@ +namespace LINGYUN.Abp.CachingManagement; + +public class AbpCachingManagementRemoteServiceConsts +{ + public const string RemoteServiceName = "CachingManagement"; + + public const string ModuleName = "caching-management"; +} \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheKeyInput.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheKeyInput.cs new file mode 100644 index 000000000..6e0c75ad4 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheKeyInput.cs @@ -0,0 +1,9 @@ +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.CachingManagement; + +public class CacheKeyInput +{ + [Required] + public string Key { get; set; } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheKeysDto.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheKeysDto.cs new file mode 100644 index 000000000..059391f19 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheKeysDto.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace LINGYUN.Abp.CachingManagement; + +public class CacheKeysDto +{ + public string NextMarker { get; set; } + + public List Keys { get; set; } = new List(); +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheRefreshInput.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheRefreshInput.cs new file mode 100644 index 000000000..4c53955e2 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheRefreshInput.cs @@ -0,0 +1,10 @@ +using System; + +namespace LINGYUN.Abp.CachingManagement; + +public class CacheRefreshInput +{ + public string Key { get; set; } + public DateTime? AbsoluteExpiration { get; set; } + public DateTime? SlidingExpiration { get; set; } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheValueDto.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheValueDto.cs new file mode 100644 index 000000000..c514312f2 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/CacheValueDto.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace LINGYUN.Abp.CachingManagement; + +public class CacheValueDto +{ + public string Type { get; set; } + public long Size { get; set; } + public DateTime? Expiration { get; set; } + public IDictionary Values { get; set; } = new Dictionary(); +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/GetCacheKeysInput.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/GetCacheKeysInput.cs new file mode 100644 index 000000000..251207ed4 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/GetCacheKeysInput.cs @@ -0,0 +1,8 @@ +namespace LINGYUN.Abp.CachingManagement; + +public class GetCacheKeysInput +{ + public string Prefix { get; set; } + public string Marker { get; set; } + public string Filter { get; set; } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/ICacheAppService.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/ICacheAppService.cs new file mode 100644 index 000000000..bdc8366f3 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/ICacheAppService.cs @@ -0,0 +1,15 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.CachingManagement; + +public interface ICacheAppService : IApplicationService +{ + Task GetKeysAsync(GetCacheKeysInput input); + + Task GetValueAsync(CacheKeyInput input); + + Task RefreshAsync(CacheRefreshInput input); + + Task RemoveAsync(CacheKeyInput input); +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/CacheResource.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/CacheResource.cs new file mode 100644 index 000000000..a1327835e --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/CacheResource.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.CachingManagement.Localization; + +[LocalizationResourceName("CachingManagement")] +public class CacheResource +{ +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/Resources/en.json b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/Resources/en.json new file mode 100644 index 000000000..fd3e1b580 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/Resources/en.json @@ -0,0 +1,21 @@ +{ + "culture": "en", + "texts": { + "Permission:CachingManagement": "Caching Management", + "Permission:Caches": "Manager Cache", + "Permission:Refresh": "Refresh", + "Permission:Delete": "Delete", + "Caches": "Caches", + "DisplayName:Marker": "Marker", + "DisplayName:NextMarker": "Next Marker", + "DisplayName:Type": "Type", + "DisplayName:Size": "Size", + "DisplayName:Ttl": "Ttl", + "DisplayName:Values": "Values", + "DisplayName:Key": "Key", + "DisplayName:Keys": "Keys", + "DisplayName:AbsoluteExpiration": "Absolute Expiration", + "DisplayName:SlidingExpiration": "Sliding Expiration", + "Abp.CachingManagement:01001": "A cache of Type {Type} does not support viewing key values." + } +} \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..738e83419 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Localization/Resources/zh-Hans.json @@ -0,0 +1,21 @@ +{ + "culture": "zh-Hans", + "texts": { + "Permission:CachingManagement": "缓存管理", + "Permission:Caches": "管理缓存", + "Permission:Refresh": "刷新", + "Permission:Delete": "删除", + "Caches": "缓存列表", + "DisplayName:Marker": "标记", + "DisplayName:NextMarker": "下一个标记", + "DisplayName:Type": "类型", + "DisplayName:Size": "大小", + "DisplayName:Ttl": "存活时间", + "DisplayName:Values": "缓存值", + "DisplayName:Key": "缓存键", + "DisplayName:Keys": "键列表", + "DisplayName:AbsoluteExpiration": "绝对过期时间", + "DisplayName:SlidingExpiration": "滑动过期时间", + "Abp.CachingManagement:01001": "类型为 {Type} 的缓存暂不支持查看键值." + } +} \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Permissions/CachingManagemenPermissionDefinitionProvider.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Permissions/CachingManagemenPermissionDefinitionProvider.cs new file mode 100644 index 000000000..f8f2b07dd --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Permissions/CachingManagemenPermissionDefinitionProvider.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.CachingManagement.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.CachingManagement.Permissions; + +public class CachingManagemenPermissionDefinitionProvider : PermissionDefinitionProvider +{ + public override void Define(IPermissionDefinitionContext context) + { + var cachingManagerGroup = context.AddGroup(CachingManagementPermissionNames.GroupName, L("Permission:CachingManagement")); + + var cacheGroup = cachingManagerGroup.AddPermission(CachingManagementPermissionNames.Cache.Default, L("Permission:Caches")); + cacheGroup.AddChild(CachingManagementPermissionNames.Cache.Refresh, L("Permission:Refresh")); + cacheGroup.AddChild(CachingManagementPermissionNames.Cache.Delete, L("Permission:Delete")); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Permissions/CachingManagementPermissionNames.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Permissions/CachingManagementPermissionNames.cs new file mode 100644 index 000000000..6df464796 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application.Contracts/LINGYUN/Abp/CachingManagement/Permissions/CachingManagementPermissionNames.cs @@ -0,0 +1,20 @@ +using Volo.Abp.Reflection; + +namespace LINGYUN.Abp.CachingManagement.Permissions; + +public static class CachingManagementPermissionNames +{ + public const string GroupName = "AbpCachingManagement"; + + public static class Cache + { + public const string Default = GroupName + ".Cache"; + public const string Refresh = Default + ".Refresh"; + public const string Delete = Default + ".Delete"; + } + + public static string[] GetAll() + { + return ReflectionHelper.GetPublicConstantsRecursively(typeof(CachingManagementPermissionNames)); + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/FodyWeavers.xml b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/FodyWeavers.xml new file mode 100644 index 000000000..c485a4548 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/FodyWeavers.xsd b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN.Abp.CachingManagement.Application.csproj b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN.Abp.CachingManagement.Application.csproj new file mode 100644 index 000000000..71d812e56 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN.Abp.CachingManagement.Application.csproj @@ -0,0 +1,20 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN/Abp/CachingManagement/AbpCachingManagementApplicationModule.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN/Abp/CachingManagement/AbpCachingManagementApplicationModule.cs new file mode 100644 index 000000000..27860dbf4 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN/Abp/CachingManagement/AbpCachingManagementApplicationModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Application; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.CachingManagement; + +[DependsOn( + typeof(AbpCachingManagementApplicationContractsModule), + typeof(AbpDddApplicationModule))] +public class AbpCachingManagementApplicationModule : AbpModule +{ + +} \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN/Abp/CachingManagement/CacheAppService.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN/Abp/CachingManagement/CacheAppService.cs new file mode 100644 index 000000000..36bb89bd8 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Application/LINGYUN/Abp/CachingManagement/CacheAppService.cs @@ -0,0 +1,78 @@ +using LINGYUN.Abp.CachingManagement.Localization; +using LINGYUN.Abp.CachingManagement.Permissions; +using Microsoft.AspNetCore.Authorization; +using System; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.CachingManagement; + +[Authorize(CachingManagementPermissionNames.Cache.Default)] +public class CacheAppService : ApplicationService, ICacheAppService +{ + protected ICacheManager CacheManager { get; } + + public CacheAppService(ICacheManager cacheManager) + { + CacheManager = cacheManager; + + LocalizationResource = typeof(CacheResource); + } + + public async virtual Task GetKeysAsync(GetCacheKeysInput input) + { + var res = await CacheManager.GetKeysAsync( + input.Prefix, + input.Filter, + input.Marker); + + return new CacheKeysDto + { + NextMarker = res.NextMarker, + Keys = res.Keys.ToList(), + }; + } + + public async virtual Task GetValueAsync(CacheKeyInput input) + { + var res = await CacheManager.GetValueAsync(input.Key); + + var value = new CacheValueDto + { + Size = res.Size, + Type = res.Type, + Values = res.Values, + }; + if (res.Ttl.HasValue) + { + value.Expiration = Clock.Now.Add(res.Ttl.Value); + } + + return value; + } + + [Authorize(CachingManagementPermissionNames.Cache.Refresh)] + public async virtual Task RefreshAsync(CacheRefreshInput input) + { + TimeSpan? absExpir = null; + TimeSpan? sldExpr = null; + + if (input.AbsoluteExpiration.HasValue && input.AbsoluteExpiration.Value > Clock.Now) + { + absExpir = input.AbsoluteExpiration.Value - Clock.Now; + } + if (input.SlidingExpiration.HasValue && input.SlidingExpiration.Value > Clock.Now) + { + sldExpr = input.SlidingExpiration.Value - Clock.Now; + } + + await CacheManager.RefreshAsync(input.Key, absExpir, sldExpr); + } + + [Authorize(CachingManagementPermissionNames.Cache.Delete)] + public async virtual Task RemoveAsync(CacheKeyInput input) + { + await CacheManager.RemoveAsync(input.Key); + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/FodyWeavers.xml b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/FodyWeavers.xml new file mode 100644 index 000000000..c485a4548 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/FodyWeavers.xsd b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN.Abp.CachingManagement.Domain.csproj b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN.Abp.CachingManagement.Domain.csproj new file mode 100644 index 000000000..8cbc20edb --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN.Abp.CachingManagement.Domain.csproj @@ -0,0 +1,15 @@ + + + + + + + netstandard2.0 + + + + + + + + diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/AbpCachingManagementDomainModule.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/AbpCachingManagementDomainModule.cs new file mode 100644 index 000000000..7f2de0989 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/AbpCachingManagementDomainModule.cs @@ -0,0 +1,17 @@ +using Volo.Abp.Caching; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.CachingManagement; + +[DependsOn( + typeof(AbpCachingModule))] +public class AbpCachingManagementDomainModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + + }); + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/CacheValueResponse.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/CacheValueResponse.cs new file mode 100644 index 000000000..0103fcb09 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/CacheValueResponse.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace LINGYUN.Abp.CachingManagement; + +public class CacheValueResponse +{ + public string Type { get; } + public long Size { get; } + public TimeSpan? Ttl { get; } + public IDictionary Values { get; } + public CacheValueResponse( + string type, + long size, + IDictionary values, + TimeSpan? ttl = null) + { + Type = type; + Size = size; + Ttl = ttl; + Values = values; + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/CackeKeysResponse.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/CackeKeysResponse.cs new file mode 100644 index 000000000..f3d69cbe8 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/CackeKeysResponse.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace LINGYUN.Abp.CachingManagement; + +public class CackeKeysResponse +{ + public string NextMarker { get; } + + public IEnumerable Keys { get; } + + public CackeKeysResponse( + string nextMarker, + IEnumerable keys) + { + NextMarker = nextMarker; + Keys = keys; + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/GetCacheKeysRequest.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/GetCacheKeysRequest.cs new file mode 100644 index 000000000..f4db4cb93 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/GetCacheKeysRequest.cs @@ -0,0 +1,18 @@ +namespace LINGYUN.Abp.CachingManagement; + +public class GetCacheKeysRequest +{ + public string Prefix { get; } + public string Filter { get; } + public string Marker { get; } + + public GetCacheKeysRequest( + string prefix = null, + string filter = null, + string marker = null) + { + Prefix = prefix; + Filter = filter; + Marker = marker; + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/ICacheManager.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/ICacheManager.cs new file mode 100644 index 000000000..6920e8591 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/ICacheManager.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.CachingManagement; + +public interface ICacheManager +{ + Task GetKeysAsync(GetCacheKeysRequest request, CancellationToken cancellationToken = default); + + Task GetValueAsync(string key, CancellationToken cancellationToken = default); + + Task RefreshAsync(RefreshCacheRequest request, CancellationToken cancellationToken = default); + + Task RemoveAsync(string key, CancellationToken cancellationToken = default); +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/ICacheManagerExtensions.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/ICacheManagerExtensions.cs new file mode 100644 index 000000000..85a257c6a --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/ICacheManagerExtensions.cs @@ -0,0 +1,32 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.CachingManagement; + +public static class ICacheManagerExtensions +{ + public static Task GetKeysAsync( + this ICacheManager cacheManager, + string prefix = null, + string filter = null, + string marker = null, + CancellationToken cancellationToken = default) + { + return cacheManager.GetKeysAsync( + new GetCacheKeysRequest(prefix, filter, marker), + cancellationToken); + } + + public static Task RefreshAsync( + this ICacheManager cacheManager, + string key, + TimeSpan? absExpr = null, + TimeSpan? sldExpr = null, + CancellationToken cancellationToken = default) + { + return cacheManager.RefreshAsync( + new RefreshCacheRequest(key, absExpr, sldExpr), + cancellationToken); + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/RefreshCacheRequest.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/RefreshCacheRequest.cs new file mode 100644 index 000000000..191e57e03 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.Domain/LINGYUN/Abp/CachingManagement/RefreshCacheRequest.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.CachingManagement; + +public class RefreshCacheRequest +{ + [Required] + public string Key { get; } + public TimeSpan? AbsoluteExpiration { get; } + public TimeSpan? SlidingExpiration { get; } + public RefreshCacheRequest( + string key, + TimeSpan? absoluteExpiration = null, + TimeSpan? slidingExpiration = null) + { + Key = key; + AbsoluteExpiration = absoluteExpiration; + SlidingExpiration = slidingExpiration; + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/FodyWeavers.xml b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/FodyWeavers.xml new file mode 100644 index 000000000..c485a4548 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/FodyWeavers.xsd b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN.Abp.CachingManagement.HttpApi.csproj b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN.Abp.CachingManagement.HttpApi.csproj new file mode 100644 index 000000000..f2f88139a --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN.Abp.CachingManagement.HttpApi.csproj @@ -0,0 +1,19 @@ + + + + + + + net6.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN/Abp/CachingManagement/AbpCachingManagementHttpApiModule.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN/Abp/CachingManagement/AbpCachingManagementHttpApiModule.cs new file mode 100644 index 000000000..90421e7b3 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN/Abp/CachingManagement/AbpCachingManagementHttpApiModule.cs @@ -0,0 +1,40 @@ +using LINGYUN.Abp.CachingManagement.Localization; +using Localization.Resources.AbpUi; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.CachingManagement; + +[DependsOn( + typeof(AbpCachingManagementApplicationContractsModule), + typeof(AbpAspNetCoreMvcModule))] +public class AbpCachingManagementHttpApiModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpCachingManagementHttpApiModule).Assembly); + }); + + PreConfigure(options => + { + options.AddAssemblyResource( + typeof(CacheResource), + typeof(AbpCachingManagementApplicationContractsModule).Assembly); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Resources + .Get() + .AddBaseTypes(typeof(AbpUiResource)); + }); + } +} \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN/Abp/CachingManagement/CacheController.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN/Abp/CachingManagement/CacheController.cs new file mode 100644 index 000000000..fabc3b059 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.HttpApi/LINGYUN/Abp/CachingManagement/CacheController.cs @@ -0,0 +1,56 @@ +using LINGYUN.Abp.CachingManagement.Localization; +using LINGYUN.Abp.CachingManagement.Permissions; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.AspNetCore.Mvc; + +namespace LINGYUN.Abp.CachingManagement; + +[Controller] +[Authorize(CachingManagementPermissionNames.Cache.Default)] +[RemoteService(Name = AbpCachingManagementRemoteServiceConsts.RemoteServiceName)] +[Area(AbpCachingManagementRemoteServiceConsts.ModuleName)] +[Route("api/caching-management/cache")] +public class CacheController : AbpControllerBase, ICacheAppService +{ + protected ICacheAppService CacheAppService { get; } + + public CacheController(ICacheAppService cacheAppService) + { + CacheAppService = cacheAppService; + + LocalizationResource = typeof(CacheResource); + } + + [HttpGet] + [Route("keys")] + public virtual Task GetKeysAsync(GetCacheKeysInput input) + { + return CacheAppService.GetKeysAsync(input); + } + + [HttpGet] + [Route("value")] + public virtual Task GetValueAsync(CacheKeyInput input) + { + return CacheAppService.GetValueAsync(input); + } + + [HttpPut] + [Route("refresh")] + [Authorize(CachingManagementPermissionNames.Cache.Refresh)] + public virtual Task RefreshAsync(CacheRefreshInput input) + { + return CacheAppService.RefreshAsync(input); + } + + [HttpDelete] + [Route("remove")] + [Authorize(CachingManagementPermissionNames.Cache.Delete)] + public virtual Task RemoveAsync(CacheKeyInput input) + { + return CacheAppService.RemoveAsync(input); + } +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/FodyWeavers.xml b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/FodyWeavers.xml new file mode 100644 index 000000000..c485a4548 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/FodyWeavers.xsd b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN.Abp.CachingManagement.StackExchangeRedis.csproj b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN.Abp.CachingManagement.StackExchangeRedis.csproj new file mode 100644 index 000000000..23b68cb16 --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN.Abp.CachingManagement.StackExchangeRedis.csproj @@ -0,0 +1,19 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN/Abp/CachingManagement/StackExchangeRedis/AbpCachingManagementStackExchangeRedisModule.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN/Abp/CachingManagement/StackExchangeRedis/AbpCachingManagementStackExchangeRedisModule.cs new file mode 100644 index 000000000..12b03ea2a --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN/Abp/CachingManagement/StackExchangeRedis/AbpCachingManagementStackExchangeRedisModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.CachingManagement.StackExchangeRedis; + +[DependsOn( + typeof(AbpCachingManagementDomainModule), + typeof(AbpCachingStackExchangeRedisModule))] +public class AbpCachingManagementStackExchangeRedisModule : AbpModule +{ +} diff --git a/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN/Abp/CachingManagement/StackExchangeRedis/StackExchangeRedisCacheManager.cs b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN/Abp/CachingManagement/StackExchangeRedis/StackExchangeRedisCacheManager.cs new file mode 100644 index 000000000..407b8280e --- /dev/null +++ b/aspnet-core/modules/caching/LINGYUN.Abp.CachingManagement.StackExchangeRedis/LINGYUN/Abp/CachingManagement/StackExchangeRedis/StackExchangeRedisCacheManager.cs @@ -0,0 +1,228 @@ +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Caching.StackExchangeRedis; +using Microsoft.Extensions.Options; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Caching; +using Volo.Abp.Caching.StackExchangeRedis; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.CachingManagement.StackExchangeRedis; + +[Dependency(ReplaceServices = true)] +public class StackExchangeRedisCacheManager : ICacheManager, ISingletonDependency +{ + private readonly static MethodInfo GetRedisDatabaseMethod; + private readonly static MethodInfo ConnectAsyncMethod; + + protected RedisCacheOptions RedisCacheOptions { get; } + protected AbpDistributedCacheOptions CacheOptions { get; } + protected ICurrentTenant CurrentTenant { get; } + protected IDistributedCache DistributedCache { get; } + protected AbpRedisCache RedisCache => DistributedCache.As(); + + protected IDatabase RedisDatabase => GetRedisDatabase(); + private IDatabase _redisDatabase; + + static StackExchangeRedisCacheManager() + { + var type = typeof(AbpRedisCache); + + ConnectAsyncMethod = type.GetMethod("ConnectAsync", BindingFlags.Instance | BindingFlags.NonPublic); + GetRedisDatabaseMethod = type.GetMethod("GetRedisDatabase", BindingFlags.Instance | BindingFlags.NonPublic); + } + + public StackExchangeRedisCacheManager( + ICurrentTenant currentTenant, + IDistributedCache distributedCache, + IOptions cacheOptions, + IOptions redisCacheOptions) + { + CurrentTenant = currentTenant; + DistributedCache = distributedCache;// distributedCache.As(); + CacheOptions = cacheOptions.Value; + RedisCacheOptions = redisCacheOptions.Value; + } + + public async virtual Task GetKeysAsync(GetCacheKeysRequest request, CancellationToken cancellationToken = default) + { + await ConnectAsync(cancellationToken); + + // 缓存键名规则: InstanceName + (t + TenantId)(CurrentTenant.IsAvailable) + CacheItemName + KeyPrefix + Key + // 缓存键名规则: InstanceName + (c:)(!CurrentTenant.IsAvailable) + CacheItemName + KeyPrefix + Key + + var match = "*"; + // abp* + if (!RedisCacheOptions.InstanceName.IsNullOrWhiteSpace()) + { + match = RedisCacheOptions.InstanceName; + } + // abp*t:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx* + // abp*c:* + if (CurrentTenant.IsAvailable) + { + match += "t:" + CurrentTenant.Id.ToString() + "*"; + } + else + { + match += "c:*"; + } + // abp*t:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx*application* + // abp*c:*application* + if (!CacheOptions.KeyPrefix.IsNullOrWhiteSpace()) + { + match += CacheOptions.KeyPrefix + "*"; + } + + // app*abp*t:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx*application* + // app*abp*c:*application* + if (!request.Prefix.IsNullOrWhiteSpace()) + { + match = request.Prefix + "*" + match; + } + + // if filter is Mailing: + // app*abp*t:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx*application*Mailing* + // app*abp*c:*application*Mailing* + if (!request.Filter.IsNullOrWhiteSpace()) + { + match += request.Filter + "*"; + } + // scan 0 match * count 50000 + // redis有自定义的key排序,由传递的marker来确定下一次检索起始位 + + var args = new object[] { request.Marker ?? "0", "match", match, "count", 50000 }; + + var result = await RedisDatabase.ExecuteAsync("scan", args); + + var results = (RedisResult[])result; + + // 第一个返回结果 下一次检索起始位 0复位 + // 第二个返回结果为key列表 + // https://redis.io/commands/scan/ + return new CackeKeysResponse( + (string)results[0], + (string[])results[1]); + } + + public async virtual Task GetValueAsync(string key, CancellationToken cancellationToken = default) + { + await ConnectAsync(cancellationToken); + + long size = 0; + var values = new Dictionary(); + + // type RedisKey + var type = await RedisDatabase.KeyTypeAsync(key); + // ttl RedisKey + var ttl = await RedisDatabase.KeyTimeToLiveAsync(key); + + switch (type) + { + case RedisType.Hash: + // hlen RedisKey + size = await RedisDatabase.HashLengthAsync(key); + // hscan RedisKey + var hvalues = RedisDatabase.HashScan(key); + foreach (var hvalue in hvalues) + { + if (!hvalue.Name.IsNullOrEmpty) + { + values.Add(hvalue.Name.ToString(), hvalue.Value.IsNullOrEmpty ? "" : hvalue.Value.ToString()); + } + } + break; + case RedisType.String: + // strlen RedisKey + size = await RedisDatabase.StringLengthAsync(key); + // get RedisKey + var svalue = RedisDatabase.StringGet(key); + values.Add("value", svalue.IsNullOrEmpty ? "" : svalue.ToString()); + break; + case RedisType.List: + // llen RedisKey + size = await RedisDatabase.ListLengthAsync(key); + // lrange RedisKey + var lvalues = RedisDatabase.ListRange(key); + for (var lindex = 0; lindex < lvalues.Length; lindex++) + { + if (!lvalues[lindex].IsNullOrEmpty) + { + values.Add($"index.{lindex}", lvalues[lindex].IsNullOrEmpty ? "" : lvalues[lindex].ToString()); + } + } + break; + default: + throw new BusinessException("Abp.CachingManagement:01001") + .WithData("Type", type.ToString()); + } + + return new CacheValueResponse( + type.ToString(), + size, + values, + ttl); + } + + public async virtual Task RefreshAsync(RefreshCacheRequest request, CancellationToken cancellationToken = default) + { + var cacheKey = request.Key; + if (!RedisCacheOptions.InstanceName.IsNullOrWhiteSpace() && cacheKey.StartsWith(RedisCacheOptions.InstanceName)) + { + cacheKey = cacheKey.Substring(RedisCacheOptions.InstanceName.Length); + } + if (request.AbsoluteExpiration.HasValue || request.SlidingExpiration.HasValue) + { + var value = await RedisCache.GetAsync(cacheKey, cancellationToken); + + await RedisCache.SetAsync( + cacheKey, + value, + new DistributedCacheEntryOptions + { + SlidingExpiration = request.SlidingExpiration, + AbsoluteExpirationRelativeToNow = request.AbsoluteExpiration, + }, + cancellationToken); + + return; + } + await RedisCache.RefreshAsync(cacheKey, cancellationToken); + } + + public async virtual Task RemoveAsync(string key, CancellationToken cancellationToken = default) + { + var cacheKey = key; + if (!RedisCacheOptions.InstanceName.IsNullOrWhiteSpace() && cacheKey.StartsWith(RedisCacheOptions.InstanceName)) + { + cacheKey = cacheKey.Substring(RedisCacheOptions.InstanceName.Length); + } + await RedisCache.RemoveAsync(cacheKey, cancellationToken); + } + + protected virtual Task ConnectAsync(CancellationToken token = default) + { + if (_redisDatabase != null) + { + return Task.CompletedTask; + } + + return (Task)ConnectAsyncMethod.Invoke(RedisCache, new object[] { token }); + } + + private IDatabase GetRedisDatabase() + { + if (_redisDatabase == null) + { + _redisDatabase = GetRedisDatabaseMethod.Invoke(RedisCache, null) as IDatabase; + } + + return _redisDatabase; + } +} diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/BackendAdminHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/BackendAdminHttpApiHostModule.cs index 82022a179..15df4069f 100644 --- a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/BackendAdminHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/BackendAdminHttpApiHostModule.cs @@ -3,6 +3,8 @@ using LINGYUN.Abp.AspNetCore.HttpOverrides; using LINGYUN.Abp.AspNetCore.Mvc.Localization; using LINGYUN.Abp.Auditing; using LINGYUN.Abp.AuditLogging.Elasticsearch; +using LINGYUN.Abp.CachingManagement; +using LINGYUN.Abp.CachingManagement.StackExchangeRedis; using LINGYUN.Abp.Data.DbMigrator; using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.ExceptionHandling.Emailing; @@ -24,6 +26,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using System.Linq; using Volo.Abp; using Volo.Abp.AspNetCore.Authentication.JwtBearer; using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; @@ -65,6 +68,9 @@ namespace LY.MicroService.BackendAdmin; typeof(AbpSaasHttpApiModule), typeof(AbpTextTemplatingApplicationModule), typeof(AbpTextTemplatingHttpApiModule), + typeof(AbpCachingManagementApplicationModule), + typeof(AbpCachingManagementHttpApiModule), + typeof(AbpCachingManagementStackExchangeRedisModule), typeof(AbpEntityFrameworkCoreMySQLModule), typeof(AbpIdentityEntityFrameworkCoreModule),// 用户角色权限需要引用包 typeof(AbpIdentityServerEntityFrameworkCoreModule), // 客户端权限需要引用包 diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/LY.MicroService.BackendAdmin.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/LY.MicroService.BackendAdmin.HttpApi.Host.csproj index b81fc267a..76fd3d42c 100644 --- a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/LY.MicroService.BackendAdmin.HttpApi.Host.csproj +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/LY.MicroService.BackendAdmin.HttpApi.Host.csproj @@ -50,6 +50,9 @@ + + +