diff --git a/Elsa.sln b/Elsa.sln index 6f8accab5..9d97cd571 100644 --- a/Elsa.sln +++ b/Elsa.sln @@ -21,11 +21,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Abstractions", "src\co EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Persistence.Abstractions", "src\core\Elsa.Persistence.Abstractions\Elsa.Persistence.Abstractions.csproj", "{A5829896-89C5-4C4E-ADC7-C806C8077316}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esla.Persistence.InMemory", "src\core\Esla.Persistence.InMemory\Esla.Persistence.InMemory.csproj", "{E93A1A6B-708F-4DCC-A399-1B8EC7682F92}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Runtime", "src\core\Elsa.Runtime\Elsa.Runtime.csproj", "{3C1DCAA2-D77E-4F96-9899-DA8E0E0C757F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esla.Runtime", "src\core\Esla.Runtime\Esla.Runtime.csproj", "{3C1DCAA2-D77E-4F96-9899-DA8E0E0C757F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Esla.Runtime.Abstractions", "src\core\Esla.Runtime.Abstractions\Esla.Runtime.Abstractions.csproj", "{792362BF-D26D-46E9-8970-E5668941AA75}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Runtime.Abstractions", "src\core\Elsa.Runtime.Abstractions\Elsa.Runtime.Abstractions.csproj", "{792362BF-D26D-46E9-8970-E5668941AA75}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{35F44BE9-13D0-417C-A01A-F0787BEE6DC3}" EndProject @@ -81,10 +79,6 @@ Global {A5829896-89C5-4C4E-ADC7-C806C8077316}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5829896-89C5-4C4E-ADC7-C806C8077316}.Release|Any CPU.ActiveCfg = Release|Any CPU {A5829896-89C5-4C4E-ADC7-C806C8077316}.Release|Any CPU.Build.0 = Release|Any CPU - {E93A1A6B-708F-4DCC-A399-1B8EC7682F92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E93A1A6B-708F-4DCC-A399-1B8EC7682F92}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E93A1A6B-708F-4DCC-A399-1B8EC7682F92}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E93A1A6B-708F-4DCC-A399-1B8EC7682F92}.Release|Any CPU.Build.0 = Release|Any CPU {3C1DCAA2-D77E-4F96-9899-DA8E0E0C757F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3C1DCAA2-D77E-4F96-9899-DA8E0E0C757F}.Debug|Any CPU.Build.0 = Debug|Any CPU {3C1DCAA2-D77E-4F96-9899-DA8E0E0C757F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -157,7 +151,6 @@ Global {300EE2D5-54C5-46F2-AD03-BB43589EA074} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3} {3130C574-557C-4DA2-933E-AED7A9EBE48A} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3} {A5829896-89C5-4C4E-ADC7-C806C8077316} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3} - {E93A1A6B-708F-4DCC-A399-1B8EC7682F92} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3} {3C1DCAA2-D77E-4F96-9899-DA8E0E0C757F} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3} {792362BF-D26D-46E9-8970-E5668941AA75} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3} {35F44BE9-13D0-417C-A01A-F0787BEE6DC3} = {DA71CDAA-8DD3-4D5F-9FBD-8E4B37A2D925} diff --git a/src/activities/Elsa.Activities.Http/Activities/HttpRequestTrigger.cs b/src/activities/Elsa.Activities.Http/Activities/HttpRequestTrigger.cs index f8e706cb3..43740ef56 100644 --- a/src/activities/Elsa.Activities.Http/Activities/HttpRequestTrigger.cs +++ b/src/activities/Elsa.Activities.Http/Activities/HttpRequestTrigger.cs @@ -14,5 +14,11 @@ namespace Elsa.Activities.Http.Activities /// The HTTP method that triggers this activity. /// public string Method { get; set; } + + /// + /// A value indicating whether the HTTP request content body should be read and stored as part of the HTTP request model. + /// The stored format depends on the content-type header. + /// + public bool ReadContent { get; set; } } } \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Http/Elsa.Activities.Http.csproj b/src/activities/Elsa.Activities.Http/Elsa.Activities.Http.csproj index ee66637ee..0c5ec15ae 100644 --- a/src/activities/Elsa.Activities.Http/Elsa.Activities.Http.csproj +++ b/src/activities/Elsa.Activities.Http/Elsa.Activities.Http.csproj @@ -13,16 +13,16 @@ - - - + + + - - - - + + + + diff --git a/src/activities/Elsa.Activities.Http/Extensions/HttpRequestExtensions.cs b/src/activities/Elsa.Activities.Http/Extensions/HttpRequestExtensions.cs new file mode 100644 index 000000000..24e60ae3d --- /dev/null +++ b/src/activities/Elsa.Activities.Http/Extensions/HttpRequestExtensions.cs @@ -0,0 +1,26 @@ +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; + +namespace Elsa.Activities.Http.Extensions +{ + public static class HttpRequestExtensions + { + public static async Task ReadBodyAsync(this HttpRequest request) + { + if (request.Body == null || request.Body == Stream.Null) + { + return null; + } + + request.EnableBuffering(); + + using (var reader = new StreamReader(request.Body)) + { + var content = await reader.ReadToEndAsync(); + request.Body.Seek(0, SeekOrigin.Begin); + return content; + } + } + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Http/Handlers/HttpRequestTriggerHandler.cs b/src/activities/Elsa.Activities.Http/Handlers/HttpRequestTriggerHandler.cs index 5111d40db..256a0bf4c 100644 --- a/src/activities/Elsa.Activities.Http/Handlers/HttpRequestTriggerHandler.cs +++ b/src/activities/Elsa.Activities.Http/Handlers/HttpRequestTriggerHandler.cs @@ -1,4 +1,10 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Elsa.Activities.Http.Activities; +using Elsa.Activities.Http.Extensions; +using Elsa.Activities.Http.Models; using Elsa.Handlers; using Elsa.Models; using Elsa.Results; @@ -29,14 +35,30 @@ namespace Elsa.Activities.Http.Handlers public override LocalizedString Description => T["Triggers when an incoming HTTP request is received."]; protected override LocalizedString GetEndpoint() => T["Done"]; - protected override ActivityExecutionResult OnExecute(HttpRequestTrigger activity, WorkflowExecutionContext workflowContext) + protected override async Task OnExecuteAsync(HttpRequestTrigger activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { var request = httpContextAccessor.HttpContext.Request; - var requestData = new + var model = new HttpRequestModel { - Path = request.Path + Path = new Uri(request.Path.ToString(), UriKind.Relative), + QueryString = request.Query.ToDictionary(x => x.Key, x => x.Value), + Headers = request.Headers.ToDictionary(x => x.Key, x => x.Value), + Method = request.Method }; - workflowContext.CurrentScope.LastResult = requestData; + + if (activity.ReadContent) + { + if (request.HasFormContentType) + { + model.Form = (await request.ReadFormAsync(cancellationToken)).ToDictionary(x => x.Key, x => x.Value); + } + else + { + model.Content = await request.ReadBodyAsync(); + } + } + + workflowContext.CurrentScope.LastResult = model; return TriggerEndpoint("Done"); } } diff --git a/src/activities/Elsa.Activities.Http/Middleware/HttpRequestTriggerMiddleware.cs b/src/activities/Elsa.Activities.Http/Middleware/HttpRequestTriggerMiddleware.cs index 064d1ff46..a82de121f 100644 --- a/src/activities/Elsa.Activities.Http/Middleware/HttpRequestTriggerMiddleware.cs +++ b/src/activities/Elsa.Activities.Http/Middleware/HttpRequestTriggerMiddleware.cs @@ -23,7 +23,6 @@ namespace Elsa.Activities.Http.Middleware public async Task InvokeAsync(HttpContext context, IWorkflowHost workflowHost, IHttpWorkflowCache httpWorkflowCache) { - await workflowHost.TriggerWorkflowAsync("a", Variables.Empty, CancellationToken.None); var requestPath = new Uri(context.Request.Path.ToString(), UriKind.Relative); var cancellationToken = context.RequestAborted; var workflows = await httpWorkflowCache.GetWorkflowsByPathAsync(requestPath, cancellationToken).ToListAsync(); diff --git a/src/activities/Elsa.Activities.Http/Models/HttpRequestHeaders.cs b/src/activities/Elsa.Activities.Http/Models/HttpRequestHeaders.cs new file mode 100644 index 000000000..291776571 --- /dev/null +++ b/src/activities/Elsa.Activities.Http/Models/HttpRequestHeaders.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Microsoft.Extensions.Primitives; + +namespace Elsa.Activities.Http.Models +{ + public class HttpRequestHeaders : Dictionary + { + public string ContentType => this["content-type"]; + } +} \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Http/Models/HttpRequestModel.cs b/src/activities/Elsa.Activities.Http/Models/HttpRequestModel.cs new file mode 100644 index 000000000..f0bfecc40 --- /dev/null +++ b/src/activities/Elsa.Activities.Http/Models/HttpRequestModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Primitives; + +namespace Elsa.Activities.Http.Models +{ + public class HttpRequestModel + { + public Uri Path { get; set; } + public string Method { get; set; } + public IDictionary QueryString { get; set; } + public IDictionary Headers { get; set; } + public string Content { get; set; } + public IDictionary Form { get; set; } + } +} \ No newline at end of file diff --git a/src/core/Elsa.Persistence.FileSystem/Extensions/ServiceCollectionExtensions.cs b/src/core/Elsa.Persistence.FileSystem/Extensions/ServiceCollectionExtensions.cs index 119233105..ac55aa775 100644 --- a/src/core/Elsa.Persistence.FileSystem/Extensions/ServiceCollectionExtensions.cs +++ b/src/core/Elsa.Persistence.FileSystem/Extensions/ServiceCollectionExtensions.cs @@ -11,7 +11,7 @@ namespace Elsa.Persistence.FileSystem.Extensions public static IServiceCollection AddWorkflowsFileSystemPersistence(this IServiceCollection services, IConfiguration configuration) { services.TryAddSingleton(); - services.AddSingleton(); + services.AddScoped(); services.Configure(configuration); return services; diff --git a/src/core/Esla.Persistence.InMemory/Esla.Persistence.InMemory.csproj b/src/core/Elsa.Persistence.InMemory/Elsa.Persistence.InMemory.csproj similarity index 100% rename from src/core/Esla.Persistence.InMemory/Esla.Persistence.InMemory.csproj rename to src/core/Elsa.Persistence.InMemory/Elsa.Persistence.InMemory.csproj diff --git a/src/core/Esla.Persistence.InMemory/InMemoryWorkflowStore.cs b/src/core/Elsa.Persistence.InMemory/InMemoryWorkflowStore.cs similarity index 100% rename from src/core/Esla.Persistence.InMemory/InMemoryWorkflowStore.cs rename to src/core/Elsa.Persistence.InMemory/InMemoryWorkflowStore.cs diff --git a/src/core/Esla.Runtime.Abstractions/Esla.Runtime.Abstractions.csproj b/src/core/Elsa.Runtime.Abstractions/Elsa.Runtime.Abstractions.csproj similarity index 100% rename from src/core/Esla.Runtime.Abstractions/Esla.Runtime.Abstractions.csproj rename to src/core/Elsa.Runtime.Abstractions/Elsa.Runtime.Abstractions.csproj diff --git a/src/core/Esla.Runtime.Abstractions/IWorkflowHost.cs b/src/core/Elsa.Runtime.Abstractions/IWorkflowHost.cs similarity index 100% rename from src/core/Esla.Runtime.Abstractions/IWorkflowHost.cs rename to src/core/Elsa.Runtime.Abstractions/IWorkflowHost.cs diff --git a/src/core/Esla.Runtime/Esla.Runtime.csproj b/src/core/Elsa.Runtime/Elsa.Runtime.csproj similarity index 90% rename from src/core/Esla.Runtime/Esla.Runtime.csproj rename to src/core/Elsa.Runtime/Elsa.Runtime.csproj index 0ad88daca..5a872233c 100644 --- a/src/core/Esla.Runtime/Esla.Runtime.csproj +++ b/src/core/Elsa.Runtime/Elsa.Runtime.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/core/Esla.Runtime/Extensions/ServiceCollectionExtensions.cs b/src/core/Elsa.Runtime/Extensions/ServiceCollectionExtensions.cs similarity index 69% rename from src/core/Esla.Runtime/Extensions/ServiceCollectionExtensions.cs rename to src/core/Elsa.Runtime/Extensions/ServiceCollectionExtensions.cs index 9531347c5..2f3dd22ce 100644 --- a/src/core/Esla.Runtime/Extensions/ServiceCollectionExtensions.cs +++ b/src/core/Elsa.Runtime/Extensions/ServiceCollectionExtensions.cs @@ -1,13 +1,14 @@ +using Elsa.Runtime; using Microsoft.Extensions.DependencyInjection; -namespace Elsa.Runtime.Extensions +namespace Esla.Runtime.Extensions { public static class ServiceCollectionExtensions { public static IServiceCollection AddWorkflowsHost(this IServiceCollection services) { return services - .AddSingleton(); + .AddScoped(); } } } \ No newline at end of file diff --git a/src/core/Esla.Runtime/WorkflowHost.cs b/src/core/Elsa.Runtime/WorkflowHost.cs similarity index 100% rename from src/core/Esla.Runtime/WorkflowHost.cs rename to src/core/Elsa.Runtime/WorkflowHost.cs diff --git a/src/samples/SampleHost.Web/SampleHost.Web.csproj b/src/samples/SampleHost.Web/SampleHost.Web.csproj index 2525e2dca..073b30edc 100644 --- a/src/samples/SampleHost.Web/SampleHost.Web.csproj +++ b/src/samples/SampleHost.Web/SampleHost.Web.csproj @@ -24,7 +24,7 @@ - + diff --git a/src/samples/SampleHost.Web/Startup.cs b/src/samples/SampleHost.Web/Startup.cs index 62aac6de9..1eace365d 100644 --- a/src/samples/SampleHost.Web/Startup.cs +++ b/src/samples/SampleHost.Web/Startup.cs @@ -3,7 +3,7 @@ using Elsa.Activities.Http.Extensions; using Elsa.Activities.Primitives.Extensions; using Elsa.Extensions; using Elsa.Persistence.FileSystem.Extensions; -using Elsa.Runtime.Extensions; +using Esla.Runtime.Extensions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; diff --git a/src/samples/SampleHost.Web/appsettings.json b/src/samples/SampleHost.Web/appsettings.json index a9f94d39a..584dd2f3e 100644 --- a/src/samples/SampleHost.Web/appsettings.json +++ b/src/samples/SampleHost.Web/appsettings.json @@ -6,7 +6,7 @@ }, "AllowedHosts": "*", "FileStore": { - "RootDirectory": "C:\\Activities\\Projects\\Elsa.Web.BootstrapTheme\\src\\web\\dashboard\\App_Data\\Sites\\Default\\workflows\\workflows", + "RootDirectory": "C:\\Activities\\Projects\\Elsa\\src\\web\\dashboard\\Elsa.Web.Dashboard\\App_Data\\Sites\\Default\\elsa\\workflows", "Format": "YAML" } } diff --git a/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDriver.cs b/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDriver.cs index 9d8346de4..e23eeea82 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDriver.cs +++ b/src/web/modules/Elsa.Web.Activities.Http/Drivers/HttpRequestTriggerDriver.cs @@ -10,12 +10,14 @@ namespace Elsa.Web.Activities.Http.Drivers { model.Path = activity.Path; model.Method = activity.Method; + model.ReadContent = activity.ReadContent; } protected override void UpdateActivity(HttpRequestTriggerViewModel model, HttpRequestTrigger activity) { activity.Path = model.Path; activity.Method = model.Method; + activity.ReadContent = model.ReadContent; } } } \ No newline at end of file diff --git a/src/web/modules/Elsa.Web.Activities.Http/ViewModels/HttpRequestTriggerViewModel.cs b/src/web/modules/Elsa.Web.Activities.Http/ViewModels/HttpRequestTriggerViewModel.cs index 80722a10e..56675a395 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/ViewModels/HttpRequestTriggerViewModel.cs +++ b/src/web/modules/Elsa.Web.Activities.Http/ViewModels/HttpRequestTriggerViewModel.cs @@ -14,6 +14,8 @@ namespace Elsa.Web.Activities.Http.ViewModels [Required] public string Method { get; set; } + public bool ReadContent { get; set; } + public ICollection GetAvailableHttpMethods() { var availableHttpMethods = new[] { "GET", "POST", "PUT", "DELETE", "OPTIONS" }; diff --git a/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestTrigger.Edit.cshtml b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestTrigger.Edit.cshtml index ca83adcb1..37456fcf7 100644 --- a/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestTrigger.Edit.cshtml +++ b/src/web/modules/Elsa.Web.Activities.Http/Views/HttpRequestTrigger.Edit.cshtml @@ -11,6 +11,12 @@ @T["The relative path that will trigger this activity. Example: '/webhooks/my'"] +
+ + + + @T["The HTTP method to match.'"] +
@@ -19,8 +25,9 @@ @T["Check to generate a nonce that needs to be included when invoking the URL.'"]
- - - - @T["The HTTP method to match.'"] +
+ + +
+ @T["Check to read the request body. If the content type represents a form, the body is parsed as a collection of key/value pairs. Otherwise the body is stored as a raw string'"]
\ No newline at end of file