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.
This commit is contained in:
Sipke Schoorstra 2025-02-07 23:10:22 +01:00
parent 7cc638b86f
commit 0e4a74bfba
9 changed files with 67 additions and 5 deletions

View file

@ -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;

View file

@ -0,0 +1,6 @@
namespace Elsa.Api.Client.Resources.Alterations.Models;
/// <summary>
/// Cancels the workflow instances in an alteration plan.
/// </summary>
public class Cancel : AlterationBase;

View file

@ -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<AlterationOption
foreach (var alterationType in alterationTypes.ToList())
{
polymorphismOptions.DerivedTypes.Add(new JsonDerivedType(alterationType, alterationType.Name));
polymorphismOptions.DerivedTypes.Add(new(alterationType, alterationType.Name));
}
typeInfo.PolymorphismOptions = polymorphismOptions;

View file

@ -13,7 +13,7 @@ namespace Elsa.Alterations.Activities;
/// Marks an alteration plan as completed.
/// </summary>
[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
{
/// <inheritdoc />

View file

@ -15,7 +15,7 @@ namespace Elsa.Alterations.Activities;
/// Submits an alteration plan for execution.
/// </summary>
[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
{
/// <inheritdoc />

View file

@ -20,7 +20,7 @@ namespace Elsa.Alterations.Activities;
/// Submits an alteration plan for execution.
/// </summary>
[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<int>
{
/// <inheritdoc />

View file

@ -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;
/// <summary>
/// Upgrades the version of the workflow instance.
/// </summary>
[UsedImplicitly]
public class CancelHandler : AlterationHandlerBase<Cancel>
{
/// <inheritdoc />
protected override ValueTask HandleAsync(AlterationContext context, Cancel alteration)
{
context.WorkflowExecutionContext.Cancel();
context.Succeed();
return ValueTask.CompletedTask;
}
}

View file

@ -0,0 +1,10 @@
using Elsa.Alterations.Core.Abstractions;
using JetBrains.Annotations;
namespace Elsa.Alterations.AlterationTypes;
/// <summary>
/// Cancels the workflow instances in an alteration plan.
/// </summary>
[UsedImplicitly]
public class Cancel : AlterationBase;

View file

@ -20,6 +20,7 @@ public static class ServiceCollectionExtensions
services.AddAlteration<ModifyVariable, ModifyVariableHandler>();
services.AddAlteration<ScheduleActivity, ScheduleActivityHandler>();
services.AddAlteration<CancelActivity, CancelActivityHandler>();
services.AddAlteration<Cancel, CancelHandler>();
services.AddNotificationHandlersFrom<AlterationsFeature>();
return services;
}