Browse Source

feat: Add notification publish interceptor

pull/1484/head
colin 7 days ago
parent
commit
e68dea143e
  1. 20
      aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishInterceptor.cs
  2. 77
      aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs

20
aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishInterceptor.cs

@ -0,0 +1,20 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications;
/// <summary>
/// 通知发布拦截器, 实现此接口来增加发布前的自定义检查
/// </summary>
public interface INotificationPublishInterceptor
{
/// <summary>
/// 拦截优先级,数值越小优先级越高
/// </summary>
int Priority { get; }
/// <summary>
/// 在通知发布前执行检查
/// </summary>
/// <param name="notification">通知信息</param>
/// <returns>true-允许发布, false-阻止发布</returns>
Task<bool> CanPublishAsync(NotificationInfo notification);
}

77
aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs

@ -1,6 +1,8 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
@ -21,6 +23,11 @@ public abstract class NotificationPublishProvider : INotificationPublishProvider
public ICancellationTokenProvider CancellationTokenProvider => ServiceProvider.LazyGetService<ICancellationTokenProvider>(NullCancellationTokenProvider.Instance);
private IEnumerable<INotificationPublishInterceptor> _interceptors;
protected IEnumerable<INotificationPublishInterceptor> Interceptors =>
_interceptors ??= ServiceProvider.LazyGetService<IEnumerable<INotificationPublishInterceptor>>()
?? Enumerable.Empty<INotificationPublishInterceptor>();
public async virtual Task<bool> CanPublishAsync(NotificationInfo notification)
{
return await CanPublishAsync(notification, GetCancellationToken());
@ -28,9 +35,23 @@ public abstract class NotificationPublishProvider : INotificationPublishProvider
public async Task PublishAsync(NotificationPublishContext context)
{
await PublishAsync(context, GetCancellationToken());
var cancellationToken = GetCancellationToken();
// 通知拦截器检查
if (!await ExecuteInterceptorsAsync(context, cancellationToken))
{
return;
}
await PublishAsync(context, cancellationToken);
}
/// <summary>
/// 是否允许发布通知
/// </summary>
/// <param name="notification"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected virtual Task<bool> CanPublishAsync(
NotificationInfo notification,
CancellationToken cancellationToken = default)
@ -38,6 +59,60 @@ public abstract class NotificationPublishProvider : INotificationPublishProvider
return Task.FromResult(true);
}
/// <summary>
/// 执行通知发布拦截器
/// </summary>
/// <param name="context"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected virtual async Task<bool> ExecuteInterceptorsAsync(
NotificationPublishContext context,
CancellationToken cancellationToken = default)
{
if (context.Notification.Type == NotificationType.System ||
context.Notification.Type == NotificationType.ServiceCallback)
{
Logger.LogDebug(
"System or service callback notification {NotificationName}, skip all interceptors.",
context.Notification.Name);
return true;
}
if (!Interceptors.Any())
{
Logger.LogDebug("No notification publishing interceptors have been registered.");
return true;
}
var orderedInterceptors = Interceptors.OrderBy(i => i.Priority);
foreach (var interceptor in orderedInterceptors)
{
try
{
if (!await interceptor.CanPublishAsync(context.Notification))
{
var reason = string.Format("The interceptor {0} prevented the publication of the notification {1}.",
interceptor.GetType().Name,
context.Notification.Name);
context.Cancel(reason);
Logger.LogWarning(reason);
return false;
}
}
catch (Exception ex)
{
Logger.LogWarning(ex,
"An exception occurred while executing the interceptor {InterceptorType}. By default, publication is allowed.",
interceptor.GetType().Name);
}
}
return true;
}
protected virtual CancellationToken GetCancellationToken(CancellationToken cancellationToken = default)
{
return CancellationTokenProvider.FallbackToProvider(cancellationToken);

Loading…
Cancel
Save