From e7fcf94b6668d43b233d38cdf6903ceb1a5890b8 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sun, 8 Jun 2025 20:11:58 +0200 Subject: [PATCH] Adds activity test-run endpoint Adds an API endpoint to facilitate testing of individual activities within a workflow. The endpoint allows developers to execute a specific activity within a given workflow definition. Also ensures latest workflow definition is marked when publishing. --- .../Endpoints/Activities/TestRun/Endpoint.cs | 56 +++++++++++++++++++ .../DefaultActivityInvokerMiddleware.cs | 8 --- .../Services/WorkflowDefinitionPublisher.cs | 1 + 3 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 src/modules/Elsa.Workflows.Api/Endpoints/Activities/TestRun/Endpoint.cs diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/Activities/TestRun/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/Activities/TestRun/Endpoint.cs new file mode 100644 index 000000000..406c1234d --- /dev/null +++ b/src/modules/Elsa.Workflows.Api/Endpoints/Activities/TestRun/Endpoint.cs @@ -0,0 +1,56 @@ +using Elsa.Abstractions; +using Elsa.Workflows.Management; +using Elsa.Workflows.Models; + +namespace Elsa.Workflows.Api.Endpoints.Activities.TestRun; + +/// +/// This abstract class provides the necessary infrastructure to handle the execution of workflows, including setup of routes, permissions, +/// and processing of HTTP requests to execute workflows. +/// +internal class Endpoint( + IWorkflowDefinitionService workflowDefinitionService, + IActivityInvoker activityInvoker, + IIdentityGenerator identityGenerator, + IServiceProvider serviceProvider) + : ElsaEndpoint +{ + /// + public override void Configure() + { + Post("/activities/test-run"); + ConfigurePermissions("exec:activities"); + } + + /// + public override async Task HandleAsync(Request request, CancellationToken cancellationToken) + { + var workflowGraph = await workflowDefinitionService.FindWorkflowGraphAsync(request.WorkflowDefinitionHandle, cancellationToken); + + if (workflowGraph == null) + { + AddError("Workflow definition not found."); + await SendErrorsAsync(cancellation: cancellationToken); + return; + } + + var workflowInstanceId = identityGenerator.GenerateId(); + var workflowExecutionContext = await WorkflowExecutionContext.CreateAsync(serviceProvider, workflowGraph, workflowInstanceId, cancellationToken: cancellationToken); + var activity = workflowExecutionContext.FindActivity(request.ActivityHandle); + + if (activity == null) + { + AddError("Activity not found."); + await SendErrorsAsync(cancellation: cancellationToken); + return; + } + + await activityInvoker.InvokeAsync(workflowExecutionContext, activity); + } +} + +public class Request +{ + public WorkflowDefinitionHandle WorkflowDefinitionHandle { get; set; } = null!; + public ActivityHandle ActivityHandle { get; set; } = null!; +} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Core/Middleware/Activities/DefaultActivityInvokerMiddleware.cs b/src/modules/Elsa.Workflows.Core/Middleware/Activities/DefaultActivityInvokerMiddleware.cs index a4eb9ba8e..6731bb8a6 100644 --- a/src/modules/Elsa.Workflows.Core/Middleware/Activities/DefaultActivityInvokerMiddleware.cs +++ b/src/modules/Elsa.Workflows.Core/Middleware/Activities/DefaultActivityInvokerMiddleware.cs @@ -82,14 +82,6 @@ public class DefaultActivityInvokerMiddleware(ActivityMiddlewareDelegate next, I // Invoke next middleware. await next(context); - // // If the activity created any bookmarks, copy them into the workflow execution context. - // if (context.Bookmarks.Any()) - // { - // // Store bookmarks. - // workflowExecutionContext.Bookmarks.AddRange(context.Bookmarks); - // logger.LogDebug("Added {BookmarkCount} bookmarks to the workflow execution context", context.Bookmarks.Count); - // } - // Conditionally commit the workflow state. if (ShouldCommit(context, ActivityLifetimeEvent.ActivityExecuted)) await context.WorkflowExecutionContext.CommitAsync(); diff --git a/src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionPublisher.cs b/src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionPublisher.cs index 88640c69d..7181e9475 100644 --- a/src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionPublisher.cs +++ b/src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionPublisher.cs @@ -113,6 +113,7 @@ public class WorkflowDefinitionPublisher( // Save the newly published definition. definition.IsPublished = true; + definition.IsLatest = true; definition = Initialize(definition); await workflowDefinitionStore.SaveAsync(definition, cancellationToken);