From 9036156709ceeac92c7bd5e8efb8ff4d61e0453e Mon Sep 17 00:00:00 2001 From: Behzad Alizadeh Date: Mon, 25 Aug 2025 23:57:23 +0330 Subject: [PATCH] Generate package Caspian.WorkflowFramework.1.1.0-preview.1.nupkg --- .../Caspian.WorkflowFramework.Package.csproj | 116 +++++------ .../Config/DependencyInjection.cs | 184 ++++++++++++++---- .../Enums/ApplicationRole.cs | 9 + .../Enums/DistributedCachingTransport.cs | 12 ++ .../Enums/MassTransitBroker.cs | 11 ++ .../Enums/PersistenceProvider.cs | 9 + .../Enums/SqlDatabaseProvider.cs | 13 ++ .../Enums/WorkflowRuntime.cs | 8 + .../Messages/OrderReceived.cs | 6 + .../Utility/StaticCheckListOptionsProvider.cs | 22 +++ NuGet.Config | 15 +- SampleWorkflowWeb/appsettings.json | 2 +- 12 files changed, 288 insertions(+), 119 deletions(-) create mode 100644 Caspian.WorkflowFramework.Package/Enums/ApplicationRole.cs create mode 100644 Caspian.WorkflowFramework.Package/Enums/DistributedCachingTransport.cs create mode 100644 Caspian.WorkflowFramework.Package/Enums/MassTransitBroker.cs create mode 100644 Caspian.WorkflowFramework.Package/Enums/PersistenceProvider.cs create mode 100644 Caspian.WorkflowFramework.Package/Enums/SqlDatabaseProvider.cs create mode 100644 Caspian.WorkflowFramework.Package/Enums/WorkflowRuntime.cs create mode 100644 Caspian.WorkflowFramework.Package/Messages/OrderReceived.cs create mode 100644 Caspian.WorkflowFramework.Package/Utility/StaticCheckListOptionsProvider.cs diff --git a/Caspian.WorkflowFramework.Package/Caspian.WorkflowFramework.Package.csproj b/Caspian.WorkflowFramework.Package/Caspian.WorkflowFramework.Package.csproj index 4fc1a11..b8be202 100644 --- a/Caspian.WorkflowFramework.Package/Caspian.WorkflowFramework.Package.csproj +++ b/Caspian.WorkflowFramework.Package/Caspian.WorkflowFramework.Package.csproj @@ -5,7 +5,7 @@ enable enable Caspian.WorkflowFramework - 1.0.1-preview.3 + 1.1.0-preview.1 Digital banking team Caspian Caspian.WorkflowFramework @@ -20,72 +20,58 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/Caspian.WorkflowFramework.Package/Config/DependencyInjection.cs b/Caspian.WorkflowFramework.Package/Config/DependencyInjection.cs index bbea838..304de4d 100644 --- a/Caspian.WorkflowFramework.Package/Config/DependencyInjection.cs +++ b/Caspian.WorkflowFramework.Package/Config/DependencyInjection.cs @@ -1,14 +1,33 @@ 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.Caching.Options; +using Elsa.Common.RecurringTasks; +using Elsa.Common.Serialization; using Elsa.EntityFrameworkCore.Extensions; +using Elsa.EntityFrameworkCore.Modules.Alterations; +using Elsa.EntityFrameworkCore.Modules.Identity; using Elsa.EntityFrameworkCore.Modules.Management; using Elsa.EntityFrameworkCore.Modules.Runtime; -using Elsa.EntityFrameworkCore.Modules.Identity; -using Elsa.Email; +using Elsa.EntityFrameworkCore.Modules.Tenants; +using Elsa.Extensions; +using Elsa.Kafka.Factories; +using Elsa.OpenTelemetry.Middleware; +using Elsa.Secrets.Management.Tasks; +using Elsa.Secrets.Persistence; +using Elsa.Server.Web; +using Elsa.Server.Web.Messages; +using Elsa.Workflows; +using Elsa.Workflows.IncidentStrategies; +using Elsa.Workflows.LogPersistence; +using Elsa.Workflows.Management; +using Elsa.Workflows.Options; +using Elsa.Workflows.Runtime.Distributed.Extensions; +using Elsa.Workflows.Runtime.Options; +using Elsa.Workflows.Runtime.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using San.MongoLogger; using San.MongoLogger.Models; @@ -16,57 +35,144 @@ namespace Caspian.WorkflowFramework; public static class DependencyInjection { - public static void AddWorkflowFramework(this IHostApplicationBuilder builder, string connectionString) + public static void AddWorkflowFramework(this IHostApplicationBuilder builder, string sqlServerConnectionString) { + //var configuration = new ConfigurationBuilder() + // .AddJsonFile(appsettingName, optional: false, reloadOnChange: true) + // .Build(); + //var sqlServerConnectionString = configuration.GetConnectionString("SqlServer")!; + + var sqlDatabaseProvider = Enum.Parse("SqlServer"); + const bool useDbContextPooling = false; + const bool runEFCoreMigrations = true; + const bool useCaching = true; + const bool useReadOnlyMode = false; + const WorkflowRuntime workflowRuntime = WorkflowRuntime.Distributed; + const bool disableVariableWrappers = false; + const bool disableVariableCopying = false; + + // Optionally create type aliases for easier configuration. + TypeAliasRegistry.RegisterAlias("OrderReceivedProducerFactory", typeof(GenericProducerFactory)); + TypeAliasRegistry.RegisterAlias("OrderReceivedConsumerFactory", typeof(GenericConsumerFactory)); + + // Add Elsa services. + builder.Services.AddScoped(); + builder.Services.AddMongoLogger(builder.Configuration); builder.Services.AddElsa(elsa => { - // Configure Management layer to use EF Core. - elsa.UseWorkflowManagement(management => management - .UseEntityFrameworkCore(ef => ef.UseSqlServer(connectionString))); + elsa + .UseWorkflows(workflows => + { + 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 => + { + management.UseEntityFrameworkCore(ef => + { + ef.UseSqlServer(sqlServerConnectionString); + }); - // Configure Runtime layer to use EF Core. - elsa.UseWorkflowRuntime(runtime => runtime - .UseEntityFrameworkCore(ef => ef.UseSqlServer(connectionString))); + if (useCaching) + management.UseCache(); - // Expose Elsa API endpoints. - elsa.UseWorkflowsApi(); + management.SetDefaultLogPersistenceMode(LogPersistenceMode.Inherit); + management.UseReadOnlyMode(useReadOnlyMode); + management.AddVariableTypeAndAlias("Application"); + }) + .UseWorkflowRuntime(runtime => + { + runtime.UseEntityFrameworkCore(ef => + { + ef.UseContextPooling = useDbContextPooling; - // Enable C# workflow expressions - elsa.UseCSharp(); + var migrationsAssembly = typeof(Elsa.EntityFrameworkCore.SqlServer.IdentityDbContextFactory).Assembly; + var connectionString = sqlServerConnectionString; + ef.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(migrationsAssembly, connectionString, null, configure => configure.CommandTimeout(60000)); - // Enable JavaScript workflow expressions - elsa.UseJavaScript(options => options.AllowClrAccess = true); + ef.RunMigrations = runEFCoreMigrations; + }); + + if (workflowRuntime == WorkflowRuntime.Distributed) + { + runtime.UseDistributedRuntime(); + } + + if (useCaching) + runtime.UseCache(); + }) + .UseCSharp(options => + { + options.DisableWrappers = disableVariableWrappers; + //options.AppendScript("string Greet(string name) => $\"Hello {name}!\";"); + //options.AppendScript("string SayHelloWorld() => Greet(\"World\");"); + }) + .UseJavaScript(options => + { + options.AllowClrAccess = true; + options.DisableWrappers = disableVariableWrappers; + options.DisableVariableCopying = disableVariableCopying; + options.RegisterType(); + //options.ConfigureEngine(engine => + //{ + // engine.Execute("function greet(name) { return `Hello ${name}!`; }"); + // engine.Execute("function sayHelloWorld() { return greet('World'); }"); + //}); + }) + .UseWorkflowContexts(); + + //elsa.AddFastEndpointsAssembly(); }); - //// 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. + // Optionally configure recurring tasks using alternative schedules. + builder.Services.Configure(options => + { + options.Schedule.ConfigureTask(TimeSpan.FromSeconds(300)); + options.Schedule.ConfigureTask(TimeSpan.FromSeconds(300)); + options.Schedule.ConfigureTask(TimeSpan.FromHours(4)); + options.Schedule.ConfigureTask(TimeSpan.FromSeconds(15)); + }); - - // Add Health Checks. - builder.Services.AddHealthChecks(); + builder.Services.Configure(options => { options.InactivityThreshold = TimeSpan.FromSeconds(15); }); + builder.Services.Configure(options => options.Ttl = TimeSpan.FromSeconds(10)); + builder.Services.Configure(options => options.CacheDuration = TimeSpan.FromDays(1)); + builder.Services.Configure(options => options.DefaultIncidentStrategy = typeof(ContinueWithIncidentsStrategy)); + //builder.Services.AddHealthChecks(); builder.Services.AddScoped(); } public static void UseWorkflowFramework(this IApplicationBuilder app) { - try - { - app.UseMongoLogger(); - } - catch (Exception ex) - { - var d = ex; - } + //try + //{ + // app.UseMongoLogger(); + //} + //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. + // Configure the pipeline. + var env = app.ApplicationServices.GetRequiredService(); + if (env.IsDevelopment()) + app.UseDeveloperExceptionPage(); + + // Health checks. + //app.MapHealthChecks("/"); + + // Captures unhandled exceptions and returns a JSON response. + app.UseJsonSerializationErrorHandler(); + + //app.UseWorkflows(); } } + diff --git a/Caspian.WorkflowFramework.Package/Enums/ApplicationRole.cs b/Caspian.WorkflowFramework.Package/Enums/ApplicationRole.cs new file mode 100644 index 0000000..a4e8c7c --- /dev/null +++ b/Caspian.WorkflowFramework.Package/Enums/ApplicationRole.cs @@ -0,0 +1,9 @@ +namespace Elsa.Server.Web; + +public enum ApplicationRole +{ + Default, + Api, + Worker, + Monitor +} diff --git a/Caspian.WorkflowFramework.Package/Enums/DistributedCachingTransport.cs b/Caspian.WorkflowFramework.Package/Enums/DistributedCachingTransport.cs new file mode 100644 index 0000000..5a5a6a8 --- /dev/null +++ b/Caspian.WorkflowFramework.Package/Enums/DistributedCachingTransport.cs @@ -0,0 +1,12 @@ +namespace Elsa.Server.Web; + +/// +/// Represents the transport options for distributed caching. +/// +public enum DistributedCachingTransport +{ + None, + Memory, + MassTransit, + ProtoActor +} \ No newline at end of file diff --git a/Caspian.WorkflowFramework.Package/Enums/MassTransitBroker.cs b/Caspian.WorkflowFramework.Package/Enums/MassTransitBroker.cs new file mode 100644 index 0000000..d4ad98f --- /dev/null +++ b/Caspian.WorkflowFramework.Package/Enums/MassTransitBroker.cs @@ -0,0 +1,11 @@ +namespace Elsa.Server.Web; + +/// +/// Represents the type of messaging broker used in MassTransit. +/// +public enum MassTransitBroker +{ + Memory, + AzureServiceBus, + RabbitMq +} \ No newline at end of file diff --git a/Caspian.WorkflowFramework.Package/Enums/PersistenceProvider.cs b/Caspian.WorkflowFramework.Package/Enums/PersistenceProvider.cs new file mode 100644 index 0000000..31e3e33 --- /dev/null +++ b/Caspian.WorkflowFramework.Package/Enums/PersistenceProvider.cs @@ -0,0 +1,9 @@ +namespace Elsa.Server.Web; + +public enum PersistenceProvider +{ + Memory, + EntityFrameworkCore, + MongoDb, + Dapper +} \ No newline at end of file diff --git a/Caspian.WorkflowFramework.Package/Enums/SqlDatabaseProvider.cs b/Caspian.WorkflowFramework.Package/Enums/SqlDatabaseProvider.cs new file mode 100644 index 0000000..72aad1b --- /dev/null +++ b/Caspian.WorkflowFramework.Package/Enums/SqlDatabaseProvider.cs @@ -0,0 +1,13 @@ +namespace Elsa.Server.Web; + +public enum SqlDatabaseProvider +{ + SqlServer, + Sqlite, + MySql, + PostgreSql, + Citus, + YugabyteDb, + Oracle, + CockroachDb +} \ No newline at end of file diff --git a/Caspian.WorkflowFramework.Package/Enums/WorkflowRuntime.cs b/Caspian.WorkflowFramework.Package/Enums/WorkflowRuntime.cs new file mode 100644 index 0000000..07bed54 --- /dev/null +++ b/Caspian.WorkflowFramework.Package/Enums/WorkflowRuntime.cs @@ -0,0 +1,8 @@ +namespace Elsa.Server.Web; + +public enum WorkflowRuntime +{ + Default, + Distributed, + ProtoActor +} \ No newline at end of file diff --git a/Caspian.WorkflowFramework.Package/Messages/OrderReceived.cs b/Caspian.WorkflowFramework.Package/Messages/OrderReceived.cs new file mode 100644 index 0000000..32151ae --- /dev/null +++ b/Caspian.WorkflowFramework.Package/Messages/OrderReceived.cs @@ -0,0 +1,6 @@ +namespace Elsa.Server.Web.Messages; + +public class OrderReceived +{ + public string OrderId { get; set; } = null!; +} \ No newline at end of file diff --git a/Caspian.WorkflowFramework.Package/Utility/StaticCheckListOptionsProvider.cs b/Caspian.WorkflowFramework.Package/Utility/StaticCheckListOptionsProvider.cs new file mode 100644 index 0000000..4154b94 --- /dev/null +++ b/Caspian.WorkflowFramework.Package/Utility/StaticCheckListOptionsProvider.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using Elsa.Workflows.UIHints.CheckList; + +namespace Elsa.Server.Web; + +/// +/// Provides static drop-down options for a given property. +/// +public class CustomCheckListOptionsProvider : CheckListOptionsProviderBase +{ + /// + protected override ValueTask> GetItemsAsync(PropertyInfo propertyInfo, object? context, CancellationToken cancellationToken) + { + var items = new[] + { + "Apple", "Banana", "Cherry" + }; + var selectListItems = items.Select(x => new CheckListItem(x, x)).ToList(); + + return new(selectListItems); + } +} \ No newline at end of file diff --git a/NuGet.Config b/NuGet.Config index 3157717..b1fd412 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -7,19 +7,6 @@ + - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SampleWorkflowWeb/appsettings.json b/SampleWorkflowWeb/appsettings.json index a3e8a6b..e908329 100644 --- a/SampleWorkflowWeb/appsettings.json +++ b/SampleWorkflowWeb/appsettings.json @@ -7,7 +7,7 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - "DefaultConnection": "Data Source=.;Initial Catalog=WorkflowFrameworkTest;User ID=sa;Password=123456;Integrated Security=false;TrustServerCertificate=True;" + "DefaultConnection": "Data Source=.;Initial Catalog=WfDb;User ID=sa;Password=123456;Integrated Security=false;TrustServerCertificate=True;" }, "LogDatabaseSettings": { "LogsCollectionName": "TestWorkflowCollection",