Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
CacheManagement
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
CacheManagement
Commits
d94c8ddc
Commit
d94c8ddc
authored
Mar 26, 2020
by
Super
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Main features completed.
parent
4d8a5451
Changes
50
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
50 changed files
with
1598 additions
and
129 deletions
+1598
-129
EasyAbp.CacheManagement.sln
EasyAbp.CacheManagement.sln
+9
-0
EasyAbp.CacheManagement.StackExchangeRedis.csproj
...geRedis/EasyAbp.CacheManagement.StackExchangeRedis.csproj
+17
-0
StackExchangeRedisCacheItemManager.cs
...nagement/CacheItems/StackExchangeRedisCacheItemManager.cs
+97
-0
CacheManagementStackExchangeRedisModule.cs
...acheManagement/CacheManagementStackExchangeRedisModule.cs
+14
-0
FodyWeavers.xml
...asyAbp.CacheManagement.StackExchangeRedis/FodyWeavers.xml
+3
-0
FodyWeavers.xsd
...asyAbp.CacheManagement.StackExchangeRedis/FodyWeavers.xsd
+30
-0
CacheManagementWebUnifiedModule.cs
...Management.Web.Unified/CacheManagementWebUnifiedModule.cs
+18
-1
EasyAbp.CacheManagement.Web.Unified.csproj
...nt.Web.Unified/EasyAbp.CacheManagement.Web.Unified.csproj
+4
-1
20200326082826_ImprovedCacheItemEntity.Designer.cs
...ations/20200326082826_ImprovedCacheItemEntity.Designer.cs
+901
-0
20200326082826_ImprovedCacheItemEntity.cs
...fied/Migrations/20200326082826_ImprovedCacheItemEntity.cs
+58
-0
UnifiedDbContextModelSnapshot.cs
...t.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs
+7
-2
appsettings.json
host/EasyAbp.CacheManagement.Web.Unified/appsettings.json
+3
-0
CacheManagementPermissionDefinitionProvider.cs
...horization/CacheManagementPermissionDefinitionProvider.cs
+2
-0
CacheManagementPermissions.cs
...cheManagement/Authorization/CacheManagementPermissions.cs
+1
-0
CacheItemDataDto.cs
...syAbp/CacheManagement/CacheItems/Dtos/CacheItemDataDto.cs
+5
-2
CacheItemDto.cs
...s/EasyAbp/CacheManagement/CacheItems/Dtos/CacheItemDto.cs
+3
-1
ClearCacheItemDto.cs
...yAbp/CacheManagement/CacheItems/Dtos/ClearCacheItemDto.cs
+0
-4
ClearCacheItemResultDto.cs
...acheManagement/CacheItems/Dtos/ClearCacheItemResultDto.cs
+0
-11
ClearSpecificCacheItemDto.cs
...heManagement/CacheItems/Dtos/ClearSpecificCacheItemDto.cs
+13
-0
CreateUpdateCacheItemDto.cs
...cheManagement/CacheItems/Dtos/CreateUpdateCacheItemDto.cs
+5
-2
ICacheItemAppService.cs
...asyAbp/CacheManagement/CacheItems/ICacheItemAppService.cs
+8
-2
CacheItemAppService.cs
...EasyAbp/CacheManagement/CacheItems/CacheItemAppService.cs
+46
-12
cs.json
...yAbp/CacheManagement/Localization/CacheManagement/cs.json
+10
-2
en.json
...yAbp/CacheManagement/Localization/CacheManagement/en.json
+10
-3
pl.json
...yAbp/CacheManagement/Localization/CacheManagement/pl.json
+10
-2
pt-BR.json
...p/CacheManagement/Localization/CacheManagement/pt-BR.json
+10
-2
sl.json
...yAbp/CacheManagement/Localization/CacheManagement/sl.json
+10
-3
tr.json
...yAbp/CacheManagement/Localization/CacheManagement/tr.json
+10
-3
vi.json
...yAbp/CacheManagement/Localization/CacheManagement/vi.json
+10
-2
zh-Hans.json
...CacheManagement/Localization/CacheManagement/zh-Hans.json
+10
-3
zh-Hant.json
...CacheManagement/Localization/CacheManagement/zh-Hant.json
+10
-3
CacheItem.cs
...nt.Domain/EasyAbp/CacheManagement/CacheItems/CacheItem.cs
+7
-3
CacheItemManager.cs
...in/EasyAbp/CacheManagement/CacheItems/CacheItemManager.cs
+0
-48
DistributedCacheProviderInvalidException.cs
...nt/CacheItems/DistributedCacheProviderInvalidException.cs
+9
-0
ICacheItemManager.cs
...n/EasyAbp/CacheManagement/CacheItems/ICacheItemManager.cs
+11
-2
CacheManagementDbContextModelCreatingExtensions.cs
...rkCore/CacheManagementDbContextModelCreatingExtensions.cs
+2
-0
ClearCacheModal.cshtml
...cheManagement/CacheItems/CacheItem/ClearCacheModal.cshtml
+9
-2
ClearCacheModal.cshtml.cs
...Management/CacheItems/CacheItem/ClearCacheModal.cshtml.cs
+11
-3
DetailModal.cshtml
...s/CacheManagement/CacheItems/CacheItem/DetailModal.cshtml
+17
-0
DetailModal.cshtml.cs
...acheManagement/CacheItems/CacheItem/DetailModal.cshtml.cs
+33
-0
Index.cshtml
...b/Pages/CacheManagement/CacheItems/CacheItem/Index.cshtml
+10
-4
KeyList.cshtml
...Pages/CacheManagement/CacheItems/CacheItem/KeyList.cshtml
+45
-0
KeyList.cshtml.cs
...es/CacheManagement/CacheItems/CacheItem/KeyList.cshtml.cs
+26
-0
CacheItemDataViewModel.cs
...CacheItems/CacheItem/ViewModels/CacheItemDataViewModel.cs
+17
-0
ClearCacheItemViewModel.cs
...acheItems/CacheItem/ViewModels/ClearCacheItemViewModel.cs
+4
-3
CreateEditCacheItemViewModel.cs
...tems/CacheItem/ViewModels/CreateEditCacheItemViewModel.cs
+5
-2
index.js
...t.Web/Pages/CacheManagement/CacheItems/CacheItem/index.js
+6
-0
keyList.css
...eb/Pages/CacheManagement/CacheItems/CacheItem/keyList.css
+0
-0
keyList.js
...Web/Pages/CacheManagement/CacheItems/CacheItem/keyList.js
+51
-0
EasyAbp.CacheManagement.Domain.Tests.csproj
....Domain.Tests/EasyAbp.CacheManagement.Domain.Tests.csproj
+1
-1
No files found.
EasyAbp.CacheManagement.sln
View file @
d94c8ddc
...
...
@@ -49,6 +49,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.CacheManagement.Hos
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyAbp.CacheManagement.Web.Unified", "host\EasyAbp.CacheManagement.Web.Unified\EasyAbp.CacheManagement.Web.Unified.csproj", "{3D872C41-E226-45C8-89C1-9D3DBD7C73F2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "driver", "driver", "{7B138737-D818-4F2C-8A56-6264CF62B5B6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.CacheManagement.StackExchangeRedis", "driver\EasyAbp.CacheManagement.StackExchangeRedis\EasyAbp.CacheManagement.StackExchangeRedis.csproj", "{32D77380-7200-4C6D-B2D7-D0CEC1BBD0B2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
...
...
@@ -135,6 +139,10 @@ Global
{3D872C41-E226-45C8-89C1-9D3DBD7C73F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D872C41-E226-45C8-89C1-9D3DBD7C73F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D872C41-E226-45C8-89C1-9D3DBD7C73F2}.Release|Any CPU.Build.0 = Release|Any CPU
{32D77380-7200-4C6D-B2D7-D0CEC1BBD0B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32D77380-7200-4C6D-B2D7-D0CEC1BBD0B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32D77380-7200-4C6D-B2D7-D0CEC1BBD0B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32D77380-7200-4C6D-B2D7-D0CEC1BBD0B2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
...
...
@@ -160,6 +168,7 @@ Global
{690203F4-3CD5-4569-88D9-EE831EEA5F5F} = {E400416D-2895-4512-9D17-90681EEC7E0A}
{F6AC8D4A-EDD7-4514-8E8A-5BCB019864DB} = {E400416D-2895-4512-9D17-90681EEC7E0A}
{3D872C41-E226-45C8-89C1-9D3DBD7C73F2} = {E400416D-2895-4512-9D17-90681EEC7E0A}
{32D77380-7200-4C6D-B2D7-D0CEC1BBD0B2} = {7B138737-D818-4F2C-8A56-6264CF62B5B6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD}
...
...
driver/EasyAbp.CacheManagement.StackExchangeRedis/EasyAbp.CacheManagement.StackExchangeRedis.csproj
0 → 100644
View file @
d94c8ddc
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\EasyAbp.CacheManagement.Domain\EasyAbp.CacheManagement.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.0" />
</ItemGroup>
</Project>
driver/EasyAbp.CacheManagement.StackExchangeRedis/EasyAbp/CacheManagement/CacheItems/StackExchangeRedisCacheItemManager.cs
0 → 100644
View file @
d94c8ddc
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.Extensions.Caching.Distributed
;
using
Microsoft.Extensions.Caching.StackExchangeRedis
;
using
Microsoft.Extensions.Configuration
;
using
StackExchange.Redis
;
using
Volo.Abp.Caching
;
using
Volo.Abp.DependencyInjection
;
using
Volo.Abp.Domain.Services
;
using
Volo.Abp.Threading
;
namespace
EasyAbp.CacheManagement.CacheItems
{
[
Dependency
(
ReplaceServices
=
true
)]
public
class
StackExchangeRedisCacheItemManager
:
DomainService
,
ICacheItemManager
{
private
readonly
IDistributedCache
_distributedCache
;
private
readonly
IDistributedCacheKeyNormalizer
_keyNormalizer
;
private
readonly
ICancellationTokenProvider
_cancellationTokenProvider
;
private
readonly
ConnectionMultiplexer
_connectionMultiplexer
;
public
StackExchangeRedisCacheItemManager
(
IDistributedCache
distributedCache
,
IDistributedCacheKeyNormalizer
keyNormalizer
,
ICancellationTokenProvider
cancellationTokenProvider
,
IConfiguration
configuration
)
{
if
(!(
distributedCache
is
RedisCache
))
{
throw
new
DistributedCacheProviderInvalidException
();
}
_distributedCache
=
distributedCache
;
_keyNormalizer
=
keyNormalizer
;
_cancellationTokenProvider
=
cancellationTokenProvider
;
_connectionMultiplexer
=
ConnectionMultiplexer
.
Connect
(
configuration
[
"Redis:Configuration"
]);
}
public
async
Task
<
IEnumerable
<
string
>>
GetKeysAsync
(
CacheItem
cacheItem
,
CancellationToken
cancellationToken
=
default
)
{
var
normalizedKey
=
GetNormalizedKey
(
cacheItem
,
"*"
);
var
endPoint
=
_connectionMultiplexer
.
GetEndPoints
().
First
();
var
redisKeys
=
_connectionMultiplexer
.
GetServer
(
endPoint
)
.
Keys
(
_connectionMultiplexer
.
GetDatabase
().
Database
,
normalizedKey
);
return
redisKeys
.
Select
(
k
=>
k
.
ToString
());
}
public
async
Task
ClearAllAsync
(
CancellationToken
cancellationToken
=
default
)
{
var
endpoints
=
_connectionMultiplexer
.
GetEndPoints
(
true
);
foreach
(
var
endpoint
in
endpoints
)
{
var
server
=
_connectionMultiplexer
.
GetServer
(
endpoint
);
await
server
.
FlushDatabaseAsync
(
_connectionMultiplexer
.
GetDatabase
().
Database
);
}
}
public
async
Task
ClearAsync
(
CacheItem
cacheItem
,
CancellationToken
cancellationToken
=
default
)
{
var
token
=
_cancellationTokenProvider
.
FallbackToProvider
();
var
keys
=
await
GetKeysAsync
(
cacheItem
,
token
);
foreach
(
var
key
in
keys
)
{
await
_distributedCache
.
RemoveAsync
(
key
,
token
);
}
}
public
async
Task
ClearSpecificAsync
(
CacheItem
cacheItem
,
string
cacheKey
,
CancellationToken
cancellationToken
=
default
)
{
var
key
=
GetNormalizedKey
(
cacheItem
,
cacheKey
);
await
_distributedCache
.
RemoveAsync
(
key
,
_cancellationTokenProvider
.
FallbackToProvider
());
}
public
async
Task
<
string
>
GetValueAsync
(
string
cacheKey
,
CancellationToken
cancellationToken
=
default
)
{
return
await
_distributedCache
.
GetStringAsync
(
cacheKey
,
_cancellationTokenProvider
.
FallbackToProvider
());
}
protected
virtual
string
GetNormalizedKey
(
CacheItem
cacheItem
,
string
cacheKey
)
{
return
_keyNormalizer
.
NormalizeKey
(
new
DistributedCacheKeyNormalizeArgs
(
cacheKey
,
cacheItem
.
CacheName
,
cacheItem
.
IgnoreMultiTenancy
));
}
}
}
\ No newline at end of file
driver/EasyAbp.CacheManagement.StackExchangeRedis/EasyAbp/CacheManagement/CacheManagementStackExchangeRedisModule.cs
0 → 100644
View file @
d94c8ddc
using
Volo.Abp.Modularity
;
namespace
EasyAbp.CacheManagement
{
[
DependsOn
(
typeof
(
CacheManagementDomainModule
)
)]
public
class
CacheManagementStackExchangeRedisModule
:
AbpModule
{
public
override
void
ConfigureServices
(
ServiceConfigurationContext
context
)
{
}
}
}
driver/EasyAbp.CacheManagement.StackExchangeRedis/FodyWeavers.xml
0 → 100644
View file @
d94c8ddc
<Weavers
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"FodyWeavers.xsd"
>
<ConfigureAwait
/>
</Weavers>
\ No newline at end of file
driver/EasyAbp.CacheManagement.StackExchangeRedis/FodyWeavers.xsd
0 → 100644
View file @
d94c8ddc
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns:xs=
"http://www.w3.org/2001/XMLSchema"
>
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element
name=
"Weavers"
>
<xs:complexType>
<xs:all>
<xs:element
name=
"ConfigureAwait"
minOccurs=
"0"
maxOccurs=
"1"
>
<xs:complexType>
<xs:attribute
name=
"ContinueOnCapturedContext"
type=
"xs:boolean"
/>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute
name=
"VerifyAssembly"
type=
"xs:boolean"
>
<xs:annotation>
<xs:documentation>
'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute
name=
"VerifyIgnoreCodes"
type=
"xs:string"
>
<xs:annotation>
<xs:documentation>
A comma-separated list of error codes that can be safely ignored in assembly verification.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute
name=
"GenerateXsd"
type=
"xs:boolean"
>
<xs:annotation>
<xs:documentation>
'false' to turn off automatic generation of the XML Schema file.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
\ No newline at end of file
host/EasyAbp.CacheManagement.Web.Unified/CacheManagementWebUnifiedModule.cs
View file @
d94c8ddc
...
...
@@ -5,7 +5,10 @@ using Microsoft.Extensions.Hosting;
using
EasyAbp.CacheManagement.EntityFrameworkCore
;
using
EasyAbp.CacheManagement.MultiTenancy
;
using
EasyAbp.CacheManagement.Web
;
using
Microsoft.AspNetCore.DataProtection
;
using
Microsoft.AspNetCore.Hosting
;
using
Microsoft.OpenApi.Models
;
using
StackExchange.Redis
;
using
Swashbuckle.AspNetCore.Swagger
;
using
Volo.Abp
;
using
Volo.Abp.Account
;
...
...
@@ -59,7 +62,8 @@ namespace EasyAbp.CacheManagement
typeof
(
AbpTenantManagementApplicationModule
),
typeof
(
AbpTenantManagementEntityFrameworkCoreModule
),
typeof
(
AbpAspNetCoreMvcUiBasicThemeModule
),
typeof
(
AbpAspNetCoreSerilogModule
)
typeof
(
AbpAspNetCoreSerilogModule
),
typeof
(
CacheManagementStackExchangeRedisModule
)
)]
public
class
CacheManagementWebUnifiedModule
:
AbpModule
{
...
...
@@ -108,6 +112,19 @@ namespace EasyAbp.CacheManagement
options
.
IsEnabled
=
MultiTenancyConsts
.
IsEnabled
;
});
context
.
Services
.
AddStackExchangeRedisCache
(
options
=>
{
options
.
Configuration
=
configuration
[
"Redis:Configuration"
];
});
if
(!
hostingEnvironment
.
IsDevelopment
())
{
var
redis
=
ConnectionMultiplexer
.
Connect
(
configuration
[
"Redis:Configuration"
]);
context
.
Services
.
AddDataProtection
()
.
PersistKeysToStackExchangeRedis
(
redis
,
"CacheManagement-Protection-Keys"
);
}
ConfigureConventionalControllers
();
}
...
...
host/EasyAbp.CacheManagement.Web.Unified/EasyAbp.CacheManagement.Web.Unified.csproj
View file @
d94c8ddc
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\common.props" />
...
...
@@ -14,6 +14,8 @@
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="3.1.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="2.3.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic" Version="2.3.0" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="2.3.0" />
...
...
@@ -35,6 +37,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\driver\EasyAbp.CacheManagement.StackExchangeRedis\EasyAbp.CacheManagement.StackExchangeRedis.csproj" />
<ProjectReference Include="..\..\src\EasyAbp.CacheManagement.Application\EasyAbp.CacheManagement.Application.csproj" />
<ProjectReference Include="..\..\src\EasyAbp.CacheManagement.EntityFrameworkCore\EasyAbp.CacheManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\src\EasyAbp.CacheManagement.Web\EasyAbp.CacheManagement.Web.csproj" />
...
...
host/EasyAbp.CacheManagement.Web.Unified/Migrations/20200326082826_ImprovedCacheItemEntity.Designer.cs
0 → 100644
View file @
d94c8ddc
This diff is collapsed.
Click to expand it.
host/EasyAbp.CacheManagement.Web.Unified/Migrations/20200326082826_ImprovedCacheItemEntity.cs
0 → 100644
View file @
d94c8ddc
using
Microsoft.EntityFrameworkCore.Migrations
;
namespace
EasyAbp.CacheManagement.Migrations
{
public
partial
class
ImprovedCacheItemEntity
:
Migration
{
protected
override
void
Up
(
MigrationBuilder
migrationBuilder
)
{
migrationBuilder
.
DropColumn
(
name
:
"FullTypeName"
,
table
:
"CacheManagementCacheItems"
);
migrationBuilder
.
AlterColumn
<
string
>(
name
:
"DisplayName"
,
table
:
"CacheManagementCacheItems"
,
nullable
:
false
,
oldClrType
:
typeof
(
string
),
oldType
:
"nvarchar(max)"
,
oldNullable
:
true
);
migrationBuilder
.
AddColumn
<
string
>(
name
:
"CacheName"
,
table
:
"CacheManagementCacheItems"
,
nullable
:
false
,
defaultValue
:
""
);
migrationBuilder
.
AddColumn
<
bool
>(
name
:
"IgnoreMultiTenancy"
,
table
:
"CacheManagementCacheItems"
,
nullable
:
false
,
defaultValue
:
false
);
}
protected
override
void
Down
(
MigrationBuilder
migrationBuilder
)
{
migrationBuilder
.
DropColumn
(
name
:
"CacheName"
,
table
:
"CacheManagementCacheItems"
);
migrationBuilder
.
DropColumn
(
name
:
"IgnoreMultiTenancy"
,
table
:
"CacheManagementCacheItems"
);
migrationBuilder
.
AlterColumn
<
string
>(
name
:
"DisplayName"
,
table
:
"CacheManagementCacheItems"
,
type
:
"nvarchar(max)"
,
nullable
:
true
,
oldClrType
:
typeof
(
string
));
migrationBuilder
.
AddColumn
<
string
>(
name
:
"FullTypeName"
,
table
:
"CacheManagementCacheItems"
,
type
:
"nvarchar(max)"
,
nullable
:
true
);
}
}
}
host/EasyAbp.CacheManagement.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs
View file @
d94c8ddc
...
...
@@ -25,6 +25,10 @@ namespace EasyAbp.CacheManagement.Migrations
.
ValueGeneratedOnAdd
()
.
HasColumnType
(
"uniqueidentifier"
);
b
.
Property
<
string
>(
"CacheName"
)
.
IsRequired
()
.
HasColumnType
(
"nvarchar(max)"
);
b
.
Property
<
string
>(
"ConcurrencyStamp"
)
.
IsConcurrencyToken
()
.
HasColumnName
(
"ConcurrencyStamp"
)
...
...
@@ -34,14 +38,15 @@ namespace EasyAbp.CacheManagement.Migrations
.
HasColumnType
(
"nvarchar(max)"
);
b
.
Property
<
string
>(
"DisplayName"
)
.
IsRequired
()
.
HasColumnType
(
"nvarchar(max)"
);
b
.
Property
<
string
>(
"ExtraProperties"
)
.
HasColumnName
(
"ExtraProperties"
)
.
HasColumnType
(
"nvarchar(max)"
);
b
.
Property
<
string
>(
"FullTypeName
"
)
.
HasColumnType
(
"
nvarchar(max)
"
);
b
.
Property
<
bool
>(
"IgnoreMultiTenancy
"
)
.
HasColumnType
(
"
bit
"
);
b
.
Property
<
bool
>(
"TenantAllowed"
)
.
HasColumnType
(
"bit"
);
...
...
host/EasyAbp.CacheManagement.Web.Unified/appsettings.json
View file @
d94c8ddc
{
"ConnectionStrings"
:
{
"Default"
:
"Server=(LocalDb)
\\
MSSQLLocalDB;Database=CacheManagement_Unified;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Redis"
:
{
"Configuration"
:
"127.0.0.1"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/Authorization/CacheManagementPermissionDefinitionProvider.cs
View file @
d94c8ddc
using
EasyAbp.CacheManagement.Localization
;
using
Volo.Abp.Authorization.Permissions
;
using
Volo.Abp.Localization
;
using
Volo.Abp.MultiTenancy
;
namespace
EasyAbp.CacheManagement.Authorization
{
...
...
@@ -15,6 +16,7 @@ namespace EasyAbp.CacheManagement.Authorization
cacheItems
.
AddChild
(
CacheManagementPermissions
.
CacheItems
.
Update
,
L
(
"Permission:SetRead"
));
cacheItems
.
AddChild
(
CacheManagementPermissions
.
CacheItems
.
Delete
,
L
(
"Permission:Delete"
));
cacheItems
.
AddChild
(
CacheManagementPermissions
.
CacheItems
.
ClearCache
,
L
(
"Permission:ClearCache"
));
cacheItems
.
AddChild
(
CacheManagementPermissions
.
CacheItems
.
ClearAllCache
,
L
(
"Permission:ClearAllCache"
),
MultiTenancySides
.
Host
);
}
private
static
LocalizableString
L
(
string
name
)
...
...
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/Authorization/CacheManagementPermissions.cs
View file @
d94c8ddc
...
...
@@ -13,6 +13,7 @@ namespace EasyAbp.CacheManagement.Authorization
public
const
string
Update
=
Default
+
".Update"
;
public
const
string
Create
=
Default
+
".Create"
;
public
const
string
ClearCache
=
Default
+
".ClearCache"
;
public
const
string
ClearAllCache
=
Default
+
".ClearAllCache"
;
}
public
static
string
[]
GetAll
()
...
...
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/CacheItems/Dtos/C
learAllCacheItem
Dto.cs
→
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/CacheItems/Dtos/C
acheItemData
Dto.cs
View file @
d94c8ddc
...
...
@@ -3,9 +3,12 @@ using System.ComponentModel;
namespace
EasyAbp.CacheManagement.CacheItems.Dtos
{
public
class
C
learAllCacheItem
Dto
public
class
C
acheItemData
Dto
{
[
DisplayName
(
"CacheItemId"
)]
public
Guid
CacheItemId
{
get
;
set
;
}
public
string
CacheKey
{
get
;
set
;
}
public
string
CacheValue
{
get
;
set
;
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/CacheItems/Dtos/CacheItemDto.cs
View file @
d94c8ddc
...
...
@@ -5,11 +5,13 @@ namespace EasyAbp.CacheManagement.CacheItems.Dtos
{
public
class
CacheItemDto
:
EntityDto
<
Guid
>
{
public
string
FullTyp
eName
{
get
;
set
;
}
public
string
Cach
eName
{
get
;
set
;
}
public
string
DisplayName
{
get
;
set
;
}
public
string
Description
{
get
;
set
;
}
public
bool
IgnoreMultiTenancy
{
get
;
set
;
}
public
bool
TenantAllowed
{
get
;
set
;
}
}
...
...
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/CacheItems/Dtos/ClearCacheItemDto.cs
View file @
d94c8ddc
...
...
@@ -8,9 +8,5 @@ namespace EasyAbp.CacheManagement.CacheItems.Dtos
{
[
DisplayName
(
"CacheItemId"
)]
public
Guid
CacheItemId
{
get
;
set
;
}
[
Required
]
[
DisplayName
(
"CacheItemCacheKey"
)]
public
string
CacheKey
{
get
;
set
;
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/CacheItems/Dtos/ClearCacheItemResultDto.cs
deleted
100644 → 0
View file @
4d8a5451
using
System
;
namespace
EasyAbp.CacheManagement.CacheItems.Dtos
{
public
class
ClearCacheItemResultDto
{
public
Guid
CacheItemId
{
get
;
set
;
}
public
long
Count
{
get
;
set
;
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/CacheItems/Dtos/ClearSpecificCacheItemDto.cs
0 → 100644
View file @
d94c8ddc
using
System
;
using
System.ComponentModel
;
using
System.ComponentModel.DataAnnotations
;
namespace
EasyAbp.CacheManagement.CacheItems.Dtos
{
public
class
ClearSpecificCacheItemDto
:
ClearCacheItemDto
{
[
Required
]
[
DisplayName
(
"CacheItemCacheKey"
)]
public
string
CacheKey
{
get
;
set
;
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/CacheItems/Dtos/CreateUpdateCacheItemDto.cs
View file @
d94c8ddc
...
...
@@ -7,8 +7,8 @@ namespace EasyAbp.CacheManagement.CacheItems.Dtos
public
class
CreateUpdateCacheItemDto
{
[
Required
]
[
DisplayName
(
"CacheItem
FullTyp
eName"
)]
public
string
FullTyp
eName
{
get
;
set
;
}
[
DisplayName
(
"CacheItem
Cach
eName"
)]
public
string
Cach
eName
{
get
;
set
;
}
[
Required
]
[
DisplayName
(
"CacheItemDisplayName"
)]
...
...
@@ -17,6 +17,9 @@ namespace EasyAbp.CacheManagement.CacheItems.Dtos
[
DisplayName
(
"CacheItemDescription"
)]
public
string
Description
{
get
;
set
;
}
[
DisplayName
(
"CacheItemIgnoreMultiTenancy"
)]
public
bool
IgnoreMultiTenancy
{
get
;
set
;
}
[
DisplayName
(
"CacheItemTenantAllowed"
)]
public
bool
TenantAllowed
{
get
;
set
;
}
}
...
...
src/EasyAbp.CacheManagement.Application.Contracts/EasyAbp/CacheManagement/CacheItems/ICacheItemAppService.cs
View file @
d94c8ddc
...
...
@@ -14,8 +14,14 @@ namespace EasyAbp.CacheManagement.CacheItems
CreateUpdateCacheItemDto
,
CreateUpdateCacheItemDto
>
{
Task
<
ClearCacheItemResultDto
>
ClearAsync
(
ClearCacheItemDto
input
);
Task
<
ListResultDto
<
CacheItemDataDto
>>
GetKeysAsync
(
Guid
cacheItemId
);
Task
<
CacheItemDataDto
>
GetDataAsync
(
Guid
cacheItemId
,
string
cacheKey
);
Task
ClearSpecificAsync
(
ClearSpecificCacheItemDto
input
);
Task
ClearAsync
(
ClearCacheItemDto
input
);
Task
<
ClearCacheItemResultDto
>
ClearAllAsync
(
ClearAllCacheItemDto
input
);
Task
ClearAllAsync
(
);
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Application/EasyAbp/CacheManagement/CacheItems/CacheItemAppService.cs
View file @
d94c8ddc
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Threading.Tasks
;
using
EasyAbp.CacheManagement.Authorization
;
using
EasyAbp.CacheManagement.CacheItems.Dtos
;
using
Microsoft.AspNetCore.Authorization
;
using
Volo.Abp.Application.Dtos
;
using
Volo.Abp.Application.Services
;
using
Volo.Abp.Caching
;
using
Volo.Abp.MultiTenancy
;
namespace
EasyAbp.CacheManagement.CacheItems
{
...
...
@@ -30,25 +30,59 @@ namespace EasyAbp.CacheManagement.CacheItems
_repository
=
repository
;
}
[
Authorize
(
CacheManagementPermissions
.
CacheItems
.
Default
)]
public
async
Task
<
ListResultDto
<
CacheItemDataDto
>>
GetKeysAsync
(
Guid
cacheItemId
)
{
var
cacheItem
=
await
_repository
.
GetAsync
(
cacheItemId
);
var
keys
=
await
_cacheItemManager
.
GetKeysAsync
(
cacheItem
);
return
new
ListResultDto
<
CacheItemDataDto
>(
new
List
<
CacheItemDataDto
>(
keys
.
Select
(
key
=>
new
CacheItemDataDto
{
CacheItemId
=
cacheItemId
,
CacheKey
=
key
})));
}
[
Authorize
(
CacheManagementPermissions
.
CacheItems
.
Default
)]
public
async
Task
<
CacheItemDataDto
>
GetDataAsync
(
Guid
cacheItemId
,
string
cacheKey
)
{
var
cacheItem
=
await
_repository
.
GetAsync
(
cacheItemId
);
var
keys
=
await
_cacheItemManager
.
GetKeysAsync
(
cacheItem
);
var
key
=
keys
.
Single
(
key
=>
key
.
Equals
(
cacheKey
));
return
new
CacheItemDataDto
{
CacheItemId
=
cacheItemId
,
CacheKey
=
cacheKey
,
CacheValue
=
await
_cacheItemManager
.
GetValueAsync
(
key
)
};
}
[
Authorize
(
CacheManagementPermissions
.
CacheItems
.
ClearCache
)]
public
async
Task
<
ClearCacheItemResultDto
>
ClearAsync
(
Clear
CacheItemDto
input
)
public
async
Task
ClearSpecificAsync
(
ClearSpecific
CacheItemDto
input
)
{
var
cacheItem
=
await
_repository
.
GetAsync
(
input
.
CacheItemId
);
await
AuthorizationService
.
CheckAsync
(
cacheItem
,
CacheManagementPermissions
.
CacheItems
.
ClearCache
);
await
_cacheItemManager
.
ClearAsync
(
cacheItem
,
input
.
CacheKey
);
return
new
ClearCacheItemResultDto
{
CacheItemId
=
cacheItem
.
Id
,
Count
=
1
};
await
_cacheItemManager
.
ClearSpecificAsync
(
cacheItem
,
input
.
CacheKey
);
}
[
Authorize
(
CacheManagementPermissions
.
CacheItems
.
ClearCache
)]
public
async
Task
ClearAsync
(
ClearCacheItemDto
input
)
{
var
cacheItem
=
await
_repository
.
GetAsync
(
input
.
CacheItemId
);
await
AuthorizationService
.
CheckAsync
(
cacheItem
,
CacheManagementPermissions
.
CacheItems
.
ClearCache
);
await
_cacheItemManager
.
ClearAsync
(
cacheItem
);
}
public
async
Task
<
ClearCacheItemResultDto
>
ClearAllAsync
(
ClearAllCacheItemDto
input
)
[
Authorize
(
CacheManagementPermissions
.
CacheItems
.
ClearAllCache
)]
public
async
Task
ClearAllAsync
()
{
throw
new
NotImplementedException
();
await
_cacheItemManager
.
ClearAllAsync
();
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/cs.json
View file @
d94c8ddc
...
...
@@ -3,13 +3,21 @@
"texts"
:
{
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/en.json
View file @
d94c8ddc
{
"culture"
:
"en"
,
"texts"
:
{
"ManageYourProfile"
:
"Manage your profile"
,
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/pl.json
View file @
d94c8ddc
...
...
@@ -3,13 +3,21 @@
"texts"
:
{
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/pt-BR.json
View file @
d94c8ddc
...
...
@@ -3,13 +3,21 @@
"texts"
:
{
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/sl.json
View file @
d94c8ddc
{
"culture"
:
"sl"
,
"texts"
:
{
"ManageYourProfile"
:
"Upravljajte svojim profilom"
,
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/tr.json
View file @
d94c8ddc
{
"culture"
:
"tr"
,
"texts"
:
{
"ManageYourProfile"
:
"Profil y�netimi"
,
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/vi.json
View file @
d94c8ddc
...
...
@@ -3,13 +3,21 @@
"texts"
:
{
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/zh-Hans.json
View file @
d94c8ddc
{
"culture"
:
"zh-Hans"
,
"texts"
:
{
"ManageYourProfile"
:
"管理个人资料"
,
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain.Shared/EasyAbp/CacheManagement/Localization/CacheManagement/zh-Hant.json
View file @
d94c8ddc
{
"culture"
:
"zh-Hant"
,
"texts"
:
{
"ManageYourProfile"
:
"管理個人資料"
,
"Menu:CacheItem"
:
"MenuCacheItem"
,
"CacheItem"
:
"CacheItem"
,
"CacheItem
FullTypeName"
:
"CacheItemFullTyp
eName"
,
"CacheItem
CacheName"
:
"CacheItemCach
eName"
,
"CacheItemDisplayName"
:
"CacheItemDisplayName"
,
"CacheItemDescription"
:
"CacheItemDescription"
,
"CacheItemIgnoreMultiTenancy"
:
"CacheItemIgnoreMultiTenancy"
,
"CacheItemTenantAllowed"
:
"CacheItemTenantAllowed"
,
"CacheItemCacheKey"
:
"CacheItemCacheKey"
,
"CacheItemCacheValue"
:
"CacheItemCacheValue"
,
"CreateCacheItem"
:
"CreateCacheItem"
,
"EditCacheItem"
:
"EditCacheItem"
,
"CacheItemDeletionConfirmationMessage"
:
"Are you sure to delete the cacheitem {0}?"
,
"SuccessfullyDeleted"
:
"Successfully deleted"
"SuccessfullyDeleted"
:
"Successfully deleted"
,
"SuccessCleared"
:
"Successfully cleared"
,
"ClearCache"
:
"ClearCache"
,
"ClearAllCache"
:
"ClearAllCache"
,
"ClearCacheConfirmationMessage"
:
"Are you sure to clear the cache {0}?"
,
"ClearAllCacheConfirmationMessage"
:
"Are you sure to clear all caches?"
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain/EasyAbp/CacheManagement/CacheItems/CacheItem.cs
View file @
d94c8ddc
...
...
@@ -7,13 +7,15 @@ namespace EasyAbp.CacheManagement.CacheItems
public
class
CacheItem
:
AggregateRoot
<
Guid
>
{
[
NotNull
]
public
virtual
string
FullTyp
eName
{
get
;
protected
set
;
}
public
virtual
string
Cach
eName
{
get
;
protected
set
;
}
[
NotNull
]
public
virtual
string
DisplayName
{
get
;
protected
set
;
}
[
CanBeNull
]
public
virtual
string
Description
{
get
;
protected
set
;
}
public
virtual
bool
IgnoreMultiTenancy
{
get
;
protected
set
;
}
public
virtual
bool
TenantAllowed
{
get
;
protected
set
;
}
...
...
@@ -23,15 +25,17 @@ namespace EasyAbp.CacheManagement.CacheItems
public
CacheItem
(
Guid
id
,
[
NotNull
]
string
fullTyp
eName
,
[
NotNull
]
string
cach
eName
,
[
NotNull
]
string
displayName
,
[
CanBeNull
]
string
description
,
bool
ignoreMultiTenancy
,
bool
tenantAllowed
)
:
base
(
id
)
{
FullTypeName
=
fullTyp
eName
;
CacheName
=
cach
eName
;
DisplayName
=
displayName
;
Description
=
description
;
IgnoreMultiTenancy
=
ignoreMultiTenancy
;
TenantAllowed
=
tenantAllowed
;
}
}
...
...
src/EasyAbp.CacheManagement.Domain/EasyAbp/CacheManagement/CacheItems/CacheItemManager.cs
deleted
100644 → 0
View file @
4d8a5451
using
System
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.Extensions.Caching.Distributed
;
using
Volo.Abp.Caching
;
using
Volo.Abp.Domain.Services
;
using
Volo.Abp.MultiTenancy
;
using
Volo.Abp.Threading
;
namespace
EasyAbp.CacheManagement.CacheItems
{
public
class
CacheItemManager
:
DomainService
,
ICacheItemManager
{
private
readonly
IDistributedCache
_distributedCache
;
private
readonly
ICancellationTokenProvider
_cancellationTokenProvider
;
private
readonly
IDistributedCacheKeyNormalizer
_keyNormalizer
;
public
CacheItemManager
(
IDistributedCache
distributedCache
,
ICancellationTokenProvider
cancellationTokenProvider
,
IDistributedCacheKeyNormalizer
keyNormalizer
)
{
_distributedCache
=
distributedCache
;
_cancellationTokenProvider
=
cancellationTokenProvider
;
_keyNormalizer
=
keyNormalizer
;
}
public
async
Task
ClearAsync
(
CacheItem
cacheItem
,
string
cacheKey
,
CancellationToken
cancellationToken
=
default
)
{
var
type
=
Type
.
GetType
(
cacheItem
.
FullTypeName
);
if
(
type
==
null
)
{
throw
new
CacheItemTypeNotFoundException
(
cacheItem
.
FullTypeName
);
}
var
normalizedKey
=
_keyNormalizer
.
NormalizeKey
(
new
DistributedCacheKeyNormalizeArgs
(
cacheKey
,
CacheNameAttribute
.
GetCacheName
(
type
),
type
.
IsDefined
(
typeof
(
IgnoreMultiTenancyAttribute
),
true
)
)
);
await
_distributedCache
.
RemoveAsync
(
normalizedKey
,
_cancellationTokenProvider
.
FallbackToProvider
());
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain/EasyAbp/CacheManagement/CacheItems/DistributedCacheProviderInvalidException.cs
0 → 100644
View file @
d94c8ddc
using
System
;
namespace
EasyAbp.CacheManagement.CacheItems
{
public
class
DistributedCacheProviderInvalidException
:
ApplicationException
{
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Domain/EasyAbp/CacheManagement/CacheItems/ICacheItemManager.cs
View file @
d94c8ddc
using
System.Threading
;
using
System.Collections.Generic
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Volo.Abp.Domain.Services
;
...
...
@@ -6,6 +7,14 @@ namespace EasyAbp.CacheManagement.CacheItems
{
public
interface
ICacheItemManager
:
IDomainService
{
Task
ClearAsync
(
CacheItem
cacheItem
,
string
cacheKey
,
CancellationToken
cancellationToken
=
default
);
Task
<
IEnumerable
<
string
>>
GetKeysAsync
(
CacheItem
cacheItem
,
CancellationToken
cancellationToken
=
default
);
Task
ClearAllAsync
(
CancellationToken
cancellationToken
=
default
);
Task
ClearAsync
(
CacheItem
cacheItem
,
CancellationToken
cancellationToken
=
default
);
Task
ClearSpecificAsync
(
CacheItem
cacheItem
,
string
cacheKey
,
CancellationToken
cancellationToken
=
default
);
Task
<
string
>
GetValueAsync
(
string
cacheKey
,
CancellationToken
cancellationToken
=
default
);
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.EntityFrameworkCore/EasyAbp/CacheManagement/EntityFrameworkCore/CacheManagementDbContextModelCreatingExtensions.cs
View file @
d94c8ddc
...
...
@@ -46,6 +46,8 @@ namespace EasyAbp.CacheManagement.EntityFrameworkCore
b
.
ToTable
(
options
.
TablePrefix
+
"CacheItems"
,
options
.
Schema
);
b
.
ConfigureByConvention
();
/* Configure more properties here */
b
.
Property
(
c
=>
c
.
CacheName
).
IsRequired
();
b
.
Property
(
c
=>
c
.
DisplayName
).
IsRequired
();
});
}
}
...
...
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/ClearCacheModal.cshtml
View file @
d94c8ddc
...
...
@@ -5,13 +5,20 @@
@{
Layout = null;
}
<script>
let cacheItemId = '@Model.CacheItemId';
</script>
<abp-dynamic-form abp-model="ViewModel" data-ajaxForm="true" asp-page="ClearCacheModal">
<abp-modal>
<abp-modal-header title="@L["ClearCache
CacheItem
"].Value"></abp-modal-header>
<abp-modal-header title="@L["ClearCache"].Value"></abp-modal-header>
<abp-modal-body>
<abp-input asp-for="CacheItemId" />
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer>
<abp-modal-footer>
<abp-button data-dismiss="modal" button-type="Secondary">@L["ClearAllCache"].Value</abp-button>
<abp-button type="submit" button-type="Danger" busy-text="@L["ClearAllCache"].Value">@L["ClearAllCache"].Value</abp-button>
</abp-modal-footer>
</abp-modal>
</abp-dynamic-form>
\ No newline at end of file
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/ClearCacheModal.cshtml.cs
View file @
d94c8ddc
...
...
@@ -13,7 +13,6 @@ namespace EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem
[
BindProperty
(
SupportsGet
=
true
)]
public
Guid
CacheItemId
{
get
;
set
;
}
[
BindProperty
]
public
ClearCacheItemViewModel
ViewModel
{
get
;
set
;
}
private
readonly
ICacheItemAppService
_service
;
...
...
@@ -22,13 +21,22 @@ namespace EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem
{
_service
=
service
;
}
public
async
Task
OnGetAsync
()
{
var
cacheItemDto
=
await
_service
.
GetAsync
(
CacheItemId
);
ViewModel
=
new
ClearCacheItemViewModel
{
DisplayName
=
cacheItemDto
.
DisplayName
};
}
public
async
Task
<
IActionResult
>
OnPostAsync
()
{
await
_service
.
ClearAsync
(
new
ClearCacheItemDto
await
_service
.
ClearAsync
(
new
ClearCacheItemDto
()
{
CacheItemId
=
CacheItemId
,
CacheKey
=
ViewModel
.
CacheKey
});
return
NoContent
();
...
...
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/DetailModal.cshtml
0 → 100644
View file @
d94c8ddc
@page
@inherits EasyAbp.CacheManagement.Web.Pages.CacheManagementPage
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@model EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem.DetailModalModel
@{
Layout = null;
}
<abp-dynamic-form abp-model="Data" data-ajaxForm="true" asp-page="DetailModal">
<abp-modal>
<abp-modal-header title="@L["CacheItem"].Value"></abp-modal-header>
<abp-modal-body>
<abp-form-content />
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.Close)"></abp-modal-footer>
</abp-modal>
</abp-dynamic-form>
\ No newline at end of file
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/DetailModal.cshtml.cs
0 → 100644
View file @
d94c8ddc
using
System
;
using
System.Threading.Tasks
;
using
EasyAbp.CacheManagement.CacheItems
;
using
EasyAbp.CacheManagement.CacheItems.Dtos
;
using
EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem.ViewModels
;
using
Microsoft.AspNetCore.Mvc
;
namespace
EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem
{
public
class
DetailModalModel
:
CacheManagementPageModel
{
[
BindProperty
]
public
CacheItemDataViewModel
Data
{
get
;
set
;
}
private
readonly
ICacheItemAppService
_service
;
public
DetailModalModel
(
ICacheItemAppService
service
)
{
_service
=
service
;
}
public
async
Task
OnGetAsync
(
Guid
cacheItemId
,
string
cacheKey
)
{
var
data
=
await
_service
.
GetDataAsync
(
cacheItemId
,
cacheKey
);
Data
=
new
CacheItemDataViewModel
{
CacheKey
=
data
.
CacheKey
,
CacheValue
=
data
.
CacheValue
};
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/Index.cshtml
View file @
d94c8ddc
@page
@using EasyAbp.CacheManagement.Authorization
@using Microsoft.AspNetCore.Authorization
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@inherits EasyAbp.CacheManagement.Web.Pages.CacheManagementPage
@model EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem.IndexModel
@inject IAuthorizationService Authorization
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = L["CacheItem"].Value;
...
...
@@ -25,10 +28,13 @@
<abp-card-title>@L["CacheItem"]</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-right">
<abp-button id="NewCacheItemButton"
text="@L["CreateCacheItem"].Value"
icon="plus"
button-type="Primary" />
@if (await Authorization.IsGrantedAsync(CacheManagementPermissions.CacheItems.Create))
{
<abp-button id="NewCacheItemButton"
text="@L["CreateCacheItem"].Value"
icon="plus"
button-type="Primary"/>
}
</abp-column>
</abp-row>
</abp-card-header>
...
...
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/KeyList.cshtml
0 → 100644
View file @
d94c8ddc
@page
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@inherits EasyAbp.CacheManagement.Web.Pages.CacheManagementPage
@model EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem.KeyListModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = L["CacheItemData"].Value;
PageLayout.Content.BreadCrumb.Add(L["Menu:CacheItem"].Value);
PageLayout.Content.MenuItemName = "CacheItem";
}
@section scripts
{
<abp-script src="/Pages/CacheManagement/CacheItems/CacheItem/keyList.js" />
}
@section styles
{
<abp-style src="/Pages/CacheManagement/CacheItems/CacheItem/keyList.css"/>
}
<script>
let cacheItemId = '@Model.CacheItem.Id'
</script>
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["CacheItemData"] - @Model.CacheItem.DisplayName</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-right">
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="CacheItemTable" class="nowrap">
<thead>
<tr>
<th>@L["Actions"]</th>
<th>@L["CacheKey"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>
\ No newline at end of file
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/KeyList.cshtml.cs
0 → 100644
View file @
d94c8ddc
using
System
;
using
System.Threading.Tasks
;
using
EasyAbp.CacheManagement.CacheItems
;
using
EasyAbp.CacheManagement.CacheItems.Dtos
;
namespace
EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem
{
public
class
KeyListModel
:
CacheManagementPageModel
{
private
readonly
ICacheItemAppService
_service
;
public
CacheItemDto
CacheItem
{
get
;
set
;
}
public
KeyListModel
(
ICacheItemAppService
service
)
{
_service
=
service
;
}
public
async
Task
OnGetAsync
(
Guid
cacheItemId
)
{
CacheItem
=
await
_service
.
GetAsync
(
cacheItemId
);
await
Task
.
CompletedTask
;
}
}
}
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/ViewModels/CacheItemDataViewModel.cs
0 → 100644
View file @
d94c8ddc
using
System.ComponentModel
;
using
Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
;
namespace
EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem.ViewModels
{
public
class
CacheItemDataViewModel
{
[
DisabledInput
]
[
DisplayName
(
"CacheItemCacheKey"
)]
public
string
CacheKey
{
get
;
set
;
}
[
DisabledInput
]
[
TextArea
(
Rows
=
4
)]
[
DisplayName
(
"CacheItemCacheValue"
)]
public
string
CacheValue
{
get
;
set
;
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/ViewModels/ClearCacheItemViewModel.cs
View file @
d94c8ddc
using
System.ComponentModel
;
using
System.ComponentModel.DataAnnotations
;
using
Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
;
namespace
EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem.ViewModels
{
public
class
ClearCacheItemViewModel
{
[
Required
]
[
DisplayName
(
"CacheItem
CacheKey
"
)]
public
string
CacheKey
{
get
;
set
;
}
[
DisabledInput
]
[
DisplayName
(
"CacheItem
DisplayName
"
)]
public
string
DisplayName
{
get
;
set
;
}
}
}
\ No newline at end of file
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/ViewModels/CreateEditCacheItemViewModel.cs
View file @
d94c8ddc
...
...
@@ -7,8 +7,8 @@ namespace EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem
public
class
CreateEditCacheItemViewModel
{
[
Required
]
[
DisplayName
(
"CacheItem
FullTyp
eName"
)]
public
string
FullTyp
eName
{
get
;
set
;
}
[
DisplayName
(
"CacheItem
Cach
eName"
)]
public
string
Cach
eName
{
get
;
set
;
}
[
Required
]
[
DisplayName
(
"CacheItemDisplayName"
)]
...
...
@@ -18,6 +18,9 @@ namespace EasyAbp.CacheManagement.Web.Pages.CacheManagement.CacheItems.CacheItem
[
TextArea
(
Rows
=
4
)]
public
string
Description
{
get
;
set
;
}
[
DisplayName
(
"CacheItemIgnoreMultiTenancy"
)]
public
bool
IgnoreMultiTenancy
{
get
;
set
;
}
[
DisplayName
(
"CacheItemTenantAllowed"
)]
public
bool
TenantAllowed
{
get
;
set
;
}
}
...
...
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/index.js
View file @
d94c8ddc
...
...
@@ -21,6 +21,12 @@ $(function () {
rowAction
:
{
items
:
[
{
text
:
l
(
'
CacheItemData
'
),
action
:
function
(
data
)
{
document
.
location
.
href
=
"
CacheItem/KeyList?cacheItemId=
"
+
data
.
record
.
id
}
},
{
text
:
l
(
'
ClearCache
'
),
action
:
function
(
data
)
{
...
...
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/keyList.css
0 → 100644
View file @
d94c8ddc
src/EasyAbp.CacheManagement.Web/Pages/CacheManagement/CacheItems/CacheItem/keyList.js
0 → 100644
View file @
d94c8ddc
$
(
function
()
{
var
l
=
abp
.
localization
.
getResource
(
'
CacheManagement
'
);
var
detailModal
=
new
abp
.
ModalManager
(
abp
.
appPath
+
'
CacheManagement/CacheItems/CacheItem/DetailModal
'
);
var
service
=
easyAbp
.
cacheManagement
.
cacheItems
.
cacheItem
;
var
dataTable
=
$
(
'
#CacheItemTable
'
).
DataTable
(
abp
.
libs
.
datatables
.
normalizeConfiguration
({
processing
:
true
,
bPaginate
:
false
,
searching
:
false
,
autoWidth
:
false
,
scrollCollapse
:
true
,
order
:
[[
1
,
"
asc
"
]],
ajax
:
abp
.
libs
.
datatables
.
createAjax
(
service
.
getKeys
,
function
()
{
return
cacheItemId
;
}),
columnDefs
:
[
{
rowAction
:
{
items
:
[
{
text
:
l
(
'
Detail
'
),
action
:
function
(
data
)
{
detailModal
.
open
({
cacheItemId
:
data
.
record
.
cacheItemId
,
cacheKey
:
data
.
record
.
cacheKey
});
}
},
{
text
:
l
(
'
ClearCache
'
),
confirmMessage
:
function
(
data
)
{
return
l
(
'
ClearCacheConfirmationMessage
'
,
data
.
record
.
cacheKey
);
},
action
:
function
(
data
)
{
service
.
clearSpecific
({
cacheItemId
:
data
.
record
.
cacheItemId
,
cacheKey
:
data
.
record
.
cacheKey
})
.
then
(
function
()
{
abp
.
notify
.
info
(
l
(
'
SuccessCleared
'
));
dataTable
.
ajax
.
reload
();
});
}
}
]
}
},
{
data
:
"
cacheKey
"
},
]
}));
});
\ No newline at end of file
test/EasyAbp.CacheManagement.Domain.Tests/EasyAbp.CacheManagement.Domain.Tests.csproj
View file @
d94c8ddc
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment