using Elsa.Common.Models; using Elsa.Workflows; using Elsa.Workflows.Management; using Elsa.Workflows.Models; using Elsa.Workflows.Options; using Elsa.Workflows.Runtime; using Elsa.Workflows.Runtime.Messages; using Elsa.Workflows.State; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; namespace Elsa.Testing.Shared; /// /// Provides extension methods for . /// [PublicAPI] public static class RunWorkflowExtensions { /// The services. extension(IServiceProvider services) { /// /// Runs a workflow until its end, automatically resuming any bookmark it encounters. /// /// The ID of the workflow definition. /// An optional dictionary of input values. /// An optional correlation id of the workflow. /// An optional set of options to specify the version of the workflow definition to retrieve. /// Optional workflow execution options. /// The workflow state. public async Task RunWorkflowUntilEndAsync(string workflowDefinitionId, IDictionary? input = null, string? correlationId = null, VersionOptions? versionOptions = null, RunWorkflowOptions? runWorkflowOptions = null) { var workflowDefinitionService = services.GetRequiredService(); var workflowGraph = await workflowDefinitionService.FindWorkflowGraphAsync(workflowDefinitionId, versionOptions ?? VersionOptions.Published); if (workflowGraph == null) throw new InvalidOperationException($"Workflow definition with ID '{workflowDefinitionId}' not found."); var workflowRuntime = services.GetRequiredService(); var workflowClient = await workflowRuntime.CreateClientAsync(); var response = await workflowClient.CreateAndRunInstanceAsync(new() { WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionVersionId(workflowGraph.Workflow.Identity.Id), Input = input, CorrelationId = correlationId, Properties = runWorkflowOptions?.Properties }); var bookmarkStore = services.GetRequiredService(); // Continue resuming the workflow for as long as there are bookmarks to resume and the workflow is not Finished. while (response.Status != WorkflowStatus.Finished) { var bookmarks = (await bookmarkStore.FindManyAsync(new() { WorkflowInstanceId = response.WorkflowInstanceId })).ToList(); if (!bookmarks.Any()) break; foreach (var bookmark in bookmarks) { var runRequest = new RunWorkflowInstanceRequest { BookmarkId = bookmark.Id, Input = input, Properties = runWorkflowOptions?.Properties }; response = await workflowClient.RunInstanceAsync(runRequest); } } // Return the workflow state. return await workflowClient.ExportStateAsync(); } /// /// Runs a workflow until its end, automatically resuming any bookmark it encounters. /// public async Task RunWorkflowUntilEndAsync(IDictionary? input = null) where TWorkflow : IWorkflow { var workflowDefinitionId = typeof(TWorkflow).Name; return await services.RunWorkflowUntilEndAsync(workflowDefinitionId, input); } } }