From 15518ba6db80596e642a28dac6944a9197ee8a06 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Wed, 13 Mar 2024 18:59:05 +0100 Subject: [PATCH] Refactor workflow instance listing and enum parsing Refactor the endpoint for listing workflow instances to use a more robust enum parsing method and improve validation. Update models to accept string collections for statuses and sub-statuses, which enables validating and parsing these enums directly within the endpoint. --- .../Workflows/OrderBatchProcessor.cs | 3 ++- .../WorkflowInstances/List/Endpoint.cs | 26 ++++++++++++++++--- .../WorkflowInstances/List/Models.cs | 4 +-- .../Activities/ParallelForEachT.cs | 11 ++++---- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/samples/aspnet/Elsa.Samples.AspNet.BatchProcessing/Workflows/OrderBatchProcessor.cs b/samples/aspnet/Elsa.Samples.AspNet.BatchProcessing/Workflows/OrderBatchProcessor.cs index 42d727eb5..0ad44abf9 100644 --- a/samples/aspnet/Elsa.Samples.AspNet.BatchProcessing/Workflows/OrderBatchProcessor.cs +++ b/samples/aspnet/Elsa.Samples.AspNet.BatchProcessing/Workflows/OrderBatchProcessor.cs @@ -1,3 +1,4 @@ +using Elsa.Extensions; using Elsa.Samples.AspNet.BatchProcessing.Activities; using Elsa.Samples.AspNet.BatchProcessing.Models; using Elsa.Workflows; @@ -14,7 +15,7 @@ public class OrderBatchProcessor : WorkflowBase /// protected override void Build(IWorkflowBuilder builder) { - var orders = builder.WithVariable>>(); + var orders = builder.WithVariable>>().WithMemoryStorage(); builder.Root = new Sequence { Activities = diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Endpoint.cs index 96bbed0c1..bbdb2a1b2 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Endpoint.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Endpoint.cs @@ -23,8 +23,12 @@ internal class List(IWorkflowInstanceStore store) : ElsaEndpoint(request.Statuses).ToList() : null; + var workflowSubStatuses = request.SubStatuses?.Any() == true ? ParseEnumStrings(request.SubStatuses).ToList() : null; - if (!await ValidateInputAsync(request, cancellationToken)) + ValidateInput(request); + + if (ValidationFailed) { await SendErrorsAsync(StatusCodes.Status400BadRequest, cancellationToken); return; @@ -39,8 +43,8 @@ internal class List(IWorkflowInstanceStore store) : ElsaEndpoint ValidateInputAsync(Request request, CancellationToken cancellationToken) + private IEnumerable ParseEnumStrings(IEnumerable strings) where TEnum : struct + { + foreach (string s in strings) + { + if (Enum.TryParse(s, true, out var result)) + yield return result; + else + { + AddError($"Invalid enum value '{s}'."); + yield break; + } + } + } + + private bool ValidateInput(Request request) { if (request.Page is < 0) { diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Models.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Models.cs index b37960763..4523df3c9 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Models.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/List/Models.cs @@ -16,9 +16,9 @@ public class Request public int? Version { get; set; } public bool? HasIncidents { get; set; } public WorkflowStatus? Status { get; set; } - public ICollection? Statuses { get; set; } + public ICollection? Statuses { get; set; } public WorkflowSubStatus? SubStatus { get; set; } - public ICollection? SubStatuses { get; set; } + public ICollection? SubStatuses { get; set; } public OrderByWorkflowInstance? OrderBy { get; set; } public OrderDirection? OrderDirection { get; set; } public ICollection? TimestampFilters { get; set; } diff --git a/src/modules/Elsa.Workflows.Core/Activities/ParallelForEachT.cs b/src/modules/Elsa.Workflows.Core/Activities/ParallelForEachT.cs index 07cee0097..d5d8fcd63 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/ParallelForEachT.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/ParallelForEachT.cs @@ -43,8 +43,10 @@ public class ParallelForEach : Activity var items = context.GetItemSource(Items); var tags = new List(); var currentIndex = 0; - - // Iterate over the items. + + context.SetProperty(ScheduledTagsProperty, tags); + context.SetProperty(CompletedTagsProperty, new List()); + await foreach (var item in items) { // For each item, declare a new variable for the work to be scheduled. @@ -62,10 +64,7 @@ public class ParallelForEach : Activity tags.Add(tag); await context.ScheduleActivityAsync(Body, OnChildCompleted, tag, variables); } - - context.SetProperty(ScheduledTagsProperty, tags); - context.SetProperty(CompletedTagsProperty, new List()); - + // If there were no items, we're done. if (tags.Count == 0) await context.CompleteActivityAsync();