Files

192 lines
8.0 KiB
C#

using Caspian.WorkflowFramework.Contracts;
using Caspian.WorkflowFramework.Services;
using Elsa.Caching.Options;
using Elsa.Caching.Features;
using Microsoft.Extensions.Configuration;
using Caspian.WorkflowFramework.Config;
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.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;
namespace Caspian.WorkflowFramework;
public static class DependencyInjection
{
public static void AddWorkflowFramework(this IHostApplicationBuilder builder, string sqlServerConnectionString)
=> builder.AddWorkflowFramework(sqlServerConnectionString, null);
public static void AddWorkflowFramework(this IHostApplicationBuilder builder, string sqlServerConnectionString,
Action<CacheFeature>? configureCache)
{
//var configuration = new ConfigurationBuilder()
// .AddJsonFile(appsettingName, optional: false, reloadOnChange: true)
// .Build();
//var sqlServerConnectionString = configuration.GetConnectionString("SqlServer")!;
var sqlDatabaseProvider = Enum.Parse<SqlDatabaseProvider>("SqlServer");
const bool useDbContextPooling = false;
const bool runEFCoreMigrations = 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<string, OrderReceived>));
TypeAliasRegistry.RegisterAlias("OrderReceivedConsumerFactory", typeof(GenericConsumerFactory<string, OrderReceived>));
// Add Elsa services.
builder.Services.AddScoped<IPropertyUIHandler, CustomCheckListOptionsProvider>();
builder.Services.AddMongoLogger<LogModel>(builder.Configuration);
builder.Services.AddElsa(elsa =>
{
elsa
.UseCaching(cache =>
{
cache.Duration = TimeSpan.FromDays(1);
cache.RegisterRedis();
cache.UseConfiguration(builder.Configuration.GetSection("Workflow:Cache"));
configureCache?.Invoke(cache);
})
.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);
});
management.UseCache();
management.SetDefaultLogPersistenceMode(LogPersistenceMode.Inherit);
management.UseReadOnlyMode(useReadOnlyMode);
management.AddVariableTypeAndAlias<OrderReceived>("Application");
})
.UseWorkflowRuntime(runtime =>
{
runtime.UseEntityFrameworkCore(ef =>
{
ef.UseContextPooling = useDbContextPooling;
var migrationsAssembly = typeof(Elsa.EntityFrameworkCore.SqlServer.IdentityDbContextFactory).Assembly;
var connectionString = sqlServerConnectionString;
ef.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(migrationsAssembly, connectionString, null, configure => configure.CommandTimeout(60000));
ef.RunMigrations = runEFCoreMigrations;
});
if (workflowRuntime == WorkflowRuntime.Distributed)
{
runtime.UseDistributedRuntime();
}
runtime.UseCache();
runtime.UseConfiguredDistributedLocking(builder.Configuration);
})
.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<OrderReceived>();
//options.ConfigureEngine(engine =>
//{
// engine.Execute("function greet(name) { return `Hello ${name}!`; }");
// engine.Execute("function sayHelloWorld() { return greet('World'); }");
//});
})
// برای ثبت Activityهایی مانند Elsa.SendHttpRequest
.UseHttp(http => http.UseCache())
.UseWorkflowContexts();
});
// Optionally configure recurring tasks using alternative schedules.
builder.Services.Configure<RecurringTaskOptions>(options =>
{
options.Schedule.ConfigureTask<TriggerBookmarkQueueRecurringTask>(TimeSpan.FromSeconds(300));
options.Schedule.ConfigureTask<PurgeBookmarkQueueRecurringTask>(TimeSpan.FromSeconds(300));
options.Schedule.ConfigureTask<UpdateExpiredSecretsRecurringTask>(TimeSpan.FromHours(4));
options.Schedule.ConfigureTask<RestartInterruptedWorkflowsTask>(TimeSpan.FromSeconds(15));
});
builder.Services.Configure<RuntimeOptions>(options => { options.InactivityThreshold = TimeSpan.FromSeconds(15); });
builder.Services.Configure<BookmarkQueuePurgeOptions>(options => options.Ttl = TimeSpan.FromSeconds(10));
builder.Services.Configure<IncidentOptions>(options => options.DefaultIncidentStrategy = typeof(ContinueWithIncidentsStrategy));
//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;
//}
// Configure the pipeline.
var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
// Health checks.
//app.MapHealthChecks("/");
// Captures unhandled exceptions and returns a JSON response.
app.UseJsonSerializationErrorHandler();
app.UseWorkflows();
}
}