Add initial version of Document Approval sample from Elsa 2

This commit is contained in:
Sipke Schoorstra 2023-09-21 00:05:50 +02:00
parent 841628011a
commit edc2335d82
6 changed files with 256 additions and 0 deletions

View file

@ -0,0 +1,150 @@
using System.Dynamic;
using System.Net;
using System.Net.Mime;
using Elsa.Expressions.Models;
using Elsa.Http;
using Elsa.Http.Models;
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Activities;
using Elsa.Workflows.Core.Contracts;
using Elsa.Workflows.Runtime.Activities;
namespace Elsa.Samples.AspNet.DocumentApproval
{
/// <summary>
/// A workflow that gives Jack and Lucy a chance to review a submitted document.
/// </summary>
public class DocumentApprovalWorkflow : WorkflowBase
{
protected override void Build(IWorkflowBuilder builder)
{
var documentVariable = builder.WithVariable<ExpandoObject>();
var approvedVariable = builder.WithVariable<bool>();
builder.Root = new Sequence
{
Activities =
{
new HttpEndpoint
{
Path = new("/documents"),
SupportedMethods = new(new[] { HttpMethods.Post }),
ParsedContent = new(documentVariable),
CanStartWorkflow = true
},
new WriteLine(context => $"Document received from {documentVariable.Get<dynamic>(context)!.Author.Name}."),
new WriteHttpResponse
{
Content = new("<h1>Request for Approval Sent</h1><p>Your document has been received and will be reviewed shortly.</p>"),
ContentType = new(MediaTypeNames.Text.Html),
StatusCode = new(HttpStatusCode.OK),
ResponseHeaders = new(new HttpResponseHeaders { ["X-Powered-By"] = new[] { "Elsa 3.0" } })
},
new Fork
{
JoinMode = ForkJoinMode.WaitAll,
Branches =
{
// Jack
new Sequence
{
Activities =
{
new WriteLine(context => $"Jack approve url: \n {GenerateSignalUrl(context, "Approve:Jack")}"),
new Fork
{
JoinMode = ForkJoinMode.WaitAny,
Branches =
{
// Approve
new Sequence
{
Activities =
{
new Event("Approve:Jack"),
new SetVariable
{
Variable = approvedVariable,
Value = new(true)
}
}
},
// Reject
new Sequence
{
Activities =
{
new Event("Reject:Jack"),
new SetVariable
{
Variable = approvedVariable,
Value = new(false)
}
}
}
}
}
}
},
// Lucy
new Sequence
{
Activities =
{
new WriteLine(context => $"Lucy approve url: \n {GenerateSignalUrl(context, "Approve:Lucy")}"),
new Fork
{
JoinMode = ForkJoinMode.WaitAny,
Branches =
{
// Approve
new Sequence
{
Activities =
{
new Event("Approve:Lucy"),
new SetVariable
{
Variable = approvedVariable,
Value = new(true)
}
}
},
// Reject
new Sequence
{
Activities =
{
new Event("Reject:Lucy"),
new SetVariable
{
Variable = approvedVariable,
Value = new(false)
}
}
}
}
}
}
}
}
},
new WriteLine(context => $"Approved: {approvedVariable.Get<bool>(context)}"),
new If(context => approvedVariable.Get<bool>(context))
{
Then = new WriteLine(context => $"Document ${documentVariable.Get<dynamic>(context)!.Id} approved!"),
Else = new WriteLine(context => $"Document ${documentVariable.Get<dynamic>(context)!.Id} rejected!")
}
}
};
}
private string GenerateSignalUrl(ExpressionExecutionContext context, string signalName)
{
return "Signal (events in Elsa 3) URL generation not yet implemented";
}
}
}

View file

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\bundles\Elsa\Elsa.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.Email\Elsa.Email.csproj" />
<ProjectReference Include="..\..\..\modules\Elsa.Http\Elsa.Http.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.Identity\Elsa.Identity.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.JavaScript\Elsa.JavaScript.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.Liquid\Elsa.Liquid.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.EntityFrameworkCore.Sqlite\Elsa.EntityFrameworkCore.Sqlite.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.ProtoActor\Elsa.ProtoActor.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.Scheduling\Elsa.Scheduling.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.Telnyx\Elsa.Telnyx.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.WorkflowContexts\Elsa.WorkflowContexts.csproj"/>
<ProjectReference Include="..\..\..\modules\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj"/>
</ItemGroup>
</Project>

View file

@ -0,0 +1,24 @@
using Elsa.Extensions;
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
// Add Elsa services.
services.AddElsa(elsa => elsa
.AddWorkflowsFrom<Program>()
// Enable Elsa HTTP module (for HTTP related activities).
.UseHttp()
);
// Configure middleware pipeline.
var app = builder.Build();
if (app.Environment.IsDevelopment())
app.UseDeveloperExceptionPage();
// Add Elsa HTTP middleware (to handle requests mapped to HTTP Endpoint activities)
app.UseWorkflows();
// Start accepting requests.
app.Run();

View file

@ -0,0 +1,37 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:5197",
"sslPort": 44323
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5065",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5065",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View file

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View file

@ -0,0 +1,11 @@
POST https://localhost:5001/workflows/documents
Content-Type: application/json
{
"Id": "document-1",
"Author": {
"Name": "Amanda"
}
}
###