Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<PackageVersion Include="Elsa.Workflows.Management" Version="$(ElsaVersion)"/>
<PackageVersion Include="Elsa.Workflows.Runtime" Version="$(ElsaVersion)"/>
<PackageVersion Include="Elsa.Workflows.Runtime.Distributed" Version="$(ElsaVersion)"/>
<PackageVersion Include="Elsa.PackageManifest.Generator" Version="0.0.1-preview.41"/>
<PackageVersion Include="Microsoft.Agents.AI" Version="1.0.0-preview.260212.1"/>
</ItemGroup>
<ItemGroup Label="Elsa Studio">
Expand Down
6 changes: 5 additions & 1 deletion src/modules/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
</ItemGroup>

</Project>
<ItemGroup Condition="Exists('$(MSBuildProjectDirectory)/ShellFeatures')">
<PackageReference Include="Elsa.PackageManifest.Generator" PrivateAssets="all" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CShells.Features;
using Elsa.PackageManifest.Generator.Hints;
using Hangfire;
using Hangfire.MemoryStorage;
using JetBrains.Annotations;
Expand All @@ -16,8 +17,25 @@ namespace Elsa.Scheduling.Hangfire.ShellFeatures;
[UsedImplicitly]
public class HangfireShellFeature : IShellFeature
{
[ManifestSetting(
DisplayName = "Use memory storage",
Description = "Use Hangfire's in-memory storage provider.",
Category = "Storage",
RestartRequired = true)]
public bool UseMemoryStorage { get; set; } = true;

[ManifestSetting(
DisplayName = "Worker count",
Description = "The number of Hangfire worker threads to run.",
Category = "Workers",
RestartRequired = true)]
public int WorkerCount { get; set; } = 1;

[ManifestSetting(
DisplayName = "Schedule polling interval",
Description = "The Hangfire schedule polling interval in seconds.",
Category = "Scheduling",
RestartRequired = true)]
public int SchedulePollingIntervalSeconds { get; set; } = 1;

public void ConfigureServices(IServiceCollection services)
Expand All @@ -38,4 +56,3 @@ public void ConfigureServices(IServiceCollection services)
});
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CShells.Features;
using CShells.Lifecycle;
using Elsa.PackageManifest.Generator.Hints;
using Elsa.Scheduling.Quartz.EFCore.MySql;
using Elsa.Scheduling.Quartz.ShellFeatures;
using JetBrains.Annotations;
Expand All @@ -17,15 +18,35 @@ namespace Elsa.Scheduling.Quartz.EFCore.MySql.ShellFeatures;
Description = "Configures Quartz.NET to persist jobs and triggers in MySQL",
DependsOn = [typeof(QuartzSchedulerFeature)])]
[UsedImplicitly]
[ManifestInfrastructure("mysql-database", "database", Reason = "Stores Quartz scheduler data in MySQL.", Providers = new[] { "MySQL" }, ConfigurationKeys = new[] { "ConnectionString" })]
public class QuartzMySqlFeature : IShellFeature
{
/// <summary>The MySQL connection string.</summary>
[ManifestSetting(
DisplayName = "Connection string",
Description = "The MySQL connection string used by the Quartz persistent job store.",
Category = "Persistence",
Secret = true,
Required = true,
HasRequired = true,
RestartRequired = true)]
public string ConnectionString { get; set; } = "Server=localhost;Database=quartz;User=root;Password=root;";

/// <summary>Enable Quartz clustering. Defaults to <c>true</c>.</summary>
[ManifestSetting(
DisplayName = "Use clustering",
Description = "Enable Quartz clustering.",
Category = "Persistence",
RestartRequired = true)]
public bool UseClustering { get; set; } = true;

/// <summary>Use a pooled <c>IDbContextFactory</c>. Defaults to <c>false</c>.</summary>
[ManifestSetting(
DisplayName = "Use context pooling",
Description = "Use a pooled EF Core IDbContextFactory.",
Category = "Persistence",
Advanced = true,
RestartRequired = true)]
public bool UseContextPooling { get; set; }

public void ConfigureServices(IServiceCollection services)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CShells.Features;
using CShells.Lifecycle;
using Elsa.PackageManifest.Generator.Hints;
using Elsa.Scheduling.Quartz.EFCore.PostgreSql;
using Elsa.Scheduling.Quartz.ShellFeatures;
using JetBrains.Annotations;
Expand All @@ -17,15 +18,35 @@ namespace Elsa.Scheduling.Quartz.EFCore.PostgreSql.ShellFeatures;
Description = "Configures Quartz.NET to persist jobs and triggers in PostgreSQL",
DependsOn = [typeof(QuartzSchedulerFeature)])]
[UsedImplicitly]
[ManifestInfrastructure("postgresql-database", "database", Reason = "Stores Quartz scheduler data in PostgreSQL.", Providers = new[] { "PostgreSQL" }, ConfigurationKeys = new[] { "ConnectionString" })]
public class QuartzPostgreSqlFeature : IShellFeature
{
/// <summary>The PostgreSQL connection string.</summary>
[ManifestSetting(
DisplayName = "Connection string",
Description = "The PostgreSQL connection string used by the Quartz persistent job store.",
Category = "Persistence",
Secret = true,
Required = true,
HasRequired = true,
RestartRequired = true)]
public string ConnectionString { get; set; } = "Host=localhost;Database=quartz;Username=postgres;Password=postgres";

/// <summary>Enable Quartz clustering. Defaults to <c>true</c>.</summary>
[ManifestSetting(
DisplayName = "Use clustering",
Description = "Enable Quartz clustering.",
Category = "Persistence",
RestartRequired = true)]
public bool UseClustering { get; set; } = true;

/// <summary>Use a pooled <c>IDbContextFactory</c>. Defaults to <c>false</c>.</summary>
[ManifestSetting(
DisplayName = "Use context pooling",
Description = "Use a pooled EF Core IDbContextFactory.",
Category = "Persistence",
Advanced = true,
RestartRequired = true)]
public bool UseContextPooling { get; set; }

public void ConfigureServices(IServiceCollection services)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CShells.Features;
using CShells.Lifecycle;
using Elsa.PackageManifest.Generator.Hints;
using Elsa.Scheduling.Quartz.EFCore.SqlServer;
using Elsa.Scheduling.Quartz.ShellFeatures;
using JetBrains.Annotations;
Expand All @@ -17,15 +18,35 @@ namespace Elsa.Scheduling.Quartz.EFCore.SqlServer.ShellFeatures;
Description = "Configures Quartz.NET to persist jobs and triggers in SQL Server",
DependsOn = [typeof(QuartzSchedulerFeature)])]
[UsedImplicitly]
[ManifestInfrastructure("sqlserver-database", "database", Reason = "Stores Quartz scheduler data in SQL Server.", Providers = new[] { "SQL Server" }, ConfigurationKeys = new[] { "ConnectionString" })]
public class QuartzSqlServerFeature : IShellFeature
{
/// <summary>The SQL Server connection string.</summary>
[ManifestSetting(
DisplayName = "Connection string",
Description = "The SQL Server connection string used by the Quartz persistent job store.",
Category = "Persistence",
Secret = true,
Required = true,
HasRequired = true,
RestartRequired = true)]
public string ConnectionString { get; set; } = "Server=localhost;Database=Quartz;Trusted_Connection=True;";

/// <summary>Enable Quartz clustering. Defaults to <c>true</c>.</summary>
[ManifestSetting(
DisplayName = "Use clustering",
Description = "Enable Quartz clustering.",
Category = "Persistence",
RestartRequired = true)]
public bool UseClustering { get; set; } = true;

/// <summary>Use a pooled <c>IDbContextFactory</c>. Defaults to <c>false</c>.</summary>
[ManifestSetting(
DisplayName = "Use context pooling",
Description = "Use a pooled EF Core IDbContextFactory.",
Category = "Persistence",
Advanced = true,
RestartRequired = true)]
public bool UseContextPooling { get; set; }

public void ConfigureServices(IServiceCollection services)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CShells.Features;
using CShells.Lifecycle;
using Elsa.PackageManifest.Generator.Hints;
using Elsa.Scheduling.Quartz.EFCore.Sqlite;
using Elsa.Scheduling.Quartz.ShellFeatures;
using JetBrains.Annotations;
Expand All @@ -17,18 +18,39 @@ namespace Elsa.Scheduling.Quartz.EFCore.Sqlite.ShellFeatures;
Description = "Configures Quartz.NET to persist jobs and triggers in SQLite",
DependsOn = [typeof(QuartzSchedulerFeature)])]
[UsedImplicitly]
[ManifestInfrastructure("sqlite-database", "database", Reason = "Stores Quartz scheduler data in SQLite.", Providers = new[] { "SQLite" }, ConfigurationKeys = new[] { "ConnectionString" })]
public class QuartzSqliteFeature : IShellFeature, IPostConfigureShellServices
{
/// <summary>The SQLite connection string.</summary>
[ManifestSetting(
DisplayName = "Connection string",
Description = "The SQLite connection string used by the Quartz persistent job store.",
Category = "Persistence",
Secret = true,
Required = true,
HasRequired = true,
RestartRequired = true)]
public string ConnectionString { get; set; } = "Data Source=quartz.db";

/// <summary>
/// Enable Quartz clustering. Defaults to <c>false</c> — SQLite does not
/// support true multi-node clustering.
/// </summary>
[ManifestSetting(
DisplayName = "Use clustering",
Description = "Enable Quartz clustering. SQLite does not support true multi-node clustering.",
Category = "Persistence",
Advanced = true,
RestartRequired = true)]
public bool UseClustering { get; set; }

/// <summary>Use a pooled <c>IDbContextFactory</c>. Defaults to <c>false</c>.</summary>
[ManifestSetting(
DisplayName = "Use context pooling",
Description = "Use a pooled EF Core IDbContextFactory.",
Category = "Persistence",
Advanced = true,
RestartRequired = true)]
public bool UseContextPooling { get; set; }

public void ConfigureServices(IServiceCollection services)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CShells.Features;
using CShells.Lifecycle;
using Elsa.PackageManifest.Generator.Hints;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
Expand All @@ -18,21 +19,42 @@ public class QuartzFeature : IShellFeature, IPostConfigureShellServices
/// <summary>
/// Optional delay before the scheduler begins processing jobs after shell activation.
/// </summary>
[ManifestSetting(
DisplayName = "Start delay",
Description = "Optional delay before the scheduler begins processing jobs after shell activation.",
Category = "Scheduler",
Advanced = true,
RestartRequired = true)]
public TimeSpan? StartDelay { get; set; }

/// <summary>
/// Whether to wait for running jobs to complete before the scheduler shuts down on
/// shell deactivation. Defaults to <c>true</c>.
/// </summary>
[ManifestSetting(
DisplayName = "Wait for jobs to complete",
Description = "Wait for running jobs to complete before the scheduler shuts down on shell deactivation.",
Category = "Scheduler",
RestartRequired = true)]
public bool WaitForJobsToComplete { get; set; } = true;

/// <summary>
/// The Quartz scheduler instance ID. Use <c>"AUTO"</c> (default) for automatic
/// generation, which is required for clustering.
/// </summary>
[ManifestSetting(
DisplayName = "Scheduler ID",
Description = "The Quartz scheduler instance ID. Use AUTO for automatic generation, which is required for clustering.",
Category = "Scheduler",
RestartRequired = true)]
public string SchedulerId { get; set; } = "AUTO";

/// <summary>The Quartz scheduler name. Defaults to <c>"ElsaScheduler"</c>.</summary>
[ManifestSetting(
DisplayName = "Scheduler name",
Description = "The Quartz scheduler name.",
Category = "Scheduler",
RestartRequired = true)]
public string SchedulerName { get; set; } = "ElsaScheduler";

public void ConfigureServices(IServiceCollection services)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ namespace Elsa.Scheduling.Quartz.ShellFeatures;
/// <summary>
/// A feature that installs Quartz.NET implementations for <see cref="IWorkflowScheduler"/>.
/// </summary>
[ShellFeature(DependsOn = [
[ShellFeature(
DisplayName = "Quartz Workflow Scheduler",
Description = "Uses Quartz.NET to schedule workflow execution.",
DependsOn = [
typeof(QuartzFeature),
typeof(SchedulingFeature),
typeof(ResilienceFeature)])]
Expand All @@ -34,4 +37,4 @@ public void ConfigureServices(IServiceCollection services)
.AddSingleton<ICronParser, QuartzCronParser>()
.AddQuartz();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CShells.Features;
using Elsa.PackageManifest.Generator.Hints;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -11,8 +12,17 @@ namespace Elsa.ServiceBus.AzureServiceBus.ShellFeatures;
DisplayName = "Azure Service Bus",
Description = "Enables Azure Service Bus for message publishing and handling")]
[UsedImplicitly]
[ManifestInfrastructure("azure-service-bus", "service-bus", Reason = "Publishes and consumes workflow messages through Azure Service Bus.", Providers = new[] { "Azure Service Bus" }, ConfigurationKeys = new[] { "ConnectionStringOrName" })]
public class AzureServiceBusShellFeature : IShellFeature
{
[ManifestSetting(
DisplayName = "Connection string or name",
Description = "The Azure Service Bus connection string or configured connection string name.",
Category = "Connection",
Secret = true,
Required = true,
HasRequired = true,
RestartRequired = true)]
public string ConnectionStringOrName { get; set; } = string.Empty;

public void ConfigureServices(IServiceCollection services)
Expand All @@ -22,4 +32,3 @@ public void ConfigureServices(IServiceCollection services)
.Configure(options => options.ConnectionStringOrName = ConnectionStringOrName);
}
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CShells.Features;
using Elsa.PackageManifest.Generator.Hints;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -11,9 +12,15 @@ namespace Elsa.ServiceBus.Kafka.ShellFeatures;
DisplayName = "Kafka Service Bus",
Description = "Enables Apache Kafka for message publishing and handling")]
[UsedImplicitly]
[ManifestInfrastructure("kafka-broker", "message-broker", Reason = "Publishes and consumes workflow messages through Apache Kafka.", Providers = new[] { "Apache Kafka" }, ConfigurationKeys = new[] { "WorkflowInstanceIdHeaderKey" })]
public class KafkaShellFeature : IShellFeature
{
public string WorkflowInstanceIdHeaderKey { get; set; } = "localhost:9092";
[ManifestSetting(
DisplayName = "Workflow instance ID header key",
Description = "The Kafka message header key used to carry the workflow instance ID.",
Category = "Headers",
RestartRequired = true)]
public string WorkflowInstanceIdHeaderKey { get; set; } = "x-workflow-instance-id";

public void ConfigureServices(IServiceCollection services)
{
Expand All @@ -25,4 +32,3 @@ public void ConfigureServices(IServiceCollection services)
});
}
}

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Azure.Messaging.ServiceBus.Administration;
using CShells.Configuration;
using CShells.Features;
using Elsa.PackageManifest.Generator.Hints;
using Elsa.ServiceBus.MassTransit.AzureServiceBus.Configurators;
using Elsa.ServiceBus.MassTransit.AzureServiceBus.Handlers;
using Elsa.ServiceBus.MassTransit.AzureServiceBus.HostedServices;
Expand Down Expand Up @@ -30,12 +31,19 @@ namespace Elsa.ServiceBus.MassTransit.AzureServiceBus.ShellFeatures;
Description = "Configures MassTransit to use Azure Service Bus as the message transport",
DependsOn = [typeof(MassTransitFeature)])]
[UsedImplicitly]
[ManifestInfrastructure("azure-service-bus", "service-bus", Reason = "Configures MassTransit to use Azure Service Bus as its transport.", Providers = new[] { "Azure Service Bus" }, ConfigurationKeys = new[] { "MassTransitAzureServiceBus:ConnectionStringOrName", "MassTransitAzureServiceBusCleanup" })]
public class MassTransitAzureServiceBusFeature : IShellFeature
{
/// <summary>
/// When <c>true</c>, registers a hosted service that periodically removes orphaned
/// subscriptions whose connected queues no longer exist.
/// </summary>
[ManifestSetting(
DisplayName = "Enable automated subscription cleanup",
Description = "Periodically removes orphaned Azure Service Bus subscriptions whose connected queues no longer exist.",
Category = "Cleanup",
Advanced = true,
RestartRequired = true)]
public bool EnableAutomatedSubscriptionCleanup { get; set; }

public void ConfigureServices(IServiceCollection services)
Expand Down Expand Up @@ -71,4 +79,4 @@ public void ConfigureServices(IServiceCollection services)
// Replace the default InMemoryTransportConfigurator.
services.AddSingleton<IBusTransportConfigurator, AzureServiceBusTransportConfigurator>();
}
}
}
Loading
Loading