From c216185c5e48decdd6a49024c723992e6b66b4e2 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 8 Jun 2023 11:39:19 +0200 Subject: [PATCH] Update Workflow model with support for Inputs, Outputs and Outcomes (#4112) * Fix mutable prop changes warning * Fix graph no longer scrolling to content * Remove unused namespace imports * Update Workflow model with support for input, output and outcomes * Update sample with EF core persistence * Rename FluentStorage to BlobStorage --- Elsa.sln | 14 +- .../Elsa.WorkflowServer.Web.csproj | 2 +- .../input-control-switch.tsx | 6 +- .../src/modules/flowchart/flowchart.tsx | 1 + .../Contracts/IBlobStorageProvider.cs | 2 +- ...Elsa.WorkflowProviders.BlobStorage.csproj} | 0 .../Extensions/ModuleExtensions.cs | 2 +- .../Features/FluentStorageFeature.cs | 8 +- .../FodyWeavers.xml | 0 .../Providers/BlobStorageProvider.cs | 4 +- .../Providers/BlobStorageWorkflowProvider.cs} | 10 +- .../JavaScript/TypeDefinitions/Endpoint.cs | 1 - .../WorkflowDefinitions/Version/List.cs | 4 +- .../Serialization/ArgumentJsonConverter.cs | 2 +- .../ArgumentJsonConverterFactory.cs | 2 +- .../Builders/WorkflowBuilder.cs | 25 ++- .../Contracts/IWorkflowBuilder.cs | 15 ++ .../Models/ArgumentDefinition.cs | 2 +- .../Models/InputDefinition.cs | 2 +- .../Models/OutputDefinition.cs | 2 +- .../Models/VariableDefinition.cs | 2 +- .../Elsa.Workflows.Core/Models/Workflow.cs | 40 +++- .../Entities/WorkflowDefinition.cs | 1 - .../Mappers/VariableDefinitionMapper.cs | 1 - .../Mappers/WorkflowDefinitionMapper.cs | 16 +- ...DefaultWorkflowDefinitionStorePopulator.cs | 3 + ....Samples.AspNet.DslWorkflowProvider.csproj | 2 +- .../Elsa.Samples.JsonWorkflowProvider.csproj | 8 +- .../Program.cs | 10 + .../Workflows/main.json | 200 ++++++++++++++++++ .../Workflows/sub.json | 95 +++++++++ .../Elsa.IntegrationTests.csproj | 2 +- 32 files changed, 430 insertions(+), 54 deletions(-) rename src/modules/{Elsa.WorkflowProviders.FluentStorage => Elsa.WorkflowProviders.BlobStorage}/Contracts/IBlobStorageProvider.cs (90%) rename src/modules/{Elsa.WorkflowProviders.FluentStorage/Elsa.WorkflowProviders.FluentStorage.csproj => Elsa.WorkflowProviders.BlobStorage/Elsa.WorkflowProviders.BlobStorage.csproj} (100%) rename src/modules/{Elsa.WorkflowProviders.FluentStorage => Elsa.WorkflowProviders.BlobStorage}/Extensions/ModuleExtensions.cs (96%) rename src/modules/{Elsa.WorkflowProviders.FluentStorage => Elsa.WorkflowProviders.BlobStorage}/Features/FluentStorageFeature.cs (85%) rename src/modules/{Elsa.WorkflowProviders.FluentStorage => Elsa.WorkflowProviders.BlobStorage}/FodyWeavers.xml (100%) rename src/modules/{Elsa.WorkflowProviders.FluentStorage => Elsa.WorkflowProviders.BlobStorage}/Providers/BlobStorageProvider.cs (84%) rename src/modules/{Elsa.WorkflowProviders.FluentStorage/Providers/FluentStorageWorkflowProvider.cs => Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageWorkflowProvider.cs} (92%) rename src/modules/{Elsa.Workflows.Management => Elsa.Workflows.Core}/Models/ArgumentDefinition.cs (94%) rename src/modules/{Elsa.Workflows.Management => Elsa.Workflows.Core}/Models/InputDefinition.cs (90%) rename src/modules/{Elsa.Workflows.Management => Elsa.Workflows.Core}/Models/OutputDefinition.cs (73%) rename src/modules/{Elsa.Workflows.Management => Elsa.Workflows.Core}/Models/VariableDefinition.cs (82%) create mode 100644 src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Workflows/main.json create mode 100644 src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Workflows/sub.json diff --git a/Elsa.sln b/Elsa.sln index 63aee96e7..81db678e9 100644 --- a/Elsa.sln +++ b/Elsa.sln @@ -192,8 +192,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.JsonWorkflows" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.JsonWorkflowProvider", "src\samples\aspnet\Elsa.Samples.JsonWorkflowProvider\Elsa.Samples.JsonWorkflowProvider.csproj", "{C5043453-5FB8-4796-9A80-C4C766F2CB62}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.WorkflowProviders.FluentStorage", "src\modules\Elsa.WorkflowProviders.FluentStorage\Elsa.WorkflowProviders.FluentStorage.csproj", "{044C3108-FE79-460A-9C31-A03C30228836}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.AspNet.ProtoActorRuntime.AzureContainerApps", "src\samples\aspnet\Elsa.Samples.AspNet.ProtoActorRuntime.AzureContainerApps\Elsa.Samples.AspNet.ProtoActorRuntime.AzureContainerApps.csproj", "{3212A999-4AC4-4911-9AA4-92AB906BCB5E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.AspNet.HttpEndpoints", "src\samples\aspnet\Elsa.Samples.AspNet.HttpEndpoints\Elsa.Samples.AspNet.HttpEndpoints.csproj", "{165ACC9D-B67C-4B49-A818-ECFD247C899C}" @@ -224,6 +222,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.AspNet.DapperP EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Dapper.Migrations", "src\modules\Elsa.Dapper.Migrations\Elsa.Dapper.Migrations.csproj", "{A86DF0F0-24E9-470E-984B-9E7332544972}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.WorkflowProviders.BlobStorage", "src\modules\Elsa.WorkflowProviders.BlobStorage\Elsa.WorkflowProviders.BlobStorage.csproj", "{A702DD84-B55C-4807-9C28-D8F5AC3CCA78}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -518,10 +518,6 @@ Global {C5043453-5FB8-4796-9A80-C4C766F2CB62}.Debug|Any CPU.Build.0 = Debug|Any CPU {C5043453-5FB8-4796-9A80-C4C766F2CB62}.Release|Any CPU.ActiveCfg = Release|Any CPU {C5043453-5FB8-4796-9A80-C4C766F2CB62}.Release|Any CPU.Build.0 = Release|Any CPU - {044C3108-FE79-460A-9C31-A03C30228836}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {044C3108-FE79-460A-9C31-A03C30228836}.Debug|Any CPU.Build.0 = Debug|Any CPU - {044C3108-FE79-460A-9C31-A03C30228836}.Release|Any CPU.ActiveCfg = Release|Any CPU - {044C3108-FE79-460A-9C31-A03C30228836}.Release|Any CPU.Build.0 = Release|Any CPU {3212A999-4AC4-4911-9AA4-92AB906BCB5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3212A999-4AC4-4911-9AA4-92AB906BCB5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {3212A999-4AC4-4911-9AA4-92AB906BCB5E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -554,6 +550,10 @@ Global {A86DF0F0-24E9-470E-984B-9E7332544972}.Debug|Any CPU.Build.0 = Debug|Any CPU {A86DF0F0-24E9-470E-984B-9E7332544972}.Release|Any CPU.ActiveCfg = Release|Any CPU {A86DF0F0-24E9-470E-984B-9E7332544972}.Release|Any CPU.Build.0 = Release|Any CPU + {A702DD84-B55C-4807-9C28-D8F5AC3CCA78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A702DD84-B55C-4807-9C28-D8F5AC3CCA78}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A702DD84-B55C-4807-9C28-D8F5AC3CCA78}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A702DD84-B55C-4807-9C28-D8F5AC3CCA78}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {155227F0-A33B-40AA-A4B4-06F813EB921B} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F} @@ -637,7 +637,6 @@ Global {30B49E42-AE61-4F7C-981F-923F07BB3986} = {5948B0A5-7873-4DBB-BA03-EB283D6EA91B} {B08B4E00-C2AB-48F3-8389-449F42AEF179} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79} {302BFC43-ED2F-43AE-8AD4-FCD481B0AC67} = {B08B4E00-C2AB-48F3-8389-449F42AEF179} - {044C3108-FE79-460A-9C31-A03C30228836} = {B08B4E00-C2AB-48F3-8389-449F42AEF179} {C9539BD8-D2AE-4A8D-8281-71A05B3FBF31} = {B08B4E00-C2AB-48F3-8389-449F42AEF179} {169E2C9B-6687-427F-A278-30BF849BFEDC} = {B08B4E00-C2AB-48F3-8389-449F42AEF179} {B191F11D-583D-44D9-8A08-F5B0DC58B822} = {B08B4E00-C2AB-48F3-8389-449F42AEF179} @@ -655,5 +654,6 @@ Global {4D8F3BB2-709D-481A-8FD3-0DA9762B366D} = {9B4F139F-7D26-435C-A561-89E65A67A8E5} {D5905087-2E73-44AD-B3CC-70FE8AAA99A1} = {56C2FFB8-EA54-45B5-A095-4A78142EB4B5} {A86DF0F0-24E9-470E-984B-9E7332544972} = {9B4F139F-7D26-435C-A561-89E65A67A8E5} + {A702DD84-B55C-4807-9C28-D8F5AC3CCA78} = {B08B4E00-C2AB-48F3-8389-449F42AEF179} EndGlobalSection EndGlobal diff --git a/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj b/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj index 5ff64b745..8909af306 100644 --- a/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj +++ b/src/bundles/Elsa.WorkflowServer.Web/Elsa.WorkflowServer.Web.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/designer/designer_packages/elsa-workflows-designer/src/components/shared/input-control-switch/input-control-switch.tsx b/src/designer/designer_packages/elsa-workflows-designer/src/components/shared/input-control-switch/input-control-switch.tsx index aa3d658cb..36f8adb27 100644 --- a/src/designer/designer_packages/elsa-workflows-designer/src/components/shared/input-control-switch/input-control-switch.tsx +++ b/src/designer/designer_packages/elsa-workflows-designer/src/components/shared/input-control-switch/input-control-switch.tsx @@ -30,9 +30,9 @@ export class InputControlSwitch { } // Tunneled props. - @Prop() workflowDefinitionId: string; - @Prop() activityType: string; - @Prop() propertyName: string; + @Prop({mutable: true}) workflowDefinitionId: string; + @Prop({mutable: true}) activityType: string; + @Prop({mutable: true}) propertyName: string; @Prop() label: string; @Prop() hideLabel: boolean; diff --git a/src/designer/designer_packages/elsa-workflows-designer/src/modules/flowchart/flowchart.tsx b/src/designer/designer_packages/elsa-workflows-designer/src/modules/flowchart/flowchart.tsx index 5213733b4..1d95917d0 100644 --- a/src/designer/designer_packages/elsa-workflows-designer/src/modules/flowchart/flowchart.tsx +++ b/src/designer/designer_packages/elsa-workflows-designer/src/modules/flowchart/flowchart.tsx @@ -441,6 +441,7 @@ export class FlowchartComponent { this.graph.fromJSON(model, {silent: false}); this.graph.unfreeze(); rebuildGraph(this.graph); + this.graph.scrollToContent(); } private getFlowchartModel = (): FlowchartModel => { diff --git a/src/modules/Elsa.WorkflowProviders.FluentStorage/Contracts/IBlobStorageProvider.cs b/src/modules/Elsa.WorkflowProviders.BlobStorage/Contracts/IBlobStorageProvider.cs similarity index 90% rename from src/modules/Elsa.WorkflowProviders.FluentStorage/Contracts/IBlobStorageProvider.cs rename to src/modules/Elsa.WorkflowProviders.BlobStorage/Contracts/IBlobStorageProvider.cs index f94ec546b..1f0f95cf5 100644 --- a/src/modules/Elsa.WorkflowProviders.FluentStorage/Contracts/IBlobStorageProvider.cs +++ b/src/modules/Elsa.WorkflowProviders.BlobStorage/Contracts/IBlobStorageProvider.cs @@ -1,6 +1,6 @@ using FluentStorage.Blobs; -namespace Elsa.WorkflowProviders.FluentStorage.Contracts; +namespace Elsa.WorkflowProviders.BlobStorage.Contracts; /// /// A provider of . The point of this interface is to provide a wrapper for actual implementations. diff --git a/src/modules/Elsa.WorkflowProviders.FluentStorage/Elsa.WorkflowProviders.FluentStorage.csproj b/src/modules/Elsa.WorkflowProviders.BlobStorage/Elsa.WorkflowProviders.BlobStorage.csproj similarity index 100% rename from src/modules/Elsa.WorkflowProviders.FluentStorage/Elsa.WorkflowProviders.FluentStorage.csproj rename to src/modules/Elsa.WorkflowProviders.BlobStorage/Elsa.WorkflowProviders.BlobStorage.csproj diff --git a/src/modules/Elsa.WorkflowProviders.FluentStorage/Extensions/ModuleExtensions.cs b/src/modules/Elsa.WorkflowProviders.BlobStorage/Extensions/ModuleExtensions.cs similarity index 96% rename from src/modules/Elsa.WorkflowProviders.FluentStorage/Extensions/ModuleExtensions.cs rename to src/modules/Elsa.WorkflowProviders.BlobStorage/Extensions/ModuleExtensions.cs index ebe4d2864..34c0b19c3 100644 --- a/src/modules/Elsa.WorkflowProviders.FluentStorage/Extensions/ModuleExtensions.cs +++ b/src/modules/Elsa.WorkflowProviders.BlobStorage/Extensions/ModuleExtensions.cs @@ -1,5 +1,5 @@ using Elsa.Features.Services; -using Elsa.WorkflowProviders.FluentStorage.Features; +using Elsa.WorkflowProviders.BlobStorage.Features; using FluentStorage.Blobs; using JetBrains.Annotations; diff --git a/src/modules/Elsa.WorkflowProviders.FluentStorage/Features/FluentStorageFeature.cs b/src/modules/Elsa.WorkflowProviders.BlobStorage/Features/FluentStorageFeature.cs similarity index 85% rename from src/modules/Elsa.WorkflowProviders.FluentStorage/Features/FluentStorageFeature.cs rename to src/modules/Elsa.WorkflowProviders.BlobStorage/Features/FluentStorageFeature.cs index 8281e6817..2ef5f6e8e 100644 --- a/src/modules/Elsa.WorkflowProviders.FluentStorage/Features/FluentStorageFeature.cs +++ b/src/modules/Elsa.WorkflowProviders.BlobStorage/Features/FluentStorageFeature.cs @@ -2,15 +2,15 @@ using System.Reflection; using Elsa.Features.Abstractions; using Elsa.Features.Attributes; using Elsa.Features.Services; -using Elsa.WorkflowProviders.FluentStorage.Contracts; -using Elsa.WorkflowProviders.FluentStorage.Providers; +using Elsa.WorkflowProviders.BlobStorage.Contracts; +using Elsa.WorkflowProviders.BlobStorage.Providers; using Elsa.Workflows.Management.Features; using FluentStorage; using FluentStorage.Blobs; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; -namespace Elsa.WorkflowProviders.FluentStorage.Features; +namespace Elsa.WorkflowProviders.BlobStorage.Features; /// /// A feature that enables the FluentStorage workflow definition provider. @@ -34,7 +34,7 @@ public class FluentStorageFeature : FeatureBase public override void Apply() { Services.AddSingleton(sp => new BlobStorageProvider(BlobStorage(sp))); - Services.AddWorkflowDefinitionProvider(); + Services.AddWorkflowDefinitionProvider(); } /// diff --git a/src/modules/Elsa.WorkflowProviders.FluentStorage/FodyWeavers.xml b/src/modules/Elsa.WorkflowProviders.BlobStorage/FodyWeavers.xml similarity index 100% rename from src/modules/Elsa.WorkflowProviders.FluentStorage/FodyWeavers.xml rename to src/modules/Elsa.WorkflowProviders.BlobStorage/FodyWeavers.xml diff --git a/src/modules/Elsa.WorkflowProviders.FluentStorage/Providers/BlobStorageProvider.cs b/src/modules/Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageProvider.cs similarity index 84% rename from src/modules/Elsa.WorkflowProviders.FluentStorage/Providers/BlobStorageProvider.cs rename to src/modules/Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageProvider.cs index cd0e90914..419c5718c 100644 --- a/src/modules/Elsa.WorkflowProviders.FluentStorage/Providers/BlobStorageProvider.cs +++ b/src/modules/Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageProvider.cs @@ -1,7 +1,7 @@ -using Elsa.WorkflowProviders.FluentStorage.Contracts; +using Elsa.WorkflowProviders.BlobStorage.Contracts; using FluentStorage.Blobs; -namespace Elsa.WorkflowProviders.FluentStorage.Providers; +namespace Elsa.WorkflowProviders.BlobStorage.Providers; /// /// A provider of . diff --git a/src/modules/Elsa.WorkflowProviders.FluentStorage/Providers/FluentStorageWorkflowProvider.cs b/src/modules/Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageWorkflowProvider.cs similarity index 92% rename from src/modules/Elsa.WorkflowProviders.FluentStorage/Providers/FluentStorageWorkflowProvider.cs rename to src/modules/Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageWorkflowProvider.cs index fc5a8476b..f325944af 100644 --- a/src/modules/Elsa.WorkflowProviders.FluentStorage/Providers/FluentStorageWorkflowProvider.cs +++ b/src/modules/Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageWorkflowProvider.cs @@ -1,6 +1,6 @@ using Elsa.Common.Contracts; using Elsa.Dsl.Contracts; -using Elsa.WorkflowProviders.FluentStorage.Contracts; +using Elsa.WorkflowProviders.BlobStorage.Contracts; using Elsa.Workflows.Core.Contracts; using Elsa.Workflows.Management.Mappers; using Elsa.Workflows.Management.Materializers; @@ -10,13 +10,13 @@ using Elsa.Workflows.Runtime.Models; using FluentStorage.Blobs; using JetBrains.Annotations; -namespace Elsa.WorkflowProviders.FluentStorage.Providers; +namespace Elsa.WorkflowProviders.BlobStorage.Providers; /// /// A workflow definition provider that loads workflow definitions from a storage using FluentStorage (See https://github.com/robinrodricks/FluentStorage). /// [PublicAPI] -public class FluentStorageWorkflowProvider : IWorkflowProvider +public class BlobStorageWorkflowProvider : IWorkflowProvider { private readonly IBlobStorageProvider _blobStorageProvider; private readonly IActivitySerializer _activitySerializer; @@ -27,9 +27,9 @@ public class FluentStorageWorkflowProvider : IWorkflowProvider private readonly VariableDefinitionMapper _variableDefinitionMapper; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public FluentStorageWorkflowProvider( + public BlobStorageWorkflowProvider( IBlobStorageProvider blobStorageProvider, IActivitySerializer activitySerializer, IDslEngine dslEngine, diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/Scripting/JavaScript/TypeDefinitions/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/Scripting/JavaScript/TypeDefinitions/Endpoint.cs index 2106307de..21f66609d 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/Scripting/JavaScript/TypeDefinitions/Endpoint.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/Scripting/JavaScript/TypeDefinitions/Endpoint.cs @@ -5,7 +5,6 @@ using Elsa.JavaScript.TypeDefinitions.Contracts; using Elsa.JavaScript.TypeDefinitions.Models; using Elsa.Workflows.Core.Models; using Elsa.Workflows.Management.Contracts; -using FastEndpoints; using JetBrains.Annotations; namespace Elsa.Workflows.Api.Endpoints.Scripting.JavaScript.TypeDefinitions; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Version/List.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Version/List.cs index b6238c0fb..c4b39e89e 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Version/List.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions/Version/List.cs @@ -1,8 +1,6 @@ -using System.DirectoryServices; -using Elsa.Common.Entities; +using Elsa.Common.Entities; using Elsa.Common.Models; using Elsa.Workflows.Management.Contracts; -using Elsa.Workflows.Management.Entities; using Elsa.Workflows.Management.Filters; using FastEndpoints; using JetBrains.Annotations; diff --git a/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverter.cs b/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverter.cs index 0518ad325..80a31d213 100644 --- a/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverter.cs +++ b/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverter.cs @@ -4,7 +4,7 @@ using System.Text.Json.Serialization; using Elsa.Expressions.Contracts; using Elsa.Expressions.Extensions; using Elsa.Extensions; -using Elsa.Workflows.Management.Models; +using Elsa.Workflows.Core.Models; namespace Elsa.Workflows.Api.Serialization; diff --git a/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverterFactory.cs b/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverterFactory.cs index 917786367..258fe9fab 100644 --- a/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverterFactory.cs +++ b/src/modules/Elsa.Workflows.Api/Serialization/ArgumentJsonConverterFactory.cs @@ -1,7 +1,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using Elsa.Expressions.Contracts; -using Elsa.Workflows.Management.Models; +using Elsa.Workflows.Core.Models; namespace Elsa.Workflows.Api.Serialization; diff --git a/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs b/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs index 5a7937713..b3e78b665 100644 --- a/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs +++ b/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs @@ -44,6 +44,15 @@ public class WorkflowBuilder : IWorkflowBuilder /// public ICollection Variables { get; set; } = new List(); + /// + public ICollection Inputs { get; set; } = new List(); + + /// + public ICollection Outputs { get; set; } = new List(); + + /// + public ICollection Outcomes { get; set; } = new List(); + /// public Variable? Result { get; set; } @@ -51,8 +60,8 @@ public class WorkflowBuilder : IWorkflowBuilder public IDictionary CustomProperties { get; set; } = new Dictionary(); /// - public WorkflowOptions WorkflowOptions { get; } = new(); - + public WorkflowOptions WorkflowOptions { get; } = new(); + /// public Variable WithVariable() { @@ -69,7 +78,7 @@ public class WorkflowBuilder : IWorkflowBuilder Name = name, Value = value }; - + Variables.Add(variable); return variable; } @@ -88,7 +97,7 @@ public class WorkflowBuilder : IWorkflowBuilder Variables.Add(variable); return this; } - + /// public IWorkflowBuilder WithVariable(Variable variable) { @@ -126,7 +135,7 @@ public class WorkflowBuilder : IWorkflowBuilder var identity = new WorkflowIdentity(definitionId, Version, id); var publication = WorkflowPublication.LatestAndPublished; var workflowMetadata = new WorkflowMetadata(Name, Description); - var workflow = new Workflow(identity, publication, workflowMetadata, WorkflowOptions, root, Variables, CustomProperties); + var workflow = new Workflow(identity, publication, workflowMetadata, WorkflowOptions, root, Variables, Inputs, Outputs, Outcomes, CustomProperties); // If a Result variable is defined, install it into the workflow so we can capture the output into it. if (Result != null) @@ -137,14 +146,14 @@ public class WorkflowBuilder : IWorkflowBuilder var graph = await _activityVisitor.VisitAsync(workflow, cancellationToken); var nodes = graph.Flatten().ToList(); - + // Register all activity types first. The identity graph service will need to know about all activity types. var distinctActivityTypes = nodes.Select(x => x.Activity.GetType()).Distinct().ToList(); await _activityRegistry.RegisterAsync(distinctActivityTypes, cancellationToken); - + // Assign identities to all activities. _identityGraphService.AssignIdentities(nodes); - + return workflow; } diff --git a/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs b/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs index 07cff7eab..71c8d9fd3 100644 --- a/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs +++ b/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs @@ -46,6 +46,21 @@ public interface IWorkflowBuilder /// The workflow variables to store with the workflow being built. /// ICollection Variables { get; set; } + + /// + /// Gets or sets the inputs. + /// + ICollection Inputs { get; set; } + + /// + /// Gets or sets the outputs. + /// + ICollection Outputs { get; set; } + + /// + /// Gets or sets the outcomes. + /// + ICollection Outcomes { get; set; } /// /// An internal variable used to get and set the result of the workflow. diff --git a/src/modules/Elsa.Workflows.Management/Models/ArgumentDefinition.cs b/src/modules/Elsa.Workflows.Core/Models/ArgumentDefinition.cs similarity index 94% rename from src/modules/Elsa.Workflows.Management/Models/ArgumentDefinition.cs rename to src/modules/Elsa.Workflows.Core/Models/ArgumentDefinition.cs index 270a68854..ff2052a2b 100644 --- a/src/modules/Elsa.Workflows.Management/Models/ArgumentDefinition.cs +++ b/src/modules/Elsa.Workflows.Core/Models/ArgumentDefinition.cs @@ -1,4 +1,4 @@ -namespace Elsa.Workflows.Management.Models; +namespace Elsa.Workflows.Core.Models; /// /// Base class for workflow input and output definitions. diff --git a/src/modules/Elsa.Workflows.Management/Models/InputDefinition.cs b/src/modules/Elsa.Workflows.Core/Models/InputDefinition.cs similarity index 90% rename from src/modules/Elsa.Workflows.Management/Models/InputDefinition.cs rename to src/modules/Elsa.Workflows.Core/Models/InputDefinition.cs index 16a59dcee..a04ca8f77 100644 --- a/src/modules/Elsa.Workflows.Management/Models/InputDefinition.cs +++ b/src/modules/Elsa.Workflows.Core/Models/InputDefinition.cs @@ -1,4 +1,4 @@ -namespace Elsa.Workflows.Management.Models; +namespace Elsa.Workflows.Core.Models; /// /// A definition of a workflow's input. diff --git a/src/modules/Elsa.Workflows.Management/Models/OutputDefinition.cs b/src/modules/Elsa.Workflows.Core/Models/OutputDefinition.cs similarity index 73% rename from src/modules/Elsa.Workflows.Management/Models/OutputDefinition.cs rename to src/modules/Elsa.Workflows.Core/Models/OutputDefinition.cs index 08728b4ad..46de4bc0a 100644 --- a/src/modules/Elsa.Workflows.Management/Models/OutputDefinition.cs +++ b/src/modules/Elsa.Workflows.Core/Models/OutputDefinition.cs @@ -1,4 +1,4 @@ -namespace Elsa.Workflows.Management.Models; +namespace Elsa.Workflows.Core.Models; /// /// A definition of a workflow's output. diff --git a/src/modules/Elsa.Workflows.Management/Models/VariableDefinition.cs b/src/modules/Elsa.Workflows.Core/Models/VariableDefinition.cs similarity index 82% rename from src/modules/Elsa.Workflows.Management/Models/VariableDefinition.cs rename to src/modules/Elsa.Workflows.Core/Models/VariableDefinition.cs index 289f6de76..8441def56 100644 --- a/src/modules/Elsa.Workflows.Management/Models/VariableDefinition.cs +++ b/src/modules/Elsa.Workflows.Core/Models/VariableDefinition.cs @@ -1,4 +1,4 @@ -namespace Elsa.Workflows.Management.Models; +namespace Elsa.Workflows.Core.Models; /// /// Stores information about a workflow variable. diff --git a/src/modules/Elsa.Workflows.Core/Models/Workflow.cs b/src/modules/Elsa.Workflows.Core/Models/Workflow.cs index 8bbe3eae4..a3cbd2ca6 100644 --- a/src/modules/Elsa.Workflows.Core/Models/Workflow.cs +++ b/src/modules/Elsa.Workflows.Core/Models/Workflow.cs @@ -22,13 +22,19 @@ public class Workflow : Composite, ICloneable WorkflowIdentity identity, WorkflowPublication publication, WorkflowMetadata workflowMetadata, - WorkflowOptions? options, + WorkflowOptions options, IActivity root, ICollection variables, + ICollection inputs, + ICollection outputs, + ICollection outcomes, IDictionary customProperties) { Identity = identity; Publication = publication; + Inputs = inputs; + Outputs = outputs; + Outcomes = outcomes; WorkflowMetadata = workflowMetadata; Options = options; Variables = variables; @@ -45,15 +51,45 @@ public class Workflow : Composite, ICloneable } /// - /// Constructor. + /// Initializes a new instance of the class. /// public Workflow() { } + /// + /// Gets or sets the workflow identity. + /// public WorkflowIdentity Identity { get; set; } = WorkflowIdentity.VersionOne; + + /// + /// Gets or sets the publication status of the workflow. + /// public WorkflowPublication Publication { get; set; } = WorkflowPublication.LatestAndPublished; + + /// + /// Gets or sets input definitions. + /// + public ICollection Inputs { get; set; } = new List(); + + /// + /// Gets or sets output definitions. + /// + public ICollection Outputs { get; set; } = new List(); + + /// + /// Gets or sets possible outcomes for this workflow. + /// + public ICollection Outcomes { get; set; } = new List(); + + /// + /// Gets or sets metadata about the workflow. + /// public WorkflowMetadata WorkflowMetadata { get; set; } = new(); + + /// + /// Gets or sets options for the workflow. + /// public WorkflowOptions Options { get; set; } = new(); /// diff --git a/src/modules/Elsa.Workflows.Management/Entities/WorkflowDefinition.cs b/src/modules/Elsa.Workflows.Management/Entities/WorkflowDefinition.cs index 354fd51d9..7b72e7661 100644 --- a/src/modules/Elsa.Workflows.Management/Entities/WorkflowDefinition.cs +++ b/src/modules/Elsa.Workflows.Management/Entities/WorkflowDefinition.cs @@ -1,6 +1,5 @@ using Elsa.Common.Entities; using Elsa.Workflows.Core.Models; -using Elsa.Workflows.Management.Models; namespace Elsa.Workflows.Management.Entities; diff --git a/src/modules/Elsa.Workflows.Management/Mappers/VariableDefinitionMapper.cs b/src/modules/Elsa.Workflows.Management/Mappers/VariableDefinitionMapper.cs index e0ed251b6..8e98545db 100644 --- a/src/modules/Elsa.Workflows.Management/Mappers/VariableDefinitionMapper.cs +++ b/src/modules/Elsa.Workflows.Management/Mappers/VariableDefinitionMapper.cs @@ -3,7 +3,6 @@ using Elsa.Expressions.Extensions; using Elsa.Expressions.Helpers; using Elsa.Extensions; using Elsa.Workflows.Core.Models; -using Elsa.Workflows.Management.Models; namespace Elsa.Workflows.Management.Mappers; diff --git a/src/modules/Elsa.Workflows.Management/Mappers/WorkflowDefinitionMapper.cs b/src/modules/Elsa.Workflows.Management/Mappers/WorkflowDefinitionMapper.cs index 22a719832..f62d24d10 100644 --- a/src/modules/Elsa.Workflows.Management/Mappers/WorkflowDefinitionMapper.cs +++ b/src/modules/Elsa.Workflows.Management/Mappers/WorkflowDefinitionMapper.cs @@ -33,7 +33,7 @@ public class WorkflowDefinitionMapper public Workflow Map(WorkflowDefinition source) { var root = _activitySerializer.Deserialize(source.StringData!); - + return new( new WorkflowIdentity(source.DefinitionId, source.Version, source.Id), new WorkflowPublication(source.IsLatest, source.IsPublished), @@ -41,9 +41,12 @@ public class WorkflowDefinitionMapper source.Options, root, source.Variables, + source.Inputs, + source.Outputs, + source.Outcomes, source.CustomProperties); } - + /// /// Maps a to a . /// @@ -54,10 +57,10 @@ public class WorkflowDefinitionMapper var root = source.Root!; var variables = _variableDefinitionMapper.Map(source.Variables).ToList(); var options = source.Options ?? new WorkflowOptions(); - + // TODO: Remove this in the future when users have migrated workflows to use the new UsableAsActivity options property. options.UsableAsActivity ??= source.UsableAsActivity ?? false; - + return new( new WorkflowIdentity(source.DefinitionId, source.Version, source.Id), new WorkflowPublication(source.IsLatest, source.IsPublished), @@ -65,9 +68,12 @@ public class WorkflowDefinitionMapper options, root, variables, + source.Inputs ?? new List(), + source.Outputs ?? new List(), + source.Outcomes ?? new List(), source.CustomProperties ?? new Dictionary()); } - + /// /// Maps a to a . /// diff --git a/src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowDefinitionStorePopulator.cs b/src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowDefinitionStorePopulator.cs index f78bc574b..5ef390c60 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowDefinitionStorePopulator.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowDefinitionStorePopulator.cs @@ -96,6 +96,9 @@ public class DefaultWorkflowDefinitionStorePopulator : IWorkflowDefinitionStoreP existingDefinition.IsPublished = workflow.Publication.IsPublished; existingDefinition.CustomProperties = workflow.CustomProperties; existingDefinition.Variables = workflow.Variables; + existingDefinition.Inputs = workflow.Inputs; + existingDefinition.Outputs = workflow.Outputs; + existingDefinition.Outcomes = workflow.Outcomes; existingDefinition.StringData = workflowJson; existingDefinition.CreatedAt = workflow.WorkflowMetadata.CreatedAt == default ? _systemClock.UtcNow : workflow.WorkflowMetadata.CreatedAt; existingDefinition.Options = workflow.Options; diff --git a/src/samples/aspnet/Elsa.Samples.AspNet.DslWorkflowProvider/Elsa.Samples.AspNet.DslWorkflowProvider.csproj b/src/samples/aspnet/Elsa.Samples.AspNet.DslWorkflowProvider/Elsa.Samples.AspNet.DslWorkflowProvider.csproj index f6c7c8fd3..c3302b0c8 100644 --- a/src/samples/aspnet/Elsa.Samples.AspNet.DslWorkflowProvider/Elsa.Samples.AspNet.DslWorkflowProvider.csproj +++ b/src/samples/aspnet/Elsa.Samples.AspNet.DslWorkflowProvider/Elsa.Samples.AspNet.DslWorkflowProvider.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Elsa.Samples.JsonWorkflowProvider.csproj b/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Elsa.Samples.JsonWorkflowProvider.csproj index c09045fbb..779886d65 100644 --- a/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Elsa.Samples.JsonWorkflowProvider.csproj +++ b/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Elsa.Samples.JsonWorkflowProvider.csproj @@ -8,8 +8,10 @@ + + - + @@ -22,4 +24,8 @@ + + + + diff --git a/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Program.cs b/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Program.cs index 31b715854..7c95967f7 100644 --- a/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Program.cs +++ b/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Program.cs @@ -1,3 +1,6 @@ +using Elsa.EntityFrameworkCore.Modules.Identity; +using Elsa.EntityFrameworkCore.Modules.Management; +using Elsa.EntityFrameworkCore.Modules.Runtime; using Elsa.Extensions; var builder = WebApplication.CreateBuilder(args); @@ -10,11 +13,15 @@ services.AddElsa(elsa => elsa // Expose API endpoints. .UseWorkflowsApi() + + .UseWorkflowManagement(management => management.UseEntityFrameworkCore()) + .UseWorkflowRuntime(runtime => runtime.UseEntityFrameworkCore()) // Configure identity so that we can create a default admin user. .UseIdentity(identity => { identity.UseAdminUserProvider(); + identity.UseEntityFrameworkCore(); identity.TokenOptions = options => { options.SigningKey = "secret-token-signing-key"; @@ -29,6 +36,8 @@ services.AddElsa(elsa => elsa .UseDefaultAuthentication(auth => auth.UseAdminApiKey()) ); +services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin())); + // Configure middleware pipeline. var app = builder.Build(); @@ -38,6 +47,7 @@ if (app.Environment.IsDevelopment()) // Configure the HTTP request pipeline. app.UseAuthentication(); app.UseAuthorization(); +app.UseCors(); app.UseWorkflowsApi(); app.UseWorkflows(); app.Run(); \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Workflows/main.json b/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Workflows/main.json new file mode 100644 index 000000000..a82eb5d6f --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Workflows/main.json @@ -0,0 +1,200 @@ +{ + "id": "f608ffca0f0a419caea715233edc0259", + "definitionId": "0b1bfb787a2e464e85ef752551a4204e", + "name": "main", + "createdAt": "2023-03-28T07:47:44.969978+00:00", + "version": 6, + "variables": [ + { + "id": "516509d438e44171ab68321a4b706f31", + "name": "fromSub", + "typeName": "String", + "isArray": false, + "value": "", + "storageDriverTypeName": "Elsa.Workflows.Core.Services.WorkflowStorageDriver, Elsa.Workflows.Core" + } + ], + "inputs": [], + "outputs": [], + "outcomes": [], + "customProperties": {}, + "usableAsActivity": false, + "isLatest": true, + "isPublished": true, + "root": { + "type": "Elsa.Flowchart", + "version": 1, + "id": "Flowchart1", + "metadata": {}, + "applicationProperties": { + "NotFoundConnectionsKey": [], + "CanStartWorkflow": false, + "RunAsynchronously": false + }, + "start": "HttpEndpoint1", + "activities": [ + { + "path": { + "typeName": "String", + "expression": { + "type": "Literal", + "value": "/mymain" + }, + "memoryReference": { + "id": "HttpEndpoint1:input-1" + } + }, + "supportedMethods": { + "typeName": "String[]", + "expression": { + "type": "Object", + "value": "[\u0022GET\u0022]" + }, + "memoryReference": { + "id": "HttpEndpoint1:input-2" + } + }, + "authorize": { + "typeName": "Boolean", + "expression": { + "type": "Literal", + "value": "False" + }, + "memoryReference": { + "id": "HttpEndpoint1:input-3" + } + }, + "policy": null, + "parsedContent": null, + "routeData": null, + "queryStringData": null, + "headers": null, + "result": null, + "id": "HttpEndpoint1", + "type": "Elsa.HttpEndpoint", + "version": 1, + "customProperties": { + "CanStartWorkflow": true, + "RunAsynchronously": false + }, + "metadata": { + "designer": { + "position": { + "x": 1484, + "y": 2317 + } + } + } + }, + { + "statusCode": { + "typeName": "System.Net.HttpStatusCode, System.Net.Primitives", + "expression": { + "type": "Literal", + "value": "OK" + }, + "memoryReference": { + "id": "WriteHttpResponse1:input-1" + } + }, + "content": { + "typeName": "Object", + "expression": { + "type": "JavaScript", + "value": "return getFromSub();" + }, + "memoryReference": { + "id": "WriteHttpResponse1:input-2" + } + }, + "contentType": { + "typeName": "String", + "expression": { + "type": "Literal", + "value": "text/plain" + }, + "memoryReference": { + "id": "WriteHttpResponse1:input-3" + } + }, + "responseHeaders": { + "typeName": "Elsa.Http.Models.HttpResponseHeaders, Elsa.Http", + "expression": { + "type": "Literal", + "value": "{}" + }, + "memoryReference": { + "id": "WriteHttpResponse1:input-4" + } + }, + "id": "WriteHttpResponse1", + "type": "Elsa.WriteHttpResponse", + "version": 1, + "customProperties": { + "CanStartWorkflow": false, + "RunAsynchronously": false + }, + "metadata": { + "designer": { + "position": { + "x": 1860, + "y": 2320 + } + } + } + }, + { + "workflowDefinitionId": "2f6ba5802e254082b00bd4dab00e650a", + "workflowDefinitionVersionId": "401f5e84019848ffa28d75e75d611b39", + "latestAvailablePublishedVersion": 3, + "latestAvailablePublishedVersionId": "401f5e84019848ffa28d75e75d611b39", + "result": null, + "id": "Sub1", + "type": "Sub", + "version": 3, + "customProperties": { + "CanStartWorkflow": false, + "RunAsynchronously": false + }, + "metadata": { + "designer": { + "position": { + "x": 1740, + "y": 2320 + } + } + }, + "fromMain": { + "typeName": "String", + "expression": { + "type": "JavaScript", + "value": "return \u0027obi wan kenobi\u0027;" + }, + "memoryReference": { + "id": "Sub1:input-1" + } + }, + "toMain": { + "typeName": "String", + "memoryReference": { + "id": "516509d438e44171ab68321a4b706f31" + } + } + } + ], + "connections": [ + { + "source": "Sub1", + "target": "WriteHttpResponse1", + "sourcePort": "Done", + "targetPort": "In" + }, + { + "source": "HttpEndpoint1", + "target": "Sub1", + "sourcePort": "Done", + "targetPort": "In" + } + ] + } +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Workflows/sub.json b/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Workflows/sub.json new file mode 100644 index 000000000..47cd85a13 --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.JsonWorkflowProvider/Workflows/sub.json @@ -0,0 +1,95 @@ +{ + "id": "401f5e84019848ffa28d75e75d611b39", + "definitionId": "2f6ba5802e254082b00bd4dab00e650a", + "name": "sub", + "createdAt": "2023-04-04T11:31:58.018203+00:00", + "version": 3, + "variables": [ + { + "id": "cb1309762f244c5c8237e0547772ef12", + "name": "subvar", + "typeName": "String", + "isArray": false, + "value": "", + "storageDriverTypeName": "Elsa.Workflows.Core.Services.WorkflowStorageDriver, Elsa.Workflows.Core" + } + ], + "inputs": [ + { + "uiHint": "single-line", + "storageDriverType": "Elsa.Workflows.Core.Services.WorkflowStorageDriver, Elsa.Workflows.Core", + "type": "String", + "name": "fromMain", + "displayName": "fromMain", + "description": "", + "category": "", + "isArray": false + } + ], + "outputs": [ + { + "type": "String", + "name": "toMain", + "displayName": "toMain", + "description": "", + "isArray": false + } + ], + "outcomes": [], + "customProperties": {}, + "usableAsActivity": true, + "isLatest": true, + "isPublished": true, + "root": { + "type": "Elsa.Flowchart", + "version": 1, + "id": "Flowchart1", + "metadata": {}, + "applicationProperties": { + "NotFoundConnectionsKey": [], + "CanStartWorkflow": false, + "RunAsynchronously": false + }, + "start": "SetOutput1", + "activities": [ + { + "outputName": { + "typeName": "String", + "expression": { + "type": "Literal", + "value": "toMain" + }, + "memoryReference": { + "id": "SetOutput1:input-1" + } + }, + "outputValue": { + "typeName": "Object", + "expression": { + "type": "JavaScript", + "value": "return \u0027hi there\u0027 \u002B getFromMain();" + }, + "memoryReference": { + "id": "SetOutput1:input-2" + } + }, + "id": "SetOutput1", + "type": "Elsa.SetOutput", + "version": 1, + "customProperties": { + "CanStartWorkflow": true, + "RunAsynchronously": false + }, + "metadata": { + "designer": { + "position": { + "x": 1660, + "y": 2260 + } + } + } + } + ], + "connections": [] + } +} \ No newline at end of file diff --git a/test/integration/Elsa.IntegrationTests/Elsa.IntegrationTests.csproj b/test/integration/Elsa.IntegrationTests/Elsa.IntegrationTests.csproj index d52c9a2db..3c30a537b 100644 --- a/test/integration/Elsa.IntegrationTests/Elsa.IntegrationTests.csproj +++ b/test/integration/Elsa.IntegrationTests/Elsa.IntegrationTests.csproj @@ -24,7 +24,7 @@ - +