Merge remote-tracking branch 'upstream/main' into enh/Connections
This commit is contained in:
commit
4565dfcfbc
|
|
@ -1,5 +1,5 @@
|
|||
# Remove the line below if you want to inherit .editorconfig settings from higher directories
|
||||
root = true
|
||||
# Remove the line below if you want to inherit .editorconfig settings from higher directories
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
|
|
@ -76,9 +76,9 @@ dotnet_style_allow_statement_immediately_after_block_experimental = true
|
|||
#### C# Coding Conventions ####
|
||||
|
||||
# var preferences
|
||||
csharp_style_var_elsewhere = false
|
||||
csharp_style_var_for_built_in_types = false
|
||||
csharp_style_var_when_type_is_apparent = false
|
||||
csharp_style_var_elsewhere = true
|
||||
csharp_style_var_for_built_in_types = true
|
||||
csharp_style_var_when_type_is_apparent = true
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_accessors = true
|
||||
|
|
|
|||
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
labels: bug
|
||||
about: Create a bug report to help us improve
|
||||
title: ""
|
||||
type: Bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: Documentation Improvement
|
||||
name: Documentation
|
||||
about: Suggest improvements to the documentation for this project
|
||||
title: "[DOC] "
|
||||
labels: documentation
|
||||
title: ""
|
||||
Type: Documentation
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
4
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: "[FEAT]"
|
||||
labels: enhancement
|
||||
title: ""
|
||||
type: Feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: Enhancement
|
||||
name: Improvement
|
||||
about: Suggest an enhancement to an existing feature for this project
|
||||
title: "[ENH] "
|
||||
labels: enhancement
|
||||
title: ""
|
||||
type: Improvement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
6
.github/ISSUE_TEMPLATE/performance.md
vendored
6
.github/ISSUE_TEMPLATE/performance.md
vendored
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: Performance Improvement
|
||||
name: Performance
|
||||
about: Suggest a performance enhancement for this project
|
||||
title: "[PERF] "
|
||||
labels: performance
|
||||
title: ""
|
||||
type: Performance
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
name: Maintenance Task
|
||||
about: Suggest a maintenance task for this project
|
||||
title: "[CHORE] "
|
||||
labels: maintenance
|
||||
name: Task
|
||||
about: Suggest a task for this project
|
||||
title: ""
|
||||
type: Task
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Maintenance Task Request
|
||||
## Task Request
|
||||
|
||||
### Task Overview
|
||||
**What maintenance task do you propose? Please describe.**
|
||||
30
.github/ISSUE_TEMPLATE/test.md
vendored
30
.github/ISSUE_TEMPLATE/test.md
vendored
|
|
@ -1,30 +0,0 @@
|
|||
---
|
||||
name: Test Improvement
|
||||
about: Suggest improvements or additions to tests for this project
|
||||
title: "[TEST] "
|
||||
labels: test
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Test Improvement Request
|
||||
|
||||
### Test Issue Overview
|
||||
**Is your test improvement related to a specific problem? Please describe.**
|
||||
Provide a detailed explanation of the testing issue, such as missing coverage, flaky tests, or inefficient testing processes. For example, "We currently have no tests covering our user authentication flow..."
|
||||
|
||||
### Proposed Test Improvements
|
||||
**Describe the improvements you'd like**
|
||||
Explain in detail what testing improvements or new tests you would like to see implemented. Describe how these tests should work and why they are necessary. Include any particular aspects like integration tests, unit tests, or end-to-end tests.
|
||||
|
||||
### Existing Tests
|
||||
**Describe any existing tests and their limitations**
|
||||
Detail the current testing setup and its limitations. This could include gaps in coverage, outdated tests, or tests that frequently fail under certain conditions.
|
||||
|
||||
### Impact of Improvements
|
||||
**Explain the potential impact**
|
||||
How would these test improvements benefit the development process, product reliability, or deployment cycles? Detail the anticipated benefits to help stakeholders understand the value of improving testing.
|
||||
|
||||
### Additional Context
|
||||
**Add any other context**
|
||||
Include any other information that might help clarify your request. This could be technical considerations, links to failed builds, or any other details that could inform the improvement process.
|
||||
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "NuGet" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
21
.github/workflows/packages.yml
vendored
21
.github/workflows/packages.yml
vendored
|
|
@ -5,10 +5,12 @@ on:
|
|||
branches:
|
||||
- 'main'
|
||||
- 'bug/*'
|
||||
- 'perf/*'
|
||||
- 'patch/*'
|
||||
release:
|
||||
types: [ prereleased, published ]
|
||||
env:
|
||||
base_version: '3.3.0'
|
||||
base_version: '3.4.0'
|
||||
feedz_feed_source: 'https://f.feedz.io/elsa-workflows/elsa-3/nuget/index.json'
|
||||
nuget_feed_source: 'https://api.nuget.org/v3/index.json'
|
||||
|
||||
|
|
@ -99,27 +101,12 @@ jobs:
|
|||
- name: Publish to feedz.io
|
||||
run: dotnet nuget push *.nupkg -k ${{ secrets.FEEDZ_API_KEY }} -s ${{ env.feedz_feed_source }} --skip-duplicate
|
||||
|
||||
publish_preview_nuget:
|
||||
name: Publish preview to nuget.org
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
if: ${{ github.event_name == 'prereleased' && github.event.action == 'published' }}
|
||||
steps:
|
||||
- name: Download Packages
|
||||
uses: actions/download-artifact@v4.1.7
|
||||
with:
|
||||
name: elsa-nuget-packages
|
||||
|
||||
- name: Publish to nuget.org
|
||||
run: dotnet nuget push *.nupkg -k ${{ secrets.NUGET_API_KEY }} -s ${{ env.nuget_feed_source }} --skip-duplicate
|
||||
|
||||
publish_nuget:
|
||||
name: Publish release to nuget.org
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
if: ${{ github.event_name == 'release' && github.event.action == 'published' }}
|
||||
if: ${{ github.event.action == 'published' }}
|
||||
steps:
|
||||
- name: Download Packages
|
||||
uses: actions/download-artifact@v4.1.7
|
||||
|
|
|
|||
7
.github/workflows/pr.yml
vendored
7
.github/workflows/pr.yml
vendored
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# - To turn off auto-generation set:
|
||||
#
|
||||
# [GitHubActions (AutoGenerate = false)]
|
||||
# [CustomGitHubActions (AutoGenerate = false)]
|
||||
#
|
||||
# - To trigger manual generation invoke:
|
||||
#
|
||||
|
|
@ -32,9 +32,10 @@ jobs:
|
|||
name: ubuntu-latest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 9.x
|
||||
dotnet-version: |
|
||||
9.x
|
||||
- uses: actions/checkout@v4
|
||||
- name: 'Run: Compile, Test, Pack'
|
||||
run: ./build.cmd Compile Test Pack
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -76,3 +76,5 @@ unlist.sh
|
|||
|
||||
# build artifacts
|
||||
/artifacts
|
||||
|
||||
/docker/data/
|
||||
|
|
|
|||
|
|
@ -1,28 +1,5 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"properties": {
|
||||
"AnalyseCode": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Configuration": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Release"
|
||||
]
|
||||
},
|
||||
"IgnoreFailedSources": {
|
||||
"type": "boolean",
|
||||
"description": "Ignore unreachable sources during Restore"
|
||||
},
|
||||
"Solution": {
|
||||
"type": "string",
|
||||
"description": "Path to a solution file that is automatically loaded"
|
||||
},
|
||||
"Version": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"Host": {
|
||||
"type": "string",
|
||||
|
|
@ -122,5 +99,34 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"$ref": "#/definitions/NukeBuild"
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"AnalyseCode": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"Configuration": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Debug",
|
||||
"Release"
|
||||
]
|
||||
},
|
||||
"IgnoreFailedSources": {
|
||||
"type": "boolean",
|
||||
"description": "Ignore unreachable sources during Restore"
|
||||
},
|
||||
"Solution": {
|
||||
"type": "string",
|
||||
"description": "Path to a solution file that is automatically loaded"
|
||||
},
|
||||
"Version": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/NukeBuild"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,6 @@
|
|||
<NoWarn>$(NoWarn);IL2026;IL2046;IL2057;IL2067;IL2070;IL2072;IL2075;IL2087;IL2091</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ElsaStudioVersion>3.3.0-preview.666</ElsaStudioVersion>
|
||||
<ElsaStudioVersion>3.3.0-rc4</ElsaStudioVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -1,234 +1,197 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Antlr4.Runtime.Standard" Version="4.13.1" />
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations" Version="0.5.1" />
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.MySql" Version="0.5.1" />
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.PostgreSQL" Version="0.5.1" />
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.SQLite" Version="0.5.1" />
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.SqlServer" Version="0.5.1" />
|
||||
<PackageVersion Include="AutoMapper" Version="13.0.1" PrivateAssets="All" />
|
||||
<PackageVersion Include="Azure.Identity" Version="1.13.1" />
|
||||
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.18.2" />
|
||||
<PackageVersion Include="Azure.ResourceManager" Version="1.13.0" />
|
||||
<PackageVersion Include="Azure.ResourceManager.AppContainers" Version="1.3.0" />
|
||||
<PackageVersion Include="Azure.ResourceManager.Resources" Version="1.9.0" />
|
||||
<PackageVersion Include="Azure.ResourceManager.ServiceBus" Version="1.0.1" />
|
||||
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
|
||||
<PackageVersion Include="Bogus" Version="35.6.1" />
|
||||
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" PrivateAssets="All" />
|
||||
<PackageVersion Include="Confluent.Kafka" Version="2.6.1" />
|
||||
<PackageVersion Include="Confluent.SchemaRegistry.Serdes.Avro" Version="2.4.0" />
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.2" PrivateAssets="All" />
|
||||
<PackageVersion Include="Cronos" Version="0.8.4" />
|
||||
<PackageVersion Include="Dapper" Version="2.1.35" />
|
||||
<PackageVersion Include="DistributedLock.Core" Version="1.0.7" />
|
||||
<PackageVersion Include="DistributedLock.FileSystem" Version="1.0.2" />
|
||||
<PackageVersion Include="DistributedLock.Postgres" Version="1.2.0" />
|
||||
<PackageVersion Include="DistributedLock.Redis" Version="1.0.3" />
|
||||
<PackageVersion Include="Elastic.Clients.Elasticsearch" Version="8.15.10" />
|
||||
<PackageVersion Include="Elsa.Studio" Version="3.3.0-preview.630" />
|
||||
<PackageVersion Include="Elsa.Studio.Agents" Version="3.3.0-preview.630" />
|
||||
<PackageVersion Include="Elsa.Studio.Core.BlazorWasm" Version="3.3.0-preview.630" />
|
||||
<PackageVersion Include="Elsa.Studio.Login.BlazorWasm" Version="3.3.0-preview.630" />
|
||||
<PackageVersion Include="FastEndpoints" Version="5.31.0" />
|
||||
<PackageVersion Include="FastEndpoints.Security" Version="5.31.0" />
|
||||
<PackageVersion Include="FastEndpoints.Swagger" Version="5.31.0" />
|
||||
<PackageVersion Include="FluentMigrator" Version="6.2.0" />
|
||||
<PackageVersion Include="FluentMigrator.Runner" Version="6.2.0" />
|
||||
<PackageVersion Include="FluentStorage" Version="5.6.0" />
|
||||
<PackageVersion Include="FluentStorage.Azure.Blobs" Version="5.3.0" />
|
||||
<PackageVersion Include="Fluid.Core" Version="2.14.0" />
|
||||
<PackageVersion Include="Fody" Version="6.9.1" />
|
||||
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1" />
|
||||
<PackageVersion Include="Google.Protobuf" Version="3.29.1" />
|
||||
<PackageVersion Include="Grpc.Net.Client" Version="2.67.0" />
|
||||
<PackageVersion Include="Grpc.Tools" Version="2.68.1" />
|
||||
<PackageVersion Include="Hangfire" Version="1.8.17" />
|
||||
<PackageVersion Include="Hangfire.MemoryStorage" Version="1.8.1.1" />
|
||||
<PackageVersion Include="Hangfire.Storage.SQLite" Version="0.4.2" />
|
||||
<PackageVersion Include="Humanizer.Core" Version="2.14.1" />
|
||||
<PackageVersion Include="IronCompress" Version="1.6.3" />
|
||||
<PackageVersion Include="JetBrains.Annotations" Version="2024.3.0" />
|
||||
<PackageVersion Include="Jint" Version="4.1.0" />
|
||||
<PackageVersion Include="LinqKit.Core" Version="1.2.7" />
|
||||
<PackageVersion Include="MailKit" Version="4.8.0" />
|
||||
<PackageVersion Include="MassTransit" Version="8.3.0" />
|
||||
<PackageVersion Include="MassTransit.Azure.ServiceBus.Core" Version="8.3.0" />
|
||||
<PackageVersion Include="MassTransit.RabbitMQ" Version="8.3.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.12.0" />
|
||||
<PackageVersion Include="Microsoft.Identity.Client" Version="4.66.2" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.25.0" />
|
||||
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
|
||||
<PackageVersion Include="MongoDB.Driver" Version="3.1.0" />
|
||||
<PackageVersion Include="MongoDB.Driver.Core.Extensions.DiagnosticSources" Version="1.5.0" />
|
||||
<PackageVersion Include="MongoDB.Driver.Extensions" Version="2.0.2" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageVersion Include="NSubstitute" Version="5.3.0" />
|
||||
<PackageVersion Include="NuGet.Packaging" Version="6.12.1" />
|
||||
<PackageVersion Include="NuGet.Protocol" Version="6.12.1" />
|
||||
<PackageVersion Include="Nuke.Components" Version="9.0.3" />
|
||||
<PackageVersion Include="Open.Linq.AsyncExtensions" Version="1.2.0" />
|
||||
<PackageVersion Include="Polly.Extensions.Http" Version="3.0.0" />
|
||||
<PackageVersion Include="PolySharp" Version="1.15.0" />
|
||||
<PackageVersion Include="Proto.Actor" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Cluster" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Cluster.AzureContainerApps" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Cluster.CodeGen" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Cluster.Kubernetes" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Cluster.TestProvider" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.OpenTelemetry" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Persistence" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Persistence.Sqlite" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Persistence.SqlServer" Version="1.7.0" />
|
||||
<PackageVersion Include="Proto.Remote" Version="1.7.0" />
|
||||
<PackageVersion Include="pythonnet" Version="3.0.4" />
|
||||
<PackageVersion Include="Quartz.Extensions.Hosting" Version="3.13.1" />
|
||||
<PackageVersion Include="Quartz.Serialization.Json" Version="3.13.1" />
|
||||
<PackageVersion Include="Scrutor" Version="5.0.2" />
|
||||
<PackageVersion Include="ShortGuid" Version="2.0.1" />
|
||||
<PackageVersion Include="StackExchange.Redis" Version="2.8.16" />
|
||||
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||
<PackageVersion Include="System.Data.SqlClient" Version="4.8.6" />
|
||||
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Linq.Dynamic.Core" Version="1.4.9" />
|
||||
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
|
||||
<PackageVersion Include="Testcontainers" Version="3.10.0" />
|
||||
<PackageVersion Include="Testcontainers.PostgreSql" Version="3.10.0" />
|
||||
<PackageVersion Include="Testcontainers.RabbitMq" Version="3.10.0" />
|
||||
<PackageVersion Include="Testcontainers.Redis" Version="3.10.0" />
|
||||
<PackageVersion Include="ThrottleDebounce" Version="2.0.0" />
|
||||
<PackageVersion Include="WebhooksCore" Version="0.0.1" />
|
||||
<PackageVersion Include="xunit" Version="2.9.2" />
|
||||
<PackageVersion Include="xunit.abstractions" Version="2.0.3" />
|
||||
<PackageVersion Include="xunit.extensibility.core" Version="2.9.2" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||
<PackageVersion Include="Yarp.ReverseProxy" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
|
||||
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="7.0.20" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
||||
<PackageVersion Include="Npgsql" Version="7.0.8" />
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.18" />
|
||||
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="7.21.13" />
|
||||
<PackageVersion Include="Polly" Version="7.2.4" />
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
|
||||
<PackageVersion Include="Refit" Version="7.2.22" />
|
||||
<PackageVersion Include="Refit.HttpClientFactory" Version="7.0.0" />
|
||||
<PackageVersion Include="System.Formats.Asn1" Version="8.0.1" />
|
||||
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="8.0.10" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||
<PackageVersion Include="Npgsql" Version="8.0.5" />
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="8.23.60" />
|
||||
<PackageVersion Include="Polly" Version="8.4.2" />
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||
<PackageVersion Include="Refit" Version="8.0.0" />
|
||||
<PackageVersion Include="Refit.HttpClientFactory" Version="8.0.0" />
|
||||
<PackageVersion Include="System.Formats.Asn1" Version="8.0.1" />
|
||||
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.0" />
|
||||
<PackageVersion Include="Npgsql" Version="9.0.1" />
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.1" />
|
||||
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="9.23.60" />
|
||||
<PackageVersion Include="Polly" Version="8.5.0" />
|
||||
<!-- <PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" /> -->
|
||||
<PackageVersion Include="Refit" Version="8.0.0" />
|
||||
<PackageVersion Include="Refit.HttpClientFactory" Version="8.0.0" />
|
||||
<PackageVersion Include="System.Formats.Asn1" Version="9.0.0" />
|
||||
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Antlr4.Runtime.Standard" Version="4.13.1"/>
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations" Version="0.5.1"/>
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.MySql" Version="0.5.1"/>
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.PostgreSQL" Version="0.5.1"/>
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.SQLite" Version="0.5.1"/>
|
||||
<PackageVersion Include="AppAny.Quartz.EntityFrameworkCore.Migrations.SqlServer" Version="0.5.1"/>
|
||||
<PackageVersion Include="AutoMapper" Version="13.0.1" PrivateAssets="All"/>
|
||||
<PackageVersion Include="Azure.Identity" Version="1.13.2"/>
|
||||
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.18.3"/>
|
||||
<PackageVersion Include="Azure.ResourceManager" Version="1.13.0"/>
|
||||
<PackageVersion Include="Azure.ResourceManager.AppContainers" Version="1.3.0"/>
|
||||
<PackageVersion Include="Azure.ResourceManager.Resources" Version="1.9.0"/>
|
||||
<PackageVersion Include="Azure.ResourceManager.ServiceBus" Version="1.1.0"/>
|
||||
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0"/>
|
||||
<PackageVersion Include="Bogus" Version="35.6.1"/>
|
||||
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" PrivateAssets="All"/>
|
||||
<PackageVersion Include="Confluent.Kafka" Version="2.8.0"/>
|
||||
<PackageVersion Include="Confluent.SchemaRegistry.Serdes.Avro" Version="2.8.0"/>
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.4" PrivateAssets="All"/>
|
||||
<PackageVersion Include="Cronos" Version="0.9.0"/>
|
||||
<PackageVersion Include="Dapper" Version="2.1.35"/>
|
||||
<PackageVersion Include="DistributedLock.Core" Version="1.0.8"/>
|
||||
<PackageVersion Include="DistributedLock.FileSystem" Version="1.0.3"/>
|
||||
<PackageVersion Include="DistributedLock.Postgres" Version="1.2.1"/>
|
||||
<PackageVersion Include="DistributedLock.Redis" Version="1.0.3"/>
|
||||
<PackageVersion Include="Elastic.Clients.Elasticsearch" Version="8.17.1"/>
|
||||
<PackageVersion Include="Elsa.Studio" Version="3.3.1"/>
|
||||
<PackageVersion Include="Elsa.Studio.Agents" Version="3.3.1"/>
|
||||
<PackageVersion Include="Elsa.Studio.Core.BlazorWasm" Version="3.3.1"/>
|
||||
<PackageVersion Include="Elsa.Studio.Login.BlazorWasm" Version="3.3.1"/>
|
||||
<PackageVersion Include="FastEndpoints" Version="5.33.0"/>
|
||||
<PackageVersion Include="FastEndpoints.Security" Version="5.33.0"/>
|
||||
<PackageVersion Include="FastEndpoints.Swagger" Version="5.33.0"/>
|
||||
<PackageVersion Include="FluentMigrator" Version="6.2.0"/>
|
||||
<PackageVersion Include="FluentMigrator.Runner" Version="6.2.0"/>
|
||||
<PackageVersion Include="FluentStorage" Version="5.6.0"/>
|
||||
<PackageVersion Include="FluentStorage.Azure.Blobs" Version="5.3.0"/>
|
||||
<PackageVersion Include="Fluid.Core" Version="2.19.0"/>
|
||||
<PackageVersion Include="Fody" Version="6.9.1"/>
|
||||
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1"/>
|
||||
<PackageVersion Include="Google.Protobuf" Version="3.29.3"/>
|
||||
<PackageVersion Include="Grpc.Net.Client" Version="2.67.0"/>
|
||||
<PackageVersion Include="Grpc.Tools" Version="2.69.0"/>
|
||||
<PackageVersion Include="Hangfire" Version="1.8.17"/>
|
||||
<PackageVersion Include="Hangfire.MemoryStorage" Version="1.8.1.1"/>
|
||||
<PackageVersion Include="Hangfire.PostgreSql" Version="1.20.10"/>
|
||||
<PackageVersion Include="Hangfire.Storage.SQLite" Version="0.4.2"/>
|
||||
<PackageVersion Include="Humanizer.Core" Version="2.14.1"/>
|
||||
<PackageVersion Include="IronCompress" Version="1.6.3"/>
|
||||
<PackageVersion Include="JetBrains.Annotations" Version="2024.3.0"/>
|
||||
<PackageVersion Include="Jint" Version="4.1.0"/>
|
||||
<PackageVersion Include="LinqKit.Core" Version="1.2.8"/>
|
||||
<PackageVersion Include="MailKit" Version="4.9.0"/>
|
||||
<PackageVersion Include="MassTransit" Version="8.3.4"/>
|
||||
<PackageVersion Include="MassTransit.Azure.ServiceBus.Core" Version="8.3.4"/>
|
||||
<PackageVersion Include="MassTransit.RabbitMQ" Version="8.3.4"/>
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.12.0"/>
|
||||
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.2.2"/>
|
||||
<PackageVersion Include="Microsoft.Identity.Client" Version="4.67.2"/>
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
|
||||
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.34.0"/>
|
||||
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0"/>
|
||||
<PackageVersion Include="MongoDB.Driver" Version="3.1.0"/>
|
||||
<PackageVersion Include="MongoDB.Driver.Core.Extensions.DiagnosticSources" Version="2.0.0"/>
|
||||
<PackageVersion Include="MongoDB.Driver.Extensions" Version="2.0.2"/>
|
||||
<PackageVersion Include="MySql.Data" Version="9.1.0"/>
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3"/>
|
||||
<PackageVersion Include="NSubstitute" Version="5.3.0"/>
|
||||
<PackageVersion Include="NuGet.Packaging" Version="6.12.1"/>
|
||||
<PackageVersion Include="NuGet.Protocol" Version="6.12.1"/>
|
||||
<PackageVersion Include="Nuke.Components" Version="9.0.4"/>
|
||||
<PackageVersion Include="Open.Linq.AsyncExtensions" Version="1.2.0"/>
|
||||
<PackageVersion Include="Polly.Extensions.Http" Version="3.0.0"/>
|
||||
<PackageVersion Include="PolySharp" Version="1.15.0"/>
|
||||
<PackageVersion Include="Proto.Actor" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Cluster" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Cluster.AzureContainerApps" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Cluster.CodeGen" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Cluster.Kubernetes" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Cluster.TestProvider" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.OpenTelemetry" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Persistence" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Persistence.Sqlite" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Persistence.SqlServer" Version="1.7.0"/>
|
||||
<PackageVersion Include="Proto.Remote" Version="1.7.0"/>
|
||||
<PackageVersion Include="pythonnet" Version="3.1.0-preview2024-09-06"/>
|
||||
<PackageVersion Include="Quartz.Extensions.Hosting" Version="3.13.1"/>
|
||||
<PackageVersion Include="Quartz.Serialization.Json" Version="3.13.1"/>
|
||||
<PackageVersion Include="Scrutor" Version="6.0.1"/>
|
||||
<PackageVersion Include="ShortGuid" Version="2.0.1"/>
|
||||
<PackageVersion Include="StackExchange.Redis" Version="2.8.24"/>
|
||||
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1"/>
|
||||
<PackageVersion Include="System.Data.SqlClient" Version="4.9.0"/>
|
||||
<PackageVersion Include="System.Linq.Async" Version="6.0.1"/>
|
||||
<PackageVersion Include="System.Linq.Dynamic.Core" Version="1.6.0-preview-02"/>
|
||||
<PackageVersion Include="System.Net.Http" Version="4.3.4"/>
|
||||
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1"/>
|
||||
<PackageVersion Include="Testcontainers" Version="4.1.0"/>
|
||||
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.1.0"/>
|
||||
<PackageVersion Include="Testcontainers.RabbitMq" Version="4.1.0"/>
|
||||
<PackageVersion Include="Testcontainers.Redis" Version="4.1.0"/>
|
||||
<PackageVersion Include="ThrottleDebounce" Version="2.0.0"/>
|
||||
<PackageVersion Include="WebhooksCore" Version="0.0.1"/>
|
||||
<PackageVersion Include="xunit" Version="2.9.3"/>
|
||||
<PackageVersion Include="xunit.abstractions" Version="2.0.3"/>
|
||||
<PackageVersion Include="xunit.extensibility.core" Version="2.9.3"/>
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1"/>
|
||||
<PackageVersion Include="Yarp.ReverseProxy" Version="2.2.0"/>
|
||||
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="8.0.1"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="8.0.2"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="8.0.12"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0"/>
|
||||
<PackageVersion Include="Npgsql" Version="8.0.6"/>
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11"/>
|
||||
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="8.23.70"/>
|
||||
<PackageVersion Include="Polly" Version="8.5.1"/>
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2"/>
|
||||
<PackageVersion Include="Refit" Version="8.0.0"/>
|
||||
<PackageVersion Include="Refit.HttpClientFactory" Version="8.0.0"/>
|
||||
<PackageVersion Include="System.Formats.Asn1" Version="8.0.1"/>
|
||||
<PackageVersion Include="System.Text.Json" Version="8.0.5"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.1"/>
|
||||
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.1"/>
|
||||
<PackageVersion Include="Npgsql" Version="9.0.2"/>
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.3"/>
|
||||
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="9.23.60"/>
|
||||
<PackageVersion Include="Polly" Version="8.5.1"/>
|
||||
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.2.efcore.9.0.0"/>
|
||||
<PackageVersion Include="Refit" Version="8.0.0"/>
|
||||
<PackageVersion Include="Refit.HttpClientFactory" Version="8.0.0"/>
|
||||
<PackageVersion Include="System.Formats.Asn1" Version="9.0.1"/>
|
||||
<PackageVersion Include="System.Text.Json" Version="9.0.1"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
22
README.md
22
README.md
|
|
@ -10,7 +10,7 @@
|
|||
[]( http://stackoverflow.com/questions/tagged/elsa-workflows )
|
||||
[](https://gurubase.io/g/elsa)
|
||||
|
||||
### [For Elsa 2 Click Here](https://github.com/elsa-workflows/elsa-core/tree/2.x)
|
||||
### [For Elsa 2, Click Here](https://github.com/elsa-workflows/elsa-core/tree/2.x)
|
||||
|
||||
## Introduction
|
||||
Elsa is a powerful workflow library that enables workflow execution within any .NET application. Elsa allows you to define workflows in various ways, including:
|
||||
|
|
@ -55,16 +55,13 @@ By default, you can access http://localhost:13000 and log in with:
|
|||
|
||||
## Documentation
|
||||
|
||||
For comprehensive documentation and to get started with Elsa, please visit the [Elsa Documentation Website](https://v3.elsaworkflows.io/).
|
||||
[Elsa Documentation Website](https://docs.elsaworkflows.io/).
|
||||
|
||||
## Known Issues and Limitations
|
||||
|
||||
Elsa is continually evolving, and while it offers powerful capabilities, there are some known limitations and ongoing work:
|
||||
|
||||
- Documentation is still a work in progress.
|
||||
- The designer is not yet fully embeddable in other applications; this feature is planned for a future release.
|
||||
- C# and Python expressions are not yet fully tested.
|
||||
- Bulk Dispatch Workflows is a new activity and not yet fully tested.
|
||||
- Input/Output is not yet implemented in the Workflow Instance Viewer.
|
||||
- Starting workflows from the designer is currently supported only for workflows that do not require input and do not start with a trigger; this is planned for a future release.
|
||||
- The designer currently only supports Flowchart activities. Support for Sequence and StateMachine activities is planned for a future release.
|
||||
|
|
@ -90,15 +87,7 @@ Elsa offers a wide range of features for building and executing workflows, inclu
|
|||
|
||||
## Roadmap
|
||||
|
||||
The following features are planned for future releases of Elsa:
|
||||
|
||||
- [ ] Multi-tenancy
|
||||
- [ ] State Machine activity
|
||||
- [ ] Designer support for Sequence activity & StateMachine activity
|
||||
- [ ] BPMN 2.0 support
|
||||
- [ ] DMN support
|
||||
- [ ] Workflow migration to new versions via UI
|
||||
- [ ] Capsules ("hot" deployable workflow packages containing activities and configuration)
|
||||
See #3232
|
||||
|
||||
## Use Cases
|
||||
|
||||
|
|
@ -109,7 +98,7 @@ Elsa can be used in a variety of scenarios, including:
|
|||
- Scheduled workflows such as sending daily reports.
|
||||
- Event-driven workflows such as sending welcome emails when a user signs up.
|
||||
|
||||
## Programmatic Workflows
|
||||
## Coding Workflows
|
||||
|
||||
Elsa allows you to define workflows in code using C#. The following example shows how to receive HTTP requests and send an email in response:
|
||||
|
||||
|
|
@ -141,13 +130,12 @@ public class SendEmailWorkflow : WorkflowBase
|
|||
}
|
||||
```
|
||||
|
||||
## Designed Workflows
|
||||
## Designing Workflows
|
||||
|
||||
Elsa allows you to define workflows using a visual designer. The following example shows how to receive HTTP requests and send an email in response:
|
||||
|
||||

|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions from the community and are pleased that you are interested in helping to improve the Elsa Workflow project! Here are the steps to contribute to our project:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using Nuke.Common.CI.GitHubActions;
|
||||
using Nuke.Common.CI.GitHubActions.Configuration;
|
||||
using Nuke.Common.Execution;
|
||||
using Nuke.Common.Utilities;
|
||||
using Nuke.Components;
|
||||
|
||||
[GitHubActions(
|
||||
[CustomGitHubActions(
|
||||
"pr",
|
||||
GitHubActionsImage.UbuntuLatest,
|
||||
OnPullRequestBranches = ["main"],
|
||||
|
|
@ -12,4 +16,55 @@ using Nuke.Components;
|
|||
ConcurrencyCancelInProgress = true
|
||||
)
|
||||
]
|
||||
public partial class Build;
|
||||
public partial class Build;
|
||||
|
||||
class CustomGitHubActionsAttribute : GitHubActionsAttribute
|
||||
{
|
||||
public CustomGitHubActionsAttribute(string name, GitHubActionsImage image, params GitHubActionsImage[] images) : base(name, image, images)
|
||||
{
|
||||
}
|
||||
|
||||
protected override GitHubActionsJob GetJobs(GitHubActionsImage image, IReadOnlyCollection<ExecutableTarget> relevantTargets)
|
||||
{
|
||||
var job = base.GetJobs(image, relevantTargets);
|
||||
|
||||
var newSteps = new List<GitHubActionsStep>(job.Steps);
|
||||
|
||||
// only need to list the ones that are missing from default image
|
||||
newSteps.Insert(0, new GitHubActionsSetupDotNetStep(["9.x"]));
|
||||
|
||||
job.Steps = newSteps.ToArray();
|
||||
return job;
|
||||
}
|
||||
}
|
||||
|
||||
class GitHubActionsSetupDotNetStep : GitHubActionsStep
|
||||
{
|
||||
public GitHubActionsSetupDotNetStep(string[] versions)
|
||||
{
|
||||
Versions = versions;
|
||||
}
|
||||
|
||||
string[] Versions { get; }
|
||||
|
||||
public override void Write(CustomFileWriter writer)
|
||||
{
|
||||
writer.WriteLine("- uses: actions/setup-dotnet@v4");
|
||||
|
||||
using (writer.Indent())
|
||||
{
|
||||
writer.WriteLine("with:");
|
||||
using (writer.Indent())
|
||||
{
|
||||
writer.WriteLine("dotnet-version: |");
|
||||
using (writer.Indent())
|
||||
{
|
||||
foreach (var version in Versions)
|
||||
{
|
||||
writer.WriteLine(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Nuke.Components" Version="9.0.3" />
|
||||
<PackageReference Include="Nuke.Components" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--Overridden for vulnerability reasons with dependencies referencing older versions.-->
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
- "5432:5432"
|
||||
|
||||
mysql:
|
||||
image: mysql:9.1.0
|
||||
image: mysql:8.0
|
||||
container_name: mysql
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
|
|
@ -23,7 +23,19 @@
|
|||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- mysql_data2:/var/lib/mysql
|
||||
|
||||
oracle:
|
||||
image: container-registry.oracle.com/database/free:latest
|
||||
container_name: oracle-db
|
||||
environment:
|
||||
ORACLE_PWD: elsa
|
||||
ports:
|
||||
- "1521:1521"
|
||||
- "5500:5500"
|
||||
volumes:
|
||||
- ./data/oracle-data:/opt/oracle/oradata
|
||||
- ./setup/oracle-setup:/opt/oracle/scripts/setup
|
||||
|
||||
mongodb:
|
||||
image: mongo:latest
|
||||
|
|
@ -72,6 +84,17 @@
|
|||
environment:
|
||||
- PlantUml__RemoteUrl=
|
||||
- ConnectionStrings__DefaultConnection=USER ID=tracelens;PASSWORD=tracelenspass;HOST=postgres;PORT=5432;DATABASE=tracelens;POOLING=true;
|
||||
|
||||
smtp4dev: # Mock SMTP server
|
||||
image: rnwood/smtp4dev
|
||||
container_name: smtp4dev
|
||||
restart: always
|
||||
ports:
|
||||
- "3000:80" # Web interface
|
||||
- "2525:25" # SMTP port
|
||||
environment:
|
||||
- ASPNETCORE_URLS=http://+:80
|
||||
- Logging__LogLevel__Default=Information
|
||||
|
||||
elsa-server:
|
||||
build:
|
||||
|
|
@ -104,6 +127,7 @@
|
|||
|
||||
volumes:
|
||||
postgres-data:
|
||||
mysql_data:
|
||||
oracle-data-free1:
|
||||
mysql_data2:
|
||||
cockroachdb-data:
|
||||
mongodb_data:
|
||||
|
|
|
|||
3
docker/setup/oracle-setup/setup.sql
Executable file
3
docker/setup/oracle-setup/setup.sql
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
alter session set "_ORACLE_SCRIPT"=true;
|
||||
CREATE USER ELSA IDENTIFIED BY elsa;
|
||||
GRANT ALL PRIVILEGES TO ELSA;
|
||||
|
|
@ -16,6 +16,6 @@ for module in "${mods[@]}"; do
|
|||
echo "Updating migrations for $provider..."
|
||||
echo "Provider path: ${providerPath:?}/${migrationsPath}"
|
||||
echo "Migrations path: $migrationsPath"
|
||||
ef-migration-runtime-schema --interface Elsa.EntityFrameworkCore.Common.Contracts.IElsaDbContextSchema --efOptions "migrations add V3_1 -c ""$module""ElsaDbContext -p ""$providerPath"" -o ""$migrationsPath"""
|
||||
ef-migration-runtime-schema --interface Elsa.EntityFrameworkCore.IElsaDbContextSchema --efOptions "migrations add V3_1 -c ""$module""ElsaDbContext -p ""$providerPath"" -o ""$migrationsPath"""
|
||||
done
|
||||
done
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ for module in "${mods[@]}"; do
|
|||
echo "Updating migrations for $provider..."
|
||||
echo "Provider path: ${providerPath:?}/${migrationsPath}"
|
||||
echo "Migrations path: $migrationsPath"
|
||||
ef-migration-runtime-schema --interface Elsa.EntityFrameworkCore.Common.Contracts.IElsaDbContextSchema --efOptions "migrations add V3_2 -c ""$module""ElsaDbContext -p ""$providerPath"" -o ""$migrationsPath"""
|
||||
ef-migration-runtime-schema --interface Elsa.EntityFrameworkCore.IElsaDbContextSchema --efOptions "migrations add V3_2 -c ""$module""ElsaDbContext -p ""$providerPath"" -o ""$migrationsPath"""
|
||||
done
|
||||
done
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
|
||||
|
||||
<PropertyGroup Label="TargetFrameworks">
|
||||
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Files">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Agents.Activities\Elsa.Agents.Activities.csproj" />
|
||||
|
|
@ -9,58 +9,76 @@
|
|||
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.MassTransit\Elsa.Caching.Distributed.MassTransit.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.ProtoActor\Elsa.Caching.Distributed.ProtoActor.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.MySql\Elsa.EntityFrameworkCore.MySql.csproj" Condition=" '$(TargetFramework)' != 'net9.0' " />
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.PostgreSql\Elsa.EntityFrameworkCore.PostgreSql.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.Oracle\Elsa.EntityFrameworkCore.Oracle.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.PostgreSql\Elsa.EntityFrameworkCore.PostgreSql.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Kafka\Elsa.Kafka.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.OpenTelemetry\Elsa.OpenTelemetry.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.MySql\Elsa.Quartz.EntityFrameworkCore.MySql.csproj" Condition=" '$(TargetFramework)' != 'net9.0' " />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.PostgreSql\Elsa.Quartz.EntityFrameworkCore.PostgreSql.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Retention\Elsa.Retention.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Secrets.Api\Elsa.Secrets.Api.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Secrets.Persistence.EntityFrameworkCore.PostgreSql\Elsa.Secrets.Persistence.EntityFrameworkCore.PostgreSql.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite\Elsa.Secrets.Persistence.EntityFrameworkCore.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Secrets.Persistence.EntityFrameworkCore.SqlServer\Elsa.Secrets.Persistence.EntityFrameworkCore.SqlServer.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Secrets.Scripting\Elsa.Secrets.Scripting.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Sql.MySql\Elsa.Sql.MySql.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Sql.PostgreSql\Elsa.Sql.PostgreSql.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Sql.Sqlite\Elsa.Sql.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Sql.SqlServer\Elsa.Sql.SqlServer.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Sql\Elsa.Sql.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Tenants.AspNetCore\Elsa.Tenants.AspNetCore.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa\Elsa.csproj"/>
|
||||
<ProjectReference Include="..\..\common\Elsa.DropIns\Elsa.DropIns.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Alterations.MassTransit\Elsa.Alterations.MassTransit.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Alterations\Elsa.Alterations.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.CSharp\Elsa.CSharp.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.Sqlite\Elsa.EntityFrameworkCore.Sqlite.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.SqlServer\Elsa.EntityFrameworkCore.SqlServer.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.RabbitMq\Elsa.MassTransit.RabbitMq.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Python\Elsa.Python.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.Sqlite\Elsa.Quartz.EntityFrameworkCore.Sqlite.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.FileStorage\Elsa.FileStorage.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Dapper.Migrations\Elsa.Dapper.Migrations.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Dapper\Elsa.Dapper.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Elasticsearch\Elsa.Elasticsearch.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Email\Elsa.Email.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Environments\Elsa.Environments.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit\Elsa.MassTransit.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.MongoDb\Elsa.MongoDb.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa\Elsa.csproj" />
|
||||
<ProjectReference Include="..\..\common\Elsa.DropIns\Elsa.DropIns.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Alterations.MassTransit\Elsa.Alterations.MassTransit.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Alterations\Elsa.Alterations.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.CSharp\Elsa.CSharp.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.Sqlite\Elsa.EntityFrameworkCore.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.SqlServer\Elsa.EntityFrameworkCore.SqlServer.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.RabbitMq\Elsa.MassTransit.RabbitMq.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Python\Elsa.Python.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Quartz.EntityFrameworkCore.Sqlite\Elsa.Quartz.EntityFrameworkCore.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.FileStorage\Elsa.FileStorage.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Dapper.Migrations\Elsa.Dapper.Migrations.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Dapper\Elsa.Dapper.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Elasticsearch\Elsa.Elasticsearch.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Email\Elsa.Email.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Environments\Elsa.Environments.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit\Elsa.MassTransit.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.MongoDb\Elsa.MongoDb.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Workflows.Runtime.ProtoActor\Elsa.Workflows.Runtime.ProtoActor.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Identity\Elsa.Identity.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.WorkflowProviders.BlobStorage\Elsa.WorkflowProviders.BlobStorage.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Hangfire\Elsa.Hangfire.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Http\Elsa.Http.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Labels\Elsa.Labels.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Liquid\Elsa.Liquid.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Quartz\Elsa.Quartz.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.WorkflowContexts\Elsa.WorkflowContexts.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Identity\Elsa.Identity.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.WorkflowProviders.BlobStorage\Elsa.WorkflowProviders.BlobStorage.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Hangfire\Elsa.Hangfire.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Http\Elsa.Http.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Labels\Elsa.Labels.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Liquid\Elsa.Liquid.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Quartz\Elsa.Quartz.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.WorkflowContexts\Elsa.WorkflowContexts.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.Workflows.Api\Elsa.Workflows.Api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Identity"/>
|
||||
<PackageReference Include="Bogus"/>
|
||||
<PackageReference Include="DistributedLock.Postgres"/>
|
||||
<PackageReference Include="DistributedLock.Redis"/>
|
||||
<PackageReference Include="FluentStorage.Azure.Blobs"/>
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Bogus" />
|
||||
<PackageReference Include="DistributedLock.Postgres" />
|
||||
<PackageReference Include="DistributedLock.Redis" />
|
||||
<PackageReference Include="FluentStorage.Azure.Blobs" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Bogus" />
|
||||
<PackageReference Include="DistributedLock.Postgres" />
|
||||
<PackageReference Include="DistributedLock.Redis" />
|
||||
<PackageReference Include="FluentStorage.Azure.Blobs" />
|
||||
<PackageReference Include="Hangfire.PostgreSql" />
|
||||
<PackageReference Include="Proto.Cluster.Kubernetes" />
|
||||
<PackageReference Include="Grpc.Net.Client" />
|
||||
<PackageReference Include="Proto.Persistence.Sqlite"/>
|
||||
<PackageReference Include="Proto.Persistence.SqlServer"/>
|
||||
<PackageReference Include="Proto.Persistence.Sqlite" />
|
||||
<PackageReference Include="Proto.Persistence.SqlServer" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Data\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -6,5 +6,6 @@ public enum SqlDatabaseProvider
|
|||
Sqlite,
|
||||
MySql,
|
||||
PostgreSql,
|
||||
Oracle,
|
||||
CockroachDb
|
||||
}
|
||||
|
|
@ -2,12 +2,14 @@ using System.Text.Encodings.Web;
|
|||
using Elsa.Agents;
|
||||
using Elsa.Alterations.Extensions;
|
||||
using Elsa.Alterations.MassTransit.Extensions;
|
||||
using Elsa.Caching.Options;
|
||||
using Elsa.Common.DistributedHosting.DistributedLocks;
|
||||
using Elsa.Common.RecurringTasks;
|
||||
using Elsa.Common.Serialization;
|
||||
using Elsa.Dapper.Extensions;
|
||||
using Elsa.Dapper.Services;
|
||||
using Elsa.DropIns.Extensions;
|
||||
using Elsa.EntityFrameworkCore;
|
||||
using Elsa.EntityFrameworkCore.Extensions;
|
||||
using Elsa.EntityFrameworkCore.Modules.Alterations;
|
||||
using Elsa.EntityFrameworkCore.Modules.Identity;
|
||||
|
|
@ -27,6 +29,8 @@ using Elsa.MongoDb.Modules.Management;
|
|||
using Elsa.MongoDb.Modules.Runtime;
|
||||
using Elsa.MongoDb.Modules.Tenants;
|
||||
using Elsa.OpenTelemetry.Middleware;
|
||||
using Elsa.Retention.Extensions;
|
||||
using Elsa.Retention.Models;
|
||||
using Elsa.Secrets.Extensions;
|
||||
using Elsa.Secrets.Management.Tasks;
|
||||
using Elsa.Secrets.Persistence;
|
||||
|
|
@ -34,9 +38,16 @@ using Elsa.Server.Web;
|
|||
using Elsa.Server.Web.Extensions;
|
||||
using Elsa.Server.Web.Filters;
|
||||
using Elsa.Server.Web.Messages;
|
||||
using Elsa.Sql.Extensions;
|
||||
using Elsa.Sql.MySql;
|
||||
using Elsa.Sql.PostgreSql;
|
||||
using Elsa.Sql.Sqlite;
|
||||
using Elsa.Sql.SqlServer;
|
||||
using Elsa.Tenants.AspNetCore;
|
||||
using Elsa.Tenants.Extensions;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Api;
|
||||
using Elsa.Workflows.CommitStates.Strategies;
|
||||
using Elsa.Workflows.LogPersistence;
|
||||
using Elsa.Workflows.Management;
|
||||
using Elsa.Workflows.Management.Compression;
|
||||
|
|
@ -45,6 +56,12 @@ using Elsa.Workflows.Runtime.Distributed.Extensions;
|
|||
using Elsa.Workflows.Runtime.Options;
|
||||
using Elsa.Workflows.Runtime.Stores;
|
||||
using Elsa.Workflows.Runtime.Tasks;
|
||||
using Hangfire;
|
||||
using Hangfire.MemoryStorage;
|
||||
using Hangfire.PostgreSql;
|
||||
using Hangfire.PostgreSql.Factories;
|
||||
using Hangfire.SqlServer;
|
||||
using Hangfire.Storage.SQLite;
|
||||
using JetBrains.Annotations;
|
||||
using Medallion.Threading.FileSystem;
|
||||
using Medallion.Threading.Postgres;
|
||||
|
|
@ -75,10 +92,11 @@ const WorkflowRuntime workflowRuntime = WorkflowRuntime.Distributed;
|
|||
const DistributedCachingTransport distributedCachingTransport = DistributedCachingTransport.MassTransit;
|
||||
const MassTransitBroker massTransitBroker = MassTransitBroker.Memory;
|
||||
const bool useMultitenancy = false;
|
||||
const bool useTenantsFromConfiguration = false;
|
||||
const bool useTenantsFromConfiguration = true;
|
||||
const bool useAgents = false;
|
||||
const bool useSecrets = true;
|
||||
const bool useSecrets = false;
|
||||
const bool disableVariableWrappers = false;
|
||||
const bool disableVariableCopying = false;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var services = builder.Services;
|
||||
|
|
@ -88,6 +106,7 @@ var identityTokenSection = identitySection.GetSection("Tokens");
|
|||
var sqliteConnectionString = configuration.GetConnectionString("Sqlite")!;
|
||||
var sqlServerConnectionString = configuration.GetConnectionString("SqlServer")!;
|
||||
var postgresConnectionString = configuration.GetConnectionString("PostgreSql")!;
|
||||
var oracleConnectionString = configuration.GetConnectionString("Oracle")!;
|
||||
var mySqlConnectionString = configuration.GetConnectionString("MySql")!;
|
||||
var cockroachDbConnectionString = configuration.GetConnectionString("CockroachDb")!;
|
||||
var mongoDbConnectionString = configuration.GetConnectionString("MongoDb")!;
|
||||
|
|
@ -129,7 +148,36 @@ services
|
|||
});
|
||||
|
||||
if (useHangfire)
|
||||
elsa.UseHangfire();
|
||||
{
|
||||
JobStorage jobStorage;
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
|
||||
{
|
||||
jobStorage = new PostgreSqlStorage(new NpgsqlConnectionFactory(postgresConnectionString, new()
|
||||
{
|
||||
QueuePollInterval = TimeSpan.FromSeconds(1)
|
||||
}));
|
||||
}
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.Sqlite)
|
||||
{
|
||||
jobStorage = new SQLiteStorage(sqliteConnectionString, new()
|
||||
{
|
||||
QueuePollInterval = TimeSpan.FromSeconds(1)
|
||||
});
|
||||
}
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer)
|
||||
{
|
||||
jobStorage = new SqlServerStorage(sqlServerConnectionString, new()
|
||||
{
|
||||
QueuePollInterval = TimeSpan.FromSeconds(1)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
jobStorage = new MemoryStorage();
|
||||
}
|
||||
|
||||
elsa.UseHangfire(hangfire => hangfire.UseJobStorage(jobStorage));
|
||||
}
|
||||
|
||||
elsa
|
||||
.AddActivitiesFrom<Program>()
|
||||
|
|
@ -150,11 +198,13 @@ services
|
|||
else if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
|
||||
ef.UsePostgreSql(postgresConnectionString!);
|
||||
#if !NET9_0
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
|
||||
ef.UseMySql(mySqlConnectionString);
|
||||
#endif
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
|
||||
ef.UsePostgreSql(cockroachDbConnectionString!);
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
|
||||
ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
|
||||
else
|
||||
ef.UseSqlite(sp => sp.GetSqliteConnectionString());
|
||||
|
||||
|
|
@ -171,6 +221,11 @@ services
|
|||
{
|
||||
workflows.WithDefaultWorkflowExecutionPipeline(pipeline => pipeline.UseWorkflowExecutionTracing());
|
||||
workflows.WithDefaultActivityExecutionPipeline(pipeline => pipeline.UseActivityExecutionTracing());
|
||||
workflows.UseCommitStrategies(strategies =>
|
||||
{
|
||||
strategies.AddStandardStrategies();
|
||||
strategies.Add("Every 10 seconds", new PeriodicWorkflowStrategy(TimeSpan.FromSeconds(10)));
|
||||
});
|
||||
})
|
||||
.UseWorkflowManagement(management =>
|
||||
{
|
||||
|
|
@ -191,6 +246,8 @@ services
|
|||
#endif
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
|
||||
ef.UsePostgreSql(cockroachDbConnectionString!);
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
|
||||
ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
|
||||
else
|
||||
ef.UseSqlite(sp => sp.GetSqliteConnectionString());
|
||||
|
||||
|
|
@ -236,7 +293,9 @@ services
|
|||
ef.UseMySql(mySqlConnectionString);
|
||||
#endif
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
|
||||
ef.UsePostgreSql(cockroachDbConnectionString!);
|
||||
ef.UsePostgreSql(cockroachDbConnectionString);
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
|
||||
ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
|
||||
else
|
||||
ef.UseSqlite(sp => sp.GetSqliteConnectionString());
|
||||
|
||||
|
|
@ -316,6 +375,7 @@ services
|
|||
{
|
||||
options.AllowClrAccess = true;
|
||||
options.DisableWrappers = disableVariableWrappers;
|
||||
options.DisableVariableCopying = disableVariableCopying;
|
||||
options.RegisterType<OrderReceived>();
|
||||
options.ConfigureEngine(engine =>
|
||||
{
|
||||
|
|
@ -330,6 +390,12 @@ services
|
|||
// Make sure to configure the path to the python DLL. E.g. /opt/homebrew/Cellar/python@3.11/3.11.6_1/Frameworks/Python.framework/Versions/3.11/bin/python3.11
|
||||
// alternatively, you can set the PYTHONNET_PYDLL environment variable.
|
||||
configuration.GetSection("Scripting:Python").Bind(options);
|
||||
|
||||
options.AddScript(sb =>
|
||||
{
|
||||
sb.AppendLine("def greet():");
|
||||
sb.AppendLine(" return \"Hello, welcome to Python!\"");
|
||||
});
|
||||
};
|
||||
})
|
||||
.UseLiquid(liquid => liquid.FluidOptions = options => options.Encoder = HtmlEncoder.Default)
|
||||
|
|
@ -340,6 +406,16 @@ services
|
|||
if (useCaching)
|
||||
http.UseCache();
|
||||
})
|
||||
.UseSql(options =>
|
||||
{
|
||||
options.Clients = client =>
|
||||
{
|
||||
client.Register<MySqlClient>("MySql");
|
||||
client.Register<PostgreSqlClient>("PostgreSql");
|
||||
client.Register<SqliteClient>("Sqlite");
|
||||
client.Register<SqlServerClient>("Sql Server");
|
||||
};
|
||||
})
|
||||
.UseEmail(email => email.ConfigureOptions = options => configuration.GetSection("Smtp").Bind(options))
|
||||
.UseAlterations(alterations =>
|
||||
{
|
||||
|
|
@ -364,7 +440,9 @@ services
|
|||
ef.UseMySql(mySqlConnectionString);
|
||||
#endif
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
|
||||
ef.UsePostgreSql(cockroachDbConnectionString!);
|
||||
ef.UsePostgreSql(cockroachDbConnectionString);
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
|
||||
ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
|
||||
else
|
||||
ef.UseSqlite(sp => sp.GetSqliteConnectionString());
|
||||
|
||||
|
|
@ -381,7 +459,13 @@ services
|
|||
|
||||
if (useQuartz)
|
||||
{
|
||||
elsa.UseQuartz(quartz => { quartz.UseSqlite(sqliteConnectionString); });
|
||||
elsa.UseQuartz(quartz =>
|
||||
{
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.Sqlite)
|
||||
quartz.UseSqlite(sqliteConnectionString);
|
||||
else if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
|
||||
quartz.UsePostgreSql(postgresConnectionString);
|
||||
});
|
||||
}
|
||||
|
||||
if (useSignalR)
|
||||
|
|
@ -514,6 +598,19 @@ services
|
|||
;
|
||||
}
|
||||
|
||||
elsa.UseRetention(r =>
|
||||
{
|
||||
r.SweepInterval = TimeSpan.FromHours(5);
|
||||
r.AddDeletePolicy("Delete all finished workflows", sp =>
|
||||
{
|
||||
var filter = new RetentionWorkflowInstanceFilter
|
||||
{
|
||||
WorkflowStatus = WorkflowStatus.Finished
|
||||
};
|
||||
return filter;
|
||||
});
|
||||
});
|
||||
|
||||
if (useMultitenancy)
|
||||
{
|
||||
elsa.UseTenants(tenants =>
|
||||
|
|
@ -548,8 +645,10 @@ services
|
|||
if (sqlDatabaseProvider == SqlDatabaseProvider.Sqlite) ef.UseSqlite(sqliteConnectionString);
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer) ef.UseSqlServer(sqlServerConnectionString);
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql) ef.UsePostgreSql(postgresConnectionString);
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) ef.UseOracle(oracleConnectionString, new ElsaDbContextOptions{ SchemaName = "ELSA"});
|
||||
#if !NET9_0
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.MySql) ef.UseMySql(mySqlConnectionString);
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
|
||||
ef.UseMySql(mySqlConnectionString);
|
||||
#endif
|
||||
if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb) ef.UsePostgreSql(cockroachDbConnectionString);
|
||||
});
|
||||
|
|
@ -560,7 +659,11 @@ services
|
|||
}
|
||||
});
|
||||
|
||||
elsa.UseTenantHttpRouting();
|
||||
elsa.UseTenantHttpRouting(tenantHttpRouting =>
|
||||
{
|
||||
// Override the tenant header name with a custom one.
|
||||
tenantHttpRouting.WithTenantHeader("X-Company-Id");
|
||||
});
|
||||
}
|
||||
|
||||
elsa.InstallDropIns(options => options.DropInRootDirectory = Path.Combine(Directory.GetCurrentDirectory(), "App_Data", "DropIns"));
|
||||
|
|
@ -582,7 +685,7 @@ services.Configure<RecurringTaskOptions>(options =>
|
|||
|
||||
services.Configure<BookmarkQueuePurgeOptions>(options => options.Ttl = TimeSpan.FromSeconds(10));
|
||||
|
||||
//services.Configure<CachingOptions>(options => options.CacheDuration = TimeSpan.FromDays(1));
|
||||
services.Configure<CachingOptions>(options => options.CacheDuration = TimeSpan.FromDays(1));
|
||||
services.AddHealthChecks();
|
||||
services.AddControllers();
|
||||
services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().WithExposedHeaders("*")));
|
||||
|
|
|
|||
25
src/apps/Elsa.Server.Web/SampleWorkflow.cs
Normal file
25
src/apps/Elsa.Server.Web/SampleWorkflow.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.CommitStates.Strategies;
|
||||
|
||||
namespace Elsa.Server.Web;
|
||||
|
||||
public class SampleWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
builder.WorkflowOptions.CommitStrategyName = "Every 10 seconds";
|
||||
builder.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Commit before executing").SetCommitStrategy(nameof(ExecutingActivityStrategy)),
|
||||
new WriteLine("Commit after executing").SetCommitStrategy(nameof(ExecutedActivityStrategy)),
|
||||
new WriteLine("Commit before & after executing").SetCommitStrategy(nameof(CommitAlwaysActivityStrategy)),
|
||||
new WriteLine("Commit only based on the workflow commit options").SetCommitStrategy(nameof(DefaultActivityStrategy)),
|
||||
new WriteLine("Never commit the workflow when this activity is about to execute or has executed").SetCommitStrategy(nameof(CommitNeverActivityStrategy)),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,7 @@
|
|||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning",
|
||||
"Elsa": "Warning",
|
||||
"MassTransit": "Warning",
|
||||
"Microsoft.Extensions.Http": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information",
|
||||
"Microsoft.EntityFrameworkCore": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"Quartz": "Warning",
|
||||
"System.Net.Http": "Warning"
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"HostBuilder": {
|
||||
|
|
@ -18,7 +11,9 @@
|
|||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"Sqlite": "Data Source=App_Data/elsa.sqlite.db;Cache=Shared;",
|
||||
"MySql": "Server=localhost;Database=elsa;Uid=admin;Pwd=password;",
|
||||
"PostgreSql": "Server=localhost;Username=elsa;Database=elsa;Port=5432;Password=elsa;SSLMode=Prefer;MaxPoolSize=2000;Timeout=60",
|
||||
"Oracle": "Data Source=(DESCRIPTION = (ADDRESS_LIST = (FAILOVER =ON) (LOAD_BALANCE = OFF) (ADDRESS = (PROTOCOL =TCP)(HOST=localhost)(PORT=1521))) (CONNECT_DATA = (SID= FREE) ));User Id=ELSA;Password=elsa;",
|
||||
"CockroachDb": "Host=localhost;Port=26257;Database=elsa;SslMode=Disable;Username=root;IncludeErrorDetail=true",
|
||||
"MongoDb": "mongodb://localhost:27017/elsa-workflows",
|
||||
"AzureServiceBus": "",
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@inject IConfiguration Configuration;
|
||||
@{
|
||||
var baseUrl = Configuration["Hosting:BaseUrl"]!;
|
||||
var apiUrl = baseUrl + Url.Content("~/elsa/api");
|
||||
var basePath = Configuration["Hosting:BasePath"]!;
|
||||
var baseUrl = Configuration["Hosting:BaseUrl"] ?? Configuration["Http:BaseUrl"]!; // HttpBaseUrl is for backward compatibility.
|
||||
var apiUrl = $"{baseUrl.TrimEnd('/')}/{(Configuration["Hosting:ApiPrefix"] ?? "elsa/api").TrimStart('/')}";
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
|
@ -15,20 +14,20 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
|
||||
<title>Elsa Studio 3.0</title>
|
||||
<base href="/"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="@basePath/_content/Elsa.Studio.Shell/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="@basePath/_content/Elsa.Studio.Shell/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="@basePath/_content/Elsa.Studio.Shell/favicon-16x16.png">
|
||||
<link rel="manifest" href="@basePath/_content/Elsa.Studio.Shell/site.webmanifest">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="@baseUrl/_content/Elsa.Studio.Shell/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="@baseUrl/_content/Elsa.Studio.Shell/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="@baseUrl/_content/Elsa.Studio.Shell/favicon-16x16.png">
|
||||
<link rel="manifest" href="@baseUrl/_content/Elsa.Studio.Shell/site.webmanifest">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Grandstander:wght@100&display=swap" rel="stylesheet">
|
||||
<link href="@basePath/_content/MudBlazor/MudBlazor.min.css" rel="stylesheet"/>
|
||||
<link href="@basePath/_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.css" rel="stylesheet"/>
|
||||
<link href="@basePath/_content/Radzen.Blazor/css/material-base.css" rel="stylesheet">
|
||||
<link href="@basePath/_content/Elsa.Studio.Shell/css/shell.css" rel="stylesheet">
|
||||
<link href="@baseUrl/_content/MudBlazor/MudBlazor.min.css" rel="stylesheet"/>
|
||||
<link href="@baseUrl/_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.css" rel="stylesheet"/>
|
||||
<link href="@baseUrl/_content/Radzen.Blazor/css/material-base.css" rel="stylesheet">
|
||||
<link href="@baseUrl/_content/Elsa.Studio.Shell/css/shell.css" rel="stylesheet">
|
||||
<link href="ElsaStudioWebAssembly.styles.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
|
|
@ -44,19 +43,18 @@
|
|||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
<script src="@basePath/_content/BlazorMonaco/jsInterop.js"></script>
|
||||
<script src="@basePath/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
|
||||
<script src="@basePath/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
|
||||
<script src="@basePath/_content/MudBlazor/MudBlazor.min.js"></script>
|
||||
<script src="@basePath/_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.js"></script>
|
||||
<script src="@basePath/_content/Radzen.Blazor/Radzen.Blazor.js"></script>
|
||||
<script src="@baseUrl/_content/BlazorMonaco/jsInterop.js"></script>
|
||||
<script src="@baseUrl/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
|
||||
<script src="@baseUrl/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
|
||||
<script src="@baseUrl/_content/MudBlazor/MudBlazor.min.js"></script>
|
||||
<script src="@baseUrl/_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.js"></script>
|
||||
<script src="@baseUrl/_content/Radzen.Blazor/Radzen.Blazor.js"></script>
|
||||
<script>
|
||||
window.getClientConfig = function() { return {
|
||||
"apiUrl": "@apiUrl",
|
||||
"basePath": "@basePath"
|
||||
"apiUrl": "@apiUrl"
|
||||
} };
|
||||
</script>
|
||||
<script src="@basePath/_framework/blazor.webassembly.js"></script>
|
||||
<script src="@baseUrl/_framework/blazor.webassembly.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -131,7 +131,11 @@ services
|
|||
if (useCaching)
|
||||
http.UseCache();
|
||||
|
||||
http.ConfigureHttpOptions = options => configuration.GetSection("Http").Bind(options);
|
||||
http.ConfigureHttpOptions = options =>
|
||||
{
|
||||
options.BaseUrl = new Uri(configuration["Hosting:BaseUrl"] ?? configuration["Http:BaseUrl"]!); // HttpBaseUrl is for backward compatibility.
|
||||
options.BasePath = configuration["Http:BasePath"];
|
||||
};
|
||||
})
|
||||
.UseEmail(email => email.ConfigureOptions = options => configuration.GetSection("Smtp").Bind(options))
|
||||
.UseWebhooks(webhooks => webhooks.ConfigureSinks = options => builder.Configuration.GetSection("Webhooks:Sinks").Bind(options))
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@
|
|||
"SqlServer": "Server=localhost;Database=elsa;User Id=sa;Password=Password12!",
|
||||
"PostgreSql": "Server=localhost;Username=elsa;Database=elsa;Port=5432;Password=elsa;SSLMode=Prefer;MaxPoolSize=2000;Timeout=60"
|
||||
},
|
||||
"DatabaseProvider": "PostgreSql",
|
||||
"DatabaseProvider": "Sqlite",
|
||||
"Hosting": {
|
||||
"BaseUrl": "https://localhost:8080",
|
||||
"BasePath": ""
|
||||
"ApiPrefix": "/elsa/api"
|
||||
},
|
||||
"Identity": {
|
||||
"Tokens": {
|
||||
|
|
@ -81,7 +81,6 @@
|
|||
"DefaultSender": "noreply@crmservices.com"
|
||||
},
|
||||
"Http": {
|
||||
"BaseUrl": "https://localhost:5001",
|
||||
"BasePath": "/api/workflows"
|
||||
},
|
||||
"Webhooks": {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
|
||||
using Elsa.Api.Client.Shared.Models;
|
||||
|
||||
namespace Elsa.Api.Client.Extensions;
|
||||
|
|
@ -182,4 +183,14 @@ public static class ActivityExtensions
|
|||
/// Sets a value indicating whether the specified activity can trigger the workflow.
|
||||
/// </summary>
|
||||
public static void SetRunAsynchronously(this JsonObject activity, bool value) => activity.SetProperty(JsonValue.Create(value), "customProperties", "runAsynchronously");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the commit state behavior for the specified activity.
|
||||
/// </summary>
|
||||
public static string? GetCommitStrategy(this JsonObject activity) => activity.TryGetProperty<string?>("customProperties", "commitStrategyName");
|
||||
|
||||
/// <summary>
|
||||
/// Sets the commit state behavior for the specified activity.
|
||||
/// </summary>
|
||||
public static void SetCommitStrategy(this JsonObject activity, string? name) => activity.SetProperty(JsonValue.Create(name), "customProperties", "commitStrategyName");
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ using Elsa.Api.Client.Options;
|
|||
using Elsa.Api.Client.Resources.ActivityDescriptorOptions.Contracts;
|
||||
using Elsa.Api.Client.Resources.ActivityDescriptors.Contracts;
|
||||
using Elsa.Api.Client.Resources.ActivityExecutions.Contracts;
|
||||
using Elsa.Api.Client.Resources.CommitStrategies.Contracts;
|
||||
using Elsa.Api.Client.Resources.Features.Contracts;
|
||||
using Elsa.Api.Client.Resources.Identity.Contracts;
|
||||
using Elsa.Api.Client.Resources.IncidentStrategies.Contracts;
|
||||
|
|
@ -73,6 +74,7 @@ public static class DependencyInjectionExtensions
|
|||
services.AddApi<IWorkflowActivationStrategiesApi>(builderOptions);
|
||||
services.AddApi<IIncidentStrategiesApi>(builderOptions);
|
||||
services.AddApi<ILogPersistenceStrategiesApi>(builderOptions);
|
||||
services.AddApi<ICommitStrategiesApi>(builderOptions);
|
||||
services.AddApi<ILoginApi>(builderOptions);
|
||||
services.AddApi<IFeaturesApi>(builderOptions);
|
||||
services.AddApi<IJavaScriptApi>(builderOptions);
|
||||
|
|
|
|||
|
|
@ -15,52 +15,43 @@ public static class JsonObjectExtensions
|
|||
{
|
||||
return obj.ContainsKey("type") && obj.ContainsKey("id") && obj.ContainsKey("version");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the specified value to a <see cref="JsonObject"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to serialize.</param>
|
||||
/// <param name="options">The <see cref="JsonSerializerOptions"/> to use.</param>
|
||||
/// <returns>A <see cref="JsonObject"/> representing the specified value.</returns>
|
||||
public static JsonNode SerializeToNode(this object value, JsonSerializerOptions? options = default)
|
||||
public static JsonNode SerializeToNode(this object value, JsonSerializerOptions? options = null)
|
||||
{
|
||||
options ??= new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
options ??= new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
|
||||
|
||||
return JsonSerializer.SerializeToNode(value, options)!;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the specified value to a <see cref="JsonArray"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to serialize.</param>
|
||||
/// <param name="options">The <see cref="JsonSerializerOptions"/> to use.</param>
|
||||
/// <returns>A <see cref="JsonObject"/> representing the specified value.</returns>
|
||||
public static JsonArray SerializeToArray(this object value, JsonSerializerOptions? options = default)
|
||||
public static JsonArray SerializeToArray(this object value, JsonSerializerOptions? options = null)
|
||||
{
|
||||
options ??= new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
options ??= new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
|
||||
|
||||
return JsonSerializer.SerializeToNode(value, options)!.AsArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the specified value to a <see cref="JsonArray"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to serialize.</param>
|
||||
/// <param name="options">The <see cref="JsonSerializerOptions"/> to use.</param>
|
||||
/// <returns>A <see cref="JsonObject"/> representing the specified value.</returns>
|
||||
public static JsonArray SerializeToArray<T>(this IEnumerable<T> value, JsonSerializerOptions? options = default)
|
||||
public static JsonArray SerializeToArray<T>(this IEnumerable<T> value, JsonSerializerOptions? options = null)
|
||||
{
|
||||
options ??= new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
options ??= new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
|
||||
|
||||
return JsonSerializer.SerializeToNode(value, options)!.AsArray();
|
||||
}
|
||||
|
||||
|
|
@ -71,19 +62,23 @@ public static class JsonObjectExtensions
|
|||
/// <param name="options">The <see cref="JsonSerializerOptions"/> to use.</param>
|
||||
/// <typeparam name="T">The type to deserialize to.</typeparam>
|
||||
/// <returns>The deserialized value.</returns>
|
||||
public static T Deserialize<T>(this JsonNode value, JsonSerializerOptions? options = default)
|
||||
public static T Deserialize<T>(this JsonNode value, JsonSerializerOptions? options = null)
|
||||
{
|
||||
options ??= new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
options ??= new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
|
||||
|
||||
if (value is JsonObject jsonObject)
|
||||
return JsonSerializer.Deserialize<T>(jsonObject, options)!;
|
||||
|
||||
if (value is JsonArray jsonArray)
|
||||
return JsonSerializer.Deserialize<T>(jsonArray, options)!;
|
||||
|
||||
if (typeof(T).IsEnum || (Nullable.GetUnderlyingType(typeof(T))?.IsEnum ?? false))
|
||||
{
|
||||
if (value.GetValueKind() == JsonValueKind.Null)
|
||||
return default!;
|
||||
return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T), value.ToString());
|
||||
}
|
||||
|
||||
if (value is JsonValue jsonValue)
|
||||
return jsonValue.GetValue<T>();
|
||||
|
||||
|
|
@ -101,7 +96,7 @@ public static class JsonObjectExtensions
|
|||
model = GetPropertyContainer(model, path);
|
||||
model[path.Last()] = value?.SerializeToNode();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the property value of the specified model.
|
||||
/// </summary>
|
||||
|
|
@ -113,7 +108,7 @@ public static class JsonObjectExtensions
|
|||
model = GetPropertyContainer(model, path);
|
||||
model[path.Last()] = value?.SerializeToNode();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the property value of the specified model.
|
||||
/// </summary>
|
||||
|
|
@ -125,7 +120,7 @@ public static class JsonObjectExtensions
|
|||
model = GetPropertyContainer(model, path);
|
||||
model[path.Last()] = new JsonArray(value.Select(x => x.SerializeToNode()).ToArray());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property value of the specified model.
|
||||
/// </summary>
|
||||
|
|
@ -139,7 +134,7 @@ public static class JsonObjectExtensions
|
|||
foreach (var prop in path.SkipLast(1))
|
||||
{
|
||||
if (currentModel[prop] is not JsonObject value)
|
||||
return default;
|
||||
return null;
|
||||
|
||||
currentModel = value;
|
||||
}
|
||||
|
|
@ -147,6 +142,25 @@ public static class JsonObjectExtensions
|
|||
return currentModel[path.Last()];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property value of the specified model.
|
||||
/// </summary>
|
||||
/// <param name="model">The model to get the property value from.</param>
|
||||
/// <param name="path">The path to the property.</param>
|
||||
/// <typeparam name="T">The type to deserialize to.</typeparam>
|
||||
/// <returns>The property value.</returns>
|
||||
public static T? TryGetProperty<T>(this JsonObject model, params string[] path)
|
||||
{
|
||||
try
|
||||
{
|
||||
return model.GetProperty<T>(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property value of the specified model.
|
||||
/// </summary>
|
||||
|
|
@ -173,7 +187,7 @@ public static class JsonObjectExtensions
|
|||
var property = GetProperty(model, path);
|
||||
return property != null ? property.Deserialize<T>(options) : default;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the property container of the specified model.
|
||||
/// </summary>
|
||||
|
|
@ -190,5 +204,4 @@ public static class JsonObjectExtensions
|
|||
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Marker interface for all alteration classes
|
||||
/// </summary>
|
||||
public interface IAlteration;
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Models;
|
||||
using Elsa.Api.Client.Resources.Alterations.Requests;
|
||||
using Elsa.Api.Client.Resources.Alterations.Responses;
|
||||
using Refit;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a client for the alterations API. Requires the Elsa.Alterations feature.
|
||||
/// </summary>
|
||||
public interface IAlterationsApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns an alteration plan and its associated jobs.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the alteration plan to return.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
[Get("/alterations/{id}")]
|
||||
Task<GetAlterationPlanResponse> GetAsync(string id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Determines which workflow instances a "Submit" request would target without actually running an alteration
|
||||
/// </summary>
|
||||
/// <param name="request">The requested workflow filter to dry run</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
[Post("/alterations/dry-run")]
|
||||
Task<DryRunResponse> DryRun(AlterationWorkflowInstanceFilter request, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Submits an alteration plan and a filter for workflows instances to be executed against
|
||||
/// </summary>
|
||||
/// <param name="request">The alterations and filter to submit</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
[Post("/alterations/submit")]
|
||||
Task<SubmitResponse> Submit(AlterationPlanParams request, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Runs an alteration plan and a list of workflow Instance Ids to be executed against
|
||||
/// </summary>
|
||||
/// <param name="request">The alterations and workflowInstanceIds to execute</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
[Post("/alterations/run")]
|
||||
Task<RunResponse> Run(RunRequest request, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Retries the specified workflow instances.
|
||||
/// </summary>
|
||||
/// <param name="request">The request containing the selection of workflow instances to retry.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
[Post("/alterations/workflows/retry")]
|
||||
Task<BulkRetryResponse> BulkRetryAsync(BulkRetryRequest request, CancellationToken cancellationToken);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the status of an activity.
|
||||
/// </summary>
|
||||
public enum ActivityStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The activity is in the Pending state.
|
||||
/// </summary>
|
||||
Pending,
|
||||
|
||||
/// <summary>
|
||||
/// The activity is in the Running state. Note that event if an activity is running, it may not be executing.
|
||||
/// </summary>
|
||||
Running,
|
||||
|
||||
/// <summary>
|
||||
/// The activity is in the Completed state.
|
||||
/// </summary>
|
||||
Completed,
|
||||
|
||||
/// <summary>
|
||||
/// The activity is in the Canceled state.
|
||||
/// </summary>
|
||||
Canceled,
|
||||
|
||||
/// <summary>
|
||||
/// The activity is in the Faulted state.
|
||||
/// </summary>
|
||||
Faulted
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// The status of an alteration plan for a workflow instance.
|
||||
/// </summary>
|
||||
public enum AlterationJobStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The plan is pending execution.
|
||||
/// </summary>
|
||||
Pending,
|
||||
|
||||
/// <summary>
|
||||
/// The plan is currently being executed.
|
||||
/// </summary>
|
||||
Running,
|
||||
|
||||
/// <summary>
|
||||
/// The plan has been completed.
|
||||
/// </summary>
|
||||
Completed,
|
||||
|
||||
/// <summary>
|
||||
/// The job has failed.
|
||||
/// </summary>
|
||||
Failed
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// The status of an alteration plan.
|
||||
/// </summary>
|
||||
public enum AlterationPlanStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The plan is pending execution.
|
||||
/// </summary>
|
||||
Pending,
|
||||
|
||||
/// <summary>
|
||||
/// The plan is currently generating jobs.
|
||||
/// </summary>
|
||||
Generating,
|
||||
|
||||
/// <summary>
|
||||
/// The plan is currently dispatching jobs.
|
||||
/// </summary>
|
||||
Dispatching,
|
||||
|
||||
/// <summary>
|
||||
/// The plan is currently being executed.
|
||||
/// </summary>
|
||||
Running,
|
||||
|
||||
/// <summary>
|
||||
/// The plan has been completed.
|
||||
/// </summary>
|
||||
Completed,
|
||||
|
||||
/// <summary>
|
||||
/// The plan has failed.
|
||||
/// </summary>
|
||||
Failed
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Enums;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A filter for activities within a workflow instance
|
||||
/// </summary>
|
||||
public class ActivityFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the activity.
|
||||
/// </summary>
|
||||
public string? ActivityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the activity instance.
|
||||
/// </summary>
|
||||
public string? ActivityInstanceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The node ID of the activity.
|
||||
/// </summary>
|
||||
public string? NodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the activity.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The status of the activity.
|
||||
/// </summary>
|
||||
public ActivityStatus? Status { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Contracts;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A base class for all IAlterations.
|
||||
/// </summary>
|
||||
public abstract class AlterationBase : IAlteration;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Enums;
|
||||
using Elsa.Api.Client.Shared.Models;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the execution of the plan for an individual workflow instance.
|
||||
/// </summary>
|
||||
public class AlterationJob : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the plan that this job belongs to.
|
||||
/// </summary>
|
||||
public string PlanId { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the workflow instance that this job applies to.
|
||||
/// </summary>
|
||||
public string WorkflowInstanceId { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The status of the job.
|
||||
/// </summary>
|
||||
public AlterationJobStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The serialized log of the job.
|
||||
/// </summary>
|
||||
public ICollection<AlterationLogEntry>? Log { get; set; } = new List<AlterationLogEntry>();
|
||||
|
||||
/// <summary>
|
||||
/// The date and time at which the job was created.
|
||||
/// </summary>
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time at which the job was started.
|
||||
/// </summary>
|
||||
public DateTimeOffset? StartedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time at which the job was completed.
|
||||
/// </summary>
|
||||
public DateTimeOffset? CompletedAt { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a log of alterations.
|
||||
/// </summary>
|
||||
public class AlterationLog
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The log entries.
|
||||
/// </summary>
|
||||
public ICollection<AlterationLogEntry> LogEntries { get; set; } = new List<AlterationLogEntry>();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// An individual log entry about an alteration
|
||||
/// </summary>
|
||||
/// <param name="Message"></param>
|
||||
/// <param name="LogLevel"></param>
|
||||
/// <param name="Timestamp"></param>
|
||||
/// <param name="EventName"></param>
|
||||
public record AlterationLogEntry(string Message, LogLevel LogLevel, DateTimeOffset Timestamp, string? EventName = null);
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Contracts;
|
||||
using Elsa.Api.Client.Resources.Alterations.Enums;
|
||||
using Elsa.Api.Client.Shared.Models;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A plan that contains a list of alterations to be applied to a set of workflow instances.
|
||||
/// </summary>
|
||||
public class AlterationPlan : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// The alterations to be applied.
|
||||
/// </summary>
|
||||
public ICollection<IAlteration> Alterations { get; set; } = new List<IAlteration>();
|
||||
|
||||
/// <summary>
|
||||
/// The IDs of the workflow instances that this plan applies to.
|
||||
/// </summary>
|
||||
public AlterationWorkflowInstanceFilter WorkflowInstanceFilter { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// The status of the plan.
|
||||
/// </summary>
|
||||
public AlterationPlanStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time at which the plan was created.
|
||||
/// </summary>
|
||||
public DateTimeOffset CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time at which the plan was started.
|
||||
/// </summary>
|
||||
public DateTimeOffset? StartedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time at which the plan was completed.
|
||||
/// </summary>
|
||||
public DateTimeOffset? CompletedAt { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Contracts;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the execution of an alteration plan against a set of workflow instances defined by the given filter
|
||||
/// </summary>
|
||||
public class AlterationPlanParams
|
||||
{
|
||||
/// <summary>
|
||||
/// The unique identifier for the alteration plan. If not specified, a new ID will be generated.
|
||||
/// </summary>
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The alterations to be applied.
|
||||
/// </summary>
|
||||
public ICollection<IAlteration> Alterations { get; set; } = new List<IAlteration>();
|
||||
|
||||
/// <summary>
|
||||
/// The IDs of the workflow instances that this plan applies to.
|
||||
/// </summary>
|
||||
public AlterationWorkflowInstanceFilter Filter { get; set; } = new();
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using Elsa.Api.Client.Shared.Models;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a filter for workflow instances.
|
||||
/// </summary>
|
||||
public class AlterationWorkflowInstanceFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// The IDs of the workflow instances that this plan applies to.
|
||||
/// </summary>
|
||||
public IEnumerable<string>? WorkflowInstanceIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The correlation IDs of the workflow instances that this plan applies to.
|
||||
/// </summary>
|
||||
public IEnumerable<string>? CorrelationIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A collection of timestamp filters used for filtering data based on specified timestamp columns and operators.
|
||||
/// </summary>
|
||||
public IEnumerable<TimestampFilter>? TimestampFilters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The IDs of the workflow definitions that this plan applies to.
|
||||
/// </summary>
|
||||
public IEnumerable<string>? DefinitionVersionIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the workflow instances to match have incidents.
|
||||
/// </summary>
|
||||
public bool? HasIncidents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the workflow instances to match are system workflows. Defaults to <c>false</c>.
|
||||
/// </summary>
|
||||
public bool? IsSystem { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of filters for activities.
|
||||
/// </summary>
|
||||
public IEnumerable<ActivityFilter>? ActivityFilters { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Cancels a workflow instance activity during an alteration
|
||||
/// </summary>
|
||||
public class CancelActivity : AlterationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the activity to be cancelled. If not specified, the activity instance ID will be used.
|
||||
/// </summary>
|
||||
public string? ActivityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the activity instance to be cancelled. If specified, overrides <see cref="ActivityId"/>.
|
||||
/// </summary>
|
||||
public string? ActivityInstanceId { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Migrates a workflow instance to a newer version in an alteration.
|
||||
/// </summary>
|
||||
public class Migrate : AlterationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The target version to upgrade to.
|
||||
/// </summary>
|
||||
public int TargetVersion { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Modifies a variable in a workflow instance alteration
|
||||
/// </summary>
|
||||
public class ModifyVariable : AlterationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the variable to modify.
|
||||
/// </summary>
|
||||
public string VariableId { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The new value of the variable.
|
||||
/// </summary>
|
||||
public object? Value { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// The result of running a series of alterations.
|
||||
/// </summary>
|
||||
public class RunAlterationsResult
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the workflow instance that was altered.
|
||||
/// </summary>
|
||||
public string WorkflowInstanceId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// A log of the alterations that were run.
|
||||
/// </summary>
|
||||
public AlterationLog Log { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// A flag indicating whether the workflow has scheduled work.
|
||||
/// </summary>
|
||||
public bool WorkflowHasScheduledWork { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A flag indicating whether the alterations have succeeded.
|
||||
/// </summary>
|
||||
public bool IsSuccessful { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Schedules an activity for execution in an alteration.
|
||||
/// </summary>
|
||||
public class ScheduleActivity : AlterationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the next activity to be scheduled. If not specified, the ActivityInstanceId will be used.
|
||||
/// </summary>
|
||||
public string? ActivityId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the activity instance to be scheduled. If not specified, the ActivityId will be used.
|
||||
/// </summary>
|
||||
public string? ActivityInstanceId { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to bulk retry workflow instances.
|
||||
/// </summary>
|
||||
public class BulkRetryRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// The IDs of the workflow instances that have incidents to be retried.
|
||||
/// </summary>
|
||||
public ICollection<string> WorkflowInstanceIds { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// An optional list of explicitly specified activity IDs to retry. If omitted, all faulted activities will be retried.
|
||||
/// </summary>
|
||||
public ICollection<string>? ActivityIds { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a response to bulk retry workflow instances.
|
||||
/// </summary>
|
||||
public class BulkRetryResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The alterations that resulted from the bulk retry request
|
||||
/// </summary>
|
||||
public ICollection<RunAlterationsResult> Results { get;set; } = new List<RunAlterationsResult>();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The response to the DryRun request
|
||||
/// </summary>
|
||||
public class DryRunResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The list of workflow instance IDs that would be affected by a "Submit" request
|
||||
/// </summary>
|
||||
public ICollection<string> WorkflowInstanceIds { get; set; } = new List<string>();
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The response from the "Get" alteration plan endpoint
|
||||
/// </summary>
|
||||
public class GetAlterationPlanResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The alteration plan mathching the provided ID
|
||||
/// </summary>
|
||||
public AlterationPlan Plan { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// The list of jobs that exist for that AlterationPlan
|
||||
/// </summary>
|
||||
public ICollection<AlterationJob> Jobs { get; set; } = new List<AlterationJob>();
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Contracts;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// A plan that contains a list of alterations to be applied to a set of workflow instances.
|
||||
/// </summary>
|
||||
public class RunRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// The alterations to be applied.
|
||||
/// </summary>
|
||||
public ICollection<IAlteration> Alterations { get; set; } = new List<IAlteration>();
|
||||
|
||||
/// <summary>
|
||||
/// The IDs of the workflow instances that this plan applies to.
|
||||
/// </summary>
|
||||
public ICollection<string> WorkflowInstanceIds { get; set; } = new List<string>();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using Elsa.Api.Client.Resources.Alterations.Models;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.Alterations.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The response to the Run endpoint
|
||||
/// </summary>
|
||||
public class RunResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The alteration results of a Run request
|
||||
/// </summary>
|
||||
private ICollection<RunAlterationsResult> Results { get; set; } = new List<RunAlterationsResult>();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
namespace Elsa.Api.Client.Resources.Alterations.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The response to the "Submit" endpoint
|
||||
/// </summary>
|
||||
public class SubmitResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the alteration plan created as part of the Submit request
|
||||
/// </summary>
|
||||
public string PlanId { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using Elsa.Api.Client.Resources.CommitStrategies.Models;
|
||||
using Elsa.Api.Client.Shared.Models;
|
||||
using Refit;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.CommitStrategies.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a client for the commit strategies API.
|
||||
/// </summary>
|
||||
public interface ICommitStrategiesApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Lists workflow commit strategies.
|
||||
/// </summary>
|
||||
/// <returns>A list response containing activity commit strategy descriptors and their count.</returns>
|
||||
[Get("/descriptors/commit-strategies/workflows")]
|
||||
Task<ListResponse<CommitStrategyDescriptor>> ListWorkflowStrategiesAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Lists activity commit strategies.
|
||||
/// </summary>
|
||||
/// <returns>A list response containing activity commit strategy descriptors and their count.</returns>
|
||||
[Get("/descriptors/commit-strategies/activities")]
|
||||
Task<ListResponse<CommitStrategyDescriptor>> ListActivityStrategiesAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace Elsa.Api.Client.Resources.CommitStrategies.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a descriptor for a commit strategy, containing information such as its technical name,
|
||||
/// display name, and description.
|
||||
/// </summary>
|
||||
public record CommitStrategyDescriptor(string Name, string DisplayName, string Description);
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
namespace Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
|
||||
|
||||
public class WorkflowCommitStateOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Commit workflow state before the workflow starts.
|
||||
/// </summary>
|
||||
public bool Starting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Commit workflow state before an activity executes, unless the activity is configured to not commit state.
|
||||
/// </summary>
|
||||
public bool ActivityExecuting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Commit workflow state after an activity executes, unless the activity is configured to not commit state.
|
||||
/// </summary>
|
||||
public bool ActivityExecuted { get; set; }
|
||||
}
|
||||
|
|
@ -29,4 +29,9 @@ public class WorkflowOptions
|
|||
/// The type of <c>IIncidentStrategy</c> to use when a fault occurs in the workflow.
|
||||
/// </summary>
|
||||
public string? IncidentStrategyType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The options for committing workflow state.
|
||||
/// </summary>
|
||||
public string? CommitStrategyName { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Elsa.Api.Client.Resources.WorkflowInstances.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Holds information about an activity incident.
|
||||
/// </summary>
|
||||
public class ActivityIncident
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ActivityIncident"/> class.
|
||||
/// </summary>
|
||||
[JsonConstructor]
|
||||
public ActivityIncident()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ActivityIncident"/> class.
|
||||
/// </summary>
|
||||
/// <param name="activityId">The ID of the activity that caused the incident.</param>
|
||||
/// <param name="activityType">The type of the activity that caused the incident.</param>
|
||||
/// <param name="message">The message of the incident.</param>
|
||||
/// <param name="exception">The exception that caused the incident.</param>
|
||||
/// <param name="timestamp">The timestamp of the incident.</param>
|
||||
public ActivityIncident(string activityId, string activityType, string message, ExceptionState? exception, DateTimeOffset timestamp)
|
||||
{
|
||||
ActivityId = activityId;
|
||||
ActivityType = activityType;
|
||||
Message = message;
|
||||
Exception = exception;
|
||||
Timestamp = timestamp;
|
||||
}
|
||||
|
||||
/// <summary>The ID of the activity that caused the incident.</summary>
|
||||
public string ActivityId { get; init; } = default!;
|
||||
|
||||
/// <summary>The type of the activity that caused the incident.</summary>
|
||||
public string ActivityType { get; init; } = default!;
|
||||
|
||||
/// <summary>The message of the incident.</summary>
|
||||
public string Message { get; init; } = default!;
|
||||
|
||||
/// <summary>The exception that caused the incident.</summary>
|
||||
public ExceptionState? Exception { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The timestamp of the incident.
|
||||
/// </summary>
|
||||
public DateTimeOffset Timestamp { get; init; }
|
||||
}
|
||||
|
|
@ -38,6 +38,11 @@ public class WorkflowState : Entity
|
|||
/// </summary>
|
||||
public ICollection<Bookmark> Bookmarks { get; set; } = new List<Bookmark>();
|
||||
|
||||
/// <summary>
|
||||
/// A collection of incidents that may have occurred during execution.
|
||||
/// </summary>
|
||||
public ICollection<ActivityIncident> Incidents { get; set; } = new List<ActivityIncident>();
|
||||
|
||||
/// <summary>
|
||||
/// The serialized workflow state, if any.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@ public interface IRequestSender
|
|||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <typeparam name="T">The type of the response.</typeparam>
|
||||
/// <returns>The response.</returns>
|
||||
Task<IEnumerable<T>> SendAsync<T>(IRequest<T> request, CancellationToken cancellationToken = default);
|
||||
Task<T?> SendAsync<T>(IRequest<T> request, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
@ -6,24 +6,10 @@ namespace Elsa.Mediator.Middleware.Request.Components;
|
|||
/// <summary>
|
||||
/// A middleware component that invokes request handlers.
|
||||
/// </summary>
|
||||
public class RequestHandlerInvokerMiddleware : IRequestMiddleware
|
||||
public class RequestHandlerInvokerMiddleware(
|
||||
RequestMiddlewareDelegate next,
|
||||
IEnumerable<IRequestHandler> requestHandlers) : IRequestMiddleware
|
||||
{
|
||||
private readonly RequestMiddlewareDelegate _next;
|
||||
private readonly IEnumerable<IRequestHandler> _requestHandlers;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestHandlerInvokerMiddleware"/> class.
|
||||
/// </summary>
|
||||
/// <param name="next">The next middleware in the pipeline.</param>
|
||||
/// <param name="requestHandlers"></param>
|
||||
public RequestHandlerInvokerMiddleware(
|
||||
RequestMiddlewareDelegate next,
|
||||
IEnumerable<IRequestHandler> requestHandlers)
|
||||
{
|
||||
_next = next;
|
||||
_requestHandlers = requestHandlers;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask InvokeAsync(RequestContext context)
|
||||
{
|
||||
|
|
@ -33,22 +19,26 @@ public class RequestHandlerInvokerMiddleware : IRequestMiddleware
|
|||
var requestType = request.GetType();
|
||||
var responseType = context.ResponseType;
|
||||
var handlerType = typeof(IRequestHandler<,>).MakeGenericType(requestType, responseType);
|
||||
var handlers = _requestHandlers.Where(x => handlerType.IsInstanceOfType(x)).ToArray();
|
||||
var handlers = requestHandlers.Where(x => handlerType.IsInstanceOfType(x)).ToArray();
|
||||
|
||||
if (handlers.Length == 0)
|
||||
throw new InvalidOperationException($"There is no handler to handle the {requestType.FullName} request");
|
||||
|
||||
foreach (var handler in handlers)
|
||||
{
|
||||
var handleMethod = handlerType.GetMethod("HandleAsync")!;
|
||||
var cancellationToken = context.CancellationToken;
|
||||
var task = (Task)handleMethod.Invoke(handler, new object?[] { request, cancellationToken })!;
|
||||
await task;
|
||||
if (handlers.Length > 1)
|
||||
throw new InvalidOperationException($"Multiple handlers were found to handle the {requestType.FullName} request");
|
||||
|
||||
// Get result of task.
|
||||
var taskWithReturnType = typeof(Task<>).MakeGenericType(responseType);
|
||||
var resultProperty = taskWithReturnType.GetProperty(nameof(Task<object>.Result))!;
|
||||
context.Responses.Add(resultProperty.GetValue(task)!);
|
||||
}
|
||||
var handler = handlers.First();
|
||||
var handleMethod = handlerType.GetMethod("HandleAsync")!;
|
||||
var cancellationToken = context.CancellationToken;
|
||||
var task = (Task)handleMethod.Invoke(handler, [request, cancellationToken])!;
|
||||
await task;
|
||||
|
||||
// Get result of task.
|
||||
var taskWithReturnType = typeof(Task<>).MakeGenericType(responseType);
|
||||
var resultProperty = taskWithReturnType.GetProperty(nameof(Task<object>.Result))!;
|
||||
context.Response = resultProperty.GetValue(task)!;
|
||||
|
||||
// Invoke next middleware.
|
||||
await _next(context);
|
||||
await next(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ public class RequestContext
|
|||
public CancellationToken CancellationToken { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the responses from each request handler.
|
||||
/// Gets the response the request handler.
|
||||
/// </summary>
|
||||
public ICollection<object> Responses { get; set; } = new List<object>();
|
||||
public object? Response { get; set; }
|
||||
}
|
||||
|
|
@ -41,23 +41,20 @@ public class DefaultMediator : IMediator
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IEnumerable<T>> SendAsync<T>(IRequest<T> request, CancellationToken cancellationToken = default)
|
||||
public async Task<T?> SendAsync<T>(IRequest<T> request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var responseType = typeof(T);
|
||||
var context = new RequestContext(request, responseType, cancellationToken);
|
||||
await _requestPipeline.ExecuteAsync(context);
|
||||
|
||||
if (context.Responses.All(x => x is T))
|
||||
return context.Responses.Cast<T>().AsEnumerable();
|
||||
|
||||
throw new InvalidCastException($"Unable to cast objects in Responses property to type {typeof(T)}");
|
||||
return (T?)context.Response;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task SendAsync(ICommand command, CancellationToken cancellationToken = default) => await SendAsync(command, _defaultCommandStrategy, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task SendAsync(ICommand command, ICommandStrategy? strategy = default, CancellationToken cancellationToken = default)
|
||||
public async Task SendAsync(ICommand command, ICommandStrategy? strategy = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var resultType = typeof(Unit);
|
||||
strategy ??= _defaultCommandStrategy;
|
||||
|
|
@ -69,7 +66,7 @@ public class DefaultMediator : IMediator
|
|||
public async Task<T> SendAsync<T>(ICommand<T> command, CancellationToken cancellationToken = default) => await SendAsync(command, _defaultCommandStrategy, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<T> SendAsync<T>(ICommand<T> command, ICommandStrategy strategy, CancellationToken cancellationToken = default)
|
||||
public async Task<T> SendAsync<T>(ICommand<T> command, ICommandStrategy? strategy, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var resultType = typeof(T);
|
||||
strategy ??= _defaultCommandStrategy;
|
||||
|
|
@ -83,7 +80,7 @@ public class DefaultMediator : IMediator
|
|||
public async Task SendAsync(INotification notification, CancellationToken cancellationToken = default) => await SendAsync(notification, _defaultPublishingStrategy, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task SendAsync(INotification notification, IEventPublishingStrategy? strategy = default, CancellationToken cancellationToken = default)
|
||||
public async Task SendAsync(INotification notification, IEventPublishingStrategy? strategy = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
strategy ??= _defaultPublishingStrategy;
|
||||
var context = new NotificationContext(notification, strategy, cancellationToken);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public class SignalManager
|
|||
await Task.WhenAny(taskCompletionSource.Task, Task.Delay(millisecondsTimeout, cancellationTokenSource.Token));
|
||||
cancellationTokenSource.Token.ThrowIfCancellationRequested();
|
||||
_signals.TryRemove(signal, out _);
|
||||
return taskCompletionSource.Task.Result;
|
||||
return await taskCompletionSource.Task;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<Description>Provides an EF Core migrations for MySQL for the Agents Persistence module.</Description>
|
||||
<PackageTags>elsa module agents semantic kernel llm ai persistence efcore entity framework core mysql</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,5 @@ public class EFCoreAgentPersistenceFeature(IModule module) : PersistenceFeatureB
|
|||
AddEntityStore<ApiKeyDefinition, EFCoreApiKeyStore>();
|
||||
AddEntityStore<ServiceDefinition, EFCoreServiceStore>();
|
||||
AddEntityStore<AgentDefinition, EFCoreAgentStore>();
|
||||
Services.AddScoped<IEntityModelCreatingHandler, SetupForOracle>();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
using Elsa.Agents.Persistence.Entities;
|
||||
using Elsa.EntityFrameworkCore;
|
||||
using Elsa.EntityFrameworkCore.Extensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
namespace Elsa.Agents.Persistence.EntityFrameworkCore;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a class that handles entity model creation for SQLite databases.
|
||||
/// </summary>
|
||||
public class SetupForOracle : IEntityModelCreatingHandler
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Handle(ElsaDbContextBase dbContext, ModelBuilder modelBuilder, IMutableEntityType entityType)
|
||||
{
|
||||
if(!dbContext.Database.IsOracle())
|
||||
return;
|
||||
|
||||
// In order to use data more than 2000 char we have to use NCLOB.
|
||||
// In Oracle, we have to explicitly say the column is NCLOB otherwise it would be considered nvarchar(2000).
|
||||
modelBuilder.Entity<ServiceDefinition>().Property("SerializedSettings").HasColumnType("NCLOB");
|
||||
modelBuilder.Entity<AgentDefinition>().Property("SerializedAgentConfig").HasColumnType("NCLOB");
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ public class AlterationPlanParams
|
|||
public ICollection<IAlteration> Alterations { get; set; } = new List<IAlteration>();
|
||||
|
||||
/// <summary>
|
||||
/// The IDs of the workflow instances that this plan applies to.
|
||||
/// The filter used to determine which workflow instances that this plan applies to.
|
||||
/// </summary>
|
||||
public AlterationWorkflowInstanceFilter Filter { get; set; } = new();
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ using JetBrains.Annotations;
|
|||
namespace Elsa.Alterations.Endpoints.Alterations.DryRun;
|
||||
|
||||
/// <summary>
|
||||
/// Executes an alteration plan.
|
||||
/// Determines which workflow instances a "Submit" request would target without actually running an alteration.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public class DryRun(IWorkflowInstanceFinder workflowInstanceFinder) : ElsaEndpoint<AlterationWorkflowInstanceFilter, Response>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using JetBrains.Annotations;
|
|||
namespace Elsa.Alterations.Endpoints.Alterations.Get;
|
||||
|
||||
/// <summary>
|
||||
/// Executes an alteration plan.
|
||||
/// Gets an alteration plan and its associated jobs.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public class Get : ElsaEndpointWithoutRequest<Response>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using JetBrains.Annotations;
|
|||
namespace Elsa.Alterations.Endpoints.Alterations.Run;
|
||||
|
||||
/// <summary>
|
||||
/// Executes an alteration plan.
|
||||
/// Executes an alteration plan by targeting workflow instances by ID.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public class Run : ElsaEndpoint<Request, Response>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using JetBrains.Annotations;
|
|||
namespace Elsa.Alterations.Endpoints.Alterations.Submit;
|
||||
|
||||
/// <summary>
|
||||
/// Executes an alteration plan.
|
||||
/// Submits an alteration plan to be executed targeting workflow instances by a filter.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public class Submit : ElsaEndpoint<AlterationPlanParams, Response>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,8 @@ public class GenerateWorkflowInputAccessors(IOptions<CSharpOptions> options) : I
|
|||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
sb.AppendLine("var Inputs = new WorkflowInputsProxy(ExecutionContext);");
|
||||
sb.AppendLine("var Inputs = new WorkflowInputsProxy(ExecutionContext);"); // Obsolete; use Input instead.
|
||||
sb.AppendLine("var Input = Inputs;");
|
||||
notification.AppendScript(sb.ToString());
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ public class GenerateWorkflowVariableAccessors(IOptions<CSharpOptions> options)
|
|||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
sb.AppendLine("var Variables = new WorkflowVariablesProxy(ExecutionContext);");
|
||||
sb.AppendLine("var Variables = new WorkflowVariablesProxy(ExecutionContext);"); // Obsolete; use Variable instead.
|
||||
sb.AppendLine("var Variable = Variables;");
|
||||
notification.AppendScript(sb.ToString());
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ public partial class Globals
|
|||
ExpressionExecutionContext = expressionExecutionContext;
|
||||
Arguments = arguments;
|
||||
ExecutionContext = new ExecutionContextProxy(expressionExecutionContext);
|
||||
Input = new InputProxy(expressionExecutionContext);
|
||||
Output = new OutputProxy(expressionExecutionContext);
|
||||
Outcome = new OutcomeProxy(expressionExecutionContext);
|
||||
}
|
||||
|
|
@ -31,11 +30,6 @@ public partial class Globals
|
|||
/// </summary>
|
||||
public OutputProxy Output { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to workflow inputs.
|
||||
/// </summary>
|
||||
public InputProxy Input { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current execution context.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
|
||||
namespace Elsa.CSharp.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to workflow inputs.
|
||||
/// </summary>
|
||||
public class InputProxy
|
||||
{
|
||||
private readonly ExpressionExecutionContext _expressionExecutionContext;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InputProxy"/> class.
|
||||
/// </summary>
|
||||
public InputProxy(ExpressionExecutionContext expressionExecutionContext)
|
||||
{
|
||||
_expressionExecutionContext = expressionExecutionContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified input.
|
||||
/// </summary>
|
||||
public object? Get(string name) => _expressionExecutionContext.GetInput(name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified input.
|
||||
/// </summary>
|
||||
public T? Get<T>(string name) => _expressionExecutionContext.GetInput<T>(name);
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ public class OutputProxy
|
|||
/// <param name="activityIdOrName">The ID or name of the activity that produced the output.</param>
|
||||
/// <param name="outputName">The name of the output.</param>
|
||||
/// <returns>The value of the output.</returns>
|
||||
public object? From(string activityIdOrName, string? outputName = default) => _expressionExecutionContext.GetOutput(activityIdOrName, outputName);
|
||||
public object? From(string activityIdOrName, string? outputName = null) => _expressionExecutionContext.GetOutput(activityIdOrName, outputName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified output from the specified activity.
|
||||
|
|
@ -33,7 +33,7 @@ public class OutputProxy
|
|||
/// <param name="activityIdOrName">The ID or name of the activity that produced the output.</param>
|
||||
/// <param name="outputName">The name of the output.</param>
|
||||
/// <returns>The value of the output.</returns>
|
||||
public T? From<T>(string activityIdOrName, string? outputName = default) => Get(activityIdOrName, outputName).ConvertTo<T>();
|
||||
public T? From<T>(string activityIdOrName, string? outputName = null) => From(activityIdOrName, outputName).ConvertTo<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified output.
|
||||
|
|
@ -42,7 +42,7 @@ public class OutputProxy
|
|||
/// <param name="outputName">The name of the output.</param>
|
||||
/// <returns>The value of the output.</returns>
|
||||
[Obsolete("Use From instead.")]
|
||||
public object? Get(string activityIdOrName, string? outputName = default) => From(activityIdOrName, outputName);
|
||||
public object? Get(string activityIdOrName, string? outputName = null) => From(activityIdOrName, outputName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified output.
|
||||
|
|
@ -51,7 +51,7 @@ public class OutputProxy
|
|||
/// <param name="outputName">The name of the output.</param>
|
||||
/// <returns>The value of the output.</returns>
|
||||
[Obsolete("Use From instead.")]
|
||||
public T? Get<T>(string activityIdOrName, string? outputName = default) => From<T>(activityIdOrName, outputName);
|
||||
public T? Get<T>(string activityIdOrName, string? outputName = null) => From<T>(activityIdOrName, outputName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the result of the last activity that executed.
|
||||
|
|
|
|||
|
|
@ -21,8 +21,4 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
namespace Elsa.Extensions;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the service with a specific implementation type only if the combination
|
||||
/// of service and implementation does not already exist in the service collection.
|
||||
/// </summary>
|
||||
public static IServiceCollection TryAddScopedImplementation<TService, TImplementation>(
|
||||
this IServiceCollection services)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
{
|
||||
if (!services.Any(sd => sd.ServiceType == typeof(TService) && sd.ImplementationType == typeof(TImplementation)))
|
||||
services.AddScoped<TService, TImplementation>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the service with a specific implementation factory only if the combination
|
||||
/// of service and implementation already doesn't exist.
|
||||
/// </summary>
|
||||
public static IServiceCollection TryAddScopedImplementation<TService>(
|
||||
this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory)
|
||||
where TService : class
|
||||
{
|
||||
if (services.All(sd => sd.ServiceType != typeof(TService)))
|
||||
services.AddScoped(implementationFactory);
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ using Elsa.Common.Multitenancy;
|
|||
using Elsa.Common.Multitenancy.EventHandlers;
|
||||
using Elsa.Common.Multitenancy.HostedServices;
|
||||
using Elsa.Common.RecurringTasks;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Features.Abstractions;
|
||||
using Elsa.Features.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -41,6 +40,9 @@ public class MultitenancyFeature(IModule module) : FeatureBase(module)
|
|||
.AddSingleton<ITenantFinder, DefaultTenantFinder>()
|
||||
.AddSingleton<ITenantService, DefaultTenantService>()
|
||||
|
||||
// Order is important: Startup task first, then background and recurring tasks.
|
||||
.AddSingleton<ITenantActivatedEvent, RunStartupTasks>()
|
||||
|
||||
.AddSingleton<RunBackgroundTasks>()
|
||||
.AddSingleton<ITenantActivatedEvent>(sp => sp.GetRequiredService<RunBackgroundTasks>())
|
||||
.AddSingleton<ITenantDeactivatedEvent>(sp => sp.GetRequiredService<RunBackgroundTasks>())
|
||||
|
|
@ -49,10 +51,8 @@ public class MultitenancyFeature(IModule module) : FeatureBase(module)
|
|||
.AddSingleton<ITenantActivatedEvent>(sp => sp.GetRequiredService<StartRecurringTasks>())
|
||||
.AddSingleton<ITenantDeactivatedEvent>(sp => sp.GetRequiredService<StartRecurringTasks>())
|
||||
|
||||
.AddSingleton<ITenantActivatedEvent, RunStartupTasks>()
|
||||
.AddSingleton<RecurringTaskScheduleManager>()
|
||||
.AddSingleton<TenantEventsManager>()
|
||||
.AddStartupTask<ConfigureRecurringTasksScheduleStartupTask>()
|
||||
.AddScoped<DefaultTenantsProvider>()
|
||||
.AddScoped<DefaultTenantResolver>()
|
||||
.AddScoped<ITaskExecutor, TaskExecutor>()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ namespace Elsa.Common.Multitenancy.EventHandlers;
|
|||
public class StartRecurringTasks(RecurringTaskScheduleManager scheduleManager, ILogger<StartRecurringTasks> logger) : ITenantActivatedEvent, ITenantDeactivatedEvent
|
||||
{
|
||||
private readonly ICollection<ScheduledTimer> _scheduledTimers = new List<ScheduledTimer>();
|
||||
private CancellationTokenSource _cancellationTokenSource = default!;
|
||||
private CancellationTokenSource _cancellationTokenSource = null!;
|
||||
|
||||
public async Task TenantActivatedAsync(TenantActivatedEventArgs args)
|
||||
{
|
||||
|
|
@ -16,7 +16,7 @@ public class StartRecurringTasks(RecurringTaskScheduleManager scheduleManager, I
|
|||
var tenantScope = args.TenantScope;
|
||||
var tasks = tenantScope.ServiceProvider.GetServices<IRecurringTask>().ToList();
|
||||
var taskExecutor = tenantScope.ServiceProvider.GetRequiredService<ITaskExecutor>();
|
||||
|
||||
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
var schedule = scheduleManager.GetScheduleFor(task.GetType());
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ public class DefaultTenantAccessor : ITenantAccessor
|
|||
public Tenant? Tenant
|
||||
{
|
||||
get => CurrentTenantField.Value;
|
||||
internal set => CurrentTenantField.Value = value;
|
||||
private set => CurrentTenantField.Value = value;
|
||||
}
|
||||
|
||||
public IDisposable PushContext(Tenant? tenant)
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
using Cronos;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.Common.RecurringTasks;
|
||||
|
||||
[UsedImplicitly]
|
||||
public class ConfigureRecurringTasksScheduleStartupTask(IOptions<RecurringTaskOptions> options, ISystemClock systemClock, RecurringTaskScheduleManager recurringTaskScheduleManager) : IStartupTask
|
||||
{
|
||||
public Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
foreach(var entry in options.Value.Schedule.ScheduledTasks)
|
||||
{
|
||||
var taskType = entry.Key;
|
||||
var intervalExpression = entry.Value;
|
||||
var schedule = intervalExpression.Type switch
|
||||
{
|
||||
IntervalExpressionType.Cron => (ISchedule)new CronSchedule(systemClock, CronExpression.Parse(intervalExpression.Expression)),
|
||||
IntervalExpressionType.Interval => new IntervalSchedule(TimeSpan.Parse(intervalExpression.Expression)),
|
||||
_ => throw new NotSupportedException($"Interval expression type '{intervalExpression.Type}' is not supported.")
|
||||
};
|
||||
recurringTaskScheduleManager.ConfigureScheduledTask(taskType, schedule);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,31 @@
|
|||
using Cronos;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Elsa.Common.RecurringTasks;
|
||||
|
||||
public class RecurringTaskScheduleManager
|
||||
public class RecurringTaskScheduleManager(IOptions<RecurringTaskOptions> options, ISystemClock systemClock)
|
||||
{
|
||||
public IDictionary<Type, ISchedule> ScheduledTasks { get; set; } = new Dictionary<Type, ISchedule>();
|
||||
|
||||
public void ConfigureScheduledTask<T>(ISchedule schedule) where T : IRecurringTask
|
||||
{
|
||||
ConfigureScheduledTask(typeof(T), schedule);
|
||||
}
|
||||
|
||||
public void ConfigureScheduledTask(Type recurringTaskType, ISchedule schedule)
|
||||
{
|
||||
ScheduledTasks[recurringTaskType] = schedule;
|
||||
}
|
||||
|
||||
public ISchedule GetScheduleFor(Type taskType)
|
||||
{
|
||||
return ScheduledTasks.TryGetValue(taskType, out var schedule) ? schedule : new IntervalSchedule(TimeSpan.FromMinutes(1));
|
||||
if (!ScheduledTasks.TryGetValue(taskType, out var schedule))
|
||||
{
|
||||
var intervalExpression = options.Value.Schedule.ScheduledTasks.TryGetValue(taskType, out var expr) ? expr : null;
|
||||
schedule = intervalExpression != null ? CreateSchedule(intervalExpression) : new IntervalSchedule(TimeSpan.FromMinutes(1));
|
||||
ScheduledTasks[taskType] = schedule;
|
||||
}
|
||||
|
||||
return schedule;
|
||||
}
|
||||
|
||||
private ISchedule CreateSchedule(IntervalExpression intervalExpression)
|
||||
{
|
||||
return intervalExpression.Type switch
|
||||
{
|
||||
IntervalExpressionType.Cron => new CronSchedule(systemClock, CronExpression.Parse(intervalExpression.Expression)),
|
||||
IntervalExpressionType.Interval => new IntervalSchedule(TimeSpan.Parse(intervalExpression.Expression)),
|
||||
_ => throw new NotSupportedException($"Interval expression type '{intervalExpression.Type}' is not supported.")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ public class TypeTypeConverter : TypeConverter
|
|||
{
|
||||
if (TypeAliasRegistry.GetType(stringValue) is { } type)
|
||||
return type;
|
||||
return Type.GetType(stringValue);
|
||||
return Type.GetType(stringValue) ?? throw new InvalidOperationException($"Type '{stringValue}' not found.");
|
||||
}
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ public class V3_3 : Migration
|
|||
/// <inheritdoc />
|
||||
public override void Up()
|
||||
{
|
||||
Delete.Table("WorkflowInboxMessages");
|
||||
Alter.Table("Triggers").AddColumn("TenantId").AsString().Nullable();
|
||||
Alter.Table("Bookmarks").AddColumn("TenantId").AsString().Nullable();
|
||||
Alter.Table("WorkflowExecutionLogRecords").AddColumn("TenantId").AsString().Nullable();
|
||||
Alter.Table("ActivityExecutionRecords").AddColumn("TenantId").AsString().Nullable();
|
||||
Alter.Table("KeyValuePairs").AddColumn("TenantId").AsString().Nullable();
|
||||
Rename.Column("Key").OnTable("KeyValuePairs").To("Id");
|
||||
|
||||
IfDatabase("SqlServer", "Oracle", "MySql", "Postgres")
|
||||
.Create
|
||||
|
|
@ -56,37 +56,7 @@ public class V3_3 : Migration
|
|||
Delete.Column("TenantId").FromTable("WorkflowExecutionLogRecords");
|
||||
Delete.Column("TenantId").FromTable("ActivityExecutionRecords");
|
||||
Delete.Column("TenantId").FromTable("KeyValuePairs");
|
||||
|
||||
IfDatabase("SqlServer", "Oracle", "MySql", "Postgres")
|
||||
.Create
|
||||
.Table("WorkflowInboxMessages")
|
||||
.WithColumn("Id").AsString().PrimaryKey()
|
||||
.WithColumn("ActivityTypeName").AsString().NotNullable().Indexed()
|
||||
.WithColumn("WorkflowInstanceId").AsString().Nullable().Indexed()
|
||||
.WithColumn("ActivityInstanceId").AsString().Nullable().Indexed()
|
||||
.WithColumn("CorrelationId").AsString().Nullable().Indexed()
|
||||
.WithColumn("Hash").AsString().NotNullable().Indexed()
|
||||
.WithColumn("SerializedBookmarkPayload").AsString(MaxValue)
|
||||
.WithColumn("SerializedInput").AsString(MaxValue).Nullable()
|
||||
.WithColumn("CreatedAt").AsDateTimeOffset().Indexed()
|
||||
.WithColumn("ExpiresAt").AsDateTimeOffset().Indexed()
|
||||
;
|
||||
|
||||
IfDatabase("Sqlite")
|
||||
.Create
|
||||
.Table("WorkflowInboxMessages")
|
||||
.WithColumn("Id").AsString().PrimaryKey()
|
||||
.WithColumn("ActivityTypeName").AsString().NotNullable().Indexed()
|
||||
.WithColumn("WorkflowInstanceId").AsString().Nullable().Indexed()
|
||||
.WithColumn("ActivityInstanceId").AsString().Nullable().Indexed()
|
||||
.WithColumn("CorrelationId").AsString().Nullable().Indexed()
|
||||
.WithColumn("Hash").AsString().NotNullable().Indexed()
|
||||
.WithColumn("SerializedBookmarkPayload").AsString(MaxValue)
|
||||
.WithColumn("SerializedInput").AsString(MaxValue).Nullable()
|
||||
.WithColumn("CreatedAt").AsDateTime2().Indexed()
|
||||
.WithColumn("ExpiresAt").AsDateTime2().Indexed()
|
||||
;
|
||||
|
||||
Rename.Column("Id").OnTable("KeyValuePairs").To("Key");
|
||||
Delete.Table("BookmarkQueueItems");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections;
|
||||
using System.Dynamic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
|
@ -84,8 +85,7 @@ public class SendEmail : Activity
|
|||
/// <summary>
|
||||
/// The activity to execute when an error occurs while trying to send the email.
|
||||
/// </summary>
|
||||
[Port]
|
||||
public IActivity? Error { get; set; }
|
||||
[Port] public IActivity? Error { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
|
|
@ -99,7 +99,10 @@ public class SendEmail : Activity
|
|||
message.From.Add(MailboxAddress.Parse(from));
|
||||
message.Subject = Subject.GetOrDefault(context) ?? "";
|
||||
|
||||
var bodyBuilder = new BodyBuilder { HtmlBody = Body.GetOrDefault(context) };
|
||||
var bodyBuilder = new BodyBuilder
|
||||
{
|
||||
HtmlBody = Body.GetOrDefault(context)
|
||||
};
|
||||
await AddAttachmentsAsync(context, bodyBuilder, cancellationToken);
|
||||
|
||||
message.Body = bodyBuilder.ToMessageBody();
|
||||
|
|
@ -119,7 +122,10 @@ public class SendEmail : Activity
|
|||
catch (Exception e)
|
||||
{
|
||||
logger.LogWarning(e, "Error while sending email message");
|
||||
context.AddExecutionLogEntry("Error", e.Message, payload: new { e.StackTrace });
|
||||
context.AddExecutionLogEntry("Error", e.Message, payload: new
|
||||
{
|
||||
e.StackTrace
|
||||
});
|
||||
await context.ScheduleActivityAsync(Error, OnErrorCompletedAsync);
|
||||
}
|
||||
}
|
||||
|
|
@ -155,38 +161,54 @@ public class SendEmail : Activity
|
|||
await AttachLocalFileAsync(bodyBuilder, path, cancellationToken);
|
||||
break;
|
||||
case byte[] bytes:
|
||||
{
|
||||
var fileName = $"Attachment-{++index}";
|
||||
bodyBuilder.Attachments.Add(fileName, bytes, ContentType.Parse("application/binary"));
|
||||
break;
|
||||
}
|
||||
{
|
||||
var fileName = $"Attachment-{++index}";
|
||||
bodyBuilder.Attachments.Add(fileName, bytes, ContentType.Parse("application/binary"));
|
||||
break;
|
||||
}
|
||||
case Stream stream:
|
||||
{
|
||||
var fileName = $"Attachment-{++index}";
|
||||
await bodyBuilder.Attachments.AddAsync(fileName, stream, ContentType.Parse("application/binary"), cancellationToken);
|
||||
break;
|
||||
}
|
||||
{
|
||||
var fileName = $"Attachment-{++index}";
|
||||
await bodyBuilder.Attachments.AddAsync(fileName, stream, ContentType.Parse("application/binary"), cancellationToken);
|
||||
break;
|
||||
}
|
||||
case EmailAttachment emailAttachment:
|
||||
{
|
||||
var fileName = emailAttachment.FileName ?? $"Attachment-{++index}";
|
||||
var contentType = emailAttachment.ContentType ?? "application/binary";
|
||||
var parsedContentType = ContentType.Parse(contentType);
|
||||
{
|
||||
var fileName = emailAttachment.FileName ?? $"Attachment-{++index}";
|
||||
var contentType = emailAttachment.ContentType ?? "application/binary";
|
||||
var parsedContentType = ContentType.Parse(contentType);
|
||||
|
||||
if (emailAttachment.Content is byte[] bytes)
|
||||
bodyBuilder.Attachments.Add(fileName, bytes, parsedContentType);
|
||||
if (emailAttachment.Content is byte[] bytes)
|
||||
bodyBuilder.Attachments.Add(fileName, bytes, parsedContentType);
|
||||
|
||||
else if (emailAttachment.Content is Stream stream)
|
||||
await bodyBuilder.Attachments.AddAsync(fileName, stream, parsedContentType, cancellationToken);
|
||||
else if (emailAttachment.Content is Stream stream)
|
||||
await bodyBuilder.Attachments.AddAsync(fileName, stream, parsedContentType, cancellationToken);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ExpandoObject expandoObject:
|
||||
{
|
||||
var dictionary = new Dictionary<string, object>(expandoObject, StringComparer.OrdinalIgnoreCase);
|
||||
var fileName = dictionary.GetValue<string>("FileName") ?? $"Attachment-{++index}";
|
||||
var contentType = dictionary.GetValue<string>("ContentType") ?? "application/binary";
|
||||
var parsedContentType = ContentType.Parse(contentType);
|
||||
var content = dictionary.GetValue<object>("Content");
|
||||
|
||||
if (content is byte[] bytes)
|
||||
bodyBuilder.Attachments.Add(fileName, bytes, parsedContentType);
|
||||
|
||||
else if (content is Stream stream)
|
||||
await bodyBuilder.Attachments.AddAsync(fileName, stream, parsedContentType, cancellationToken);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
var json = JsonSerializer.Serialize(attachmentObject);
|
||||
var fileName = $"Attachment-{++index}";
|
||||
bodyBuilder.Attachments.Add(fileName, Encoding.UTF8.GetBytes(json), ContentType.Parse("application/json"));
|
||||
break;
|
||||
}
|
||||
{
|
||||
var json = JsonSerializer.Serialize(attachmentObject);
|
||||
var fileName = $"Attachment-{++index}";
|
||||
bodyBuilder.Attachments.Add(fileName, Encoding.UTF8.GetBytes(json), ContentType.Parse("application/json"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -203,7 +225,24 @@ public class SendEmail : Activity
|
|||
await bodyBuilder.Attachments.AddAsync(fileName, contentStream, ContentType.Parse(contentType), cancellationToken);
|
||||
}
|
||||
|
||||
private IEnumerable InterpretAttachmentsModel(object attachments) => attachments is string text ? new[] { text } : attachments is IEnumerable enumerable ? enumerable : new[] { attachments };
|
||||
private IEnumerable InterpretAttachmentsModel(object attachments)
|
||||
{
|
||||
if (attachments is byte[] bytes)
|
||||
return new[]
|
||||
{
|
||||
bytes
|
||||
};
|
||||
|
||||
return attachments is string text
|
||||
? new[]
|
||||
{
|
||||
text
|
||||
}
|
||||
: attachments as IEnumerable ?? new[]
|
||||
{
|
||||
attachments
|
||||
};
|
||||
}
|
||||
|
||||
private void SetRecipientsEmailAddresses(InternetAddressList list, IEnumerable<string>? addresses)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public abstract class DesignTimeDbContextFactoryBase<TDbContext> : IDesignTimeDb
|
|||
|
||||
ConfigureBuilder(builder, connectionString);
|
||||
|
||||
return (TDbContext)Activator.CreateInstance(typeof(TDbContext), builder.Options, serviceProvider)!;
|
||||
return (TDbContext)ActivatorUtilities.CreateInstance(serviceProvider, typeof(TDbContext), builder.Options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,5 @@ public class CommonPersistenceFeature(IModule module) : FeatureBase(module)
|
|||
{
|
||||
Services.AddScoped<IEntitySavingHandler, ApplyTenantId>();
|
||||
Services.AddScoped<IEntityModelCreatingHandler, SetTenantIdFilter>();
|
||||
Services.AddScoped<IEntityModelCreatingHandler, SetupForSqlite>();
|
||||
}
|
||||
}
|
||||
|
|
@ -10,17 +10,14 @@ namespace Elsa.EntityFrameworkCore;
|
|||
/// <summary>
|
||||
/// Class That enable Schema change for Migration
|
||||
/// </summary>
|
||||
public class DbSchemaAwareMigrationAssembly : MigrationsAssembly
|
||||
public class DbSchemaAwareMigrationAssembly(
|
||||
ICurrentDbContext currentContext,
|
||||
IDbContextOptions options,
|
||||
IMigrationsIdGenerator idGenerator,
|
||||
IDiagnosticsLogger<DbLoggerCategory.Migrations> logger)
|
||||
: MigrationsAssembly(currentContext, options, idGenerator, logger)
|
||||
{
|
||||
private readonly DbContext _context;
|
||||
|
||||
public DbSchemaAwareMigrationAssembly(ICurrentDbContext currentContext,
|
||||
IDbContextOptions options, IMigrationsIdGenerator idGenerator,
|
||||
IDiagnosticsLogger<DbLoggerCategory.Migrations> logger)
|
||||
: base(currentContext, options, idGenerator, logger)
|
||||
{
|
||||
_context = currentContext.Context;
|
||||
}
|
||||
private readonly DbContext _context = currentContext.Context;
|
||||
|
||||
public override Migration CreateMigration(TypeInfo migrationClass, string activeProvider)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
<PackageReference Include="Microsoft.EntityFrameworkCore" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
|
||||
<PackageReference Include="Open.Linq.AsyncExtensions" />
|
||||
<PackageReference Include="System.CommandLine" />
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Elsa.Common.Entities;
|
|||
using Elsa.Common.Multitenancy;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.EntityFrameworkCore;
|
||||
|
|
@ -16,8 +17,9 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema
|
|||
EntityState.Added,
|
||||
EntityState.Modified,
|
||||
};
|
||||
|
||||
protected readonly IServiceProvider ServiceProvider;
|
||||
|
||||
protected IServiceProvider ServiceProvider { get; }
|
||||
private readonly ElsaDbContextOptions? _elsaDbContextOptions;
|
||||
public string? TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -39,18 +41,18 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema
|
|||
protected ElsaDbContextBase(DbContextOptions options, IServiceProvider serviceProvider) : base(options)
|
||||
{
|
||||
ServiceProvider = serviceProvider;
|
||||
var elsaDbContextOptions = options.FindExtension<ElsaDbContextOptionsExtension>()?.Options;
|
||||
|
||||
// ReSharper disable once VirtualMemberCallInConstructor
|
||||
Schema = !string.IsNullOrWhiteSpace(elsaDbContextOptions?.SchemaName) ? elsaDbContextOptions.SchemaName : ElsaSchema;
|
||||
_elsaDbContextOptions = options.FindExtension<ElsaDbContextOptionsExtension>()?.Options;
|
||||
|
||||
// ReSharper disable once VirtualMemberCallInConstructor
|
||||
Schema = !string.IsNullOrWhiteSpace(_elsaDbContextOptions?.SchemaName) ? _elsaDbContextOptions.SchemaName : ElsaSchema;
|
||||
|
||||
var tenantAccessor = serviceProvider.GetService<ITenantAccessor>();
|
||||
var tenantId = tenantAccessor?.Tenant?.Id;
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(tenantId))
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tenantId))
|
||||
TenantId = tenantId;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
|
@ -58,26 +60,33 @@ public abstract class ElsaDbContextBase : DbContext, IElsaDbContextSchema
|
|||
return await base.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.EnableSensitiveDataLogging();
|
||||
#if NET9_0_OR_GREATER
|
||||
optionsBuilder.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(Schema))
|
||||
{
|
||||
if (!Database.IsSqlite())
|
||||
modelBuilder.HasDefaultSchema(Schema);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(Schema))
|
||||
modelBuilder.HasDefaultSchema(Schema);
|
||||
|
||||
var additionalConfigurations = _elsaDbContextOptions?.GetModelConfigurations(this);
|
||||
|
||||
additionalConfigurations?.Invoke(modelBuilder);
|
||||
|
||||
var entityTypeHandlers = ServiceProvider.GetServices<IEntityModelCreatingHandler>().ToList();
|
||||
|
||||
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
|
||||
foreach (var entityType in modelBuilder.Model.GetEntityTypes().ToList())
|
||||
{
|
||||
foreach (var handler in entityTypeHandlers)
|
||||
{
|
||||
foreach (var handler in entityTypeHandlers)
|
||||
handler.Handle(this, modelBuilder, entityType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task OnBeforeSavingAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var handlers = ServiceProvider.GetServices<IEntitySavingHandler>().ToList();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue