Browse Source

Provide a way to clear the `application configuration` cache for all users.

https://abp.io/support/questions/10259
pull/24486/head
maliming 1 month ago
parent
commit
a565abc59a
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 3
      framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiCurrentApplicationConfigurationCacheResetService.cs
  2. 9
      framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Configuration/BlazorServerCurrentApplicationConfigurationCacheResetService.cs
  3. 5
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/ICurrentApplicationConfigurationCacheResetService.cs
  4. 3
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/NullCurrentApplicationConfigurationCacheResetService.cs
  5. 3
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Configuration/BlazorWebAssemblyCurrentApplicationConfigurationCacheResetService.cs
  6. 25
      framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs
  7. 13
      framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationVersionCacheItem.cs
  8. 7
      framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs
  9. 14
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs
  10. 27
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs
  11. 14
      framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs
  12. 9
      modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs
  13. 14
      modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs

3
framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiCurrentApplicationConfigurationCacheResetService.cs

@ -1,3 +1,4 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Components.Web.Configuration;
using Volo.Abp.DependencyInjection;
@ -16,7 +17,7 @@ public class MauiCurrentApplicationConfigurationCacheResetService :
_mauiBlazorCachedApplicationConfigurationClient = mauiBlazorCachedApplicationConfigurationClient;
}
public async Task ResetAsync()
public async Task ResetAsync(Guid? userId = null)
{
await _mauiBlazorCachedApplicationConfigurationClient.InitializeAsync();
}

9
framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Configuration/BlazorServerCurrentApplicationConfigurationCacheResetService.cs

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Components.Web.Configuration;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.DependencyInjection;
@ -19,10 +20,8 @@ public class BlazorServerCurrentApplicationConfigurationCacheResetService :
_localEventBus = localEventBus;
}
public async Task ResetAsync()
public async Task ResetAsync(Guid? userId = null)
{
await _localEventBus.PublishAsync(
new CurrentApplicationConfigurationCacheResetEventData()
);
await _localEventBus.PublishAsync(new CurrentApplicationConfigurationCacheResetEventData(userId));
}
}

5
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/ICurrentApplicationConfigurationCacheResetService.cs

@ -1,8 +1,9 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Configuration;
public interface ICurrentApplicationConfigurationCacheResetService
{
Task ResetAsync();
Task ResetAsync(Guid? userId = null);
}

3
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/NullCurrentApplicationConfigurationCacheResetService.cs

@ -1,3 +1,4 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
@ -5,7 +6,7 @@ namespace Volo.Abp.AspNetCore.Components.Web.Configuration;
public class NullCurrentApplicationConfigurationCacheResetService : ICurrentApplicationConfigurationCacheResetService, ISingletonDependency
{
public Task ResetAsync()
public Task ResetAsync(Guid? userId = null)
{
return Task.CompletedTask;
}

3
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Configuration/BlazorWebAssemblyCurrentApplicationConfigurationCacheResetService.cs

@ -1,3 +1,4 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Components.Web.Configuration;
using Volo.Abp.DependencyInjection;
@ -16,7 +17,7 @@ public class BlazorWebAssemblyCurrentApplicationConfigurationCacheResetService :
_webAssemblyCachedApplicationConfigurationClient = webAssemblyCachedApplicationConfigurationClient;
}
public async Task ResetAsync()
public async Task ResetAsync(Guid? userId = null)
{
await _webAssemblyCachedApplicationConfigurationClient.InitializeAsync();
}

25
framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs

@ -1,13 +1,26 @@
using System.Globalization;
using Volo.Abp.Users;
using System;
using System.Globalization;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.Client;
public static class MvcCachedApplicationConfigurationClientHelper
public class MvcCachedApplicationConfigurationClientHelper : ITransientDependency
{
public static string CreateCacheKey(ICurrentUser currentUser)
protected IDistributedCache<MvcCachedApplicationVersionCacheItem> ApplicationVersionCache { get; }
public MvcCachedApplicationConfigurationClientHelper(IDistributedCache<MvcCachedApplicationVersionCacheItem> applicationVersionCache)
{
ApplicationVersionCache = applicationVersionCache;
}
public virtual async Task<string> CreateCacheKeyAsync(Guid? userId)
{
var userKey = currentUser.Id?.ToString("N") ?? "Anonymous";
return $"ApplicationConfiguration_{userKey}_{CultureInfo.CurrentUICulture.Name}";
var appVersion = await ApplicationVersionCache.GetOrAddAsync(MvcCachedApplicationVersionCacheItem.CacheKey,
() => Task.FromResult(new MvcCachedApplicationVersionCacheItem(Guid.NewGuid().ToString()))) ??
new MvcCachedApplicationVersionCacheItem(Guid.NewGuid().ToString());
var userKey = userId?.ToString("N") ?? "Anonymous";
return $"ApplicationConfiguration_{appVersion}_{userKey}_{CultureInfo.CurrentUICulture.Name}";
}
}

13
framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationVersionCacheItem.cs

@ -0,0 +1,13 @@
namespace Volo.Abp.AspNetCore.Mvc.Client;
public class MvcCachedApplicationVersionCacheItem
{
public const string CacheKey = "Mvc_Application_Version";
public string Version { get; set; }
public MvcCachedApplicationVersionCacheItem(string version)
{
Version = version;
}
}

7
framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs

@ -20,6 +20,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP
protected IHttpClientFactory HttpClientFactory { get; }
protected IRemoteServiceHttpClientAuthenticator HttpClientAuthenticator { get; }
protected IDistributedCache<ApplicationConfigurationDto> ApplicationConfigurationDtoCache { get; }
protected MvcCachedApplicationConfigurationClientHelper CacheHelper { get; }
protected ICurrentUser CurrentUser { get; }
public RemoteDynamicClaimsPrincipalContributorCache(
@ -28,7 +29,8 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP
IOptions<AbpClaimsPrincipalFactoryOptions> abpClaimsPrincipalFactoryOptions,
IRemoteServiceHttpClientAuthenticator httpClientAuthenticator,
IDistributedCache<ApplicationConfigurationDto> applicationConfigurationDtoCache,
ICurrentUser currentUser)
ICurrentUser currentUser,
MvcCachedApplicationConfigurationClientHelper cacheHelper)
: base(abpClaimsPrincipalFactoryOptions)
{
Cache = cache;
@ -36,6 +38,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP
HttpClientAuthenticator = httpClientAuthenticator;
ApplicationConfigurationDtoCache = applicationConfigurationDtoCache;
CurrentUser = currentUser;
CacheHelper = cacheHelper;
}
protected async override Task<AbpDynamicClaimCacheItem?> GetCacheAsync(Guid userId, Guid? tenantId = null)
@ -56,7 +59,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP
catch (Exception e)
{
Logger.LogWarning(e, $"Failed to refresh remote claims for user: {userId}");
await ApplicationConfigurationDtoCache.RemoveAsync(MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser));
await ApplicationConfigurationDtoCache.RemoveAsync(await CacheHelper.CreateCacheKeyAsync(CurrentUser.Id));
throw;
}
}

14
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs

@ -1,3 +1,4 @@
using System;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
@ -17,10 +18,12 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu
protected AbpApplicationConfigurationClientProxy ApplicationConfigurationAppService { get; }
protected AbpApplicationLocalizationClientProxy ApplicationLocalizationClientProxy { get; }
protected ICurrentUser CurrentUser { get; }
protected MvcCachedApplicationConfigurationClientHelper CacheHelper { get; }
protected IDistributedCache<ApplicationConfigurationDto> Cache { get; }
protected AbpAspNetCoreMvcClientCacheOptions Options { get; }
public MvcCachedApplicationConfigurationClient(
MvcCachedApplicationConfigurationClientHelper cacheHelper,
IDistributedCache<ApplicationConfigurationDto> cache,
AbpApplicationConfigurationClientProxy applicationConfigurationAppService,
ICurrentUser currentUser,
@ -33,12 +36,13 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu
HttpContextAccessor = httpContextAccessor;
ApplicationLocalizationClientProxy = applicationLocalizationClientProxy;
Options = options.Value;
CacheHelper = cacheHelper;
Cache = cache;
}
public async Task<ApplicationConfigurationDto> GetAsync()
public virtual async Task<ApplicationConfigurationDto> GetAsync()
{
var cacheKey = CreateCacheKey();
var cacheKey = await CreateCacheKeyAsync();
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration)
@ -86,7 +90,7 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu
public ApplicationConfigurationDto Get()
{
var cacheKey = CreateCacheKey();
var cacheKey = AsyncHelper.RunSync(CreateCacheKeyAsync);
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration)
@ -97,8 +101,8 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu
return AsyncHelper.RunSync(GetAsync);
}
protected virtual string CreateCacheKey()
protected virtual async Task<string> CreateCacheKeyAsync()
{
return MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser);
return await CacheHelper.CreateCacheKeyAsync(CurrentUser.Id);
}
}

27
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs

@ -3,7 +3,6 @@ using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Mvc.Client;
@ -11,23 +10,29 @@ public class MvcCurrentApplicationConfigurationCacheResetEventHandler :
ILocalEventHandler<CurrentApplicationConfigurationCacheResetEventData>,
ITransientDependency
{
protected ICurrentUser CurrentUser { get; }
protected IDistributedCache<ApplicationConfigurationDto> Cache { get; }
protected IDistributedCache<MvcCachedApplicationVersionCacheItem> ApplicationVersionCache { get; }
protected MvcCachedApplicationConfigurationClientHelper CacheHelper { get; }
public MvcCurrentApplicationConfigurationCacheResetEventHandler(ICurrentUser currentUser,
IDistributedCache<ApplicationConfigurationDto> cache)
public MvcCurrentApplicationConfigurationCacheResetEventHandler(
IDistributedCache<ApplicationConfigurationDto> cache,
IDistributedCache<MvcCachedApplicationVersionCacheItem> applicationVersionCache,
MvcCachedApplicationConfigurationClientHelper cacheHelper)
{
CurrentUser = currentUser;
Cache = cache;
ApplicationVersionCache = applicationVersionCache;
CacheHelper = cacheHelper;
}
public virtual async Task HandleEventAsync(CurrentApplicationConfigurationCacheResetEventData eventData)
{
await Cache.RemoveAsync(CreateCacheKey());
}
protected virtual string CreateCacheKey()
{
return MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser);
if (eventData.UserId.HasValue)
{
await Cache.RemoveAsync(await CacheHelper.CreateCacheKeyAsync(eventData.UserId));
}
else
{
await ApplicationVersionCache.RemoveAsync(MvcCachedApplicationVersionCacheItem.CacheKey);
}
}
}

14
framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs

@ -1,9 +1,21 @@
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using System;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
/// <summary>
/// This event is used to invalidate current user's cached configuration.
/// </summary>
public class CurrentApplicationConfigurationCacheResetEventData
{
public Guid? UserId { get; set; }
public CurrentApplicationConfigurationCacheResetEventData()
{
}
public CurrentApplicationConfigurationCacheResetEventData(Guid? userId)
{
UserId = userId;
}
}

9
modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs

@ -6,6 +6,7 @@ using Blazorise;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Components.Web.Configuration;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
using Volo.Abp.PermissionManagement.Localization;
@ -153,7 +154,13 @@ public partial class PermissionManagementModal
await PermissionAppService.UpdateAsync(_providerName, _providerKey, updateDto);
await CurrentApplicationConfigurationCacheResetService.ResetAsync();
Guid? userId = null;
if (_providerName == UserPermissionValueProvider.ProviderName && Guid.TryParse(_providerKey, out var parsedUserId))
{
userId = parsedUserId;
}
await CurrentApplicationConfigurationCacheResetService.ResetAsync(userId);
await InvokeAsync(_modal.Hide);
await Notify.Success(L["SavedSuccessfully"]);

14
modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
@ -6,6 +7,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Localization;
using Volo.Abp.PermissionManagement.Web.Utils;
@ -105,9 +107,13 @@ public class PermissionManagementModal : AbpPageModel
}
);
await LocalEventBus.PublishAsync(
new CurrentApplicationConfigurationCacheResetEventData()
);
Guid? userId = null;
if (ProviderName == UserPermissionValueProvider.ProviderName && Guid.TryParse(ProviderName, out var parsedUserId))
{
userId = parsedUserId;
}
await LocalEventBus.PublishAsync(new CurrentApplicationConfigurationCacheResetEventData(userId));
return NoContent();
}
@ -130,7 +136,7 @@ public class PermissionManagementModal : AbpPageModel
public bool IsDisabled(string currentProviderName)
{
var grantedProviders = Permissions.SelectMany(x => x.GrantedProviders);
return Permissions.All(x => x.IsGranted) && grantedProviders.All(p => p.ProviderName != currentProviderName);
}
}

Loading…
Cancel
Save