From f71e5c89ce01f7bb9f6e0bbfce52aa3183c5c2a9 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 20 Jul 2023 13:00:09 +0200 Subject: [PATCH] Ensure schedules are deleted when bookmarks are deleted --- .../Handlers/DeleteSchedules.cs | 8 +++-- .../Contracts/IBookmarkManager.cs | 17 +++++++++ .../Features/WorkflowRuntimeFeature.cs | 1 + .../Filters/BookmarkFilter.cs | 12 +++++++ .../Handlers/DeleteBookmarks.cs | 8 ++--- .../Notifications/BookmarksDeleted.cs | 10 ++++++ .../Notifications/BookmarksDeleting.cs | 10 ++++++ .../Services/DefaultBookmarkManager.cs | 35 +++++++++++++++++++ 8 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 src/modules/Elsa.Workflows.Runtime/Contracts/IBookmarkManager.cs create mode 100644 src/modules/Elsa.Workflows.Runtime/Notifications/BookmarksDeleted.cs create mode 100644 src/modules/Elsa.Workflows.Runtime/Notifications/BookmarksDeleting.cs create mode 100644 src/modules/Elsa.Workflows.Runtime/Services/DefaultBookmarkManager.cs diff --git a/src/modules/Elsa.Scheduling/Handlers/DeleteSchedules.cs b/src/modules/Elsa.Scheduling/Handlers/DeleteSchedules.cs index 9cf124ed4..8aea9a6f8 100644 --- a/src/modules/Elsa.Scheduling/Handlers/DeleteSchedules.cs +++ b/src/modules/Elsa.Scheduling/Handlers/DeleteSchedules.cs @@ -3,6 +3,7 @@ using Elsa.Scheduling.Contracts; using Elsa.Workflows.Management.Notifications; using Elsa.Workflows.Runtime.Contracts; using Elsa.Workflows.Runtime.Filters; +using Elsa.Workflows.Runtime.Notifications; namespace Elsa.Scheduling.Handlers; @@ -14,7 +15,7 @@ public class DeleteSchedules : INotificationHandler, INotificationHandler, INotificationHandler, - INotificationHandler + INotificationHandler { private readonly ITriggerScheduler _triggerScheduler; private readonly IBookmarkScheduler _bookmarkScheduler; @@ -32,9 +33,10 @@ public class DeleteSchedules : _bookmarkStore = bookmarkStore; } - async Task INotificationHandler.HandleAsync(WorkflowInstancesDeleting notification, CancellationToken cancellationToken) + async Task INotificationHandler.HandleAsync(BookmarksDeleting notification, CancellationToken cancellationToken) { - var bookmarks = await _bookmarkStore.FindManyAsync(new BookmarkFilter { WorkflowInstanceIds = notification.Ids }, cancellationToken); + var ids = notification.Bookmarks.Select(x => x.BookmarkId).ToList(); + var bookmarks = await _bookmarkStore.FindManyAsync(new BookmarkFilter { BookmarkIds = ids }, cancellationToken); await _bookmarkScheduler.UnscheduleAsync(bookmarks, cancellationToken); } diff --git a/src/modules/Elsa.Workflows.Runtime/Contracts/IBookmarkManager.cs b/src/modules/Elsa.Workflows.Runtime/Contracts/IBookmarkManager.cs new file mode 100644 index 000000000..6ee8dff13 --- /dev/null +++ b/src/modules/Elsa.Workflows.Runtime/Contracts/IBookmarkManager.cs @@ -0,0 +1,17 @@ +using Elsa.Workflows.Runtime.Filters; + +namespace Elsa.Workflows.Runtime.Contracts; + +/// +/// Manages bookmarks. +/// +public interface IBookmarkManager +{ + /// + /// Deletes all bookmarks matching the specified filter. + /// + /// The filter. + /// An optional cancellation token. + /// The number of deleted bookmarks. + Task DeleteManyAsync(BookmarkFilter filter, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs index 77e68b946..a2205cb25 100644 --- a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs +++ b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs @@ -149,6 +149,7 @@ public class WorkflowRuntimeFeature : FeatureBase .AddSingleton(WorkflowExecutionLogStore) .AddSingleton(RunTaskDispatcher) .AddSingleton(BackgroundActivityInvoker) + .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() diff --git a/src/modules/Elsa.Workflows.Runtime/Filters/BookmarkFilter.cs b/src/modules/Elsa.Workflows.Runtime/Filters/BookmarkFilter.cs index 485f74ca0..5dddcd13a 100644 --- a/src/modules/Elsa.Workflows.Runtime/Filters/BookmarkFilter.cs +++ b/src/modules/Elsa.Workflows.Runtime/Filters/BookmarkFilter.cs @@ -7,6 +7,16 @@ namespace Elsa.Workflows.Runtime.Filters; /// public class BookmarkFilter { + /// + /// Gets or sets the ID of the bookmark. + /// + public string? BookmarkId { get; set; } + + /// + /// Gets or sets the IDs of the bookmark. + /// + public ICollection? BookmarkIds { get; set; } + /// /// Gets or sets the IDs of the workflow instance. /// @@ -43,6 +53,8 @@ public class BookmarkFilter public IQueryable Apply(IQueryable query) { var filter = this; + if (filter.BookmarkId != null) query = query.Where(x => x.BookmarkId == filter.BookmarkId); + if (filter.BookmarkIds != null) query = query.Where(x => filter.BookmarkIds.Contains(x.BookmarkId)); if (filter.CorrelationId != null) query = query.Where(x => x.CorrelationId == filter.CorrelationId); if (filter.Hash != null) query = query.Where(x => x.Hash == filter.Hash); if (filter.WorkflowInstanceId != null) query = query.Where(x => x.WorkflowInstanceId == filter.WorkflowInstanceId); diff --git a/src/modules/Elsa.Workflows.Runtime/Handlers/DeleteBookmarks.cs b/src/modules/Elsa.Workflows.Runtime/Handlers/DeleteBookmarks.cs index d356850aa..8af81d966 100644 --- a/src/modules/Elsa.Workflows.Runtime/Handlers/DeleteBookmarks.cs +++ b/src/modules/Elsa.Workflows.Runtime/Handlers/DeleteBookmarks.cs @@ -10,19 +10,19 @@ namespace Elsa.Workflows.Runtime.Handlers; /// public class DeleteBookmarks : INotificationHandler { - private readonly IBookmarkStore _bookmarkStore; + private readonly IBookmarkManager _bookmarkManager; /// /// Initializes a new instance of the class. /// - public DeleteBookmarks(IBookmarkStore bookmarkStore) + public DeleteBookmarks(IBookmarkManager bookmarkManager) { - _bookmarkStore = bookmarkStore; + _bookmarkManager = bookmarkManager; } /// public async Task HandleAsync(WorkflowInstancesDeleting notification, CancellationToken cancellationToken) { - await _bookmarkStore.DeleteAsync(new BookmarkFilter { WorkflowInstanceIds = notification.Ids }, cancellationToken); + await _bookmarkManager.DeleteManyAsync(new BookmarkFilter { WorkflowInstanceIds = notification.Ids }, cancellationToken); } } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Notifications/BookmarksDeleted.cs b/src/modules/Elsa.Workflows.Runtime/Notifications/BookmarksDeleted.cs new file mode 100644 index 000000000..081595e45 --- /dev/null +++ b/src/modules/Elsa.Workflows.Runtime/Notifications/BookmarksDeleted.cs @@ -0,0 +1,10 @@ +using Elsa.Mediator.Contracts; +using Elsa.Workflows.Runtime.Entities; + +namespace Elsa.Workflows.Runtime.Notifications; + +/// +/// Triggered when bookmarks have been deleted. +/// +/// The bookmarks that have been deleted. +public record BookmarksDeleted(ICollection Bookmarks) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Notifications/BookmarksDeleting.cs b/src/modules/Elsa.Workflows.Runtime/Notifications/BookmarksDeleting.cs new file mode 100644 index 000000000..807409774 --- /dev/null +++ b/src/modules/Elsa.Workflows.Runtime/Notifications/BookmarksDeleting.cs @@ -0,0 +1,10 @@ +using Elsa.Mediator.Contracts; +using Elsa.Workflows.Runtime.Entities; + +namespace Elsa.Workflows.Runtime.Notifications; + +/// +/// Triggered when bookmarks are being deleted. +/// +/// The bookmarks being deleted. +public record BookmarksDeleting(ICollection Bookmarks) : INotification; \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Services/DefaultBookmarkManager.cs b/src/modules/Elsa.Workflows.Runtime/Services/DefaultBookmarkManager.cs new file mode 100644 index 000000000..a83c85f88 --- /dev/null +++ b/src/modules/Elsa.Workflows.Runtime/Services/DefaultBookmarkManager.cs @@ -0,0 +1,35 @@ +using Elsa.Extensions; +using Elsa.Mediator.Contracts; +using Elsa.Workflows.Runtime.Contracts; +using Elsa.Workflows.Runtime.Filters; +using Elsa.Workflows.Runtime.Notifications; + +namespace Elsa.Workflows.Runtime.Services; + +/// +/// Default implementation of . +/// +public class DefaultBookmarkManager : IBookmarkManager +{ + private readonly IBookmarkStore _bookmarkStore; + private readonly INotificationSender _notificationSender; + + /// + /// Initializes a new instance of the class. + /// + public DefaultBookmarkManager(IBookmarkStore bookmarkStore, INotificationSender notificationSender) + { + _bookmarkStore = bookmarkStore; + _notificationSender = notificationSender; + } + + /// + public async Task DeleteManyAsync(BookmarkFilter filter, CancellationToken cancellationToken = default) + { + var bookmarks = (await _bookmarkStore.FindManyAsync(filter, cancellationToken)).ToList(); + await _notificationSender.SendAsync(new BookmarksDeleting(bookmarks), cancellationToken); + var count = await _bookmarkStore.DeleteAsync(filter, cancellationToken); + await _notificationSender.SendAsync(new BookmarksDeleted(bookmarks), cancellationToken); + return count; + } +} \ No newline at end of file