From be911646e60bbe8c7619b15888edaeae65098fa2 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 18 Apr 2023 00:01:24 +0200 Subject: [PATCH] Add sample project for WorkflowContext module --- Elsa.sln | 7 ++ .../Contracts/ICustomerStore.cs | 10 ++ .../Elsa.Samples.WorkflowContexts/Dockerfile | 20 ++++ .../Elsa.Samples.WorkflowContexts.csproj | 28 +++++ .../Entities/Customer.cs | 10 ++ .../ExpressionExecutionContextExtensions.cs | 11 ++ .../WorkflowExecutionContextExtensions.cs | 10 ++ .../Elsa.Samples.WorkflowContexts/Program.cs | 106 ++++++++++++++++++ .../Properties/launchSettings.json | 37 ++++++ .../CustomerWorkflowContextProvider.cs | 31 +++++ .../Elsa.Samples.WorkflowContexts/README.md | 10 ++ .../Services/MemoryCustomerStore.cs | 53 +++++++++ .../CustomerCommunicationsWorkflow.cs | 57 ++++++++++ .../appsettings.json | 57 ++++++++++ .../docker-compose.yaml | 12 ++ 15 files changed, 459 insertions(+) create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Contracts/ICustomerStore.cs create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Dockerfile create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Elsa.Samples.WorkflowContexts.csproj create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Entities/Customer.cs create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Extensions/ExpressionExecutionContextExtensions.cs create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Extensions/WorkflowExecutionContextExtensions.cs create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Program.cs create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Properties/launchSettings.json create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Providers/CustomerWorkflowContextProvider.cs create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/README.md create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Services/MemoryCustomerStore.cs create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/Workflows/CustomerCommunicationsWorkflow.cs create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/appsettings.json create mode 100644 src/samples/aspnet/Elsa.Samples.WorkflowContexts/docker-compose.yaml diff --git a/Elsa.sln b/Elsa.sln index 851dc810a..44b64a5df 100644 --- a/Elsa.sln +++ b/Elsa.sln @@ -174,6 +174,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.HangfireIntegr EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.ProtoActorRuntime", "src\samples\aspnet\Elsa.Samples.ProtoActorRuntime\Elsa.Samples.ProtoActorRuntime.csproj", "{A41E24C6-B16D-4C6A-A9A9-2C5AF424F20F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Samples.WorkflowContexts", "src\samples\aspnet\Elsa.Samples.WorkflowContexts\Elsa.Samples.WorkflowContexts.csproj", "{F88AB1C2-100E-459F-B2BE-5F2ACF050A0A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -432,6 +434,10 @@ Global {A41E24C6-B16D-4C6A-A9A9-2C5AF424F20F}.Debug|Any CPU.Build.0 = Debug|Any CPU {A41E24C6-B16D-4C6A-A9A9-2C5AF424F20F}.Release|Any CPU.ActiveCfg = Release|Any CPU {A41E24C6-B16D-4C6A-A9A9-2C5AF424F20F}.Release|Any CPU.Build.0 = Release|Any CPU + {F88AB1C2-100E-459F-B2BE-5F2ACF050A0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F88AB1C2-100E-459F-B2BE-5F2ACF050A0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F88AB1C2-100E-459F-B2BE-5F2ACF050A0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F88AB1C2-100E-459F-B2BE-5F2ACF050A0A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {155227F0-A33B-40AA-A4B4-06F813EB921B} = {61017E64-6D00-49CB-9E81-5002DC8F7D5F} @@ -508,5 +514,6 @@ Global {B0312D9E-FA30-43E9-B666-40A8782D6E1C} = {56C2FFB8-EA54-45B5-A095-4A78142EB4B5} {D2614FC7-102F-4F78-BB06-7C87304A10BA} = {56C2FFB8-EA54-45B5-A095-4A78142EB4B5} {A41E24C6-B16D-4C6A-A9A9-2C5AF424F20F} = {56C2FFB8-EA54-45B5-A095-4A78142EB4B5} + {F88AB1C2-100E-459F-B2BE-5F2ACF050A0A} = {56C2FFB8-EA54-45B5-A095-4A78142EB4B5} EndGlobalSection EndGlobal diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Contracts/ICustomerStore.cs b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Contracts/ICustomerStore.cs new file mode 100644 index 000000000..f957146eb --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Contracts/ICustomerStore.cs @@ -0,0 +1,10 @@ +namespace Elsa.Samples.WorkflowContexts.Contracts; + +/// +/// A sample repository of customers. +/// +public interface ICustomerStore +{ + Task GetAsync(string id, CancellationToken cancellationToken = default); + Task SaveAsync(Customer customer, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Dockerfile b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Dockerfile new file mode 100644 index 000000000..0d58c3066 --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["src/samples/aspnet/Elsa.Samples.WorkflowContexts/Elsa.Samples.WorkflowContexts.csproj", "src/samples/aspnet/Elsa.Samples.WorkflowContexts/"] +RUN dotnet restore "src/samples/aspnet/Elsa.Samples.WorkflowContexts/Elsa.Samples.WorkflowContexts.csproj" +COPY . . +WORKDIR "/src/src/samples/aspnet/Elsa.Samples.WorkflowContexts" +RUN dotnet build "Elsa.Samples.WorkflowContexts.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Elsa.Samples.WorkflowContexts.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Elsa.Samples.WorkflowContexts.dll"] diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Elsa.Samples.WorkflowContexts.csproj b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Elsa.Samples.WorkflowContexts.csproj new file mode 100644 index 000000000..aaf4dbf46 --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Elsa.Samples.WorkflowContexts.csproj @@ -0,0 +1,28 @@ + + + + net7.0 + enable + enable + Linux + + + + + .dockerignore + + + + + + + + + + + + + + + + diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Entities/Customer.cs b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Entities/Customer.cs new file mode 100644 index 000000000..97cbbc3f2 --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Entities/Customer.cs @@ -0,0 +1,10 @@ +namespace Elsa.Samples.WorkflowContexts.Contracts; + +public class Customer +{ + public string Id { get; set; } + public string Name { get; set; } + public string Email { get; set; } + public string Phone { get; set; } + public string Website { get; set; } +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Extensions/ExpressionExecutionContextExtensions.cs b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Extensions/ExpressionExecutionContextExtensions.cs new file mode 100644 index 000000000..69e96e64b --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Extensions/ExpressionExecutionContextExtensions.cs @@ -0,0 +1,11 @@ +using Elsa.Expressions.Models; +using Elsa.Extensions; +using Elsa.Samples.WorkflowContexts.Contracts; +using Elsa.Samples.WorkflowContexts.Providers; + +namespace Elsa.Samples.WorkflowContexts.Extensions; + +public static class ExpressionExecutionContextExtensions +{ + public static Customer GetCustomer(this ExpressionExecutionContext context) => context.GetWorkflowContext(); +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Extensions/WorkflowExecutionContextExtensions.cs b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Extensions/WorkflowExecutionContextExtensions.cs new file mode 100644 index 000000000..c879625d7 --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Extensions/WorkflowExecutionContextExtensions.cs @@ -0,0 +1,10 @@ +using Elsa.Workflows.Core.Models; + +namespace Elsa.Samples.WorkflowContexts.Extensions; + +public static class WorkflowExecutionContextExtensions +{ + private const string CustomerIdKey = "CustomerId"; + public static string? GetCustomerId(this WorkflowExecutionContext context) => context.GetProperty(CustomerIdKey); + public static void SetCustomerId(this WorkflowExecutionContext context, string? customerId) => context.SetProperty(CustomerIdKey, customerId); +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Program.cs b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Program.cs new file mode 100644 index 000000000..f31418c4b --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Program.cs @@ -0,0 +1,106 @@ +using Elsa.EntityFrameworkCore.Extensions; +using Elsa.EntityFrameworkCore.Modules.Management; +using Elsa.EntityFrameworkCore.Modules.Runtime; +using Elsa.Extensions; +using Elsa.Samples.WorkflowContexts.Contracts; +using Elsa.Samples.WorkflowContexts.Providers; +using Elsa.Samples.WorkflowContexts.Services; +using Elsa.Samples.WorkflowContexts.Workflows; +using Elsa.Workflows.Core.Middleware.Workflows; + +var builder = WebApplication.CreateBuilder(args); +var services = builder.Services; +var configuration = builder.Configuration; +var sqliteConnectionString = configuration.GetConnectionString("Sqlite")!; +var identitySection = configuration.GetSection("Identity"); +var identityTokenSection = identitySection.GetSection("Tokens"); + +// Add Elsa services. +services + .AddElsa(elsa => elsa + .AddActivitiesFrom() + .AddWorkflow() + .UseIdentity(identity => + { + identity.IdentityOptions = options => identitySection.Bind(options); + identity.TokenOptions = options => identityTokenSection.Bind(options); + identity.UseConfigurationBasedUserProvider(options => identitySection.Bind(options)); + identity.UseConfigurationBasedApplicationProvider(options => identitySection.Bind(options)); + identity.UseConfigurationBasedRoleProvider(options => identitySection.Bind(options)); + }) + .UseDefaultAuthentication() + .UseWorkflows(workflows => workflows.WithWorkflowExecutionPipeline(pipeline => pipeline + .Reset() + .UsePersistentVariables() + .UseBookmarkPersistence() + .UseWorkflowExecutionLogPersistence() + .UseWorkflowStatePersistence() + .UseWorkflowContexts() + .UseDefaultActivityScheduler() + )) + .UseWorkflowManagement(management => + { + // Use EF core for workflow definitions and instances. + management.UseWorkflowInstances(m => m.UseEntityFrameworkCore(ef => ef.UseSqlite(sqliteConnectionString))); + management.UseEntityFrameworkCore(m => m.UseSqlite(sqliteConnectionString)); + }) + .UseWorkflowRuntime(runtime => + { + // Use EF core for triggers and bookmarks. + runtime.UseEntityFrameworkCore(ef => ef.UseSqlite(sqliteConnectionString)); + + // Use EF core for execution log records. + runtime.UseExecutionLogRecords(log => log.UseEntityFrameworkCore(ef => ef.UseSqlite(sqliteConnectionString))); + + // Use the default workflow runtime with EF core. + runtime.UseDefaultRuntime(defaultRuntime => defaultRuntime.UseEntityFrameworkCore(ef => ef.UseSqlite(sqliteConnectionString))); + + // Install a workflow state exporter to capture workflow states and store them in IWorkflowInstanceStore. + runtime.UseAsyncWorkflowStateExporter(); + }) + .UseScheduling() + .UseWorkflowsApi(api => api.AddFastEndpointsAssembly()) + .UseJavaScript() + .UseLiquid() + .UseHttp() + .UseEmail(email => email.ConfigureOptions = options => configuration.GetSection("Smtp").Bind(options)) + ); + +// Add health checks. +services.AddHealthChecks(); + +// Add CORS. +services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin())); + +// Add domain services. +services.AddSingleton(); + +// Add workflow context providers. +services.AddWorkflowContextProvider(); + +// Configure middleware pipeline. +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) + app.UseDeveloperExceptionPage(); + +// CORS. +app.UseCors(); + +// Health checks. +app.MapHealthChecks("/"); + +app.UseAuthentication(); +app.UseAuthorization(); + +// Elsa API endpoints for designer. +app.UseWorkflowsApi(); + +// Captures unhandled exceptions and returns a JSON response. +app.UseJsonSerializationErrorHandler(); + +// Elsa HTTP Endpoint activities +app.UseWorkflows(); + +// Run. +app.Run(); \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Properties/launchSettings.json b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Properties/launchSettings.json new file mode 100644 index 000000000..a937a615b --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:32709", + "sslPort": 44321 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5286", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7019;http://localhost:5286", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Providers/CustomerWorkflowContextProvider.cs b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Providers/CustomerWorkflowContextProvider.cs new file mode 100644 index 000000000..02b6698dc --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Providers/CustomerWorkflowContextProvider.cs @@ -0,0 +1,31 @@ +using Elsa.Samples.WorkflowContexts.Contracts; +using Elsa.Samples.WorkflowContexts.Extensions; +using Elsa.WorkflowContexts.Abstractions; +using Elsa.Workflows.Core.Models; + +namespace Elsa.Samples.WorkflowContexts.Providers; + +public class CustomerWorkflowContextProvider : WorkflowContextProvider +{ + private readonly ICustomerStore _customerStore; + + public CustomerWorkflowContextProvider(ICustomerStore customerStore) + { + _customerStore = customerStore; + } + + protected override async ValueTask LoadAsync(WorkflowExecutionContext workflowExecutionContext) + { + var customerId = workflowExecutionContext.GetCustomerId(); + return customerId != null ? await _customerStore.GetAsync(customerId) : null; + } + + protected override async ValueTask SaveAsync(WorkflowExecutionContext workflowExecutionContext, Customer? context) + { + if (context != null) + { + await _customerStore.SaveAsync(context); + workflowExecutionContext.SetCustomerId(context.Id); + } + } +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/README.md b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/README.md new file mode 100644 index 000000000..1a514869e --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/README.md @@ -0,0 +1,10 @@ +# Server + +This project represents an Elsa application that hosts workflows and exposes API endpoints to manage & execute workflows. + +## Secrets +The following are the secrets stored in hashed form in appsettings.json: + +**API key**: `4E753976726458745954355043687772-e54d5a2c-33a3-4c05-a216-b09569062aed` +**Admin user**: `admin` +**Admin password**: `password` \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Services/MemoryCustomerStore.cs b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Services/MemoryCustomerStore.cs new file mode 100644 index 000000000..0eb4cb79d --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Services/MemoryCustomerStore.cs @@ -0,0 +1,53 @@ +using Elsa.Samples.WorkflowContexts.Contracts; + +namespace Elsa.Samples.WorkflowContexts.Services; + +/// +/// An in-memory implementation of . +/// +public class MemoryCustomerStore : ICustomerStore +{ + private readonly IDictionary _customers = CreateCustomersDatabase(); + + public Task GetAsync(string id, CancellationToken cancellationToken = default) + { + return Task.FromResult(_customers.TryGetValue(id, out var customer) ? customer : null); + } + + public Task SaveAsync(Customer customer, CancellationToken cancellationToken = default) + { + _customers[customer.Id] = customer; + return Task.CompletedTask; + } + + private static IDictionary CreateCustomersDatabase() + { + return new Dictionary + { + ["1"] = new() + { + Id = "1", + Name = "John Doe", + Email = "john.doe@acme.com", + Phone = "+1 555 123 4567", + Website = "https://acme.com" + }, + ["2"] = new() + { + Id = "2", + Name = "Alice Smith", + Email = "alice.smith@example.com", + Phone = "+1 555 123 4567", + Website = "https://example.com" + }, + ["3"] = new() + { + Id = "3", + Name = "Bob Jones", + Email = "bob.jones@supplier.com", + Phone = "+1 555 123 4567", + Website = "https://supplier.com" + }, + }; + } +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Workflows/CustomerCommunicationsWorkflow.cs b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Workflows/CustomerCommunicationsWorkflow.cs new file mode 100644 index 000000000..182bd5859 --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/Workflows/CustomerCommunicationsWorkflow.cs @@ -0,0 +1,57 @@ +using Elsa.Email.Activities; +using Elsa.Extensions; +using Elsa.Samples.WorkflowContexts.Extensions; +using Elsa.Samples.WorkflowContexts.Providers; +using Elsa.Scheduling.Activities; +using Elsa.Workflows.Core.Abstractions; +using Elsa.Workflows.Core.Activities; +using Elsa.Workflows.Core.Contracts; + +namespace Elsa.Samples.WorkflowContexts.Workflows; + +/// +/// A workflow that sends annoying emails to customers. +/// +public class CustomerCommunicationsWorkflow : WorkflowBase +{ + protected override void Build(IWorkflowBuilder builder) + { + builder.AddWorkflowContextProvider(); + + builder.Root = new Sequence + { + Activities = + { + Inline.From(context => context.WorkflowExecutionContext.SetCustomerId(context.GetInput("CustomerId"))), + Delay.FromSeconds(5), + new SendEmail + { + Subject = new(context => $"Welcome to our family, {context.GetCustomer().Name}!"), + Body = new("Welcome aboard!"), + To = new(context => new[] { context.GetCustomer().Email }) + }, + Delay.FromSeconds(5), + new SendEmail + { + Subject = new(context => $"{context.GetCustomer().Name}, we got great deals for you!"), + Body = new("Get your creditcard ready!"), + To = new(context => new[] { context.GetCustomer().Email }) + }, + Delay.FromSeconds(5), + new SendEmail + { + Subject = new(context => $"{context.GetCustomer().Name}, you're missing out!"), + Body = new("Sale ends in 2 hours!"), + To = new(context => new[] { context.GetCustomer().Email }) + }, + Delay.FromSeconds(5), + new SendEmail + { + Subject = new(context => $"{context.GetCustomer().Name}, the clock is ticking!"), + Body = new("Tick tik tick!"), + To = new(context => new[] { context.GetCustomer().Email }) + }, + } + }; + } +} \ No newline at end of file diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/appsettings.json b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/appsettings.json new file mode 100644 index 000000000..b8d078878 --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/appsettings.json @@ -0,0 +1,57 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "Elsa.Mediator": "Warning", + "MassTransit": "Warning", + "Microsoft.Extensions.Http": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "Microsoft.AspNetCore": "Warning", + "System.Net.Http": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "Sqlite": "Data Source=elsa.sqlite.db;Cache=Shared;" + }, + "Identity": { + "Tokens": { + "SigningKey": "secret-signing-key", + "AccessTokenLifetime": "1:00:00:00", + "RefreshTokenLifetime": "1:00:10:00" + }, + "Roles": [{ + "Id": "admin", + "Name": "Administrator", + "Permissions": ["*"] + }], + "Users": [ + { + "Id": "a2323f46-42db-4e15-af8b-94238717d817", + "Name": "admin", + "HashedPassword": "TfKzh9RLix6FPcCNeHLkGrysFu3bYxqzGqduNdi8v1U=", + "HashedPasswordSalt": "JEy9kBlhHCNsencitRHlGxmErmSgY+FVyMJulCH27Ds=", + "Roles": ["admin"] + } + ], + "Applications": [{ + "id": "529572c2df854b13807b8bf23f1784cd", + "name": "Postman", + "roles": [ + "admin" + ], + "clientId": "Nu9vrdXtYT5PChwr", + "clientSecret": "011pp2C$|j01-qrMZpC9VC0F00XCJq(5", + "hashedApiKey": "d0rDld3A+ugKmdctGtMzOLTYjQFkOlUWN+kt0VyW9D0=", + "hashedApiKeySalt": "EnutGOyy5MuJWV0fF5jCQiciK7a8PU/DRF+fr6nekSY=", + "hashedClientSecret": "ERia2zBcCSWb/9dvB0grQ9yf7fWgFrClNeR8A5RMTzk=", + "hashedClientSecretSalt": "z3z8KmzHt+xkAj/zYTXcB8I7y0xAkLm95v4Er/oNqiY=" + }] + }, + "Smtp": { + "Host": "localhost", + "Port": 2525, + "DefaultSender": "noreply@crmservices.com" + } +} diff --git a/src/samples/aspnet/Elsa.Samples.WorkflowContexts/docker-compose.yaml b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/docker-compose.yaml new file mode 100644 index 000000000..452ce9877 --- /dev/null +++ b/src/samples/aspnet/Elsa.Samples.WorkflowContexts/docker-compose.yaml @@ -0,0 +1,12 @@ +version: '3.9' + +services: + + smtp4dev: + image: rnwood/smtp4dev:3.1.3-ci20211206101 + ports: + - "3000:80" + - "2525:25" + +volumes: + mssql-azuresql-edge-data: \ No newline at end of file