From 0e4a74bfbab0a10740337ec1e693f9492e133a8d Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Fri, 7 Feb 2025 23:10:22 +0100 Subject: [PATCH] Add `Cancel` alteration type and handler for workflow cancellation Introduced a new `Cancel` alteration type with its corresponding handler to allow workflow instance cancellations in alteration plans. Updated related services, serialization configurations, and activity metadata to support the new type. Improved JSON polymorphism handling to include the `Cancel` type. --- .../Helpers/RefitSettingsHelper.cs | 24 +++++++++++++++++++ .../Resources/Alterations/Models/Cancel.cs | 6 +++++ ...terationSerializationOptionConfigurator.cs | 3 +-- .../Activities/CompleteAlterationPlan.cs | 2 +- .../Activities/DispatchAlterationJobs.cs | 2 +- .../Activities/GenerateAlterationJobs.cs | 2 +- .../AlterationHandlers/CancelHandler.cs | 22 +++++++++++++++++ .../AlterationTypes/Cancel.cs | 10 ++++++++ .../Extensions/ServiceCollectionExtensions.cs | 1 + 9 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 src/clients/Elsa.Api.Client/Resources/Alterations/Models/Cancel.cs create mode 100644 src/modules/Elsa.Alterations/AlterationHandlers/CancelHandler.cs create mode 100644 src/modules/Elsa.Alterations/AlterationTypes/Cancel.cs diff --git a/src/clients/Elsa.Api.Client/Helpers/RefitSettingsHelper.cs b/src/clients/Elsa.Api.Client/Helpers/RefitSettingsHelper.cs index 8a87220a3..fafd23891 100644 --- a/src/clients/Elsa.Api.Client/Helpers/RefitSettingsHelper.cs +++ b/src/clients/Elsa.Api.Client/Helpers/RefitSettingsHelper.cs @@ -1,6 +1,9 @@ using System.Text.Json; using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; using Elsa.Api.Client.Converters; +using Elsa.Api.Client.Resources.Alterations.Contracts; +using Elsa.Api.Client.Resources.Alterations.Models; using Refit; namespace Elsa.Api.Client; @@ -34,6 +37,27 @@ public static class RefitSettingsHelper options.Converters.Add(new VersionOptionsJsonConverter()); options.Converters.Add(new TypeJsonConverter()); + var alterationTypes = new[] { typeof(Cancel) }; + + options.TypeInfoResolver = new DefaultJsonTypeInfoResolver() + .WithAddedModifier(typeInfo => + { + if (typeInfo.Type != typeof(IAlteration)) + return; + + if (typeInfo.Kind != JsonTypeInfoKind.Object) + return; + + var polymorphismOptions = new JsonPolymorphismOptions { TypeDiscriminatorPropertyName = "type" }; + + foreach (var alterationType in alterationTypes.ToList()) + { + polymorphismOptions.DerivedTypes.Add(new(alterationType, alterationType.Name)); + } + + typeInfo.PolymorphismOptions = polymorphismOptions; + }); + configureJsonSerializerOptions?.Invoke(serviceProvider, options); return options; diff --git a/src/clients/Elsa.Api.Client/Resources/Alterations/Models/Cancel.cs b/src/clients/Elsa.Api.Client/Resources/Alterations/Models/Cancel.cs new file mode 100644 index 000000000..45b2c836d --- /dev/null +++ b/src/clients/Elsa.Api.Client/Resources/Alterations/Models/Cancel.cs @@ -0,0 +1,6 @@ +namespace Elsa.Api.Client.Resources.Alterations.Models; + +/// +/// Cancels the workflow instances in an alteration plan. +/// +public class Cancel : AlterationBase; \ No newline at end of file diff --git a/src/modules/Elsa.Alterations.Core/Serialization/AlterationSerializationOptionConfigurator.cs b/src/modules/Elsa.Alterations.Core/Serialization/AlterationSerializationOptionConfigurator.cs index d5614b6d9..217331a5f 100644 --- a/src/modules/Elsa.Alterations.Core/Serialization/AlterationSerializationOptionConfigurator.cs +++ b/src/modules/Elsa.Alterations.Core/Serialization/AlterationSerializationOptionConfigurator.cs @@ -1,4 +1,3 @@ -using System.Text.Json; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; using Elsa.Alterations.Core.Contracts; @@ -35,7 +34,7 @@ public class AlterationSerializationOptionConfigurator(IOptions [Browsable(false)] -[Activity("Elsa", "Alterations", "Dispatches jobs for the specified Alteration Plan", Kind = ActivityKind.Job)] +[Activity("Elsa", "Alterations", "Dispatches jobs for the specified Alteration Plan", Kind = ActivityKind.Task)] public class CompleteAlterationPlan : CodeActivity { /// diff --git a/src/modules/Elsa.Alterations/Activities/DispatchAlterationJobs.cs b/src/modules/Elsa.Alterations/Activities/DispatchAlterationJobs.cs index a8c2c6fe5..a22a45652 100644 --- a/src/modules/Elsa.Alterations/Activities/DispatchAlterationJobs.cs +++ b/src/modules/Elsa.Alterations/Activities/DispatchAlterationJobs.cs @@ -15,7 +15,7 @@ namespace Elsa.Alterations.Activities; /// Submits an alteration plan for execution. /// [Browsable(false)] -[Activity("Elsa", "Alterations", "Dispatches jobs for the specified Alteration Plan", Kind = ActivityKind.Job)] +[Activity("Elsa", "Alterations", "Dispatches jobs for the specified Alteration Plan", Kind = ActivityKind.Task)] public class DispatchAlterationJobs : CodeActivity { /// diff --git a/src/modules/Elsa.Alterations/Activities/GenerateAlterationJobs.cs b/src/modules/Elsa.Alterations/Activities/GenerateAlterationJobs.cs index fd2357501..03a68cca5 100644 --- a/src/modules/Elsa.Alterations/Activities/GenerateAlterationJobs.cs +++ b/src/modules/Elsa.Alterations/Activities/GenerateAlterationJobs.cs @@ -20,7 +20,7 @@ namespace Elsa.Alterations.Activities; /// Submits an alteration plan for execution. /// [Browsable(false)] -[Activity("Elsa", "Alterations", "Generates jobs for the specified Alteration Plan", Kind = ActivityKind.Job)] +[Activity("Elsa", "Alterations", "Generates jobs for the specified Alteration Plan", Kind = ActivityKind.Task)] public class GenerateAlterationJobs : CodeActivity { /// diff --git a/src/modules/Elsa.Alterations/AlterationHandlers/CancelHandler.cs b/src/modules/Elsa.Alterations/AlterationHandlers/CancelHandler.cs new file mode 100644 index 000000000..38bc32404 --- /dev/null +++ b/src/modules/Elsa.Alterations/AlterationHandlers/CancelHandler.cs @@ -0,0 +1,22 @@ +using Elsa.Alterations.AlterationTypes; +using Elsa.Alterations.Core.Abstractions; +using Elsa.Alterations.Core.Contexts; +using JetBrains.Annotations; + +namespace Elsa.Alterations.AlterationHandlers; + +/// +/// Upgrades the version of the workflow instance. +/// +[UsedImplicitly] +public class CancelHandler : AlterationHandlerBase +{ + /// + protected override ValueTask HandleAsync(AlterationContext context, Cancel alteration) + { + context.WorkflowExecutionContext.Cancel(); + + context.Succeed(); + return ValueTask.CompletedTask; + } +} \ No newline at end of file diff --git a/src/modules/Elsa.Alterations/AlterationTypes/Cancel.cs b/src/modules/Elsa.Alterations/AlterationTypes/Cancel.cs new file mode 100644 index 000000000..c0a5f7fde --- /dev/null +++ b/src/modules/Elsa.Alterations/AlterationTypes/Cancel.cs @@ -0,0 +1,10 @@ +using Elsa.Alterations.Core.Abstractions; +using JetBrains.Annotations; + +namespace Elsa.Alterations.AlterationTypes; + +/// +/// Cancels the workflow instances in an alteration plan. +/// +[UsedImplicitly] +public class Cancel : AlterationBase; \ No newline at end of file diff --git a/src/modules/Elsa.Alterations/Extensions/ServiceCollectionExtensions.cs b/src/modules/Elsa.Alterations/Extensions/ServiceCollectionExtensions.cs index 76a6818b8..b930d2878 100644 --- a/src/modules/Elsa.Alterations/Extensions/ServiceCollectionExtensions.cs +++ b/src/modules/Elsa.Alterations/Extensions/ServiceCollectionExtensions.cs @@ -20,6 +20,7 @@ public static class ServiceCollectionExtensions services.AddAlteration(); services.AddAlteration(); services.AddAlteration(); + services.AddAlteration(); services.AddNotificationHandlersFrom(); return services; }