From eadbdc4dac0ad2a031735ac97b971344a7159b85 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Sat, 3 Sep 2022 10:29:17 +0800 Subject: [PATCH] added global notification handling --- .../Abp/Notifications/NotificationType.cs | 6 +- .../Distributed/NotificationEventHandler.cs | 69 ++++++++++++++++--- .../MultiTenancy/ITenantConfigurationCache.cs | 10 +++ .../MultiTenancy/TenantConfigurationCache.cs | 49 +++++++++++++ .../TenantConfigurationCacheItem.cs | 20 ++++++ 5 files changed, 140 insertions(+), 14 deletions(-) create mode 100644 aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/ITenantConfigurationCache.cs create mode 100644 aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/TenantConfigurationCache.cs create mode 100644 aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/TenantConfigurationCacheItem.cs diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Core/LINGYUN/Abp/Notifications/NotificationType.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Core/LINGYUN/Abp/Notifications/NotificationType.cs index f13b34542..d9ab166f7 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Core/LINGYUN/Abp/Notifications/NotificationType.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Core/LINGYUN/Abp/Notifications/NotificationType.cs @@ -6,15 +6,15 @@ public enum NotificationType { /// - /// 应用(对应租户) + /// 应用(仅对当前租户) /// Application = 0, /// - /// 系统(对应宿主) + /// 系统通知(全局发布) /// System = 10, /// - /// 用户(对应用户) + /// 用户(对应用户,受租户控制) /// User = 20 } diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs index d2f45cf90..a891482ac 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs @@ -1,5 +1,6 @@ using LINGYUN.Abp.Notifications; using LY.MicroService.RealtimeMessage.BackgroundJobs; +using LY.MicroService.RealtimeMessage.MultiTenancy; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -43,6 +44,10 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed /// protected ICurrentTenant CurrentTenant { get; } /// + /// Reference to . + /// + protected ITenantConfigurationCache TenantConfigurationCache { get; } + /// /// Reference to . /// protected IJsonSerializer JsonSerializer { get; } @@ -80,6 +85,7 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed /// public NotificationEventHandler( ICurrentTenant currentTenant, + ITenantConfigurationCache tenantConfigurationCache, IJsonSerializer jsonSerializer, ITemplateRenderer templateRenderer, IBackgroundJobManager backgroundJobManager, @@ -91,6 +97,7 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed INotificationPublishProviderManager notificationPublishProviderManager) { Options = options.Value; + TenantConfigurationCache = tenantConfigurationCache; CurrentTenant = currentTenant; JsonSerializer = jsonSerializer; TemplateRenderer = templateRenderer; @@ -107,18 +114,38 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed [UnitOfWork] public async virtual Task HandleEventAsync(NotificationEto eventData) { - using (CurrentTenant.Change(eventData.TenantId)) + var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name); + if (notification == null) + { + return; + } + + if (notification.NotificationType == NotificationType.System) { - var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name); - if (notification == null) + var allActiveTenants = await TenantConfigurationCache.GetTenantsAsync(); + + foreach (var activeTenant in allActiveTenants) { - return; + await SendToTenantAsync(activeTenant.Id, notification, eventData); } + } + else + { + await SendToTenantAsync(eventData.TenantId, notification, eventData); + } + } + protected async virtual Task SendToTenantAsync( + Guid? tenantId, + NotificationDefinition notification, + NotificationEto eventData) + { + using (CurrentTenant.Change(tenantId)) + { var notificationInfo = new NotificationInfo { Name = notification.Name, - TenantId = eventData.TenantId, + TenantId = tenantId, Severity = eventData.Severity, Type = notification.NotificationType, CreationTime = eventData.CreationTime, @@ -144,7 +171,7 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed var notificationData = new NotificationData(); notificationData.WriteStandardData( title: title, - message: message, + message: message, createTime: eventData.CreationTime, formUser: eventData.Data.FormUser); notificationData.ExtraProperties.AddIfNotContains(eventData.Data.ExtraProperties); @@ -175,14 +202,34 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed [UnitOfWork] public async virtual Task HandleEventAsync(NotificationEto eventData) { - using (CurrentTenant.Change(eventData.TenantId)) + var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name); + if (notification == null) + { + return; + } + + if (notification.NotificationType == NotificationType.System) { - var notification = await NotificationDefinitionManager.GetOrNullAsync(eventData.Name); - if (notification == null) + var allActiveTenants = await TenantConfigurationCache.GetTenantsAsync(); + + foreach (var activeTenant in allActiveTenants) { - return; + await SendToTenantAsync(activeTenant.Id, notification, eventData); } + } + else + { + await SendToTenantAsync(eventData.TenantId, notification, eventData); + } + } + protected async virtual Task SendToTenantAsync( + Guid? tenantId, + NotificationDefinition notification, + NotificationEto eventData) + { + using (CurrentTenant.Change(tenantId)) + { var notificationInfo = new NotificationInfo { Name = notification.Name, @@ -190,7 +237,7 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed Data = eventData.Data, Severity = eventData.Severity, Lifetime = notification.NotificationLifetime, - TenantId = eventData.TenantId, + TenantId = tenantId, Type = notification.NotificationType }; notificationInfo.SetId(eventData.Id); diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/ITenantConfigurationCache.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/ITenantConfigurationCache.cs new file mode 100644 index 000000000..edc99602b --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/ITenantConfigurationCache.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.MultiTenancy; + +namespace LY.MicroService.RealtimeMessage.MultiTenancy; + +public interface ITenantConfigurationCache +{ + Task> GetTenantsAsync(); +} diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/TenantConfigurationCache.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/TenantConfigurationCache.cs new file mode 100644 index 000000000..d6f3dbb55 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/TenantConfigurationCache.cs @@ -0,0 +1,49 @@ +using LINGYUN.Abp.Saas.Tenants; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace LY.MicroService.RealtimeMessage.MultiTenancy; + +public class TenantConfigurationCache : ITenantConfigurationCache, ITransientDependency +{ + protected ITenantRepository TenantRepository { get; } + protected IDistributedCache TenantCache { get; } + + public TenantConfigurationCache( + ITenantRepository tenantRepository, + IDistributedCache tenantCache) + { + TenantRepository = tenantRepository; + TenantCache = tenantCache; + } + + public async virtual Task> GetTenantsAsync() + { + return (await GetForCacheItemAsync()).Tenants; + } + + protected async virtual Task GetForCacheItemAsync() + { + var cacheKey = "_Abp_Tenant_Configuration"; + var cacheItem = await TenantCache.GetAsync(cacheKey); + if (cacheItem == null) + { + var allActiveTenants = await TenantRepository.GetListAsync(); + + cacheItem = new TenantConfigurationCacheItem( + allActiveTenants.Select(t => + new TenantConfiguration(t.Id, t.Name) + { + IsActive = t.IsActive, + }).ToList()); + + await TenantCache.SetAsync(cacheKey, cacheItem); + } + + return cacheItem; + } +} diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/TenantConfigurationCacheItem.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/TenantConfigurationCacheItem.cs new file mode 100644 index 000000000..7c2b77e2c --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/MultiTenancy/TenantConfigurationCacheItem.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using Volo.Abp.MultiTenancy; + +namespace LY.MicroService.RealtimeMessage.MultiTenancy; + +[IgnoreMultiTenancy] +public class TenantConfigurationCacheItem +{ + public List Tenants { get; set; } + + public TenantConfigurationCacheItem() + { + Tenants = new List(); + } + + public TenantConfigurationCacheItem(List tenants) + { + Tenants = tenants; + } +}