Add project files.
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageId>Caspian.WorkflowFramework</PackageId>
|
||||
<Version>1.0.1-preview2</Version>
|
||||
<Authors>Digital banking team</Authors>
|
||||
<Company>Caspian</Company>
|
||||
<Product>Caspian.WorkflowFramework</Product>
|
||||
<Description>Caspian Workflow Framework</Description>
|
||||
<PackageProjectUrl>https://caspco.ir</PackageProjectUrl>
|
||||
<PackageIcon>package-icon.png</PackageIcon>
|
||||
<PackageReadmeFile>readme.md</PackageReadmeFile>
|
||||
<PackageTags>caspian, nextbank, workflow</PackageTags>
|
||||
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>caspian-pkg-key.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<PackageReference Include="Caspian.Elsa" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Expressions" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Alterations" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Alterations.Core" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Alterations.MassTransit" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Api.Client" Version="1.0.2-preview1" />
|
||||
<PackageReference Include="Caspian.Elsa.Api.Common" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Caching" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Caching.Distributed.ProtoActor" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Common" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Connections.Api" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Connections.Core" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Connections.Models" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.CSharp" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Dapper.Migrations" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.DropIns" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.DropIns.Core" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Dsl" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Email" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.Common" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.MySql" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.Oracle" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.PostgreSql" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.Sqlite" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.EntityFrameworkCore.SqlServer" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Environments" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Features" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Hangfire" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Hosting.Management" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Http" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Identity" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.JavaScript" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.JavaScript.Libraries" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Liquid" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Mediator" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.ProtoActor.Core" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Python" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Quartz" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.MySql" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.PostgreSql" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.Sqlite" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Quartz.EntityFrameworkCore.SqlServer" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Retention" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.SasTokens" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Scheduling" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Sql.PostgreSql" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Sql.Sqlite" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Sql.SqlServer" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Tenants" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Tenants.AspNetCore" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Testing.Shared" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Testing.Shared.Component" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Testing.Shared.Integration" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Webhooks" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.WorkflowContexts" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.WorkflowProviders.BlobStorage" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Workflows.Api" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Workflows.Core" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Workflows.Management" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Workflows.Runtime" Version="1.0.1" />
|
||||
<PackageReference Include="Caspian.Elsa.Workflows.Runtime.Distributed" Version="1.0.1" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
|
||||
<PackageReference Include="MongoLogger" Version="1.9.2.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="LICENSE.txt">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
<None Update="package-icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
<None Update="readme.md">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Caspian.WorkflowFramework</id>
|
||||
<version>1.0.0-preview34</version>
|
||||
<authors>Digital Banking Team</authors>
|
||||
<owners>Caspian</owners>
|
||||
<description>Caspian workflow framework</description>
|
||||
<projectUrl>https://caspco.ir</projectUrl>
|
||||
<icon>package-icon.png</icon>
|
||||
<readme>readme.md</readme>
|
||||
<tags>caspian, nextbank, workflow</tags>
|
||||
<license type="file">LICENSE.txt</license>
|
||||
<dependencies>
|
||||
<group targetFramework="net9.0">
|
||||
<dependency id="Microsoft.EntityFrameworkCore" version="*" />
|
||||
<dependency id="ConfigureAwait.Fody" version="*" />
|
||||
<dependency id="Cronos" version="*" />
|
||||
<dependency id="DistributedLock.Core" version="*" />
|
||||
<dependency id="Fody" version="*" />
|
||||
<dependency id="IronCompress" version="*" />
|
||||
<dependency id="JetBrains.Annotations" version="*" />
|
||||
<dependency id="LinqKit.Core" version="*" />
|
||||
<dependency id="Microsoft.AspNetCore.Http.Abstractions" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Configuration" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Configuration.Json" version="*" />
|
||||
<dependency id="Microsoft.Extensions.DependencyInjection.Abstractions" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Hosting" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Hosting.Abstractions" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Logging" version="*" />
|
||||
<dependency id="Microsoft.SourceLink.GitHub" version="*" />
|
||||
<dependency id="MongoLogger" version="*" />
|
||||
<dependency id="Open.Linq.AsyncExtensions" version="*" />
|
||||
<dependency id="Proto.Actor" version="*" />
|
||||
<dependency id="Proto.Cluster" version="*" />
|
||||
<dependency id="Proto.Cluster.TestProvider" version="*" />
|
||||
<dependency id="Proto.OpenTelemetry" version="*" />
|
||||
<dependency id="Proto.Persistence" version="*" />
|
||||
<dependency id="Proto.Remote" version="*" />
|
||||
<dependency id="FastEndpoints" version="*" />
|
||||
<dependency id="FastEndpoints.Security" version="*" />
|
||||
<dependency id="FastEndpoints.Swagger" version="*" />
|
||||
<dependency id="Microsoft.Extensions.DependencyInjection" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Options" version="*" />
|
||||
<dependency id="NuGet.Packaging" version="*" />
|
||||
<dependency id="NuGet.Protocol" version="*" />
|
||||
<dependency id="System.Formats.Asn1" version="*" />
|
||||
<dependency id="ThrottleDebounce" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Options.ConfigurationExtensions" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Caching.Memory" version="*" />
|
||||
<dependency id="Scrutor" version="*" />
|
||||
<dependency id="Google.Protobuf" version="*" />
|
||||
<dependency id="Grpc.Tools" version="*" />
|
||||
<dependency id="Proto.Cluster.CodeGen" version="*" />
|
||||
<dependency id="Microsoft.Data.Sqlite" version="*" />
|
||||
<dependency id="Microsoft.EntityFrameworkCore.Sqlite" version="*" />
|
||||
<!-- <dependency id="Microsoft.EntityFrameworkCore.Design" version="*" /> -->
|
||||
<dependency id="MailKit" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Http" version="*" />
|
||||
<dependency id="FluentStorage" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Http.Resilience" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Resilience" version="*" />
|
||||
<dependency id="Microsoft.Extensions.Http.Polly" version="*" />
|
||||
<dependency id="WebhooksCore" version="*" />
|
||||
<dependency id="Azure.Identity" version="*" />
|
||||
<dependency id="Dapper" version="*" />
|
||||
<dependency id="FluentMigrator" version="*" />
|
||||
<dependency id="FluentMigrator.Runner" version="*" />
|
||||
<dependency id="Microsoft.Data.Sqlite.Core" version="*" />
|
||||
<dependency id="Microsoft.Identity.Client" version="*" />
|
||||
<!-- <dependency id="Npgsql" /> -->
|
||||
<dependency id="System.Data.SqlClient" version="*" />
|
||||
<dependency id="Microsoft.EntityFrameworkCore.Relational" version="*" />
|
||||
<dependency id="System.CommandLine" version="*" />
|
||||
<dependency id="DistributedLock.FileSystem" version="*" />
|
||||
<!-- <dependency id="Microsoft.CodeAnalysis.CSharp.Scripting" version="*" /> -->
|
||||
<dependency id="Antlr4.Runtime.Standard" version="*" />
|
||||
<dependency id="System.Linq.Async" version="*" />
|
||||
<dependency id="Jint" version="*" />
|
||||
<dependency id="Fluid.Core" version="*" />
|
||||
<dependency id="pythonnet" version="*" />
|
||||
<dependency id="Microsoft.AspNetCore.DataProtection.Abstractions" version="*" />
|
||||
<dependency id="AspNetCore.Authentication.ApiKey" version="*" />
|
||||
<dependency id="Azure.Messaging.ServiceBus" version="*" />
|
||||
<dependency id="Azure.ResourceManager.ServiceBus" version="*" />
|
||||
<dependency id="Confluent.Kafka" version="*" />
|
||||
<dependency id="Confluent.SchemaRegistry.Serdes.Avro" version="*" />
|
||||
<dependency id="MassTransit" version="*" />
|
||||
<dependency id="MassTransit.Azure.ServiceBus.Core" version="*" />
|
||||
<dependency id="MassTransit.RabbitMQ" version="*" />
|
||||
<dependency id="Hangfire" version="*" />
|
||||
<dependency id="Hangfire.MemoryStorage" version="*" />
|
||||
<dependency id="Hangfire.Storage.SQLite" version="*" />
|
||||
<dependency id="Quartz.Extensions.Hosting" version="*" />
|
||||
<dependency id="AppAny.Quartz.EntityFrameworkCore.Migrations.MySql" version="*" />
|
||||
<dependency id="Quartz.Serialization.Json" version="*" />
|
||||
<dependency id="AppAny.Quartz.EntityFrameworkCore.Migrations.SqlServer" version="*" />
|
||||
<dependency id="Humanizer.Core" version="*" />
|
||||
<dependency id="Newtonsoft.Json" version="*" />
|
||||
<dependency id="ShortGuid" version="*" />
|
||||
<dependency id="System.Linq.Dynamic.Core" version="*" />
|
||||
<dependency id="PolySharp" version="*" />
|
||||
</group>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<!-- Include the favicon -->
|
||||
<file src="favicon.ico" target="\" />
|
||||
|
||||
<!-- Include license, icon, and readme files -->
|
||||
<file src="LICENSE.txt" target="\" />
|
||||
<file src="package-icon.png" target="\" />
|
||||
<file src="readme.md" target="\" />
|
||||
|
||||
<!-- Include all required DLLs in the lib folder -->
|
||||
<file src="bin\release\net9.0\*.dll" target="lib\net9.0" />
|
||||
<!-- <file src="..\..\common\Elsa.Features\bin\Release\net9.0\Elsa.Features.dll" target="lib\net9.0\Elsa.Features.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.CSharp\bin\Release\net9.0\Elsa.CSharp.dll" target="lib\net9.0\Elsa.CSharp.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.Email\bin\Release\net9.0\Elsa.Email.dll" target="lib\net9.0\Elsa.Email.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.EntityFrameworkCore.Common\bin\Release\net9.0\Elsa.EntityFrameworkCore.Common.dll" target="lib\net9.0\Elsa.EntityFrameworkCore.Common.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.EntityFrameworkCore.SqlServer\bin\Release\net9.0\Elsa.EntityFrameworkCore.SqlServer.dll" target="lib\net9.0\Elsa.EntityFrameworkCore.SqlServer.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.EntityFrameworkCore\bin\Release\net9.0\Elsa.EntityFrameworkCore.dll" target="lib\net9.0\Elsa.EntityFrameworkCore.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.JavaScript\bin\Release\net9.0\Elsa.JavaScript.dll" target="lib\net9.0\Elsa.JavaScript.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.Scheduling\bin\Release\net9.0\Elsa.Scheduling.dll" target="lib\net9.0\Elsa.Scheduling.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.Workflows.Api\bin\Release\net9.0\Elsa.Workflows.Api.dll" target="lib\net9.0\Elsa.Workflows.Api.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.Workflows.Management\bin\Release\net9.0\Elsa.Workflows.Management.dll" target="lib\net9.0\Elsa.Workflows.Management.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa.Workflows.Runtime\bin\Release\net9.0\Elsa.Workflows.Runtime.dll" target="lib\net9.0\Elsa.Workflows.Runtime.dll" /> -->
|
||||
<!-- <file src="..\..\modules\Elsa\bin\Release\net9.0\Elsa.dll" target="lib\net9.0\Elsa.dll" /> -->
|
||||
</files>
|
||||
</package>
|
||||
@@ -0,0 +1,72 @@
|
||||
using Caspian.WorkflowFramework.Contracts;
|
||||
using Caspian.WorkflowFramework.Services;
|
||||
using Elsa.Extensions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Elsa.EntityFrameworkCore.Extensions;
|
||||
using Elsa.EntityFrameworkCore.Modules.Management;
|
||||
using Elsa.EntityFrameworkCore.Modules.Runtime;
|
||||
using Elsa.EntityFrameworkCore.Modules.Identity;
|
||||
using Elsa.Email;
|
||||
using MongoLogger;
|
||||
using MongoLogger.Models;
|
||||
|
||||
namespace Caspian.WorkflowFramework;
|
||||
|
||||
public static class DependencyInjectionq
|
||||
{
|
||||
public static void AddWorkflowFramework(this IHostApplicationBuilder builder, string connectionString)
|
||||
{
|
||||
builder.Services.AddMongoLogger<LogModel>(builder.Configuration);
|
||||
|
||||
builder.Services.AddElsa(elsa =>
|
||||
{
|
||||
// Configure Management layer to use EF Core.
|
||||
elsa.UseWorkflowManagement(management => management
|
||||
.UseEntityFrameworkCore(ef => ef.UseSqlServer(connectionString)));
|
||||
|
||||
// Configure Runtime layer to use EF Core.
|
||||
elsa.UseWorkflowRuntime(runtime => runtime
|
||||
.UseEntityFrameworkCore(ef => ef.UseSqlServer(connectionString)));
|
||||
|
||||
// Expose Elsa API endpoints.
|
||||
elsa.UseWorkflowsApi();
|
||||
|
||||
// Enable C# workflow expressions
|
||||
elsa.UseCSharp();
|
||||
|
||||
// Enable JavaScript workflow expressions
|
||||
elsa.UseJavaScript(options => options.AllowClrAccess = true);
|
||||
});
|
||||
|
||||
//// Configure CORS to allow designer app hosted on a different origin to invoke the APIs.
|
||||
//builder.Services.AddCors(cors => cors
|
||||
// .AddDefaultPolicy(policy => policy
|
||||
// .AllowAnyOrigin() // For demo purposes only. Use a specific origin instead.
|
||||
// .AllowAnyHeader()
|
||||
// .AllowAnyMethod()
|
||||
// .WithExposedHeaders("x-elsa-workflow-instance-id"))); // Required for Elsa Studio in order to support running workflows from the designer. Alternatively, you can use the `*` wildcard to expose all headers.
|
||||
|
||||
|
||||
// Add Health Checks.
|
||||
builder.Services.AddHealthChecks();
|
||||
|
||||
builder.Services.AddScoped<IWorkflowService, WorkflowService>();
|
||||
}
|
||||
|
||||
public static void UseWorkflowFramework(this IApplicationBuilder app)
|
||||
{
|
||||
try
|
||||
{
|
||||
app.UseMongoLogger<LogModel>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var d = ex;
|
||||
}
|
||||
|
||||
//app.UseWorkflowsApi(); // Use Elsa API endpoints.
|
||||
app.UseWorkflows(); // Use Elsa middleware to handle HTTP requests mapped to HTTP Endpoint activities.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Caspian.WorkflowFramework.Models;
|
||||
|
||||
namespace Caspian.WorkflowFramework.Contracts
|
||||
{
|
||||
public interface IWorkflowService
|
||||
{
|
||||
/// <summary>
|
||||
/// Create and executes a new workflow instance.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns>A new <see cref="WorkflowResponse<WorkflowModel>"/> object.</returns>
|
||||
/// <remarks>Create a new workflow instance and executes it and waits for it to complete or reach a suspend point.</remarks>
|
||||
Task<WorkflowResponse<WorkflowModel>> CreateAndExecuteAsync(CreateAndExecuteWorkflowModel input);
|
||||
|
||||
/// <summary>
|
||||
/// Publishes the specified event.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns>A new <see cref="WorkflowResponse<WorkflowModel>"/> object.</returns>
|
||||
Task<WorkflowResponse<WorkflowModel>> PublishEventAsync(PublishEventModel input);
|
||||
|
||||
/// <summary>
|
||||
/// Inquiry last state of workflow instance.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns>A new <see cref="WorkflowResponse<WorkflowModel>"/> object.</returns>
|
||||
Task<WorkflowResponse<WorkflowModel>> InquiryStateAsync(InquiryStateModel input);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,3 @@
|
||||
Terms and Conditions of Use, Reproduction and Distribution are permitted only for Caspian Company.
|
||||
|
||||
Copyright [2025] Caspian Company
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Common.Models;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Caspian.WorkflowFramework.Models
|
||||
{
|
||||
[PublicAPI]
|
||||
public class CreateAndExecuteWorkflowModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Workflow name
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Workflow version
|
||||
/// </summary>
|
||||
[Required]
|
||||
public VersionOptions Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current user's id
|
||||
/// </summary>
|
||||
[Required]
|
||||
public long? UserId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Caspian.WorkflowFramework.Models
|
||||
{
|
||||
public class InquiryStateModel
|
||||
{
|
||||
[Required]
|
||||
public string WorkflowInstanceId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Caspian.WorkflowFramework.Models
|
||||
{
|
||||
[PublicAPI]
|
||||
public class PublishEventModel
|
||||
{
|
||||
[Required]
|
||||
public string WorkflowInstanceId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string EventName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string? EventData { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Caspian.WorkflowFramework.Models
|
||||
{
|
||||
[PublicAPI]
|
||||
public class WorkflowModel
|
||||
{
|
||||
/// <summary>
|
||||
/// شناسه گردش کار
|
||||
/// </summary>
|
||||
public string? InstanceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// نام گردش کار
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// اتمام گردش کار؟
|
||||
/// </summary>
|
||||
public bool IsComplete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// برای کدام کاربر؟
|
||||
/// </summary>
|
||||
public long? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// داده صفحه جاری
|
||||
/// </summary>
|
||||
public string? CurrentPageData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// داده صفحه بعد
|
||||
/// <remark>
|
||||
/// فعلا استفاده ای نداریم
|
||||
/// </remark>
|
||||
/// </summary>
|
||||
public string? NextPageData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// آدرس صفحه بعدی
|
||||
/// </summary>
|
||||
public string? NextPageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// رویدادی که باید پس از سابمیت صفحه بعدی منتشر شود
|
||||
/// </summary>
|
||||
public string? NextPageEventName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Caspian.WorkflowFramework.Models
|
||||
{
|
||||
[PublicAPI]
|
||||
public class WorkflowResponse<T> : WorkflowResponseBase where T : class, new()
|
||||
{
|
||||
public WorkflowResponse()
|
||||
{
|
||||
Data = new T();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// پاسخ
|
||||
/// </summary>
|
||||
public T? Data { get; set; }
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public class WorkflowResponseBase
|
||||
{
|
||||
/// <summary>
|
||||
/// وضعیت پاسخ
|
||||
/// </summary>
|
||||
public int? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// پیام پاسخ
|
||||
/// </summary>
|
||||
public string? Message { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
using Caspian.WorkflowFramework.Models;
|
||||
using Caspian.WorkflowFramework.Contracts;
|
||||
using Newtonsoft.Json;
|
||||
using Elsa.Workflows.Runtime;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Elsa.Workflows.Management;
|
||||
using Elsa.Workflows.Management.Filters;
|
||||
using Elsa.Workflows.Runtime.Messages;
|
||||
using Elsa.Workflows.Models;
|
||||
using Elsa.Common.Models;
|
||||
using Caspian.WorkflowFramework.Utility;
|
||||
using MongoLogger;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Caspian.WorkflowFramework.Services
|
||||
{
|
||||
public class WorkflowService : IWorkflowService, ILoggable
|
||||
{
|
||||
#region Fields
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IWorkflowRuntime _workflowRuntime;
|
||||
private readonly IWorkflowDefinitionService _workflowDefinitionService;
|
||||
private readonly IWorkflowInstanceVariableManager _workflowInstanceVariableManager;
|
||||
private readonly IWorkflowInstanceManager _workflowInstanceManager;
|
||||
private readonly IEventPublisher _eventPublisher;
|
||||
private readonly IMdbLogger<WorkflowService> _logger;
|
||||
#endregion
|
||||
|
||||
#region Ctor
|
||||
public WorkflowService(IServiceProvider serviceProvider,
|
||||
IMdbLogger<WorkflowService> logger)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_workflowRuntime = _serviceProvider.GetRequiredService<IWorkflowRuntime>();
|
||||
_workflowDefinitionService = _serviceProvider.GetRequiredService<IWorkflowDefinitionService>();
|
||||
_workflowInstanceVariableManager = _serviceProvider.GetRequiredService<IWorkflowInstanceVariableManager>();
|
||||
_workflowInstanceManager = _serviceProvider.GetRequiredService<IWorkflowInstanceManager>();
|
||||
_eventPublisher = _serviceProvider.GetRequiredService<IEventPublisher>();
|
||||
_logger = logger;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CreateAndExecuteAsync
|
||||
/// <inheritdoc />
|
||||
public async Task<WorkflowResponse<WorkflowModel>> CreateAndExecuteAsync(CreateAndExecuteWorkflowModel input)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Log("Start of CreateAndExecuteAsync", JsonConvert.SerializeObject(input));
|
||||
|
||||
WorkflowResponse<WorkflowModel> response;
|
||||
|
||||
var workflowClient = await _workflowRuntime.CreateClientAsync();
|
||||
|
||||
var definition = await _workflowDefinitionService
|
||||
.FindWorkflowDefinitionAsync(new WorkflowDefinitionFilter()
|
||||
{
|
||||
Name = input.Name
|
||||
});
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
var msg = $"Workflow '{input.Name}' defintion not found";
|
||||
response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 1,
|
||||
Message = msg,
|
||||
Data = null
|
||||
};
|
||||
|
||||
_logger.Log("End of CreateAndExecuteAsync", WFInstanceId: response.Data?.InstanceId, JsonConvert.SerializeObject(response));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
var instanceInput = new Dictionary<string, object> { ["UserId"] = input.UserId };
|
||||
input.Version = VersionOptions.Published;
|
||||
var newInstance = await workflowClient.CreateInstanceAsync(new CreateWorkflowInstanceRequest
|
||||
{
|
||||
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionId(definition.DefinitionId, input.Version),
|
||||
Input = instanceInput,
|
||||
ExternalUserId = input.UserId
|
||||
});
|
||||
|
||||
var result = await workflowClient.RunInstanceAsync(RunWorkflowInstanceRequest.Empty);
|
||||
|
||||
var variables = await _workflowInstanceVariableManager.GetVariablesAsync(result.WorkflowInstanceId);
|
||||
|
||||
// تبدیل به دیکشنری
|
||||
var dictionary = variables.ToDictionary(a => a.Variable.Name, a => a.Value);
|
||||
|
||||
var workflowModel = dictionary.ConvertToWorkflowModel();
|
||||
workflowModel.InstanceId = workflowClient.WorkflowInstanceId;
|
||||
workflowModel.UserId = input.UserId;
|
||||
|
||||
response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 0,
|
||||
Message = "Success",
|
||||
Data = workflowModel
|
||||
};
|
||||
|
||||
_logger.Log("End of CreateAndExecuteAsync", WFInstanceId: response.Data?.InstanceId, JsonConvert.SerializeObject(response));
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 100,
|
||||
Message = ex.Message,
|
||||
Data = null
|
||||
};
|
||||
|
||||
_logger.Log("Exception occurs in CreateAndExecuteAsync", WFInstanceId: response.Data?.InstanceId, JsonConvert.SerializeObject(response), ex);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublishEventAsync
|
||||
/// <inheritdoc />
|
||||
public async Task<WorkflowResponse<WorkflowModel>> PublishEventAsync(PublishEventModel input)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Log("Start of PublishEventAsync", WFInstanceId: input.WorkflowInstanceId, JsonConvert.SerializeObject(input));
|
||||
|
||||
WorkflowResponse<WorkflowModel> response;
|
||||
|
||||
var instance = await _workflowInstanceManager.FindByIdAsync(input.WorkflowInstanceId);
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
var msg = $"Workflow instance with id '{input.WorkflowInstanceId}' not found";
|
||||
response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 1,
|
||||
Message = msg,
|
||||
Data = null
|
||||
};
|
||||
|
||||
_logger.Log("End of PublishEventAsync", WFInstanceId: input.WorkflowInstanceId, JsonConvert.SerializeObject(response));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
await _eventPublisher.PublishAsync(input.EventName, null, input.WorkflowInstanceId, null, input.EventData);
|
||||
|
||||
var variables = await _workflowInstanceVariableManager.GetVariablesAsync(input.WorkflowInstanceId);
|
||||
|
||||
// تبدیل به دیکشنری
|
||||
var dictionary = variables.ToDictionary(a => a.Variable.Name, a => a.Value);
|
||||
|
||||
var workflowModel = dictionary.ConvertToWorkflowModel();
|
||||
workflowModel.InstanceId = instance.Id;
|
||||
workflowModel.UserId = instance.ExternalUserId;
|
||||
|
||||
response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 0,
|
||||
Message = "Success",
|
||||
Data = workflowModel
|
||||
};
|
||||
|
||||
_logger.Log("End of PublishEventAsync", WFInstanceId: input.WorkflowInstanceId, JsonConvert.SerializeObject(response));
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 100,
|
||||
Message = ex.Message,
|
||||
Data = null
|
||||
};
|
||||
|
||||
_logger.Log("Exception occurs in PublishEventAsync", WFInstanceId: input.WorkflowInstanceId, JsonConvert.SerializeObject(response), ex);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region InquiryStateAsync
|
||||
/// <inheritdoc />
|
||||
public async Task<WorkflowResponse<WorkflowModel>> InquiryStateAsync(InquiryStateModel input)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Log("Start of InquiryStateAsync", WFInstanceId: input.WorkflowInstanceId, JsonConvert.SerializeObject(input));
|
||||
|
||||
WorkflowResponse<WorkflowModel> response;
|
||||
|
||||
var instance = await _workflowInstanceManager.FindByIdAsync(input.WorkflowInstanceId);
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
var msg = $"Workflow instance with id '{input.WorkflowInstanceId}' not found";
|
||||
response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 1,
|
||||
Message = msg,
|
||||
Data = null
|
||||
};
|
||||
|
||||
_logger.Log("End of InquiryStateAsync", WFInstanceId: input.WorkflowInstanceId, JsonConvert.SerializeObject(response));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
var variables = await _workflowInstanceVariableManager.GetVariablesAsync(input.WorkflowInstanceId);
|
||||
|
||||
// تبدیل به دیکشنری
|
||||
var dictionary = variables.ToDictionary(a => a.Variable.Name, a => a.Value);
|
||||
|
||||
var workflowModel = dictionary.ConvertToWorkflowModel();
|
||||
workflowModel.InstanceId = instance.Id;
|
||||
workflowModel.UserId = instance.ExternalUserId;
|
||||
|
||||
response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 0,
|
||||
Message = "Success",
|
||||
Data = workflowModel
|
||||
};
|
||||
|
||||
_logger.Log("End of InquiryStateAsync", WFInstanceId: input.WorkflowInstanceId, JsonConvert.SerializeObject(response));
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var response = new WorkflowResponse<WorkflowModel>()
|
||||
{
|
||||
Status = 100,
|
||||
Message = ex.Message,
|
||||
Data = null
|
||||
};
|
||||
|
||||
_logger.Log("Exception occurs in InquiryStateAsync", WFInstanceId: input.WorkflowInstanceId, JsonConvert.SerializeObject(response), ex);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Caspian.WorkflowFramework.Models;
|
||||
|
||||
namespace Caspian.WorkflowFramework.Utility
|
||||
{
|
||||
public static class ConversionExtensions
|
||||
{
|
||||
public static WorkflowModel ConvertToWorkflowModel(this Dictionary<string, object?> dictionary)
|
||||
{
|
||||
var workflowModel = new WorkflowModel();
|
||||
|
||||
if (dictionary == null || dictionary.Count == 0)
|
||||
return workflowModel;
|
||||
|
||||
//Map dictionary values to WorkflowModel properties
|
||||
workflowModel.InstanceId = dictionary.ContainsKey(nameof(workflowModel.InstanceId))
|
||||
? dictionary[nameof(workflowModel.InstanceId)]?.ToString()
|
||||
: null;
|
||||
|
||||
workflowModel.Name = dictionary.ContainsKey(nameof(workflowModel.Name))
|
||||
? dictionary[nameof(workflowModel.Name)]?.ToString()
|
||||
: null;
|
||||
|
||||
workflowModel.IsComplete = dictionary.ContainsKey(nameof(workflowModel.IsComplete))
|
||||
? bool.TryParse(dictionary[nameof(workflowModel.IsComplete)]?.ToString(), out var isComplete) && isComplete
|
||||
: false;
|
||||
|
||||
workflowModel.UserId = dictionary.ContainsKey(nameof(workflowModel.UserId))
|
||||
? long.TryParse(dictionary[nameof(workflowModel.UserId)]?.ToString(), out var userId) ? userId : (long?)null
|
||||
: null;
|
||||
|
||||
//workflowModel.CurrentPageData = dictionary.ContainsKey(nameof(workflowModel.CurrentPageData))
|
||||
// ? (object?)dictionary[nameof(workflowModel.CurrentPageData)]
|
||||
// : null;
|
||||
|
||||
workflowModel.CurrentPageData = dictionary.ContainsKey(nameof(workflowModel.CurrentPageData))
|
||||
? dictionary[nameof(workflowModel.CurrentPageData)]?.ToString()
|
||||
: null;
|
||||
|
||||
//workflowModel.NextPageData = dictionary.ContainsKey(nameof(workflowModel.NextPageData))
|
||||
// ? (object?)dictionary[nameof(workflowModel.NextPageData)]
|
||||
// : null;
|
||||
|
||||
workflowModel.NextPageData = dictionary.ContainsKey(nameof(workflowModel.NextPageData))
|
||||
? dictionary[nameof(workflowModel.NextPageData)]?.ToString()
|
||||
: null;
|
||||
|
||||
workflowModel.NextPageUrl = dictionary.ContainsKey(nameof(workflowModel.NextPageUrl))
|
||||
? dictionary[nameof(workflowModel.NextPageUrl)]?.ToString()
|
||||
: null;
|
||||
|
||||
workflowModel.NextPageEventName = dictionary.ContainsKey(nameof(workflowModel.NextPageEventName))
|
||||
? dictionary[nameof(workflowModel.NextPageEventName)]?.ToString()
|
||||
: null;
|
||||
|
||||
return workflowModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
@@ -0,0 +1 @@
|
||||
nuget pack Caspian.WorkflowFramework.nuspec -IncludeReferencedProjects
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,37 @@
|
||||
# Caspian.WorkflowFramework
|
||||
|
||||
Caspian workflow framework
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
install-package Caspian.WorkflowFramework
|
||||
```
|
||||
|
||||
## Usage Example
|
||||
In your Program.cs :
|
||||
```csharp
|
||||
//Workflow
|
||||
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
||||
builder.AddWorkflowFramework(connectionString);
|
||||
|
||||
//Mongo
|
||||
builder.Services.AddMongoLogger<LogModel>(builder.Configuration);
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
//Mongo
|
||||
app.UseMongoLogger<LogModel>();
|
||||
|
||||
//Workflow
|
||||
app.UseWorkflowFramework();
|
||||
```
|
||||
Then use service "WorkflowService"
|
||||
|
||||
## Features
|
||||
- Start new instance of every workflow
|
||||
- Publish event and get next step information
|
||||
- Get last status of workflow instance
|
||||
|
||||
## Version History
|
||||
### 1.0.0-alfa
|
||||
- Initial prerelease
|
||||
Reference in New Issue
Block a user