From 145107be45cb466395c06d7b15b2389e0765f6bb Mon Sep 17 00:00:00 2001 From: Kevin Jump Date: Fri, 3 Nov 2023 13:30:13 +0000 Subject: [PATCH] New WebhookEventBase class (#15129) --- .../Events/ContentDeleteWebhookEvent.cs | 2 +- .../Events/ContentPublishWebhookEvent.cs | 2 +- .../Events/ContentUnpublishWebhookEvent.cs | 2 +- .../Events/MediaDeleteWebhookEvent.cs | 2 +- .../Webhooks/Events/MediaSaveWebhookEvent.cs | 2 +- src/Umbraco.Core/Webhooks/WebhookEventBase.cs | 89 +++++++++++-------- .../Webhooks/WebhookEventContentBase.cs | 49 ++++++++++ 7 files changed, 105 insertions(+), 43 deletions(-) create mode 100644 src/Umbraco.Core/Webhooks/WebhookEventContentBase.cs diff --git a/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs index 629f47539a..52b8d233e5 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs @@ -7,7 +7,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; -public class ContentDeleteWebhookEvent : WebhookEventBase +public class ContentDeleteWebhookEvent : WebhookEventContentBase { public ContentDeleteWebhookEvent( IWebhookFiringService webhookFiringService, diff --git a/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs index 4c75516420..8f308432b8 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs @@ -10,7 +10,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; -public class ContentPublishWebhookEvent : WebhookEventBase +public class ContentPublishWebhookEvent : WebhookEventContentBase { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; private readonly IApiContentBuilder _apiContentBuilder; diff --git a/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs index 6c8fdf3598..c8a8fd789e 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs @@ -7,7 +7,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; -public class ContentUnpublishWebhookEvent : WebhookEventBase +public class ContentUnpublishWebhookEvent : WebhookEventContentBase { public ContentUnpublishWebhookEvent( IWebhookFiringService webhookFiringService, diff --git a/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs index 51e1337f7d..eb19e3e888 100644 --- a/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs @@ -7,7 +7,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; -public class MediaDeleteWebhookEvent : WebhookEventBase +public class MediaDeleteWebhookEvent : WebhookEventContentBase { public MediaDeleteWebhookEvent( IWebhookFiringService webhookFiringService, diff --git a/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs index d5a4dc57c5..9a7dcaa3d5 100644 --- a/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs @@ -10,7 +10,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; -public class MediaSaveWebhookEvent : WebhookEventBase +public class MediaSaveWebhookEvent : WebhookEventContentBase { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; private readonly IApiMediaBuilder _apiMediaBuilder; diff --git a/src/Umbraco.Core/Webhooks/WebhookEventBase.cs b/src/Umbraco.Core/Webhooks/WebhookEventBase.cs index 01384ea43f..8753eeecf9 100644 --- a/src/Umbraco.Core/Webhooks/WebhookEventBase.cs +++ b/src/Umbraco.Core/Webhooks/WebhookEventBase.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options; + using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; @@ -8,14 +9,17 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks; -public abstract class WebhookEventBase : IWebhookEvent, INotificationAsyncHandler +public abstract class WebhookEventBase : IWebhookEvent, INotificationAsyncHandler where TNotification : INotification - where TEntity : IContentBase { - private readonly IWebhookFiringService _webhookFiringService; - private readonly IWebHookService _webHookService; private readonly IServerRoleAccessor _serverRoleAccessor; - private WebhookSettings _webhookSettings; + + /// + public string EventName { get; set; } + + protected IWebhookFiringService WebhookFiringService { get; } + protected IWebHookService WebHookService { get; } + protected WebhookSettings WebhookSettings { get; private set; } protected WebhookEventBase( IWebhookFiringService webhookFiringService, @@ -24,50 +28,59 @@ public abstract class WebhookEventBase : IWebhookEvent, IServerRoleAccessor serverRoleAccessor, string eventName) { - _webhookFiringService = webhookFiringService; - _webHookService = webHookService; - _serverRoleAccessor = serverRoleAccessor; EventName = eventName; - _webhookSettings = webhookSettings.CurrentValue; - webhookSettings.OnChange(x => _webhookSettings = x); + + WebhookFiringService = webhookFiringService; + WebHookService = webHookService; + _serverRoleAccessor = serverRoleAccessor; + + WebhookSettings = webhookSettings.CurrentValue; + webhookSettings.OnChange(x => WebhookSettings = x); } - public string EventName { get; set; } - - public virtual async Task HandleAsync(TNotification notification, CancellationToken cancellationToken) + /// + /// Process the webhooks for the given notification. + /// + public virtual async Task ProcessWebhooks(TNotification notification, IEnumerable webhooks, CancellationToken cancellationToken) { - if (_serverRoleAccessor.CurrentServerRole is not ServerRole.Single && _serverRoleAccessor.CurrentServerRole is not ServerRole.SchedulingPublisher) - { - return; - } - - if (_webhookSettings.Enabled is false) - { - return; - } - - IEnumerable webhooks = await _webHookService.GetByEventNameAsync(EventName); - foreach (Webhook webhook in webhooks) { - if (!webhook.Enabled) + if (webhook.Enabled is false) { continue; } - foreach (TEntity entity in GetEntitiesFromNotification(notification)) - { - if (webhook.ContentTypeKeys.Any() && !webhook.ContentTypeKeys.Contains(entity.ContentType.Key)) - { - continue; - } - - await _webhookFiringService.FireAsync(webhook, EventName, ConvertEntityToRequestPayload(entity), cancellationToken); - } + await WebhookFiringService.FireAsync(webhook, EventName, notification, cancellationToken); } } - protected abstract IEnumerable GetEntitiesFromNotification(TNotification notification); + /// + /// should webhooks fire for this notification. + /// + /// true if webhooks should be fired. + public virtual bool ShouldFireWebhookForNotification(TNotification notificationObject) + => true; - protected abstract object? ConvertEntityToRequestPayload(TEntity entity); + public async Task HandleAsync(TNotification notification, CancellationToken cancellationToken) + { + if (WebhookSettings.Enabled is false) + { + return; + } + + if (_serverRoleAccessor.CurrentServerRole is not ServerRole.Single + && _serverRoleAccessor.CurrentServerRole is not ServerRole.SchedulingPublisher) + { + return; + } + + if (ShouldFireWebhookForNotification(notification) is false) + { + return; + } + + IEnumerable webhooks = await WebHookService.GetByEventNameAsync(EventName); + + await ProcessWebhooks(notification, webhooks, cancellationToken); + } } diff --git a/src/Umbraco.Core/Webhooks/WebhookEventContentBase.cs b/src/Umbraco.Core/Webhooks/WebhookEventContentBase.cs new file mode 100644 index 0000000000..5b8b8c626e --- /dev/null +++ b/src/Umbraco.Core/Webhooks/WebhookEventContentBase.cs @@ -0,0 +1,49 @@ +using Microsoft.Extensions.Options; + +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; + +namespace Umbraco.Cms.Core.Webhooks; + +public abstract class WebhookEventContentBase : WebhookEventBase + where TNotification : INotification + where TEntity : IContentBase +{ + protected WebhookEventContentBase( + IWebhookFiringService webhookFiringService, + IWebHookService webHookService, + IOptionsMonitor webhookSettings, + IServerRoleAccessor serverRoleAccessor, + string eventName) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor, eventName) + { + } + + public override async Task ProcessWebhooks(TNotification notification, IEnumerable webhooks, CancellationToken cancellationToken) + { + foreach (Webhook webhook in webhooks) + { + if (!webhook.Enabled) + { + continue; + } + + foreach (TEntity entity in GetEntitiesFromNotification(notification)) + { + if (webhook.ContentTypeKeys.Any() && !webhook.ContentTypeKeys.Contains(entity.ContentType.Key)) + { + continue; + } + + await WebhookFiringService.FireAsync(webhook, EventName, ConvertEntityToRequestPayload(entity), cancellationToken); + } + } + } + + protected abstract IEnumerable GetEntitiesFromNotification(TNotification notification); + + protected abstract object? ConvertEntityToRequestPayload(TEntity entity); +}