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);
}
}
}