From 61418385646320c462967ad359d72fdb1716a1ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 21 Feb 2018 13:55:42 +0300 Subject: [PATCH] Implemented permission store cache invalidations. --- .../Volo/Abp/EventBus/ActionEventHandler.cs | 12 +-- .../Abp/EventBus/AsyncActionEventHandler.cs | 12 +-- .../Volo/Abp/EventBus/EventBus.cs | 64 +++++++------- .../Volo/Abp/EventBus/IAsyncEventHandler.cs | 6 +- .../Volo/Abp/EventBus/IEventBus.cs | 84 +++++++++---------- .../Volo/Abp/EventBus/IEventHandler.cs | 6 +- .../Volo/Abp/EventBus/NullEventBus.cs | 28 +++---- .../Volo/Abp/MongoDB/AbpMongoDbModule.cs | 2 +- .../Volo/Abp/Permissions/PermissionStore.cs | 52 ++++++------ 9 files changed, 135 insertions(+), 131 deletions(-) diff --git a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs index a0bc1a6797..e5b6767770 100644 --- a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs +++ b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs @@ -6,21 +6,21 @@ namespace Volo.Abp.EventBus /// /// This event handler is an adapter to be able to use an action as implementation. /// - /// Event type - internal class ActionEventHandler : - IEventHandler, + /// Event type + internal class ActionEventHandler : + IEventHandler, ITransientDependency { /// /// Action to handle the event. /// - public Action Action { get; private set; } + public Action Action { get; private set; } /// /// Creates a new instance of . /// /// Action to handle the event - public ActionEventHandler(Action handler) + public ActionEventHandler(Action handler) { Action = handler; } @@ -29,7 +29,7 @@ namespace Volo.Abp.EventBus /// Handles the event. /// /// - public void HandleEvent(TEventData eventData) + public void HandleEvent(TEvent eventData) { Action(eventData); } diff --git a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AsyncActionEventHandler.cs b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AsyncActionEventHandler.cs index d44dc5494d..fb566f8775 100644 --- a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AsyncActionEventHandler.cs +++ b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AsyncActionEventHandler.cs @@ -7,21 +7,21 @@ namespace Volo.Abp.EventBus /// /// This event handler is an adapter to be able to use an action as implementation. /// - /// Event type - internal class AsyncActionEventHandler : - IAsyncEventHandler, + /// Event type + internal class AsyncActionEventHandler : + IAsyncEventHandler, ITransientDependency { /// /// Function to handle the event. /// - public Func Action { get; } + public Func Action { get; } /// /// Creates a new instance of . /// /// Action to handle the event - public AsyncActionEventHandler(Func handler) + public AsyncActionEventHandler(Func handler) { Action = handler; } @@ -30,7 +30,7 @@ namespace Volo.Abp.EventBus /// Handles the event. /// /// - public async Task HandleEventAsync(TEventData eventData) + public async Task HandleEventAsync(TEvent eventData) { await Action(eventData); } diff --git a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBus.cs b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBus.cs index 9166909881..f0a10c678f 100644 --- a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBus.cs +++ b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBus.cs @@ -64,36 +64,36 @@ namespace Volo.Abp.EventBus } /// - public IDisposable Register(Action action) - where TEventData : class + public IDisposable Register(Action action) + where TEvent : class { - return Register(typeof(TEventData), new ActionEventHandler(action)); + return Register(typeof(TEvent), new ActionEventHandler(action)); } /// - public IDisposable AsyncRegister(Func action) where TEventData : class + public IDisposable AsyncRegister(Func action) where TEvent : class { - return Register(typeof(TEventData), new AsyncActionEventHandler(action)); + return Register(typeof(TEvent), new AsyncActionEventHandler(action)); } /// - public IDisposable Register(IEventHandler handler) where TEventData : class + public IDisposable Register(IEventHandler handler) where TEvent : class { - return Register(typeof(TEventData), handler); + return Register(typeof(TEvent), handler); } /// - public IDisposable AsyncRegister(IAsyncEventHandler handler) where TEventData : class + public IDisposable AsyncRegister(IAsyncEventHandler handler) where TEvent : class { - return Register(typeof(TEventData), handler); + return Register(typeof(TEvent), handler); } /// - public IDisposable Register() - where TEventData : class + public IDisposable Register() + where TEvent : class where THandler : IEventHandler, new() { - return Register(typeof(TEventData), new TransientEventHandlerFactory()); + return Register(typeof(TEvent), new TransientEventHandlerFactory()); } /// @@ -103,9 +103,9 @@ namespace Volo.Abp.EventBus } /// - public IDisposable Register(IEventHandlerFactory factory) where TEventData : class + public IDisposable Register(IEventHandlerFactory factory) where TEvent : class { - return Register(typeof(TEventData), factory); + return Register(typeof(TEvent), factory); } /// @@ -118,11 +118,11 @@ namespace Volo.Abp.EventBus } /// - public void Unregister(Action action) where TEventData : class + public void Unregister(Action action) where TEvent : class { Check.NotNull(action, nameof(action)); - GetOrCreateHandlerFactories(typeof(TEventData)) + GetOrCreateHandlerFactories(typeof(TEvent)) .Locking(factories => { factories.RemoveAll( @@ -134,7 +134,7 @@ namespace Volo.Abp.EventBus return false; } - var actionHandler = singleInstanceFactory.HandlerInstance as ActionEventHandler; + var actionHandler = singleInstanceFactory.HandlerInstance as ActionEventHandler; if (actionHandler == null) { return false; @@ -146,11 +146,11 @@ namespace Volo.Abp.EventBus } /// - public void AsyncUnregister(Func action) where TEventData : class + public void AsyncUnregister(Func action) where TEvent : class { Check.NotNull(action, nameof(action)); - GetOrCreateHandlerFactories(typeof(TEventData)) + GetOrCreateHandlerFactories(typeof(TEvent)) .Locking(factories => { factories.RemoveAll( @@ -162,7 +162,7 @@ namespace Volo.Abp.EventBus return false; } - var actionHandler = singleInstanceFactory.HandlerInstance as AsyncActionEventHandler; + var actionHandler = singleInstanceFactory.HandlerInstance as AsyncActionEventHandler; if (actionHandler == null) { return false; @@ -174,15 +174,15 @@ namespace Volo.Abp.EventBus } /// - public void Unregister(IEventHandler handler) where TEventData : class + public void Unregister(IEventHandler handler) where TEvent : class { - Unregister(typeof(TEventData), handler); + Unregister(typeof(TEvent), handler); } /// - public void AsyncUnregister(IAsyncEventHandler handler) where TEventData : class + public void AsyncUnregister(IAsyncEventHandler handler) where TEvent : class { - Unregister(typeof(TEventData), handler); + Unregister(typeof(TEvent), handler); } /// @@ -200,9 +200,9 @@ namespace Volo.Abp.EventBus } /// - public void Unregister(IEventHandlerFactory factory) where TEventData : class + public void Unregister(IEventHandlerFactory factory) where TEvent : class { - Unregister(typeof(TEventData), factory); + Unregister(typeof(TEvent), factory); } /// @@ -212,9 +212,9 @@ namespace Volo.Abp.EventBus } /// - public void UnregisterAll() where TEventData : class + public void UnregisterAll() where TEvent : class { - UnregisterAll(typeof(TEventData)); + UnregisterAll(typeof(TEvent)); } /// @@ -224,9 +224,9 @@ namespace Volo.Abp.EventBus } /// - public void Trigger(TEventData eventData) where TEventData : class + public void Trigger(TEvent eventData) where TEvent : class { - Trigger(typeof(TEventData), eventData); + Trigger(typeof(TEvent), eventData); } /// @@ -284,9 +284,9 @@ namespace Volo.Abp.EventBus } /// - public Task TriggerAsync(TEventData eventData) where TEventData : class + public Task TriggerAsync(TEvent eventData) where TEvent : class { - return TriggerAsync(typeof(TEventData), eventData); + return TriggerAsync(typeof(TEvent), eventData); } /// diff --git a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IAsyncEventHandler.cs b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IAsyncEventHandler.cs index fa73727a6b..d5336a578f 100644 --- a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IAsyncEventHandler.cs +++ b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IAsyncEventHandler.cs @@ -5,13 +5,13 @@ namespace Volo.Abp.EventBus /// /// Defines an interface of a class that handles events asynchrounously of type . /// - /// Event type to handle - public interface IAsyncEventHandler : IEventHandler + /// Event type to handle + public interface IAsyncEventHandler : IEventHandler { /// /// Handler handles the event by implementing this method. /// /// Event data - Task HandleEventAsync(TEventData eventData); + Task HandleEventAsync(TEvent eventData); } } diff --git a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs index 416a6bd38f..0f12b7a619 100644 --- a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs +++ b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs @@ -15,45 +15,45 @@ namespace Volo.Abp.EventBus /// Given action is called for all event occurrences. /// /// Action to handle events - /// Event type - IDisposable Register(Action action) - where TEventData : class; + /// Event type + IDisposable Register(Action action) + where TEvent : class; /// /// Registers to an event. /// Given action is called for all event occurrences. /// /// Action to handle events - /// Event type - IDisposable AsyncRegister(Func action) - where TEventData : class; + /// Event type + IDisposable AsyncRegister(Func action) + where TEvent : class; /// /// Registers to an event. /// Same (given) instance of the handler is used for all event occurrences. /// - /// Event type + /// Event type /// Object to handle the event - IDisposable Register(IEventHandler handler) - where TEventData : class; + IDisposable Register(IEventHandler handler) + where TEvent : class; /// /// Registers to an event. /// Same (given) instance of the async handler is used for all event occurrences. /// - /// Event type + /// Event type /// Object to handle the event - IDisposable AsyncRegister(IAsyncEventHandler handler) - where TEventData : class; + IDisposable AsyncRegister(IAsyncEventHandler handler) + where TEvent : class; /// /// Registers to an event. /// A new instance of object is created for every event occurrence. /// - /// Event type + /// Event type /// Type of the event handler - IDisposable Register() - where TEventData : class + IDisposable Register() + where TEvent : class where THandler : IEventHandler, new(); /// @@ -68,10 +68,10 @@ namespace Volo.Abp.EventBus /// Registers to an event. /// Given factory is used to create/release handlers /// - /// Event type + /// Event type /// A factory to create/release handlers - IDisposable Register(IEventHandlerFactory factory) - where TEventData : class; + IDisposable Register(IEventHandlerFactory factory) + where TEvent : class; /// /// Registers to an event. @@ -87,34 +87,34 @@ namespace Volo.Abp.EventBus /// /// Unregisters from an event. /// - /// Event type + /// Event type /// - void Unregister(Action action) - where TEventData : class; + void Unregister(Action action) + where TEvent : class; /// /// Unregisters from an event. /// - /// Event type + /// Event type /// - void AsyncUnregister(Func action) - where TEventData : class; + void AsyncUnregister(Func action) + where TEvent : class; /// /// Unregisters from an event. /// - /// Event type + /// Event type /// Handler object that is registered before - void Unregister(IEventHandler handler) - where TEventData : class; + void Unregister(IEventHandler handler) + where TEvent : class; /// /// Unregisters from an event. /// - /// Event type + /// Event type /// Handler object that is registered before - void AsyncUnregister(IAsyncEventHandler handler) - where TEventData : class; + void AsyncUnregister(IAsyncEventHandler handler) + where TEvent : class; /// /// Unregisters from an event. @@ -126,10 +126,10 @@ namespace Volo.Abp.EventBus /// /// Unregisters from an event. /// - /// Event type + /// Event type /// Factory object that is registered before - void Unregister(IEventHandlerFactory factory) - where TEventData : class; + void Unregister(IEventHandlerFactory factory) + where TEvent : class; /// /// Unregisters from an event. @@ -141,9 +141,9 @@ namespace Volo.Abp.EventBus /// /// Unregisters all event handlers of given event type. /// - /// Event type - void UnregisterAll() - where TEventData : class; + /// Event type + void UnregisterAll() + where TEvent : class; /// /// Unregisters all event handlers of given event type. @@ -158,10 +158,10 @@ namespace Volo.Abp.EventBus /// /// Triggers an event. /// - /// Event type + /// Event type /// Related data for the event - void Trigger(TEventData eventData) - where TEventData : class; + void Trigger(TEvent eventData) + where TEvent : class; /// /// Triggers an event. @@ -173,11 +173,11 @@ namespace Volo.Abp.EventBus /// /// Triggers an event asynchronously. /// - /// Event type + /// Event type /// Related data for the event /// The task to handle async operation - Task TriggerAsync(TEventData eventData) - where TEventData : class; + Task TriggerAsync(TEvent eventData) + where TEvent : class; /// /// Triggers an event asynchronously. diff --git a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs index 64db2728bb..2d2e72494c 100644 --- a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs +++ b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs @@ -12,13 +12,13 @@ namespace Volo.Abp.EventBus /// /// Defines an interface of a class that handles events of type . /// - /// Event type to handle - public interface IEventHandler : IEventHandler + /// Event type to handle + public interface IEventHandler : IEventHandler { /// /// Handler handles the event by implementing this method. /// /// Event data - void HandleEvent(TEventData eventData); + void HandleEvent(TEvent eventData); } } \ No newline at end of file diff --git a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/NullEventBus.cs b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/NullEventBus.cs index e412f2b8ff..b15e818831 100644 --- a/src/Volo.Abp.EventBus/Volo/Abp/EventBus/NullEventBus.cs +++ b/src/Volo.Abp.EventBus/Volo/Abp/EventBus/NullEventBus.cs @@ -12,27 +12,27 @@ namespace Volo.Abp.EventBus } - public IDisposable Register(Action action) where TEventData : class + public IDisposable Register(Action action) where TEvent : class { return NullDisposable.Instance; } - public IDisposable AsyncRegister(Func action) where TEventData : class + public IDisposable AsyncRegister(Func action) where TEvent : class { return NullDisposable.Instance; } - public IDisposable Register(IEventHandler handler) where TEventData : class + public IDisposable Register(IEventHandler handler) where TEvent : class { return NullDisposable.Instance; } - public IDisposable AsyncRegister(IAsyncEventHandler handler) where TEventData : class + public IDisposable AsyncRegister(IAsyncEventHandler handler) where TEvent : class { return NullDisposable.Instance; } - public IDisposable Register() where TEventData : class where THandler : IEventHandler, new() + public IDisposable Register() where TEvent : class where THandler : IEventHandler, new() { return NullDisposable.Instance; } @@ -42,7 +42,7 @@ namespace Volo.Abp.EventBus return NullDisposable.Instance; } - public IDisposable Register(IEventHandlerFactory factory) where TEventData : class + public IDisposable Register(IEventHandlerFactory factory) where TEvent : class { return NullDisposable.Instance; } @@ -52,22 +52,22 @@ namespace Volo.Abp.EventBus return NullDisposable.Instance; } - public void Unregister(Action action) where TEventData : class + public void Unregister(Action action) where TEvent : class { } - public void AsyncUnregister(Func action) where TEventData : class + public void AsyncUnregister(Func action) where TEvent : class { } - public void Unregister(IEventHandler handler) where TEventData : class + public void Unregister(IEventHandler handler) where TEvent : class { } - public void AsyncUnregister(IAsyncEventHandler handler) where TEventData : class + public void AsyncUnregister(IAsyncEventHandler handler) where TEvent : class { } @@ -77,7 +77,7 @@ namespace Volo.Abp.EventBus } - public void Unregister(IEventHandlerFactory factory) where TEventData : class + public void Unregister(IEventHandlerFactory factory) where TEvent : class { } @@ -87,7 +87,7 @@ namespace Volo.Abp.EventBus } - public void UnregisterAll() where TEventData : class + public void UnregisterAll() where TEvent : class { } @@ -97,7 +97,7 @@ namespace Volo.Abp.EventBus } - public void Trigger(TEventData eventData) where TEventData : class + public void Trigger(TEvent eventData) where TEvent : class { } @@ -107,7 +107,7 @@ namespace Volo.Abp.EventBus } - public Task TriggerAsync(TEventData eventData) where TEventData : class + public Task TriggerAsync(TEvent eventData) where TEvent : class { return Task.CompletedTask; } diff --git a/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs b/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs index 009654e01c..aab7acbd1d 100644 --- a/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs +++ b/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/AbpMongoDbModule.cs @@ -6,7 +6,7 @@ using Volo.Abp.Uow.MongoDB; namespace Volo.Abp.MongoDB { [DependsOn(typeof(AbpCommonModule))] - [DependsOn(typeof(AbpDddModule))] //TODO: Is it possible to not depend DDD and seperate to another module? + [DependsOn(typeof(AbpDddModule))] public class AbpMongoDbModule : AbpModule { public override void ConfigureServices(IServiceCollection services) diff --git a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionStore.cs b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionStore.cs index afd79ebd20..2b84b3e8e5 100644 --- a/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionStore.cs +++ b/src/Volo.Abp.Permissions.Domain/Volo/Abp/Permissions/PermissionStore.cs @@ -3,22 +3,15 @@ using System.Threading.Tasks; using Microsoft.Extensions.Caching.Distributed; using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; using Volo.Abp.Json; using Volo.Abp.MultiTenancy; using Volo.Abp.Threading; namespace Volo.Abp.Permissions { - /* TODO: - * - Cache Invalidation (via entity events - eventbus) - * - Wrap distributed cache - * - Add multi-tenancy - * - Add _cancellationTokenProvider support - * - Add object serialization support - * - Wrap in-memory cache! - */ - - public class PermissionStore : AbpServiceBase, IPermissionStore, ITransientDependency + public class PermissionStore : AbpServiceBase, IPermissionStore, IAsyncEventHandler>, ITransientDependency { private readonly IPermissionGrantRepository _permissionGrantRepository; private readonly ICurrentTenant _currentTenant; @@ -42,25 +35,24 @@ namespace Volo.Abp.Permissions public async Task IsGrantedAsync(string name, string providerName, string providerKey) { - return await _permissionGrantRepository.FindAsync(name, providerName, providerKey) != null; - //return (await GetCacheItemAsync(name, providerName, providerKey)).IsGranted; //TODO: Use cache when invalidation is possible! + return (await GetCacheItemAsync(name, providerName, providerKey)).IsGranted; } - - private string CalculateCacheKey(string name, string providerName, string providerKey) + + public virtual Task HandleEventAsync(EntityChangedEventData eventData) { - var key = "P:" + providerName + "#K:" + providerKey + "#N:" + name; - - if (_currentTenant.Id.HasValue) - { - key = "T:" + _currentTenant.Id + "#" + key; - } - - return key; + return _distributedCache.RemoveAsync( + CalculateCacheKey( + eventData.Entity.Name, + eventData.Entity.ProviderName, + eventData.Entity.ProviderKey, + eventData.Entity.TenantId + ) + ); } - private async Task GetCacheItemAsync(string name, string providerName, string providerKey) + protected virtual async Task GetCacheItemAsync(string name, string providerName, string providerKey) { - var cacheKey = CalculateCacheKey(name, providerName, providerKey); + var cacheKey = CalculateCacheKey(name, providerName, providerKey, _currentTenant.Id); var cachedString = await _distributedCache.GetStringAsync(cacheKey, _cancellationTokenProvider.Token); if (cachedString != null) @@ -82,5 +74,17 @@ namespace Volo.Abp.Permissions return cacheItem; } + + protected virtual string CalculateCacheKey(string name, string providerName, string providerKey, Guid? tenantId) + { + var key = "N:" + "PermissionGrant" + "#P:" + providerName + "#K:" + providerKey + "#N:" + name; + + if (tenantId.HasValue) + { + key += "#T:" + tenantId.Value; + } + + return key; + } } }