Implement V3 stores (#2980)

* Implement IWorkflowInstanceStore

* Implement IWorkflowDefinitionStore

* Implement IWorkflowTriggerStore

* Implement IWorkflowBookmarkStore

* Implement IWorkflowExecutonLogStore

* Restructure folders

* Persist workflow instance status timestamps
This commit is contained in:
Sipke Schoorstra 2022-04-30 15:10:11 +02:00 committed by GitHub
parent 261c9cb1a5
commit a44ceaeb55
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
182 changed files with 941 additions and 1547 deletions

View file

@ -30,12 +30,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Api", "src\api\Elsa.Ap
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "persistence", "persistence", "{9B7776E2-0014-4C87-B1F4-22FB0BC076F1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.InMemory", "src\persistence\Elsa.Persistence.InMemory\Elsa.Persistence.InMemory.csproj", "{BC97FD3A-1351-443C-9EAE-0F28F8204A6C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "runtime", "runtime", "{04584653-8E42-47DB-850B-7C6C37B307B7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.Abstractions", "src\persistence\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj", "{C0226CDD-DF79-4767-A4A5-3D9037535929}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dsl", "dsl", "{CE121DFD-72D4-4DB7-968F-C0DB320D08FB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Dsl", "src\dsl\Elsa.Dsl\Elsa.Dsl.csproj", "{61F5C50C-C572-46AB-8F37-54D1F84CC31D}"
@ -58,10 +54,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Management", "src\core
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "efcore", "efcore", "{9F8AE7FB-E5F9-4DCB-9CF8-0362B3D18DAA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.EntityFrameworkCore", "src\persistence\Elsa.Persistence.EntityFrameworkCore\Elsa.Persistence.EntityFrameworkCore.csproj", "{D8130816-C1D9-40A3-9079-F2887FE35EA9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.EntityFrameworkCore.Sqlite", "src\persistence\Elsa.Persistence.EntityFrameworkCore.Sqlite\Elsa.Persistence.EntityFrameworkCore.Sqlite.csproj", "{820016B7-01CD-4032-8239-6A4E53F1A352}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Scripting.Liquid", "src\scripting\Elsa.Scripting.Liquid\Elsa.Scripting.Liquid.csproj", "{A7473430-F228-4534-AEA5-AA8D80E09364}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}"
@ -84,8 +76,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Modules.Hangfire", "sr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Modules.WorkflowContexts", "src\modules\Elsa.Modules.WorkflowContexts\Elsa.Modules.WorkflowContexts.csproj", "{302BFC43-ED2F-43AE-8AD4-FCD481B0AC67}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Modules.SetName", "src\modules\Elsa.Modules.SetName\Elsa.Modules.SetName.csproj", "{E4EB94A0-E6F6-4EFA-BE55-7CEED1D8431A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Modules.Activities", "src\modules\Elsa.Modules.Activities\Elsa.Modules.Activities.csproj", "{05249066-9125-47D8-847B-A86887B1D269}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.ServiceBus.Abstractions", "src\core\Elsa.ServiceBus.Abstractions\Elsa.ServiceBus.Abstractions.csproj", "{61FAFEED-A477-4D8F-A293-C0196F11EA0F}"
@ -108,6 +98,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.AllInOne.Web", "src\ap
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Runtime", "src\core\Elsa.Runtime\Elsa.Runtime.csproj", "{B3C22F07-C20C-440A-91EF-57685B6BFB42}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.Abstractions", "src\core\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj", "{904FF38F-32AE-4046-AD80-474D0E702C7C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "memory", "memory", "{1B264AAB-D41D-4457-988D-CBEB34EA4A9E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.InMemory", "src\persistence\memory\Elsa.Persistence.InMemory\Elsa.Persistence.InMemory.csproj", "{5F00DBC2-12B5-483C-A875-A5BC7CDCA8C0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.EntityFrameworkCore", "src\persistence\efcore\Elsa.Persistence.EntityFrameworkCore\Elsa.Persistence.EntityFrameworkCore.csproj", "{92CC542F-942B-4EF4-A4DE-970332B68394}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.EntityFrameworkCore.Sqlite", "src\persistence\efcore\Elsa.Persistence.EntityFrameworkCore.Sqlite\Elsa.Persistence.EntityFrameworkCore.Sqlite.csproj", "{C81E2148-283E-409F-BFE7-60CD2E227887}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -130,14 +130,6 @@ Global
{39C6C4A2-077E-48C2-B295-DFE357EC38B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39C6C4A2-077E-48C2-B295-DFE357EC38B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39C6C4A2-077E-48C2-B295-DFE357EC38B2}.Release|Any CPU.Build.0 = Release|Any CPU
{BC97FD3A-1351-443C-9EAE-0F28F8204A6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC97FD3A-1351-443C-9EAE-0F28F8204A6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC97FD3A-1351-443C-9EAE-0F28F8204A6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC97FD3A-1351-443C-9EAE-0F28F8204A6C}.Release|Any CPU.Build.0 = Release|Any CPU
{C0226CDD-DF79-4767-A4A5-3D9037535929}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C0226CDD-DF79-4767-A4A5-3D9037535929}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C0226CDD-DF79-4767-A4A5-3D9037535929}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C0226CDD-DF79-4767-A4A5-3D9037535929}.Release|Any CPU.Build.0 = Release|Any CPU
{61F5C50C-C572-46AB-8F37-54D1F84CC31D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61F5C50C-C572-46AB-8F37-54D1F84CC31D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61F5C50C-C572-46AB-8F37-54D1F84CC31D}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -170,14 +162,6 @@ Global
{03C2D8B9-C61F-4750-8107-765E3FE02ADA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03C2D8B9-C61F-4750-8107-765E3FE02ADA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03C2D8B9-C61F-4750-8107-765E3FE02ADA}.Release|Any CPU.Build.0 = Release|Any CPU
{D8130816-C1D9-40A3-9079-F2887FE35EA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D8130816-C1D9-40A3-9079-F2887FE35EA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D8130816-C1D9-40A3-9079-F2887FE35EA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D8130816-C1D9-40A3-9079-F2887FE35EA9}.Release|Any CPU.Build.0 = Release|Any CPU
{820016B7-01CD-4032-8239-6A4E53F1A352}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{820016B7-01CD-4032-8239-6A4E53F1A352}.Debug|Any CPU.Build.0 = Debug|Any CPU
{820016B7-01CD-4032-8239-6A4E53F1A352}.Release|Any CPU.ActiveCfg = Release|Any CPU
{820016B7-01CD-4032-8239-6A4E53F1A352}.Release|Any CPU.Build.0 = Release|Any CPU
{A7473430-F228-4534-AEA5-AA8D80E09364}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7473430-F228-4534-AEA5-AA8D80E09364}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7473430-F228-4534-AEA5-AA8D80E09364}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -218,10 +202,6 @@ Global
{302BFC43-ED2F-43AE-8AD4-FCD481B0AC67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{302BFC43-ED2F-43AE-8AD4-FCD481B0AC67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{302BFC43-ED2F-43AE-8AD4-FCD481B0AC67}.Release|Any CPU.Build.0 = Release|Any CPU
{E4EB94A0-E6F6-4EFA-BE55-7CEED1D8431A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E4EB94A0-E6F6-4EFA-BE55-7CEED1D8431A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4EB94A0-E6F6-4EFA-BE55-7CEED1D8431A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4EB94A0-E6F6-4EFA-BE55-7CEED1D8431A}.Release|Any CPU.Build.0 = Release|Any CPU
{05249066-9125-47D8-847B-A86887B1D269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{05249066-9125-47D8-847B-A86887B1D269}.Debug|Any CPU.Build.0 = Debug|Any CPU
{05249066-9125-47D8-847B-A86887B1D269}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -258,6 +238,22 @@ Global
{B3C22F07-C20C-440A-91EF-57685B6BFB42}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3C22F07-C20C-440A-91EF-57685B6BFB42}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3C22F07-C20C-440A-91EF-57685B6BFB42}.Release|Any CPU.Build.0 = Release|Any CPU
{904FF38F-32AE-4046-AD80-474D0E702C7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{904FF38F-32AE-4046-AD80-474D0E702C7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{904FF38F-32AE-4046-AD80-474D0E702C7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{904FF38F-32AE-4046-AD80-474D0E702C7C}.Release|Any CPU.Build.0 = Release|Any CPU
{5F00DBC2-12B5-483C-A875-A5BC7CDCA8C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5F00DBC2-12B5-483C-A875-A5BC7CDCA8C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5F00DBC2-12B5-483C-A875-A5BC7CDCA8C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F00DBC2-12B5-483C-A875-A5BC7CDCA8C0}.Release|Any CPU.Build.0 = Release|Any CPU
{92CC542F-942B-4EF4-A4DE-970332B68394}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92CC542F-942B-4EF4-A4DE-970332B68394}.Debug|Any CPU.Build.0 = Debug|Any CPU
{92CC542F-942B-4EF4-A4DE-970332B68394}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92CC542F-942B-4EF4-A4DE-970332B68394}.Release|Any CPU.Build.0 = Release|Any CPU
{C81E2148-283E-409F-BFE7-60CD2E227887}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C81E2148-283E-409F-BFE7-60CD2E227887}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C81E2148-283E-409F-BFE7-60CD2E227887}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C81E2148-283E-409F-BFE7-60CD2E227887}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{155227F0-A33B-40AA-A4B4-06F813EB921B} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
@ -270,9 +266,7 @@ Global
{298BA226-B766-40AE-933F-EB9AFCDE051C} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
{39C6C4A2-077E-48C2-B295-DFE357EC38B2} = {298BA226-B766-40AE-933F-EB9AFCDE051C}
{9B7776E2-0014-4C87-B1F4-22FB0BC076F1} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
{BC97FD3A-1351-443C-9EAE-0F28F8204A6C} = {9B7776E2-0014-4C87-B1F4-22FB0BC076F1}
{04584653-8E42-47DB-850B-7C6C37B307B7} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
{C0226CDD-DF79-4767-A4A5-3D9037535929} = {9B7776E2-0014-4C87-B1F4-22FB0BC076F1}
{CE121DFD-72D4-4DB7-968F-C0DB320D08FB} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
{61F5C50C-C572-46AB-8F37-54D1F84CC31D} = {CE121DFD-72D4-4DB7-968F-C0DB320D08FB}
{48960E35-903C-4EF0-A8F4-3871B000B12D} = {873BFC3E-63C2-4495-A503-5EC05DCD84E4}
@ -284,8 +278,6 @@ Global
{5CC45C6C-0751-4A33-8306-758BB17417F7} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
{03C2D8B9-C61F-4750-8107-765E3FE02ADA} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
{9F8AE7FB-E5F9-4DCB-9CF8-0362B3D18DAA} = {9B7776E2-0014-4C87-B1F4-22FB0BC076F1}
{D8130816-C1D9-40A3-9079-F2887FE35EA9} = {9F8AE7FB-E5F9-4DCB-9CF8-0362B3D18DAA}
{820016B7-01CD-4032-8239-6A4E53F1A352} = {9F8AE7FB-E5F9-4DCB-9CF8-0362B3D18DAA}
{A7473430-F228-4534-AEA5-AA8D80E09364} = {2633B8B9-4AEC-4A54-8832-1C940B54E041}
{5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
{7D5A49B4-9A9B-496E-803B-DEB85B2C3132} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
@ -297,7 +289,6 @@ Global
{D31581AB-A6C1-4B73-AB63-45667F6C82AE} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{0601A2A6-2C62-418B-9104-8CDE497E5283} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{302BFC43-ED2F-43AE-8AD4-FCD481B0AC67} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{E4EB94A0-E6F6-4EFA-BE55-7CEED1D8431A} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{05249066-9125-47D8-847B-A86887B1D269} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{61FAFEED-A477-4D8F-A293-C0196F11EA0F} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
{BB983D0B-A939-4008-B9E3-C7C172BCF83A} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
@ -308,5 +299,10 @@ Global
{2CA48C3F-1B7C-454B-BEA8-58718090B4EB} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F}
{8CB06629-BD00-46FF-B727-FC86B286A07E} = {2CA48C3F-1B7C-454B-BEA8-58718090B4EB}
{B3C22F07-C20C-440A-91EF-57685B6BFB42} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
{904FF38F-32AE-4046-AD80-474D0E702C7C} = {C6658DE0-2B2F-47F0-BB61-2CA66D435C09}
{1B264AAB-D41D-4457-988D-CBEB34EA4A9E} = {9B7776E2-0014-4C87-B1F4-22FB0BC076F1}
{5F00DBC2-12B5-483C-A875-A5BC7CDCA8C0} = {1B264AAB-D41D-4457-988D-CBEB34EA4A9E}
{92CC542F-942B-4EF4-A4DE-970332B68394} = {9F8AE7FB-E5F9-4DCB-9CF8-0362B3D18DAA}
{C81E2148-283E-409F-BFE7-60CD2E227887} = {9F8AE7FB-E5F9-4DCB-9CF8-0362B3D18DAA}
EndGlobalSection
EndGlobal

View file

@ -1,26 +1,23 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Management.Services;
using Elsa.Mediator.Services;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Microsoft.AspNetCore.Http;
namespace Elsa.Api.Endpoints.WorkflowInstances;
public static partial class WorkflowInstances
{
public static async Task<IResult> DeleteAsync(string id, IRequestSender requestSender,
IWorkflowInstancePublisher workflowInstancePublisher, CancellationToken cancellationToken)
public static async Task<IResult> DeleteAsync(
string id,
IWorkflowInstanceStore workflowInstanceStore,
CancellationToken cancellationToken)
{
var request = new FindWorkflowInstance(id);
var workflowInstance = await requestSender.RequestAsync(request, cancellationToken);
var workflowInstance = await workflowInstanceStore.FindByIdAsync(id, cancellationToken);
if (workflowInstance == null)
{
return Results.NotFound();
}
await workflowInstancePublisher.DeleteAsync(id, cancellationToken);
await workflowInstanceStore.DeleteAsync(id, cancellationToken);
return Results.NoContent();
}
}

View file

@ -1,7 +1,6 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Mediator.Services;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
@ -9,11 +8,10 @@ namespace Elsa.Api.Endpoints.WorkflowInstances;
public static partial class WorkflowInstances
{
public static async Task<IResult> GetAsync(IRequestSender requestSender, WorkflowSerializerOptionsProvider serializerOptionsProvider, string id, CancellationToken cancellationToken)
public static async Task<IResult> GetAsync(IWorkflowInstanceStore workflowInstanceStore, WorkflowSerializerOptionsProvider serializerOptionsProvider, string id, CancellationToken cancellationToken)
{
var serializerOptions = serializerOptionsProvider.CreateApiOptions();
var request = new FindWorkflowInstance(id);
var workflowInstance = await requestSender.RequestAsync(request, cancellationToken);
var workflowInstance = await workflowInstanceStore.FindByIdAsync(id, cancellationToken);
return workflowInstance != null ? Results.Json(workflowInstance, serializerOptions, statusCode: StatusCodes.Status200OK) : Results.NotFound();
}
}

View file

@ -1,10 +1,9 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -14,7 +13,7 @@ namespace Elsa.Api.Endpoints.WorkflowInstances;
public static partial class WorkflowInstances
{
public static async Task<IResult> ListAsync(
IRequestSender requestSender,
IWorkflowInstanceStore workflowInstanceStore,
WorkflowSerializerOptionsProvider serializerOptionsProvider,
CancellationToken cancellationToken,
[FromQuery] int? page,
@ -31,7 +30,7 @@ public static partial class WorkflowInstances
var serializerOptions = serializerOptionsProvider.CreateApiOptions();
var pageArgs = new PageArgs(page, pageSize);
var request = new ListWorkflowInstanceSummaries(
var request = new FindWorkflowInstancesArgs(
searchTerm,
definitionId,
version,
@ -42,7 +41,7 @@ public static partial class WorkflowInstances
orderBy ?? OrderBy.Created,
orderDirection ?? OrderDirection.Ascending);
var summaries = await requestSender.RequestAsync(request, cancellationToken);
var summaries = await workflowInstanceStore.FindManyAsync(request, cancellationToken);
return Results.Json(summaries, serializerOptions, statusCode: StatusCodes.Status200OK);
}

View file

@ -1,16 +1,15 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Mediator.Services;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Services;
using Microsoft.AspNetCore.Http;
namespace Elsa.Api.Endpoints.Workflows;
public static partial class Workflows
{
public static async Task<IResult> DeleteAsync(string definitionId, ICommandSender commandSender, CancellationToken cancellationToken)
public static async Task<IResult> DeleteAsync(string definitionId, IWorkflowDefinitionStore workflowDefinitionStore, CancellationToken cancellationToken)
{
var result = await commandSender.ExecuteAsync(new DeleteWorkflowDefinition(definitionId), cancellationToken);
return !result ? Results.NotFound() : Results.NoContent();
var result = await workflowDefinitionStore.DeleteByDefinitionIdAsync(definitionId, cancellationToken);
return result == 0 ? Results.NotFound() : Results.NoContent();
}
}

View file

@ -1,8 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Mediator.Services;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -12,7 +11,7 @@ namespace Elsa.Api.Endpoints.Workflows;
public static partial class Workflows
{
public static async Task<IResult> Get(
IRequestSender requestSender,
IWorkflowDefinitionStore workflowDefinitionStore,
WorkflowSerializerOptionsProvider serializerOptionsProvider,
CancellationToken cancellationToken,
[FromRoute] string definitionId,
@ -20,7 +19,7 @@ public static partial class Workflows
{
var serializerOptions = serializerOptionsProvider.CreateApiOptions();
var parsedVersionOptions = versionOptions != null ? VersionOptions.FromString(versionOptions) : VersionOptions.Latest;
var workflow = await requestSender.RequestAsync(new FindWorkflowDefinitionByDefinitionId(definitionId, parsedVersionOptions), cancellationToken);
var workflow = await workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, parsedVersionOptions, cancellationToken);
return workflow == null ? Results.NotFound() : Results.Json(workflow, serializerOptions, statusCode: StatusCodes.Status200OK);
}
}

View file

@ -1,9 +1,8 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Mediator.Services;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -13,7 +12,7 @@ namespace Elsa.Api.Endpoints.Workflows;
public static partial class Workflows
{
public static async Task<IResult> GetManyAsync(
IRequestSender requestSender,
IWorkflowDefinitionStore workflowDefinitionStore,
WorkflowSerializerOptionsProvider serializerOptionsProvider,
CancellationToken cancellationToken,
[FromQuery] string? definitionIds = default,
@ -22,7 +21,7 @@ public static partial class Workflows
var serializerOptions = serializerOptionsProvider.CreateApiOptions();
var splitIds = definitionIds?.Split(',', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>();
var parsedVersionOptions = versionOptions != null ? VersionOptions.FromString(versionOptions) : VersionOptions.Latest;
var workflowSummaries = await requestSender.RequestAsync(new FindManyWorkflowDefinitions(splitIds, parsedVersionOptions), cancellationToken);
var workflowSummaries = await workflowDefinitionStore.FindManySummariesAsync(splitIds, parsedVersionOptions, cancellationToken);
return Results.Json(workflowSummaries, serializerOptions, statusCode: StatusCodes.Status200OK);
}

View file

@ -1,8 +1,7 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Mediator.Services;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -12,7 +11,7 @@ namespace Elsa.Api.Endpoints.Workflows;
public static partial class Workflows
{
public static async Task<IResult> ListAsync(
IRequestSender requestSender,
IWorkflowDefinitionStore workflowDefinitionStore,
WorkflowSerializerOptionsProvider serializerOptionsProvider,
CancellationToken cancellationToken,
[FromQuery] string? versionOptions,
@ -22,7 +21,7 @@ public static partial class Workflows
var serializerOptions = serializerOptionsProvider.CreateApiOptions();
var pageArgs = new PageArgs(page, pageSize);
var parsedVersionOptions = versionOptions != null ? VersionOptions.FromString(versionOptions) : default;
var workflowSummaries = await requestSender.RequestAsync(new ListWorkflowDefinitionSummaries(parsedVersionOptions, pageArgs), cancellationToken);
var workflowSummaries = await workflowDefinitionStore.ListSummariesAsync(parsedVersionOptions, pageArgs, cancellationToken);
return Results.Json(workflowSummaries, serializerOptions, statusCode: StatusCodes.Status200OK);
}

View file

@ -1,9 +1,8 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Management.Services;
using Elsa.Mediator.Services;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
@ -14,11 +13,11 @@ public static partial class Workflows
public static async Task<IResult> PublishAsync(
string definitionId,
WorkflowSerializerOptionsProvider serializerOptionsProvider,
IRequestSender requestSender,
IWorkflowDefinitionStore workflowDefinitionStore,
IWorkflowPublisher workflowPublisher,
CancellationToken cancellationToken)
{
var definition = await requestSender.RequestAsync(new FindWorkflowDefinitionByDefinitionId(definitionId, VersionOptions.Latest), cancellationToken);
var definition = await workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
if (definition == null)
return Results.NotFound();

View file

@ -1,9 +1,8 @@
using System.Threading;
using System.Threading.Tasks;
using Elsa.Management.Services;
using Elsa.Mediator.Services;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Runtime.Services;
using Elsa.Serialization;
using Microsoft.AspNetCore.Http;
@ -15,12 +14,12 @@ public static partial class Workflows
public static async Task<IResult> RetractAsync(
string definitionId,
WorkflowSerializerOptionsProvider serializerOptionsProvider,
IRequestSender requestSender,
IWorkflowDefinitionStore workflowDefinitionStore,
IWorkflowPublisher workflowPublisher,
IWorkflowDefinitionService workflowDefinitionService,
CancellationToken cancellationToken)
{
var definition = await requestSender.RequestAsync(new FindWorkflowDefinitionByDefinitionId(definitionId, VersionOptions.LatestOrPublished), cancellationToken);
var definition = await workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.LatestOrPublished, cancellationToken);
if (definition == null)
return Results.NotFound();

View file

@ -9,7 +9,6 @@
<ItemGroup>
<ProjectReference Include="..\..\api\Elsa.Api\Elsa.Api.csproj" />
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Modules.Activities\Elsa.Modules.Activities.csproj" />
<ProjectReference Include="..\..\modules\Elsa.Modules.Hangfire\Elsa.Modules.Hangfire.csproj" />

View file

@ -13,7 +13,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\persistence\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj" />
<ProjectReference Include="..\..\core\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj" />
</ItemGroup>
</Project>

View file

@ -16,7 +16,6 @@ public static class ServiceCollectionExtensions
{
return services
.AddSingleton<IWorkflowPublisher, WorkflowPublisher>()
.AddSingleton<IWorkflowInstancePublisher, WorkflowInstancePublisher>()
.AddSingleton<IActivityDescriber, ActivityDescriber>()
.AddSingleton<IActivityRegistry, ActivityRegistry>()
.AddSingleton<IActivityRegistryPopulator, ActivityRegistryPopulator>()

View file

@ -1,25 +0,0 @@
using Elsa.Management.Services;
using Elsa.Mediator.Services;
using Elsa.Persistence.Commands;
namespace Elsa.Management.Implementations;
public class WorkflowInstancePublisher : IWorkflowInstancePublisher
{
private readonly IMediator _mediator;
public WorkflowInstancePublisher(IMediator mediator)
{
_mediator = mediator;
}
public async Task DeleteAsync(string instanceId, CancellationToken cancellationToken = default)
{
await _mediator.ExecuteAsync(new DeleteWorkflowInstance(instanceId),
cancellationToken);
}
public async Task BulkDeleteAsync(IEnumerable<string> instanceIds, CancellationToken cancellationToken = default)
{
await _mediator.ExecuteAsync(new DeleteWorkflowInstances(instanceIds), cancellationToken);
}
}

View file

@ -4,10 +4,9 @@ using Elsa.Management.Materializers;
using Elsa.Management.Notifications;
using Elsa.Management.Services;
using Elsa.Mediator.Services;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Serialization;
using Elsa.Services;
@ -15,14 +14,21 @@ namespace Elsa.Management.Implementations
{
public class WorkflowPublisher : IWorkflowPublisher
{
private readonly IMediator _mediator;
private readonly IWorkflowDefinitionStore _workflowDefinitionStore;
private readonly IEventPublisher _eventPublisher;
private readonly IIdentityGenerator _identityGenerator;
private readonly WorkflowSerializerOptionsProvider _workflowSerializerOptionsProvider;
private readonly ISystemClock _systemClock;
public WorkflowPublisher(IMediator mediator, IIdentityGenerator identityGenerator, WorkflowSerializerOptionsProvider workflowSerializerOptionsProvider, ISystemClock systemClock)
public WorkflowPublisher(
IWorkflowDefinitionStore workflowDefinitionStore,
IEventPublisher eventPublisher,
IIdentityGenerator identityGenerator,
WorkflowSerializerOptionsProvider workflowSerializerOptionsProvider,
ISystemClock systemClock)
{
_mediator = mediator;
_workflowDefinitionStore = workflowDefinitionStore;
_eventPublisher = eventPublisher;
_identityGenerator = identityGenerator;
_workflowSerializerOptionsProvider = workflowSerializerOptionsProvider;
_systemClock = systemClock;
@ -49,7 +55,7 @@ namespace Elsa.Management.Implementations
public async Task<WorkflowDefinition?> PublishAsync(string definitionId, CancellationToken cancellationToken = default)
{
var definition = await _mediator.RequestAsync(new FindWorkflowDefinitionByDefinitionId(definitionId, VersionOptions.Latest), cancellationToken);
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
if (definition == null)
return null;
@ -62,13 +68,13 @@ namespace Elsa.Management.Implementations
var definitionId = definition.DefinitionId;
// Reset current latest and published definitions.
var publishedAndOrLatestWorkflows = await _mediator.RequestAsync(new FindLatestAndPublishedWorkflows(definitionId), cancellationToken);
var publishedAndOrLatestWorkflows = await _workflowDefinitionStore.FindLatestAndPublishedByDefinitionIdAsync(definitionId, cancellationToken);
foreach (var publishedAndOrLatestWorkflow in publishedAndOrLatestWorkflows)
{
publishedAndOrLatestWorkflow.IsPublished = false;
publishedAndOrLatestWorkflow.IsLatest = false;
await _mediator.ExecuteAsync(new SaveWorkflowDefinition(publishedAndOrLatestWorkflow), cancellationToken);
await _workflowDefinitionStore.SaveAsync(publishedAndOrLatestWorkflow, cancellationToken);
}
if (definition.IsPublished)
@ -79,15 +85,15 @@ namespace Elsa.Management.Implementations
definition.IsLatest = true;
definition = Initialize(definition);
await _mediator.PublishAsync(new WorkflowDefinitionPublishing(definition), cancellationToken);
await _mediator.ExecuteAsync(new SaveWorkflowDefinition(definition), cancellationToken);
await _mediator.PublishAsync(new WorkflowDefinitionPublished(definition), cancellationToken);
await _eventPublisher.PublishAsync(new WorkflowDefinitionPublishing(definition), cancellationToken);
await _workflowDefinitionStore.SaveAsync(definition, cancellationToken);
await _eventPublisher.PublishAsync(new WorkflowDefinitionPublished(definition), cancellationToken);
return definition;
}
public async Task<WorkflowDefinition?> RetractAsync(string definitionId, CancellationToken cancellationToken = default)
{
var definition = await _mediator.RequestAsync(new FindWorkflowDefinitionByDefinitionId(definitionId, VersionOptions.Published), cancellationToken);
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Published, cancellationToken);
if (definition == null)
return null;
@ -103,15 +109,15 @@ namespace Elsa.Management.Implementations
definition.IsPublished = false;
definition = Initialize(definition);
await _mediator.PublishAsync(new WorkflowDefinitionRetracting(definition), cancellationToken);
await _mediator.ExecuteAsync(new SaveWorkflowDefinition(definition), cancellationToken);
await _mediator.PublishAsync(new WorkflowDefinitionRetracted(definition), cancellationToken);
await _eventPublisher.PublishAsync(new WorkflowDefinitionRetracting(definition), cancellationToken);
await _workflowDefinitionStore.SaveAsync(definition, cancellationToken);
await _eventPublisher.PublishAsync(new WorkflowDefinitionRetracted(definition), cancellationToken);
return definition;
}
public async Task<WorkflowDefinition?> GetDraftAsync(string definitionId, CancellationToken cancellationToken = default)
{
var definition = await _mediator.RequestAsync(new FindWorkflowDefinitionByDefinitionId(definitionId, VersionOptions.Latest), cancellationToken);
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
if (definition == null)
return null;
@ -132,30 +138,22 @@ namespace Elsa.Management.Implementations
{
var draft = definition;
var definitionId = definition.DefinitionId;
var latestVersion = await _mediator.RequestAsync(new FindWorkflowDefinitionByDefinitionId(definitionId, VersionOptions.Latest), cancellationToken);
var latestVersion = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
if (latestVersion is { IsPublished: true, IsLatest: true })
{
latestVersion.IsLatest = false;
await _mediator.ExecuteAsync(new SaveWorkflowDefinition(latestVersion), cancellationToken);
await _workflowDefinitionStore.SaveAsync(latestVersion, cancellationToken);
}
draft.IsLatest = true;
draft.IsPublished = false;
draft = Initialize(draft);
await _mediator.ExecuteAsync(new SaveWorkflowDefinition(draft), cancellationToken);
await _workflowDefinitionStore.SaveAsync(draft, cancellationToken);
return draft;
}
public async Task DeleteAsync(string definitionId, CancellationToken cancellationToken = default)
{
await _mediator.ExecuteAsync(new DeleteWorkflowInstances(definitionId), cancellationToken);
await _mediator.ExecuteAsync(new DeleteWorkflowDefinition(definitionId), cancellationToken);
}
public Task DeleteAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default) => DeleteAsync(definition.DefinitionId, cancellationToken);
private WorkflowDefinition Initialize(WorkflowDefinition definition)
{
if (definition.Id == null!)

View file

@ -1,5 +1,4 @@
using System.Text.Json;
using System.Threading.Tasks;
using Elsa.Management.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;

View file

@ -1,5 +1,4 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
namespace Elsa.Management.Notifications;

View file

@ -1,5 +1,4 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
namespace Elsa.Management.Notifications;

View file

@ -1,5 +1,4 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
namespace Elsa.Management.Notifications;

View file

@ -1,5 +1,4 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
namespace Elsa.Management.Notifications;

View file

@ -1,6 +0,0 @@
namespace Elsa.Management.Services;
public interface IWorkflowInstancePublisher
{
Task DeleteAsync(string instanceId, CancellationToken cancellationToken = default);
}

View file

@ -1,4 +1,3 @@
using Elsa.Models;
using Elsa.Persistence.Entities;
namespace Elsa.Management.Services
@ -12,7 +11,5 @@ namespace Elsa.Management.Services
Task<WorkflowDefinition> RetractAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default);
Task<WorkflowDefinition?> GetDraftAsync(string definitionId, CancellationToken cancellationToken = default);
Task<WorkflowDefinition> SaveDraftAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default);
Task DeleteAsync(string definitionId, CancellationToken cancellationToken = default);
Task DeleteAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default);
}
}

View file

@ -1,5 +1,4 @@
using Elsa.Models;
using Elsa.Services;
namespace Elsa.Persistence.Entities;

View file

@ -2,6 +2,7 @@ namespace Elsa.Persistence.Entities
{
public class WorkflowExecutionLogRecord : Entity
{
public string WorkflowDefinitionId { get; set; } = default!;
public string WorkflowInstanceId { get; set; } = default!;
public string ActivityId { get; set; } = default!;
public string ActivityType { get; set; } = default!;

View file

@ -0,0 +1,14 @@
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Services;
public interface IWorkflowBookmarkStore
{
Task SaveAsync(WorkflowBookmark record, CancellationToken cancellationToken = default);
Task SaveManyAsync(IEnumerable<WorkflowBookmark> records, CancellationToken cancellationToken = default);
Task<WorkflowBookmark?> FindByIdAsync(string id, CancellationToken cancellationToken = default);
Task<IEnumerable<WorkflowBookmark>> FindManyAsync(string name, string? hash = default, CancellationToken cancellationToken = default);
Task<IEnumerable<WorkflowBookmark>> FindManyByWorkflowInstanceIdAsync(string workflowInstanceId, CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(string id, CancellationToken cancellationToken = default);
Task<int> DeleteManyAsync(IEnumerable<string> ids, CancellationToken cancellationToken = default);
}

View file

@ -0,0 +1,17 @@
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
namespace Elsa.Persistence.Services;
public interface IWorkflowDefinitionStore
{
Task<WorkflowDefinition?> FindByDefinitionIdAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default);
Task<WorkflowDefinition?> FindByNameAsync(string name, VersionOptions versionOptions, CancellationToken cancellationToken = default);
Task<IEnumerable<WorkflowDefinitionSummary>> FindManySummariesAsync(IEnumerable<string> definitionIds, VersionOptions? versionOptions = default, CancellationToken cancellationToken = default);
Task<IEnumerable<WorkflowDefinition>> FindLatestAndPublishedByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default);
Task SaveAsync(WorkflowDefinition record, CancellationToken cancellationToken = default);
Task SaveManyAsync(IEnumerable<WorkflowDefinition> records, CancellationToken cancellationToken = default);
Task<int> DeleteByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default);
Task<int> DeleteManyByDefinitionIdsAsync(IEnumerable<string> definitionIds, CancellationToken cancellationToken = default);
Task<Page<WorkflowDefinitionSummary>> ListSummariesAsync(VersionOptions? versionOptions = default, PageArgs? pageArgs = default, CancellationToken cancellationToken = default);
}

View file

@ -0,0 +1,9 @@
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Services;
public interface IWorkflowExecutionLogStore
{
Task SaveAsync(WorkflowExecutionLogRecord record, CancellationToken cancellationToken = default);
Task SaveManyAsync(IEnumerable<WorkflowExecutionLogRecord> records, CancellationToken cancellationToken = default);
}

View file

@ -0,0 +1,28 @@
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
namespace Elsa.Persistence.Services;
public interface IWorkflowInstanceStore
{
Task<WorkflowInstance?> FindByIdAsync(string id, CancellationToken cancellationToken = default);
Task SaveAsync(WorkflowInstance record, CancellationToken cancellationToken = default);
Task SaveManyAsync(IEnumerable<WorkflowInstance> records, CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(string id, CancellationToken cancellationToken = default);
Task<int> DeleteManyAsync(IEnumerable<string> ids, CancellationToken cancellationToken = default);
Task DeleteManyByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default);
Task<Page<WorkflowInstanceSummary>> FindManyAsync(FindWorkflowInstancesArgs args, CancellationToken cancellationToken = default);
}
public record FindWorkflowInstancesArgs(
string? SearchTerm = default,
string? DefinitionId = default,
int? Version = default,
string? CorrelationId = default,
WorkflowStatus? WorkflowStatus = default,
WorkflowSubStatus? WorkflowSubStatus = default,
PageArgs? PageArgs = default,
OrderBy OrderBy = OrderBy.Created,
OrderDirection OrderDirection = OrderDirection.Ascending
);

View file

@ -0,0 +1,13 @@
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Services;
public interface IWorkflowTriggerStore
{
Task SaveAsync(WorkflowTrigger record, CancellationToken cancellationToken = default);
Task SaveManyAsync(IEnumerable<WorkflowTrigger> records, CancellationToken cancellationToken = default);
Task<IEnumerable<WorkflowTrigger>> FindManyByNameAsync(string name, string? hash, CancellationToken cancellationToken = default);
Task<IEnumerable<WorkflowTrigger>> FindManyByWorkflowDefinitionIdAsync(string workflowDefinitionId, CancellationToken cancellationToken = default);
Task ReplaceAsync(IEnumerable<WorkflowTrigger> removed, IEnumerable<WorkflowTrigger> added, CancellationToken cancellationToken = default);
Task DeleteManyAsync(IEnumerable<string> ids, CancellationToken cancellationToken = default);
}

View file

@ -10,14 +10,13 @@
<ItemGroup>
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
<ProjectReference Include="..\..\core\Elsa.Management\Elsa.Management.csproj" />
<ProjectReference Include="..\..\persistence\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj" />
<ProjectReference Include="..\..\core\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Open.Linq.AsyncExtensions" Version="1.2.0" />
<!-- <PackageReference Include="System.Linq.Async" Version="6.0.1" />-->
</ItemGroup>
</Project>

View file

@ -1,9 +1,7 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Runtime.Services;
using Microsoft.Extensions.Hosting;
using Open.Linq.AsyncExtensions;
@ -17,15 +15,16 @@ public class PopulateWorkflowDefinitionStore : IHostedService
{
private readonly IEnumerable<IWorkflowDefinitionProvider> _workflowDefinitionProviders;
private readonly ITriggerIndexer _triggerIndexer;
private readonly IRequestSender _requestSender;
private readonly ICommandSender _commandSender;
private readonly IWorkflowDefinitionStore _workflowDefinitionStore;
public PopulateWorkflowDefinitionStore(IEnumerable<IWorkflowDefinitionProvider> workflowDefinitionProviders, ITriggerIndexer triggerIndexer, IRequestSender requestSender, ICommandSender commandSender)
public PopulateWorkflowDefinitionStore(
IEnumerable<IWorkflowDefinitionProvider> workflowDefinitionProviders,
ITriggerIndexer triggerIndexer,
IWorkflowDefinitionStore workflowDefinitionStore)
{
_workflowDefinitionProviders = workflowDefinitionProviders;
_triggerIndexer = triggerIndexer;
_requestSender = requestSender;
_commandSender = commandSender;
_workflowDefinitionStore = workflowDefinitionStore;
}
public async Task StartAsync(CancellationToken cancellationToken)
@ -45,10 +44,9 @@ public class PopulateWorkflowDefinitionStore : IHostedService
private async Task AddOrUpdateAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default)
{
// Check if there's already a workflow definition by the definition ID and version.
var existingDefinition = await _requestSender.RequestAsync(
new FindWorkflowDefinitionByDefinitionId(
definition.DefinitionId,
VersionOptions.SpecificVersion(definition.Version)),
var existingDefinition = await _workflowDefinitionStore.FindByDefinitionIdAsync(
definition.DefinitionId,
VersionOptions.SpecificVersion(definition.Version),
cancellationToken);
if (existingDefinition == null)
@ -68,7 +66,7 @@ public class PopulateWorkflowDefinitionStore : IHostedService
existingDefinition.MaterializerName = definition.MaterializerName;
}
await _commandSender.ExecuteAsync(new SaveWorkflowDefinition(existingDefinition), cancellationToken);
await _workflowDefinitionStore.SaveAsync(existingDefinition, cancellationToken);
}
private async Task IndexTriggersAsync(Workflow workflow, CancellationToken cancellationToken) => await _triggerIndexer.IndexTriggersAsync(workflow, cancellationToken);

View file

@ -1,6 +1,6 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Services;
using Elsa.Runtime.Notifications;
using Elsa.Runtime.Services;
@ -8,12 +8,12 @@ namespace Elsa.Runtime.Implementations;
public class BookmarkManager : IBookmarkManager
{
private readonly ICommandSender _commandSender;
private readonly IWorkflowBookmarkStore _bookmarkStore;
private readonly IEventPublisher _eventPublisher;
public BookmarkManager(ICommandSender commandSender, IEventPublisher eventPublisher)
public BookmarkManager(IWorkflowBookmarkStore bookmarkStore, IEventPublisher eventPublisher)
{
_commandSender = commandSender;
_bookmarkStore = bookmarkStore;
_eventPublisher = eventPublisher;
}
@ -21,14 +21,14 @@ public class BookmarkManager : IBookmarkManager
{
var list = bookmarks.ToList();
var ids = list.Select(x => x.Id).ToList();
await _commandSender.ExecuteAsync(new DeleteWorkflowBookmarks(ids), cancellationToken);
await _bookmarkStore.DeleteManyAsync(ids, cancellationToken);
await _eventPublisher.PublishAsync(new WorkflowBookmarksDeleted(list), cancellationToken);
}
public async Task SaveBookmarksAsync(IEnumerable<WorkflowBookmark> bookmarks, CancellationToken cancellationToken = default)
{
var list = bookmarks.ToList();
await _commandSender.ExecuteAsync(new SaveWorkflowBookmarks(list), cancellationToken);
await _bookmarkStore.SaveManyAsync(list, cancellationToken);
await _eventPublisher.PublishAsync(new WorkflowBookmarksSaved(list), cancellationToken);
}
}

View file

@ -1,8 +1,7 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Runtime.Models;
using Elsa.Runtime.Services;
using Elsa.Services;
@ -15,15 +14,16 @@ namespace Elsa.Runtime.Implementations;
/// </summary>
public class DefaultWorkflowInvoker : IWorkflowInvoker
{
private readonly IWorkflowInstanceFactory _workflowInstanceFactory;
private readonly IRequestSender _requestSender;
private readonly IWorkflowInstanceStore _workflowInstanceStore;
private readonly IWorkflowRunner _workflowRunner;
private readonly IWorkflowRegistry _workflowRegistry;
public DefaultWorkflowInvoker(IWorkflowInstanceFactory workflowInstanceFactory, IRequestSender requestSender, IWorkflowRunner workflowRunner, IWorkflowRegistry workflowRegistry)
public DefaultWorkflowInvoker(
IWorkflowInstanceStore workflowInstanceStore,
IWorkflowRunner workflowRunner,
IWorkflowRegistry workflowRegistry)
{
_workflowInstanceFactory = workflowInstanceFactory;
_requestSender = requestSender;
_workflowInstanceStore = workflowInstanceStore;
_workflowRunner = workflowRunner;
_workflowRegistry = workflowRegistry;
}
@ -37,7 +37,7 @@ public class DefaultWorkflowInvoker : IWorkflowInvoker
public async Task<InvokeWorkflowResult> InvokeAsync(InvokeWorkflowInstanceRequest request, CancellationToken cancellationToken = default)
{
var workflowInstance = await _requestSender.RequestAsync(new FindWorkflowInstance(request.InstanceId), cancellationToken);
var workflowInstance = await _workflowInstanceStore.FindByIdAsync(request.InstanceId, cancellationToken);
return await InvokeAsync(workflowInstance!, request.Bookmark, request.Input, cancellationToken);
}

View file

@ -3,14 +3,14 @@ using System.Text.Json;
using Elsa.Helpers;
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Comparers;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Runtime.Models;
using Elsa.Runtime.Services;
using Elsa.Services;
using Microsoft.Extensions.Logging;
using Open.Linq.AsyncExtensions;
namespace Elsa.Runtime.Implementations;
@ -26,8 +26,7 @@ public class TriggerIndexer : ITriggerIndexer
private readonly IWorkflowDefinitionService _workflowDefinitionService;
private readonly IExpressionEvaluator _expressionEvaluator;
private readonly IIdentityGenerator _identityGenerator;
private readonly IRequestSender _requestSender;
private readonly ICommandSender _commandSender;
private readonly IWorkflowTriggerStore _workflowTriggerStore;
private readonly IEventPublisher _eventPublisher;
private readonly IServiceProvider _serviceProvider;
private readonly IHasher _hasher;
@ -38,8 +37,7 @@ public class TriggerIndexer : ITriggerIndexer
IWorkflowDefinitionService workflowDefinitionService,
IExpressionEvaluator expressionEvaluator,
IIdentityGenerator identityGenerator,
IRequestSender requestSender,
ICommandSender commandSender,
IWorkflowTriggerStore workflowTriggerStore,
IEventPublisher eventPublisher,
IServiceProvider serviceProvider,
IHasher hasher,
@ -48,8 +46,7 @@ public class TriggerIndexer : ITriggerIndexer
_activityWalker = activityWalker;
_expressionEvaluator = expressionEvaluator;
_identityGenerator = identityGenerator;
_requestSender = requestSender;
_commandSender = commandSender;
_workflowTriggerStore = workflowTriggerStore;
_eventPublisher = eventPublisher;
_serviceProvider = serviceProvider;
_hasher = hasher;
@ -66,7 +63,7 @@ public class TriggerIndexer : ITriggerIndexer
public async Task<IndexedWorkflowTriggers> IndexTriggersAsync(Workflow workflow, CancellationToken cancellationToken = default)
{
// Get current triggers
var currentTriggers = await GetCurrentTriggersAsync(workflow.Identity.DefinitionId, cancellationToken);
var currentTriggers = await GetCurrentTriggersAsync(workflow.Identity.DefinitionId, cancellationToken).ToList();
// Collect new triggers **if workflow is published**.
var newTriggers = workflow.Publication.IsPublished
@ -77,7 +74,7 @@ public class TriggerIndexer : ITriggerIndexer
var diff = Diff.For(currentTriggers, newTriggers, new WorkflowTriggerHashEqualityComparer());
// Replace triggers for the specified workflow.
await _commandSender.ExecuteAsync(new ReplaceWorkflowTriggers(workflow, diff.Removed, diff.Added), cancellationToken);
await _workflowTriggerStore.ReplaceAsync(diff.Removed, diff.Added, cancellationToken);
var indexedWorkflow = new IndexedWorkflowTriggers(workflow, diff.Added, diff.Removed, diff.Unchanged);
@ -86,8 +83,8 @@ public class TriggerIndexer : ITriggerIndexer
return indexedWorkflow;
}
private async Task<ICollection<WorkflowTrigger>> GetCurrentTriggersAsync(string workflowDefinitionId, CancellationToken cancellationToken) =>
await _requestSender.RequestAsync(new FindWorkflowTriggersByWorkflowDefinition(workflowDefinitionId), cancellationToken);
private async Task<IEnumerable<WorkflowTrigger>> GetCurrentTriggersAsync(string workflowDefinitionId, CancellationToken cancellationToken) =>
await _workflowTriggerStore.FindManyByWorkflowDefinitionIdAsync(workflowDefinitionId, cancellationToken);
private async IAsyncEnumerable<WorkflowTrigger> GetTriggersAsync(Workflow workflow, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{

View file

@ -1,32 +1,31 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Runtime.Services;
namespace Elsa.Runtime.Implementations;
public class WorkflowRegistry : IWorkflowRegistry
{
private readonly IRequestSender _requestSender;
private readonly IWorkflowDefinitionStore _workflowDefinitionStore;
private readonly IWorkflowDefinitionService _workflowDefinitionService;
public WorkflowRegistry(IRequestSender requestSender, IWorkflowDefinitionService workflowDefinitionService)
public WorkflowRegistry(IWorkflowDefinitionStore workflowDefinitionStore, IWorkflowDefinitionService workflowDefinitionService)
{
_requestSender = requestSender;
_workflowDefinitionStore = workflowDefinitionStore;
_workflowDefinitionService = workflowDefinitionService;
}
public async Task<Workflow?> FindByDefinitionIdAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default)
{
var definition = await _requestSender.RequestAsync(new FindWorkflowDefinitionByDefinitionId(definitionId, versionOptions), cancellationToken);
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, versionOptions, cancellationToken);
return await MaterializeAsync(definition, cancellationToken);
}
public async Task<Workflow?> FindByNameAsync(string name, VersionOptions versionOptions, CancellationToken cancellationToken = default)
{
var definition = await _requestSender.RequestAsync(new FindWorkflowDefinitionByName(name, versionOptions), cancellationToken);
var definition = await _workflowDefinitionStore.FindByNameAsync(name, versionOptions, cancellationToken);
return await MaterializeAsync(definition, cancellationToken);
}

View file

@ -1,8 +1,7 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Runtime.Abstractions;
using Elsa.Runtime.Models;
using Elsa.Runtime.Services;
@ -17,14 +16,18 @@ public class ResumeWorkflowInstructionInterpreter : WorkflowInstructionInterpret
{
private readonly IWorkflowRunner _workflowRunner;
private readonly IWorkflowRegistry _workflowRegistry;
private readonly IRequestSender _mediator;
private readonly IWorkflowInstanceStore _workflowInstanceStore;
private readonly ILogger _logger;
public ResumeWorkflowInstructionInterpreter(IWorkflowRunner workflowRunner, IWorkflowRegistry workflowRegistry, IRequestSender mediator, ILogger<ResumeWorkflowInstructionInterpreter> logger)
public ResumeWorkflowInstructionInterpreter(
IWorkflowRunner workflowRunner,
IWorkflowRegistry workflowRegistry,
IWorkflowInstanceStore workflowInstanceStore,
ILogger<ResumeWorkflowInstructionInterpreter> logger)
{
_workflowRunner = workflowRunner;
_workflowRegistry = workflowRegistry;
_mediator = mediator;
_workflowInstanceStore = workflowInstanceStore;
_logger = logger;
}
@ -33,7 +36,7 @@ public class ResumeWorkflowInstructionInterpreter : WorkflowInstructionInterpret
var workflowBookmark = instruction.WorkflowBookmark;
var workflowDefinitionId = workflowBookmark.WorkflowDefinitionId;
var workflowInstanceId = workflowBookmark.WorkflowInstanceId;
var workflowInstance = await _mediator.RequestAsync(new FindWorkflowInstance(workflowInstanceId), cancellationToken);
var workflowInstance = await _workflowInstanceStore.FindByIdAsync(workflowInstanceId, cancellationToken);
if (workflowInstance == null)
{

View file

@ -1,7 +1,6 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Services;
using Elsa.Pipelines.WorkflowExecution;
using Elsa.Pipelines.WorkflowExecution.Components;
using Elsa.Services;
@ -13,12 +12,12 @@ namespace Elsa.Runtime.Middleware;
/// </summary>
public class PersistWorkflowExecutionLogMiddleware : WorkflowExecutionMiddleware
{
private readonly ICommandSender _commandSender;
private readonly IWorkflowExecutionLogStore _workflowExecutionLogStore;
private readonly IIdentityGenerator _identityGenerator;
public PersistWorkflowExecutionLogMiddleware(WorkflowMiddlewareDelegate next, ICommandSender commandSender, IIdentityGenerator identityGenerator) : base(next)
public PersistWorkflowExecutionLogMiddleware(WorkflowMiddlewareDelegate next, IWorkflowExecutionLogStore workflowExecutionLogStore, IIdentityGenerator identityGenerator) : base(next)
{
_commandSender = commandSender;
_workflowExecutionLogStore = workflowExecutionLogStore;
_identityGenerator = identityGenerator;
}
@ -35,12 +34,13 @@ public class PersistWorkflowExecutionLogMiddleware : WorkflowExecutionMiddleware
ActivityType = x.ActivityType,
Message = x.Message,
EventName = x.EventName,
WorkflowDefinitionId = context.Workflow.Identity.DefinitionId,
WorkflowInstanceId = context.Id,
Source = x.Source,
Payload = x.Payload,
Timestamp = x.Timestamp
}).ToList();
await _commandSender.ExecuteAsync(new SaveWorkflowExecutionLog(entries), context.CancellationToken);
await _workflowExecutionLogStore.SaveManyAsync(entries, context.CancellationToken);
}
}

View file

@ -1,9 +1,8 @@
using Elsa.Helpers;
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Pipelines.WorkflowExecution;
using Elsa.Pipelines.WorkflowExecution.Components;
using Elsa.Runtime.Models;
@ -21,8 +20,9 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
public static readonly object WorkflowInstanceKey = new();
public static readonly object WorkflowInstanceNameKey = new();
private readonly IWorkflowInstanceStore _workflowInstanceStore;
private readonly IWorkflowBookmarkStore _bookmarkStore;
private readonly IRequestSender _requestSender;
private readonly ICommandSender _commandSender;
private readonly IEventPublisher _eventPublisher;
private readonly IWorkflowStateSerializer _workflowStateSerializer;
private readonly IBookmarkManager _bookmarkManager;
@ -31,16 +31,18 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
public PersistWorkflowInstanceMiddleware(
WorkflowMiddlewareDelegate next,
IWorkflowInstanceStore workflowInstanceStore,
IWorkflowBookmarkStore bookmarkStore,
IRequestSender requestSender,
ICommandSender commandSender,
IEventPublisher eventPublisher,
IBookmarkManager bookmarkManager,
IWorkflowStateSerializer workflowStateSerializer,
IIdentityGenerator identityGenerator,
ISystemClock clock) : base(next)
{
_workflowInstanceStore = workflowInstanceStore;
_bookmarkStore = bookmarkStore;
_requestSender = requestSender;
_commandSender = commandSender;
_eventPublisher = eventPublisher;
_bookmarkManager = bookmarkManager;
_workflowStateSerializer = workflowStateSerializer;
@ -53,8 +55,9 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
var cancellationToken = context.CancellationToken;
var workflow = context.Workflow;
var (definitionId, version, definitionVersionId) = workflow.Identity;
var existingWorkflowInstance = await _requestSender.RequestAsync(new FindWorkflowInstance(context.Id), cancellationToken);
var existingWorkflowInstance = await _workflowInstanceStore.FindByIdAsync(context.Id, cancellationToken);
var workflowInstanceName = default(string?);
var now = _clock.UtcNow;
// Get the workflow instance name, if any (could be provided by previously executed middleware).
if (context.TransientProperties.TryGetValue(WorkflowInstanceNameKey, out var name))
@ -67,7 +70,7 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
DefinitionId = definitionId,
Version = version,
DefinitionVersionId = definitionVersionId,
CreatedAt = _clock.UtcNow,
CreatedAt = now,
Status = WorkflowStatus.Running,
SubStatus = WorkflowSubStatus.Executing,
CorrelationId = _identityGenerator.GenerateId(),
@ -79,7 +82,7 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
context.TransientProperties[WorkflowInstanceKey] = workflowInstance;
// Get a copy of current bookmarks.
var existingBookmarks = await _requestSender.RequestAsync(new FindWorkflowBookmarks(workflowInstance.Id), cancellationToken);
var existingBookmarks = await _bookmarkStore.FindManyByWorkflowInstanceIdAsync(workflowInstance.Id, cancellationToken);
var bookmarksSnapshot = existingBookmarks.Select(x => x.ToBookmark()).ToList();
var bookmarks = bookmarksSnapshot.ToList();
@ -91,7 +94,7 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
context.RegisterBookmarks(bookmarks);
// Persist workflow instance.
await _commandSender.ExecuteAsync(new SaveWorkflowInstance(workflowInstance), cancellationToken);
await _workflowInstanceStore.SaveAsync(workflowInstance, cancellationToken);
// Invoke next middleware.
await Next(context);
@ -102,14 +105,31 @@ public class PersistWorkflowInstanceMiddleware : WorkflowExecutionMiddleware
workflowInstance.Status = workflowState.Status;
workflowInstance.SubStatus = workflowState.SubStatus;
workflowInstance.CorrelationId = workflowState.CorrelationId;
workflowInstance.LastExecutedAt = _clock.UtcNow;
workflowInstance.LastExecutedAt = now;
// Update timestamps.
if (workflowInstance.Status == WorkflowStatus.Finished)
{
switch (workflowInstance.SubStatus)
{
case WorkflowSubStatus.Cancelled:
workflowInstance.CancelledAt = now;
break;
case WorkflowSubStatus.Faulted:
workflowInstance.FaultedAt = now;
break;
case WorkflowSubStatus.Finished:
workflowInstance.FinishedAt = now;
break;
}
}
// Get the workflow instance name, if any (could be provided by previously executed middleware).
if (context.TransientProperties.TryGetValue(WorkflowInstanceNameKey, out name))
workflowInstance.Name = (string?)name;
// Persist updated workflow instance.
await _commandSender.ExecuteAsync(new SaveWorkflowInstance(workflowInstance), cancellationToken);
await _workflowInstanceStore.SaveAsync(workflowInstance, cancellationToken);
// Get a diff between bookmarks that were in the snapshot but no longer present in context.
var diff = Diff.For(bookmarksSnapshot, context.Bookmarks.ToList());

View file

@ -1,19 +1,19 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Runtime.Abstractions;
using Elsa.Runtime.Interpreters;
using Elsa.Runtime.Services;
using Open.Linq.AsyncExtensions;
namespace Elsa.Runtime.Stimuli.Handlers;
public class ResumeWorkflowsStimulusHandler : StimulusHandler<StandardStimulus>
{
private readonly IRequestSender _mediator;
public ResumeWorkflowsStimulusHandler(IRequestSender mediator) => _mediator = mediator;
private readonly IWorkflowBookmarkStore _bookmarkStore;
public ResumeWorkflowsStimulusHandler(IWorkflowBookmarkStore bookmarkStore) => _bookmarkStore = bookmarkStore;
protected override async ValueTask<IEnumerable<IWorkflowInstruction>> GetInstructionsAsync(StandardStimulus stimulus, CancellationToken cancellationToken = default)
{
var workflowBookmarks = (await _mediator.RequestAsync(new FindWorkflowBookmarks(stimulus.ActivityTypeName, stimulus.Hash), cancellationToken)).ToList();
var workflowBookmarks = await _bookmarkStore.FindManyAsync(stimulus.ActivityTypeName, stimulus.Hash, cancellationToken).ToList();
return workflowBookmarks.Select(x => new ResumeWorkflowInstruction(x, stimulus.Input, stimulus.CorrelationId));
}
}

View file

@ -1,5 +1,4 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Elsa.Runtime.Abstractions;
using Elsa.Runtime.Interpreters;
using Elsa.Runtime.Services;
@ -8,12 +7,16 @@ namespace Elsa.Runtime.Stimuli.Handlers;
public class TriggerWorkflowsStimulusHandler : StimulusHandler<StandardStimulus>
{
private readonly IRequestSender _mediator;
public TriggerWorkflowsStimulusHandler(IRequestSender mediator) => _mediator = mediator;
private readonly IWorkflowTriggerStore _workflowTriggerStore;
public TriggerWorkflowsStimulusHandler(IWorkflowTriggerStore workflowTriggerStore)
{
_workflowTriggerStore = workflowTriggerStore;
}
protected override async ValueTask<IEnumerable<IWorkflowInstruction>> GetInstructionsAsync(StandardStimulus stimulus, CancellationToken cancellationToken = default)
{
var workflowTriggers = (await _mediator.RequestAsync(new FindWorkflowTriggersByName(stimulus.ActivityTypeName, stimulus.Hash), cancellationToken)).ToList();
var workflowTriggers = (await _workflowTriggerStore.FindManyByNameAsync(stimulus.ActivityTypeName, stimulus.Hash, cancellationToken)).ToList();
return workflowTriggers.Select(x => new TriggerWorkflowInstruction(x, stimulus.Input, stimulus.CorrelationId));
}
}

View file

@ -15,7 +15,7 @@
<ItemGroup>
<ProjectReference Include="..\..\modules\Elsa.Modules.Activities\Elsa.Modules.Activities.csproj" />
<ProjectReference Include="..\..\persistence\Elsa.Persistence.InMemory\Elsa.Persistence.InMemory.csproj" />
<ProjectReference Include="..\..\persistence\memory\Elsa.Persistence.InMemory\Elsa.Persistence.InMemory.csproj" />
<ProjectReference Include="..\..\core\Elsa.Runtime\Elsa.Runtime.csproj" />
<ProjectReference Include="..\Elsa.Core\Elsa.Core.csproj" />
</ItemGroup>

View file

@ -19,7 +19,7 @@
<ProjectReference Include="..\..\core\Elsa.Formatting\Elsa.Formatting.csproj"/>
<ProjectReference Include="..\..\core\Elsa.Mediator\Elsa.Mediator.csproj"/>
<ProjectReference Include="..\..\core\Elsa.Runtime\Elsa.Runtime.csproj"/>
<ProjectReference Include="..\..\persistence\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj"/>
<ProjectReference Include="..\..\core\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj"/>
</ItemGroup>
</Project>

View file

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Elsa.Attributes;
using Elsa.Models;

View file

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Elsa.Attributes;
using Elsa.Models;

View file

@ -2,10 +2,10 @@ using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Mediator.Services;
using Elsa.Helpers;
using Elsa.Modules.Scheduling.Activities;
using Elsa.Modules.Scheduling.Services;
using Elsa.Persistence.Requests;
using Elsa.Persistence.Services;
using Microsoft.Extensions.Hosting;
namespace Elsa.Modules.Scheduling.HostedServices;
@ -15,12 +15,12 @@ namespace Elsa.Modules.Scheduling.HostedServices;
/// </summary>
public class ScheduleWorkflows : BackgroundService
{
private readonly IRequestSender _requestSender;
private readonly IWorkflowBookmarkStore _bookmarkStore;
private readonly IWorkflowBookmarkScheduler _workflowBookmarkScheduler;
public ScheduleWorkflows(IRequestSender requestSender, IWorkflowBookmarkScheduler workflowBookmarkScheduler)
public ScheduleWorkflows(IWorkflowBookmarkStore bookmarkStore, IWorkflowBookmarkScheduler workflowBookmarkScheduler)
{
_requestSender = requestSender;
_bookmarkStore = bookmarkStore;
_workflowBookmarkScheduler = workflowBookmarkScheduler;
}
@ -31,7 +31,7 @@ public class ScheduleWorkflows : BackgroundService
private async Task ScheduleBookmarksAsync(CancellationToken cancellationToken)
{
var workflowBookmarks = (await _requestSender.RequestAsync(FindWorkflowBookmarks.ForActivity<Delay>(), cancellationToken)).ToImmutableList();
var workflowBookmarks = (await _bookmarkStore.FindManyAsync(ActivityTypeNameHelper.GenerateTypeName<Delay>(), cancellationToken: cancellationToken)).ToImmutableList();
var groupedBookmarks = workflowBookmarks.GroupBy(x => x.WorkflowInstanceId);
foreach (var bookmarksGroup in groupedBookmarks)

View file

@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
<ProjectReference Include="..\..\persistence\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj" />
<ProjectReference Include="..\..\runtime\Elsa.Runtime\Elsa.Runtime.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Activities" />
</ItemGroup>
</Project>

View file

@ -1,12 +0,0 @@
using Elsa.Mediator.Services;
namespace Elsa.Persistence.Commands;
/// <summary>
/// Represents a command to delete all of the specified <see cref="BookmarkIds"/>.
/// </summary>
public record DeleteWorkflowBookmarks : ICommand<int>
{
public DeleteWorkflowBookmarks(IEnumerable<string> bookmarkIds) => BookmarkIds = bookmarkIds.ToList();
public ICollection<string> BookmarkIds { get; set; }
}

View file

@ -1,8 +0,0 @@
using Elsa.Mediator.Services;
namespace Elsa.Persistence.Commands;
/// <summary>
/// Represents a command to delete all versions of the specified definition ID.
/// </summary>
public record DeleteWorkflowDefinition(string DefinitionId) : ICommand<bool>;

View file

@ -1,9 +0,0 @@
using Elsa.Mediator.Services;
namespace Elsa.Persistence.Commands;
public record DeleteWorkflowInstance : ICommand<int>
{
public DeleteWorkflowInstance(string instanceId) => InstanceId = instanceId;
public string? InstanceId { get; set; }
}

View file

@ -1,15 +0,0 @@
using Elsa.Mediator.Services;
namespace Elsa.Persistence.Commands;
/// <summary>
/// Represents a command to delete all instances of the specified <see cref="DefinitionId"/> or having one of the specified <see cref="InstanceIds"/>.
/// </summary>
public record DeleteWorkflowInstances : ICommand<int>
{
public DeleteWorkflowInstances(string definitionId) => DefinitionId = definitionId;
public DeleteWorkflowInstances(IEnumerable<string> instanceIds) => InstanceIds = instanceIds.ToList();
public string? DefinitionId { get; set; }
public ICollection<string>? InstanceIds { get; set; }
}

View file

@ -1,7 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Commands;
public record ReplaceWorkflowTriggers(Workflow Workflow, ICollection<WorkflowTrigger> Removed, ICollection<WorkflowTrigger> Added) : ICommand;

View file

@ -1,13 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Commands;
/// <summary>
/// Represents a command to persist the specified <see cref="WorkflowBookmarks"/> to storage.
/// </summary>
public record SaveWorkflowBookmarks : ICommand
{
public SaveWorkflowBookmarks(IEnumerable<WorkflowBookmark> workflowBookmarks) => WorkflowBookmarks = workflowBookmarks.ToList();
public IReadOnlyCollection<WorkflowBookmark> WorkflowBookmarks { get; }
}

View file

@ -1,10 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Commands;
/// <summary>
/// Represents a command to persist the specified <see cref="WorkflowDefinition"/> to storage.
/// </summary>
public record SaveWorkflowDefinition(WorkflowDefinition WorkflowDefinition) : ICommand;

View file

@ -1,10 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Commands;
public record SaveWorkflowExecutionLog : ICommand
{
public SaveWorkflowExecutionLog(IEnumerable<WorkflowExecutionLogRecord> records) => Records = records.ToList();
public IReadOnlyCollection<WorkflowExecutionLogRecord> Records { get; }
}

View file

@ -1,9 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Commands;
/// <summary>
/// Represents a command to persist the specified <see cref="WorkflowInstance"/> to storage.
/// </summary>
public record SaveWorkflowInstance(WorkflowInstance WorkflowInstance) : ICommand;

View file

@ -1,7 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Requests;
public record FindLatestAndPublishedWorkflows(string DefinitionId) : IRequest<IEnumerable<WorkflowDefinition>>;

View file

@ -1,6 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Models;
namespace Elsa.Persistence.Requests;
public record FindManyWorkflowDefinitions(string[] DefinitionIds, VersionOptions? VersionOptions = default) : IRequest<IEnumerable<WorkflowDefinitionSummary>>;

View file

@ -1,6 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Requests;
public record FindWorkflowBookmark(string BookmarkId) : IRequest<WorkflowBookmark?>;

View file

@ -1,26 +0,0 @@
using Elsa.Helpers;
using Elsa.Mediator.Services;
using Elsa.Persistence.Entities;
using Elsa.Services;
namespace Elsa.Persistence.Requests;
public record FindWorkflowBookmarks : IRequest<IEnumerable<WorkflowBookmark>>
{
public FindWorkflowBookmarks(string workflowInstanceId)
{
WorkflowInstanceId = workflowInstanceId;
}
public FindWorkflowBookmarks(string name, string? hash)
{
Name = name;
Hash = hash;
}
public string? WorkflowInstanceId { get; }
public string? Name { get; }
public string? Hash { get; }
public static FindWorkflowBookmarks ForActivity<T>(string? hash = default) where T : IActivity => new(TypeNameHelper.GenerateTypeName<T>(), hash);
}

View file

@ -1,8 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
namespace Elsa.Persistence.Requests;
public record FindWorkflowDefinitionByDefinitionId(string DefinitionId, VersionOptions VersionOptions) : IRequest<WorkflowDefinition?>;

View file

@ -1,8 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
namespace Elsa.Persistence.Requests;
public record FindWorkflowDefinitionByName(string Name, VersionOptions VersionOptions) : IRequest<WorkflowDefinition?>;

View file

@ -1,6 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Requests;
public record FindWorkflowInstance(string InstanceId) : IRequest<WorkflowInstance?>;

View file

@ -1,11 +0,0 @@
using Elsa.Helpers;
using Elsa.Mediator.Services;
using Elsa.Persistence.Entities;
using Elsa.Services;
namespace Elsa.Persistence.Requests;
public record FindWorkflowTriggersByName(string Name, string? Hash = default) : IRequest<ICollection<WorkflowTrigger>>
{
public static FindWorkflowTriggersByName ForTrigger<T>(string? hash = default) where T : IEventGenerator => new(TypeNameHelper.GenerateTypeName<T>(), hash);
}

View file

@ -1,6 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Entities;
namespace Elsa.Persistence.Requests;
public record FindWorkflowTriggersByWorkflowDefinition(string WorkflowDefinitionId) : IRequest<ICollection<WorkflowTrigger>>;

View file

@ -1,6 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Models;
namespace Elsa.Persistence.Requests;
public record ListWorkflowDefinitionSummaries(VersionOptions? VersionOptions = default, PageArgs? PageArgs = default) : IRequest<Page<WorkflowDefinitionSummary>>;

View file

@ -1,8 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
namespace Elsa.Persistence.Requests;
public record ListWorkflowDefinitions(VersionOptions? VersionOptions = default, PageArgs? PageArgs = default) : IRequest<Page<WorkflowDefinition>>;

View file

@ -1,18 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Models;
using Elsa.Persistence.Entities;
using Elsa.Persistence.Models;
namespace Elsa.Persistence.Requests;
public record ListWorkflowInstanceSummaries(
string? SearchTerm = default,
string? DefinitionId = default,
int? Version = default,
string? CorrelationId = default,
WorkflowStatus? WorkflowStatus = default,
WorkflowSubStatus? WorkflowSubStatus = default,
PageArgs? PageArgs = default,
OrderBy OrderBy = OrderBy.Created,
OrderDirection OrderDirection = OrderDirection.Ascending
) : IRequest<Page<WorkflowInstanceSummary>>;

View file

@ -1,16 +0,0 @@
// using System.Collections.Generic;
// using System.Threading;
// using System.Threading.Tasks;
// using Elsa.Persistence.Entities;
//
// namespace Elsa.Persistence.Contracts;
//
// public interface IWorkflowBookmarkStore
// {
// Task SaveAsync(WorkflowBookmark record, CancellationToken cancellationToken = default);
// Task SaveManyAsync(IEnumerable<WorkflowBookmark> records, CancellationToken cancellationToken = default);
// Task<IEnumerable<WorkflowBookmark>> FindManyAsync(string name, string? hash, CancellationToken cancellationToken = default);
// Task<IEnumerable<WorkflowBookmark>> FindManyByWorkflowInstanceAsync(string workflowInstanceId, CancellationToken cancellationToken = default);
// Task DeleteAsync(string id, CancellationToken cancellationToken = default);
// Task DeleteManyAsync(IEnumerable<string> ids, CancellationToken cancellationToken = default);
// }

View file

@ -1,13 +0,0 @@
// using System.Collections.Generic;
// using System.Threading;
// using System.Threading.Tasks;
// using Elsa.Persistence.Entities;
//
// namespace Elsa.Persistence.Contracts;
//
// public interface IWorkflowInstanceStore
// {
// Task<WorkflowInstance?> FindByIdAsync(string id, CancellationToken cancellationToken = default);
// Task SaveAsync(WorkflowInstance record, CancellationToken cancellationToken = default);
// Task SaveManyAsync(IEnumerable<WorkflowInstance> records, CancellationToken cancellationToken = default);
// }

View file

@ -1,15 +0,0 @@
// using System.Collections.Generic;
// using System.Threading;
// using System.Threading.Tasks;
// using Elsa.Persistence.Entities;
//
// namespace Elsa.Persistence.Contracts;
//
// public interface IWorkflowTriggerStore
// {
// Task SaveAsync(WorkflowTrigger record, CancellationToken cancellationToken = default);
// Task SaveManyAsync(IEnumerable<WorkflowTrigger> records, CancellationToken cancellationToken = default);
// Task<IEnumerable<WorkflowTrigger>> FindManyAsync(string name, string? hash, CancellationToken cancellationToken = default);
// Task DeleteManyAsync(IEnumerable<string> ids, CancellationToken cancellationToken = default);
// Task ReplaceTriggersAsync(string workflowDefinitionId, IEnumerable<WorkflowTrigger> triggers, CancellationToken cancellationToken = default);
// }

View file

@ -1,13 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Entities;
using Elsa.Persistence.EntityFrameworkCore.Services;
namespace Elsa.Persistence.EntityFrameworkCore.Handlers.Commands;
public class DeleteWorkflowBookmarksHandler : ICommandHandler<DeleteWorkflowBookmarks, int>
{
private readonly IStore<WorkflowBookmark> _store;
public DeleteWorkflowBookmarksHandler(IStore<WorkflowBookmark> store) => _store = store;
public async Task<int> HandleAsync(DeleteWorkflowBookmarks command, CancellationToken cancellationToken) => await _store.DeleteWhereAsync(x => command.BookmarkIds.Contains(x.Id), cancellationToken);
}

View file

@ -1,13 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Entities;
using Elsa.Persistence.EntityFrameworkCore.Services;
namespace Elsa.Persistence.EntityFrameworkCore.Handlers.Commands;
public class DeleteWorkflowDefinitionHandler : ICommandHandler<DeleteWorkflowDefinition, bool>
{
private readonly IStore<WorkflowDefinition> _store;
public DeleteWorkflowDefinitionHandler(IStore<WorkflowDefinition> store) => _store = store;
public async Task<bool> HandleAsync(DeleteWorkflowDefinition command, CancellationToken cancellationToken) => await _store.DeleteWhereAsync(x => x.DefinitionId == command.DefinitionId, cancellationToken) > 0;
}

View file

@ -1,31 +0,0 @@
using Elsa.Mediator.Services;
using Elsa.Persistence.Commands;
using Elsa.Persistence.Entities;
using Elsa.Persistence.EntityFrameworkCore.Services;
namespace Elsa.Persistence.EntityFrameworkCore.Handlers.Commands;
public class DeleteWorkflowInstancesHandler : ICommandHandler<DeleteWorkflowInstances, int>, ICommandHandler<DeleteWorkflowInstance, int>
{
private readonly IStore<WorkflowInstance> _store;
public DeleteWorkflowInstancesHandler(IStore<WorkflowInstance> store) => _store = store;
public async Task<int> HandleAsync(DeleteWorkflowInstances command, CancellationToken cancellationToken)
{
if (command.DefinitionId != null)
return await _store.DeleteWhereAsync(x => x.DefinitionId == command.DefinitionId, cancellationToken);
if (command.InstanceIds != null)
return await _store.DeleteWhereAsync(x => command.InstanceIds.Contains(x.Id), cancellationToken);
return 0;
}
public async Task<int> HandleAsync(DeleteWorkflowInstance command, CancellationToken cancellationToken)
{
if (command.InstanceId != null)
return await _store.DeleteWhereAsync(x => x.Id == command.InstanceId, cancellationToken);
return 0;
}
}

Some files were not shown because too many files have changed in this diff Show more