| | | 1 | | |
| | | 2 | | using Elsa.Common.Models; |
| | | 3 | | using Elsa.Workflows.Management; |
| | | 4 | | using Elsa.Workflows.Management.Filters; |
| | | 5 | | using Elsa.Workflows.Models; |
| | | 6 | | using Elsa.Workflows.Runtime.Entities; |
| | | 7 | | using Elsa.Workflows.Runtime.Filters; |
| | | 8 | | using Elsa.Workflows.Runtime.Matches; |
| | | 9 | | using Elsa.Workflows.Runtime.Messages; |
| | | 10 | | using Elsa.Workflows.Runtime.Options; |
| | | 11 | | using Elsa.Workflows.Runtime.Parameters; |
| | | 12 | | using Elsa.Workflows.Runtime.Params; |
| | | 13 | | using Elsa.Workflows.Runtime.Requests; |
| | | 14 | | using Elsa.Workflows.Runtime.Results; |
| | | 15 | | using Elsa.Workflows.State; |
| | | 16 | | using Microsoft.Extensions.DependencyInjection; |
| | | 17 | | using Open.Linq.AsyncExtensions; |
| | | 18 | | |
| | | 19 | | namespace Elsa.Workflows.Runtime; |
| | | 20 | | |
| | | 21 | | /// <summary> |
| | | 22 | | /// Implements the now deprecated workflow runtime API methods. |
| | | 23 | | /// </summary> |
| | 0 | 24 | | public class ObsoleteWorkflowRuntime( |
| | 0 | 25 | | Func<string?, CancellationToken, ValueTask<IWorkflowClient>> createClientAsync, |
| | 0 | 26 | | IWorkflowDefinitionService workflowDefinitionService, |
| | 0 | 27 | | IWorkflowActivationStrategyEvaluator workflowActivationStrategyEvaluator, |
| | 0 | 28 | | IStimulusSender stimulusSender, |
| | 0 | 29 | | IStimulusHasher stimulusHasher, |
| | 0 | 30 | | IBookmarkStore bookmarkStore, |
| | 0 | 31 | | IWorkflowInstanceStore workflowInstanceStore, |
| | 0 | 32 | | ITriggerBoundWorkflowService triggerBoundWorkflowService, |
| | 0 | 33 | | IBookmarkBoundWorkflowService bookmarkBoundWorkflowService) |
| | | 34 | | { |
| | | 35 | | public static ObsoleteWorkflowRuntime Create(IServiceProvider serviceProvider, Func<string?, CancellationToken, Valu |
| | | 36 | | { |
| | 0 | 37 | | return ActivatorUtilities.CreateInstance<ObsoleteWorkflowRuntime>(serviceProvider, createClientAsync); |
| | | 38 | | } |
| | | 39 | | |
| | | 40 | | public async Task<CanStartWorkflowResult> CanStartWorkflowAsync(string definitionId, StartWorkflowRuntimeParams? opt |
| | | 41 | | { |
| | 0 | 42 | | var cancellationToken = options?.CancellationToken ?? CancellationToken.None; |
| | 0 | 43 | | var workflowGraph = await workflowDefinitionService.FindWorkflowGraphAsync(definitionId, options?.VersionOptions |
| | 0 | 44 | | var workflow = workflowGraph!.Workflow; |
| | | 45 | | |
| | 0 | 46 | | var canStart = await workflowActivationStrategyEvaluator.CanStartWorkflowAsync(new() |
| | 0 | 47 | | { |
| | 0 | 48 | | Workflow = workflow, |
| | 0 | 49 | | CorrelationId = options?.CorrelationId, |
| | 0 | 50 | | CancellationToken = cancellationToken |
| | 0 | 51 | | }); |
| | | 52 | | |
| | 0 | 53 | | return new(null, canStart); |
| | 0 | 54 | | } |
| | | 55 | | |
| | | 56 | | public async Task<WorkflowExecutionResult> StartWorkflowAsync(string definitionId, StartWorkflowRuntimeParams? optio |
| | | 57 | | { |
| | 0 | 58 | | var cancellationToken = options?.CancellationToken ?? CancellationToken.None; |
| | 0 | 59 | | var client = await createClientAsync(options?.InstanceId, cancellationToken); |
| | 0 | 60 | | var createRequest = new CreateAndRunWorkflowInstanceRequest |
| | 0 | 61 | | { |
| | 0 | 62 | | Properties = options?.Properties, |
| | 0 | 63 | | CorrelationId = options?.CorrelationId, |
| | 0 | 64 | | Input = options?.Input, |
| | 0 | 65 | | WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionId(definitionId, options?.VersionOptions ?? |
| | 0 | 66 | | ParentId = options?.ParentWorkflowInstanceId, |
| | 0 | 67 | | TriggerActivityId = options?.TriggerActivityId |
| | 0 | 68 | | }; |
| | 0 | 69 | | var response = await client.CreateAndRunInstanceAsync(createRequest, cancellationToken); |
| | 0 | 70 | | return new(response.WorkflowInstanceId, response.Status, response.SubStatus, response.Bookmarks, response.Incide |
| | 0 | 71 | | } |
| | | 72 | | |
| | | 73 | | public async Task<ICollection<WorkflowExecutionResult>> StartWorkflowsAsync(string activityTypeName, object bookmark |
| | | 74 | | { |
| | 0 | 75 | | var cancellationToken = options?.CancellationToken ?? CancellationToken.None; |
| | 0 | 76 | | var metadata = new StimulusMetadata |
| | 0 | 77 | | { |
| | 0 | 78 | | CorrelationId = options?.CorrelationId, |
| | 0 | 79 | | WorkflowInstanceId = options?.WorkflowInstanceId, |
| | 0 | 80 | | Properties = options?.Properties, |
| | 0 | 81 | | ActivityInstanceId = options?.ActivityInstanceId, |
| | 0 | 82 | | Input = options?.Input |
| | 0 | 83 | | }; |
| | 0 | 84 | | var result = await stimulusSender.SendAsync(activityTypeName, bookmarkPayload, metadata, cancellationToken); |
| | 0 | 85 | | var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.S |
| | 0 | 86 | | return results; |
| | 0 | 87 | | } |
| | | 88 | | |
| | | 89 | | public async Task<WorkflowExecutionResult?> TryStartWorkflowAsync(string definitionId, StartWorkflowRuntimeParams? o |
| | | 90 | | { |
| | 0 | 91 | | return await StartWorkflowAsync(definitionId, options); |
| | 0 | 92 | | } |
| | | 93 | | |
| | | 94 | | public async Task<WorkflowExecutionResult?> ResumeWorkflowAsync(string workflowInstanceId, ResumeWorkflowRuntimePara |
| | | 95 | | { |
| | 0 | 96 | | var cancellationToken = options?.CancellationToken ?? CancellationToken.None; |
| | 0 | 97 | | var workflowClient = await createClientAsync(workflowInstanceId, cancellationToken); |
| | 0 | 98 | | var exists = await workflowClient.InstanceExistsAsync(cancellationToken); |
| | | 99 | | |
| | 0 | 100 | | if (!exists) |
| | 0 | 101 | | return null; |
| | | 102 | | |
| | 0 | 103 | | var runWorkflowRequest = new RunWorkflowInstanceRequest |
| | 0 | 104 | | { |
| | 0 | 105 | | Input = options?.Input, |
| | 0 | 106 | | Properties = options?.Properties, |
| | 0 | 107 | | ActivityHandle = options?.ActivityHandle, |
| | 0 | 108 | | BookmarkId = options?.BookmarkId |
| | 0 | 109 | | }; |
| | | 110 | | |
| | 0 | 111 | | var response = await workflowClient.RunInstanceAsync(runWorkflowRequest, cancellationToken); |
| | | 112 | | |
| | 0 | 113 | | return new(response.WorkflowInstanceId, response.Status, response.SubStatus, response.Bookmarks, response.Incide |
| | 0 | 114 | | } |
| | | 115 | | |
| | | 116 | | public async Task<ICollection<WorkflowExecutionResult>> ResumeWorkflowsAsync(string activityTypeName, object bookmar |
| | | 117 | | { |
| | 0 | 118 | | var cancellationToken = options?.CancellationToken ?? CancellationToken.None; |
| | 0 | 119 | | var metadata = new StimulusMetadata |
| | 0 | 120 | | { |
| | 0 | 121 | | CorrelationId = options?.CorrelationId, |
| | 0 | 122 | | WorkflowInstanceId = options?.WorkflowInstanceId, |
| | 0 | 123 | | Properties = options?.Properties, |
| | 0 | 124 | | ActivityInstanceId = options?.ActivityInstanceId, |
| | 0 | 125 | | Input = options?.Input |
| | 0 | 126 | | }; |
| | 0 | 127 | | var result = await stimulusSender.SendAsync(activityTypeName, bookmarkPayload, metadata, cancellationToken); |
| | 0 | 128 | | var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.S |
| | 0 | 129 | | return results; |
| | 0 | 130 | | } |
| | | 131 | | |
| | | 132 | | public async Task<TriggerWorkflowsResult> TriggerWorkflowsAsync(string activityTypeName, object bookmarkPayload, Tri |
| | | 133 | | { |
| | 0 | 134 | | var cancellationToken = options?.CancellationToken ?? CancellationToken.None; |
| | 0 | 135 | | var metadata = new StimulusMetadata |
| | 0 | 136 | | { |
| | 0 | 137 | | CorrelationId = options?.CorrelationId, |
| | 0 | 138 | | WorkflowInstanceId = options?.WorkflowInstanceId, |
| | 0 | 139 | | Properties = options?.Properties, |
| | 0 | 140 | | ActivityInstanceId = options?.ActivityInstanceId, |
| | 0 | 141 | | Input = options?.Input |
| | 0 | 142 | | }; |
| | 0 | 143 | | var result = await stimulusSender.SendAsync(activityTypeName, bookmarkPayload, metadata, cancellationToken); |
| | 0 | 144 | | var results = result.WorkflowInstanceResponses.Select(x => new WorkflowExecutionResult(x.WorkflowInstanceId, x.S |
| | 0 | 145 | | return new(results); |
| | 0 | 146 | | } |
| | | 147 | | |
| | | 148 | | public async Task<WorkflowExecutionResult> ExecuteWorkflowAsync(WorkflowMatch match, ExecuteWorkflowParams? options |
| | | 149 | | { |
| | 0 | 150 | | var cancellationToken = options?.CancellationToken ?? CancellationToken.None; |
| | 0 | 151 | | if (match is StartableWorkflowMatch collectedStartableWorkflow) |
| | | 152 | | { |
| | 0 | 153 | | var startOptions = new StartWorkflowRuntimeParams |
| | 0 | 154 | | { |
| | 0 | 155 | | CorrelationId = collectedStartableWorkflow.CorrelationId, |
| | 0 | 156 | | Input = options?.Input, |
| | 0 | 157 | | Properties = options?.Properties, |
| | 0 | 158 | | VersionOptions = VersionOptions.Published, |
| | 0 | 159 | | TriggerActivityId = collectedStartableWorkflow.ActivityId, |
| | 0 | 160 | | CancellationToken = cancellationToken |
| | 0 | 161 | | }; |
| | | 162 | | |
| | 0 | 163 | | var startResult = await StartWorkflowAsync(collectedStartableWorkflow.DefinitionId!, startOptions); |
| | 0 | 164 | | return startResult with |
| | 0 | 165 | | { |
| | 0 | 166 | | TriggeredActivityId = collectedStartableWorkflow.ActivityId |
| | 0 | 167 | | }; |
| | | 168 | | } |
| | | 169 | | |
| | 0 | 170 | | var collectedResumableWorkflow = (match as ResumableWorkflowMatch)!; |
| | 0 | 171 | | var runtimeOptions = new ResumeWorkflowRuntimeParams |
| | 0 | 172 | | { |
| | 0 | 173 | | CorrelationId = collectedResumableWorkflow.CorrelationId, |
| | 0 | 174 | | BookmarkId = collectedResumableWorkflow.BookmarkId, |
| | 0 | 175 | | Input = options?.Input, |
| | 0 | 176 | | Properties = options?.Properties, |
| | 0 | 177 | | CancellationToken = cancellationToken, |
| | 0 | 178 | | }; |
| | | 179 | | |
| | 0 | 180 | | return (await ResumeWorkflowAsync(collectedResumableWorkflow.WorkflowInstanceId, runtimeOptions))!; |
| | 0 | 181 | | } |
| | | 182 | | |
| | | 183 | | public async Task<CancellationResult> CancelWorkflowAsync(string workflowInstanceId, CancellationToken cancellationT |
| | | 184 | | { |
| | 0 | 185 | | var client = await createClientAsync(workflowInstanceId, cancellationToken); |
| | 0 | 186 | | await client.CancelAsync(cancellationToken); |
| | 0 | 187 | | return new(true); |
| | 0 | 188 | | } |
| | | 189 | | |
| | | 190 | | public async Task<IEnumerable<WorkflowMatch>> FindWorkflowsAsync(WorkflowsFilter filter, CancellationToken cancellat |
| | | 191 | | { |
| | 0 | 192 | | var startableWorkflows = await FindStartableWorkflowsAsync(filter, cancellationToken); |
| | 0 | 193 | | var resumableWorkflows = await FindResumableWorkflowsAsync(filter, cancellationToken); |
| | 0 | 194 | | var results = startableWorkflows.Concat(resumableWorkflows).ToList(); |
| | 0 | 195 | | return results; |
| | 0 | 196 | | } |
| | | 197 | | |
| | | 198 | | public async Task<WorkflowState?> ExportWorkflowStateAsync(string workflowInstanceId, CancellationToken cancellation |
| | | 199 | | { |
| | 0 | 200 | | var client = await createClientAsync(workflowInstanceId, cancellationToken); |
| | 0 | 201 | | return await client.ExportStateAsync(cancellationToken); |
| | 0 | 202 | | } |
| | | 203 | | |
| | | 204 | | public async Task ImportWorkflowStateAsync(WorkflowState workflowState, CancellationToken cancellationToken = defaul |
| | | 205 | | { |
| | 0 | 206 | | var client = await createClientAsync(workflowState.Id, cancellationToken); |
| | 0 | 207 | | await client.ImportStateAsync(workflowState, cancellationToken); |
| | 0 | 208 | | } |
| | | 209 | | |
| | | 210 | | public async Task UpdateBookmarkAsync(StoredBookmark bookmark, CancellationToken cancellationToken = default) |
| | | 211 | | { |
| | 0 | 212 | | await bookmarkStore.SaveAsync(bookmark, cancellationToken); |
| | 0 | 213 | | } |
| | | 214 | | |
| | | 215 | | public async Task<long> CountRunningWorkflowsAsync(CountRunningWorkflowsRequest request, CancellationToken cancellat |
| | | 216 | | { |
| | 0 | 217 | | var filter = new WorkflowInstanceFilter |
| | 0 | 218 | | { |
| | 0 | 219 | | DefinitionId = request.DefinitionId, |
| | 0 | 220 | | Version = request.Version, |
| | 0 | 221 | | CorrelationId = request.CorrelationId, |
| | 0 | 222 | | WorkflowStatus = WorkflowStatus.Running |
| | 0 | 223 | | }; |
| | 0 | 224 | | return await workflowInstanceStore.CountAsync(filter, cancellationToken); |
| | 0 | 225 | | } |
| | | 226 | | |
| | | 227 | | private async Task<IEnumerable<WorkflowMatch>> FindStartableWorkflowsAsync(WorkflowsFilter filter, CancellationToken |
| | | 228 | | { |
| | 0 | 229 | | var stimulusHash = stimulusHasher.Hash(filter.ActivityTypeName, filter.BookmarkPayload, filter.Options.ActivityI |
| | 0 | 230 | | var triggerBoundWorkflows = await triggerBoundWorkflowService.FindManyAsync(stimulusHash, cancellationToken).ToL |
| | 0 | 231 | | var correlationId = filter.Options.CorrelationId; |
| | | 232 | | |
| | 0 | 233 | | var query = |
| | 0 | 234 | | from triggerBoundWorkflow in triggerBoundWorkflows |
| | 0 | 235 | | from trigger in triggerBoundWorkflow.Triggers |
| | 0 | 236 | | select new StartableWorkflowMatch(correlationId, trigger.ActivityId, triggerBoundWorkflow.WorkflowGraph. |
| | | 237 | | |
| | 0 | 238 | | return query.ToList(); |
| | 0 | 239 | | } |
| | | 240 | | |
| | | 241 | | private async Task<IEnumerable<WorkflowMatch>> FindResumableWorkflowsAsync(WorkflowsFilter filter, CancellationToken |
| | | 242 | | { |
| | 0 | 243 | | var bookmarkOptions = new FindBookmarkOptions |
| | 0 | 244 | | { |
| | 0 | 245 | | CorrelationId = filter.Options.CorrelationId, |
| | 0 | 246 | | WorkflowInstanceId = filter.Options.WorkflowInstanceId, |
| | 0 | 247 | | ActivityInstanceId = filter.Options.ActivityInstanceId |
| | 0 | 248 | | }; |
| | 0 | 249 | | var bookmarkBoundWorkflows = await bookmarkBoundWorkflowService.FindManyAsync(filter.ActivityTypeName, filter.Bo |
| | | 250 | | |
| | 0 | 251 | | return ( |
| | 0 | 252 | | from bookmarkBoundWorkflow in bookmarkBoundWorkflows |
| | 0 | 253 | | from bookmark in bookmarkBoundWorkflow.Bookmarks |
| | 0 | 254 | | select new ResumableWorkflowMatch(bookmarkBoundWorkflow.WorkflowInstanceId, bookmark.CorrelationId, book |
| | 0 | 255 | | .ToList(); |
| | 0 | 256 | | } |
| | | 257 | | } |