From e00fc418872ce09caba2f463ac6c90d6adf52c7b Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 10:23:17 +0300 Subject: [PATCH 01/13] Stop using arrays for Features in the appsettings Stop using arrays for Features in the appsettings --- .../EntityFrameworkWebhookStartupBase.cs | 2 +- .../Startup.cs | 3 +- .../Startups.cs | 2 +- src/core/Elsa.Core/ElsaOptions.cs | 1 + src/core/Elsa.Core/ElsaOptionsBuilder.cs | 21 ++++++ .../Extensions/ElsaOptionBuilderExtensions.cs | 9 +-- src/core/Elsa.Core/FeatureOptions.cs | 9 +++ .../EntityFrameworkCoreStartupBase.cs | 2 +- .../Elsa.Persistence.MongoDb/Startup.cs | 2 +- .../Elsa.Persistence.YesSql/Startups.cs | 2 +- .../Elsa.Samples.Server.Host/Startup.cs | 7 +- .../Elsa.Samples.Server.Host/appsettings.json | 67 +++++++++++-------- 12 files changed, 85 insertions(+), 42 deletions(-) create mode 100644 src/core/Elsa.Core/FeatureOptions.cs diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs index af5e3f21c..d5aa71dd8 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs @@ -16,7 +16,7 @@ namespace Elsa.Webhooks.Persistence.EntityFramework.Core public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var services = elsa.Services; - var section = configuration.GetSection($"Elsa:Persistence:{ProviderName}"); + var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:EntityFrameworkCore:{ProviderName}"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs index c8295b9dd..98a249f44 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs @@ -1,7 +1,6 @@ using Elsa.Activities.Webhooks; using Elsa.Activities.Webhooks.Persistence.Decorators; using Elsa.Attributes; -using Elsa.Persistence.MongoDb.Options; using Elsa.Services.Startup; using Elsa.Webhooks.Persistence.MongoDb.Extensions; using Microsoft.Extensions.Configuration; @@ -15,7 +14,7 @@ namespace Elsa.Webhooks.Persistence.MongoDb public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var services = elsa.Services; - var section = configuration.GetSection($"Elsa:Persistence:MongoDb"); + var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:MongoDb"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs index 51081f3cf..b605ee7bb 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs @@ -49,7 +49,7 @@ namespace Elsa.Webhooks.Persistence.YesSql public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var services = elsa.Services; - var section = configuration.GetSection($"Elsa:Persistence:{ProviderName}"); + var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:YesSql:{ProviderName}"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/core/Elsa.Core/ElsaOptions.cs b/src/core/Elsa.Core/ElsaOptions.cs index e0bd103ac..c80107e2e 100644 --- a/src/core/Elsa.Core/ElsaOptions.cs +++ b/src/core/Elsa.Core/ElsaOptions.cs @@ -77,6 +77,7 @@ namespace Elsa public Type DefaultWorkflowStorageProviderType { get; set; } public WorkflowChannelOptions WorkflowChannelOptions { get; set; } = new(); + public FeatureOptions FeatureOptions { get; set; } = new(); internal Func StorageFactory { get; set; } internal Func WorkflowDefinitionStoreFactory { get; set; } diff --git a/src/core/Elsa.Core/ElsaOptionsBuilder.cs b/src/core/Elsa.Core/ElsaOptionsBuilder.cs index 9b5261b8a..ad2c9d53d 100644 --- a/src/core/Elsa.Core/ElsaOptionsBuilder.cs +++ b/src/core/Elsa.Core/ElsaOptionsBuilder.cs @@ -8,6 +8,7 @@ using Elsa.Persistence; using Elsa.Providers.WorkflowStorage; using Elsa.Services; using Elsa.Services.Messaging; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Rebus.DataBus.InMem; @@ -64,6 +65,26 @@ namespace Elsa return this; } + public ElsaOptionsBuilder ConfigureFeatures(IConfigurationSection configuration) + { + ElsaOptions.FeatureOptions.Features = new Dictionary(); + var features = configuration.AsEnumerable(); + + foreach (var feature in features) + { + if (feature.Key.EndsWith(":ConnectionStringName")) continue; + + if (feature.Value != null && bool.Parse(feature.Value)) + { + ElsaOptions.FeatureOptions.Features.Add(feature.Key + .Replace("Elsa:Features:", string.Empty) + .Replace(":Enabled", string.Empty), true); + } + } + + return this; + } + public ElsaOptionsBuilder AddActivity() where T : IActivity => AddActivity(typeof(T)); public ElsaOptionsBuilder AddActivity(Type activityType) diff --git a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs index 3661d3476..7be9c0eab 100644 --- a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs @@ -10,17 +10,18 @@ namespace Elsa { public static class ElsaOptionBuilderExtensions { - public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblyMarkerTypes, IConfiguration configuration, IEnumerable features) => AddFeatures(builder, GetAssemblies(assemblyMarkerTypes), configuration, features); + public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblyMarkerTypes, IConfiguration configuration) => AddFeatures(builder, GetAssemblies(assemblyMarkerTypes), configuration); - public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblies, IConfiguration configuration, IEnumerable features) + public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblies, IConfiguration configuration) { - var enabledFeatures = features.ToHashSet(); + var enabledFeatures = builder.ElsaOptions.FeatureOptions.Features.ToHashSet(); var startupTypesQuery = from assembly in assemblies from type in assembly.GetExportedTypes() where type.IsClass && !type.IsAbstract && typeof(IStartup).IsAssignableFrom(type) let featureAttribute = type.GetCustomAttribute() - where featureAttribute != null && enabledFeatures.Contains(featureAttribute.FeatureName) + let enabledFeature = enabledFeatures.FirstOrDefault(x => x.Key == featureAttribute.FeatureName && x.Value) + where featureAttribute != null && !enabledFeature.Equals(default(KeyValuePair)) select type; var startupTypes = startupTypesQuery.ToList(); diff --git a/src/core/Elsa.Core/FeatureOptions.cs b/src/core/Elsa.Core/FeatureOptions.cs new file mode 100644 index 000000000..1eb301cca --- /dev/null +++ b/src/core/Elsa.Core/FeatureOptions.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Elsa +{ + public class FeatureOptions + { + public Dictionary? Features { get; set; } + } +} diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs index 25026ca10..6cf381516 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs @@ -12,7 +12,7 @@ namespace Elsa.Persistence.EntityFramework.Core public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { - var section = configuration.GetSection($"Elsa:Persistence:{ProviderName}"); + var section = configuration.GetSection($"Elsa:Features:Persistence:EntityFrameworkCore:{ProviderName}"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/persistence/Elsa.Persistence.MongoDb/Startup.cs b/src/persistence/Elsa.Persistence.MongoDb/Startup.cs index 20c55c9c5..38eaf73ca 100644 --- a/src/persistence/Elsa.Persistence.MongoDb/Startup.cs +++ b/src/persistence/Elsa.Persistence.MongoDb/Startup.cs @@ -9,7 +9,7 @@ namespace Elsa.Persistence.MongoDb { public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { - var section = configuration.GetSection($"Elsa:Persistence:MongoDb"); + var section = configuration.GetSection($"Elsa:Features:Persistence:MongoDb"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/persistence/Elsa.Persistence.YesSql/Startups.cs b/src/persistence/Elsa.Persistence.YesSql/Startups.cs index c1d608981..ffcce94d6 100644 --- a/src/persistence/Elsa.Persistence.YesSql/Startups.cs +++ b/src/persistence/Elsa.Persistence.YesSql/Startups.cs @@ -44,7 +44,7 @@ namespace Elsa.Persistence.YesSql public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { - var section = configuration.GetSection($"Elsa:Persistence:{ProviderName}"); + var section = configuration.GetSection($"Elsa:Features:Persistence:YesSql:{ProviderName}"); var connectionStringName = section.GetValue("ConnectionStringName"); var connectionString = section.GetValue("ConnectionString"); diff --git a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs index 4178a5ff0..25bf66065 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs +++ b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using Elsa.Samples.Server.Host.Activities; using Elsa.Server.Hangfire.Extensions; using Hangfire; using Microsoft.AspNetCore.Builder; @@ -7,6 +5,8 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using System.Collections.Generic; +using System.Linq; namespace Elsa.Samples.Server.Host { @@ -67,7 +67,8 @@ namespace Elsa.Samples.Server.Host .AddElsa(elsa => elsa .AddActivitiesFrom() .AddWorkflowsFrom() - .AddFeatures(startups, Configuration, elsaSection.GetSection("Features").Get>()) + .ConfigureFeatures(elsaSection.GetSection("Features")) + .AddFeatures(startups, Configuration) .ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)) ); diff --git a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json index 4a9984de6..de5793da5 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json +++ b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json @@ -18,34 +18,45 @@ "PostgreSql": "Server=127.0.0.1;Port=5432;Database=elsa;User Id=postgres;Password=password;" }, "Elsa": { - "Features": [ - "Persistence:EntityFrameworkCore:Sqlite", - "Dispatcher:Hangfire", - "Console", - "Http", - "Email", - "Temporal:Quartz", - "JavaScript:Activities", - "UserTask", - "Conductor", - "Telnyx", - "Webhooks", - "Webhooks:Persistence:EntityFrameworkCore:Sqlite" - ], - "Persistence:MySql": { - "ConnectionStringName": "MySql" - }, - "Persistence:SqlServer": { - "ConnectionStringName": "SqlServer" - }, - "Persistence:Sqlite": { - "ConnectionStringName": "Sqlite" - }, - "Persistence:MongoDb": { - "ConnectionStringName": "MongoDb" - }, - "Persistence:PostgreSql": { - "ConnectionStringName": "PostgreSql" + "Features": { + "Persistence:EntityFrameworkCore:Sqlite": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + }, + "Dispatcher:Hangfire": { + "Enabled": "true" + }, + "Console": { + "Enabled": "true" + }, + "Http": { + "Enabled": "true" + }, + "Email": { + "Enabled": "true" + }, + "Temporal:Quartz": { + "Enabled": "true" + }, + "JavaScript:Activities": { + "Enabled": "true" + }, + "UserTask": { + "Enabled": "true" + }, + "Conductor": { + "Enabled": "true" + }, + "Telnyx": { + "Enabled": "true" + }, + "Webhooks": { + "Enabled": "true" + }, + "Webhooks:Persistence:EntityFrameworkCore:Sqlite": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + } }, "WorkflowChannels": { "Channels": [ From 1be303329a7d595be9920e71ba852714db816f18 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 10:32:45 +0300 Subject: [PATCH 02/13] README.md updated README.md updated --- .../server/Elsa.Samples.Server.Host/README.md | 123 +++++++++++------- 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/src/samples/server/Elsa.Samples.Server.Host/README.md b/src/samples/server/Elsa.Samples.Server.Host/README.md index ea7b451d1..17c9ddee4 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/README.md +++ b/src/samples/server/Elsa.Samples.Server.Host/README.md @@ -1,93 +1,104 @@ -### Configure persistence in appsettings.json +### Configure persistence for Elsa Core in the appsettings.json + +It is required to specify the persistence, it's enabled status and connection string name in Features EF Sqlite ``` "Elsa": { -"Features": [ - "Persistence:EntityFrameworkCore:Sqlite", + "Features": { + "Persistence:EntityFrameworkCore:Sqlite": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + }, ... - ], -} ``` EF MySQL ``` "Elsa": { -"Features": [ - "Persistence:EntityFrameworkCore:MySql", + "Features": { + "Persistence:EntityFrameworkCore:MySql": { + "Enabled": "true", + "ConnectionStringName": "MySql" + }, ... - ], -} ``` EF SQL Server ``` "Elsa": { -"Features": [ - "Persistence:EntityFrameworkCore:SqlServer", - ... - ], -} + "Features": { + "Persistence:EntityFrameworkCore:SqlServer": { + "Enabled": "true", + "ConnectionStringName": "SqlServer" + }, + ... ``` EF Postgre ``` "Elsa": { -"Features": [ - "Persistence:EntityFrameworkCore:PostgreSql", + "Features": { + "Persistence:EntityFrameworkCore:PostgreSql": { + "Enabled": "true", + "ConnectionStringName": "PostgreSql" + }, ... - ], -} ``` EF MongoDB ``` "Elsa": { -"Features": [ - "Persistence:MongoDb", + "Features": { + "Persistence:MongoDb": { + "Enabled": "true", + "ConnectionStringName": "MongoDb" + }, ... - ], -} ``` YesSql Sqlite ``` "Elsa": { -"Features": [ - "Persistence:YesSql:Sqlite", + "Features": { + "Persistence:YesSql:Sqlite": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + }, ... - ], -} ``` YesSql MySQL ``` "Elsa": { -"Features": [ - "Persistence:YesSql:MySql", + "Features": { + "Persistence:YesSql:MySql": { + "Enabled": "true", + "ConnectionStringName": "MySql" + }, ... - ], -} ``` YesSql SQL Server ``` "Elsa": { -"Features": [ - "Persistence:YesSql:SqlServer", + "Features": { + "Persistence:YesSql:SqlServer": { + "Enabled": "true", + "ConnectionStringName": "SqlServer" + }, ... - ], -} ``` YesSql Postgre ``` "Elsa": { -"Features": [ - "Persistence:YesSql:PostgreSql", + "Features": { + "Persistence:YesSql:PostgreSql": { + "Enabled": "true", + "ConnectionStringName": "PostgreSql" + }, ... - ], -} ``` ### Configure modular activity providers such as Webhooks @@ -98,25 +109,37 @@ Two examples below are given to set up Elsa Core and Webhooks persistence as fol EF Sqlite ``` "Elsa": { -"Features": [ - "Persistence:EntityFrameworkCore:Sqlite", - "Webhooks" - "Webhooks:Persistence:EntityFrameworkCore:Sqlite", + "Features": { + "Persistence:EntityFrameworkCore:Sqlite": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + }, + "Webhooks": { + "Enabled": "true" + }, + "Webhooks:Persistence:EntityFrameworkCore:Sqlite": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + } ... - ], -} ``` EF MongoDB ``` "Elsa": { -"Features": [ - "Persistence:MongoDb", - "Webhooks" - "Webhooks:Persistence:MongoDb", + "Features": { + "Persistence:MongoDb": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + }, + "Webhooks": { + "Enabled": "true" + }, + "Webhooks:Persistence:MongoDb": { + "Enabled": "true", + "ConnectionStringName": "Sqlite" + } ... - ], -} ``` ### Configure connection strings for each persistence From 05843c221e9a7f32b6337331147652e89395ec39 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 10:41:37 +0300 Subject: [PATCH 03/13] Code clean up Code clean up --- src/samples/server/Elsa.Samples.Server.Host/Startup.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs index 25bf66065..83224645b 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs +++ b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs @@ -5,8 +5,6 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using System.Collections.Generic; -using System.Linq; namespace Elsa.Samples.Server.Host { From 8c7a2ac12d1c4569da14b4d9d8f6d7a616aa39f9 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 14:48:28 +0300 Subject: [PATCH 04/13] FeatureOptions made more generic FeatureOptions made more generic --- .../EntityFrameworkWebhookStartupBase.cs | 4 +-- .../Startup.cs | 4 +-- .../Startups.cs | 4 +-- src/core/Elsa.Core/ElsaOptionsBuilder.cs | 33 +++++++++++++------ .../Extensions/ElsaOptionBuilderExtensions.cs | 5 +-- src/core/Elsa.Core/FeatureOptions.cs | 3 +- src/core/Elsa.Core/Models/FeatureOption.cs | 11 +++++++ .../EntityFrameworkCoreStartupBase.cs | 4 +-- .../Elsa.Persistence.MongoDb/Startup.cs | 4 +-- .../Elsa.Persistence.YesSql/Startups.cs | 4 +-- .../Elsa.Samples.Server.Host/Startup.cs | 2 +- .../Elsa.Samples.Server.Host/appsettings.json | 8 +++-- 12 files changed, 58 insertions(+), 28 deletions(-) create mode 100644 src/core/Elsa.Core/Models/FeatureOption.cs diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs index d5aa71dd8..91116db56 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs @@ -17,8 +17,8 @@ namespace Elsa.Webhooks.Persistence.EntityFramework.Core { var services = elsa.Services; var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:EntityFrameworkCore:{ProviderName}"); - var connectionStringName = section.GetValue("ConnectionStringName"); - var connectionString = section.GetValue("ConnectionString"); + var connectionStringName = section.GetValue("Options:ConnectionStringName"); + var connectionString = section.GetValue("Options:ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs index 98a249f44..93a318ac6 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs @@ -15,8 +15,8 @@ namespace Elsa.Webhooks.Persistence.MongoDb { var services = elsa.Services; var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:MongoDb"); - var connectionStringName = section.GetValue("ConnectionStringName"); - var connectionString = section.GetValue("ConnectionString"); + var connectionStringName = section.GetValue("Options:ConnectionStringName"); + var connectionString = section.GetValue("Options:ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs index b605ee7bb..cd396dea7 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs @@ -50,8 +50,8 @@ namespace Elsa.Webhooks.Persistence.YesSql { var services = elsa.Services; var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:YesSql:{ProviderName}"); - var connectionStringName = section.GetValue("ConnectionStringName"); - var connectionString = section.GetValue("ConnectionString"); + var connectionStringName = section.GetValue("Options:ConnectionStringName"); + var connectionString = section.GetValue("Options:ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/core/Elsa.Core/ElsaOptionsBuilder.cs b/src/core/Elsa.Core/ElsaOptionsBuilder.cs index ad2c9d53d..8ee06078a 100644 --- a/src/core/Elsa.Core/ElsaOptionsBuilder.cs +++ b/src/core/Elsa.Core/ElsaOptionsBuilder.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using Elsa.Builders; using Elsa.Caching; +using Elsa.Models; using Elsa.Persistence; using Elsa.Providers.WorkflowStorage; using Elsa.Services; @@ -65,21 +66,33 @@ namespace Elsa return this; } - public ElsaOptionsBuilder ConfigureFeatures(IConfigurationSection configuration) + public ElsaOptionsBuilder ConfigureFeatures(IConfiguration configuration) { - ElsaOptions.FeatureOptions.Features = new Dictionary(); - var features = configuration.AsEnumerable(); + var elsaFeaturesSection = "Elsa:Features"; + + ElsaOptions.FeatureOptions.Features = new List(); + var features = configuration.GetSection(elsaFeaturesSection).AsEnumerable(); foreach (var feature in features) { - if (feature.Key.EndsWith(":ConnectionStringName")) continue; + if (!configuration.GetSection($"{feature.Key}:Enabled").Exists()) continue; - if (feature.Value != null && bool.Parse(feature.Value)) - { - ElsaOptions.FeatureOptions.Features.Add(feature.Key - .Replace("Elsa:Features:", string.Empty) - .Replace(":Enabled", string.Empty), true); - } + var enabled = configuration.GetValue($"{feature.Key}:Enabled"); + if (!enabled) continue; + + var opts = new Dictionary(); + var config = configuration.GetSection($"{feature.Key}:Options"); + config.Bind(opts); + + var name = feature.Key.Replace($"{elsaFeaturesSection}:", string.Empty); + + ElsaOptions.FeatureOptions.Features.Add( + new FeatureOption + { + Name = name, + Enabled = enabled, + Options = opts + }); } return this; diff --git a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs index 7be9c0eab..8afb73553 100644 --- a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using Elsa.Attributes; +using Elsa.Models; using Elsa.Services.Startup; using Microsoft.Extensions.Configuration; @@ -20,8 +21,8 @@ namespace Elsa from type in assembly.GetExportedTypes() where type.IsClass && !type.IsAbstract && typeof(IStartup).IsAssignableFrom(type) let featureAttribute = type.GetCustomAttribute() - let enabledFeature = enabledFeatures.FirstOrDefault(x => x.Key == featureAttribute.FeatureName && x.Value) - where featureAttribute != null && !enabledFeature.Equals(default(KeyValuePair)) + let enabledFeature = enabledFeatures.FirstOrDefault(x => x.Name == featureAttribute.FeatureName) + where featureAttribute != null && enabledFeature != null select type; var startupTypes = startupTypesQuery.ToList(); diff --git a/src/core/Elsa.Core/FeatureOptions.cs b/src/core/Elsa.Core/FeatureOptions.cs index 1eb301cca..fa3ff1213 100644 --- a/src/core/Elsa.Core/FeatureOptions.cs +++ b/src/core/Elsa.Core/FeatureOptions.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; +using Elsa.Models; namespace Elsa { public class FeatureOptions { - public Dictionary? Features { get; set; } + public ICollection? Features { get; set; } } } diff --git a/src/core/Elsa.Core/Models/FeatureOption.cs b/src/core/Elsa.Core/Models/FeatureOption.cs new file mode 100644 index 000000000..976e1cfb0 --- /dev/null +++ b/src/core/Elsa.Core/Models/FeatureOption.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace Elsa.Models +{ + public class FeatureOption + { + public string Name { get; set; } = default!; + public bool Enabled { get; set; } = default!; + public Dictionary? Options { get; set; } + } +} diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs index 6cf381516..d69244c95 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs @@ -13,8 +13,8 @@ namespace Elsa.Persistence.EntityFramework.Core public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var section = configuration.GetSection($"Elsa:Features:Persistence:EntityFrameworkCore:{ProviderName}"); - var connectionStringName = section.GetValue("ConnectionStringName"); - var connectionString = section.GetValue("ConnectionString"); + var connectionStringName = section.GetValue("Options:ConnectionStringName"); + var connectionString = section.GetValue("Options:ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/persistence/Elsa.Persistence.MongoDb/Startup.cs b/src/persistence/Elsa.Persistence.MongoDb/Startup.cs index 38eaf73ca..a14faa3b1 100644 --- a/src/persistence/Elsa.Persistence.MongoDb/Startup.cs +++ b/src/persistence/Elsa.Persistence.MongoDb/Startup.cs @@ -10,8 +10,8 @@ namespace Elsa.Persistence.MongoDb public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var section = configuration.GetSection($"Elsa:Features:Persistence:MongoDb"); - var connectionStringName = section.GetValue("ConnectionStringName"); - var connectionString = section.GetValue("ConnectionString"); + var connectionStringName = section.GetValue("Options:ConnectionStringName"); + var connectionString = section.GetValue("Options:ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/persistence/Elsa.Persistence.YesSql/Startups.cs b/src/persistence/Elsa.Persistence.YesSql/Startups.cs index ffcce94d6..58e7763e2 100644 --- a/src/persistence/Elsa.Persistence.YesSql/Startups.cs +++ b/src/persistence/Elsa.Persistence.YesSql/Startups.cs @@ -45,8 +45,8 @@ namespace Elsa.Persistence.YesSql public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var section = configuration.GetSection($"Elsa:Features:Persistence:YesSql:{ProviderName}"); - var connectionStringName = section.GetValue("ConnectionStringName"); - var connectionString = section.GetValue("ConnectionString"); + var connectionStringName = section.GetValue("Options:ConnectionStringName"); + var connectionString = section.GetValue("Options:ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs index 83224645b..3b6ceb8a7 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs +++ b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs @@ -65,7 +65,7 @@ namespace Elsa.Samples.Server.Host .AddElsa(elsa => elsa .AddActivitiesFrom() .AddWorkflowsFrom() - .ConfigureFeatures(elsaSection.GetSection("Features")) + .ConfigureFeatures(Configuration) .AddFeatures(startups, Configuration) .ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)) ); diff --git a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json index de5793da5..6a5d011c3 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json +++ b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json @@ -21,7 +21,9 @@ "Features": { "Persistence:EntityFrameworkCore:Sqlite": { "Enabled": "true", - "ConnectionStringName": "Sqlite" + "Options": { + "ConnectionStringName": "Sqlite" + } }, "Dispatcher:Hangfire": { "Enabled": "true" @@ -55,7 +57,9 @@ }, "Webhooks:Persistence:EntityFrameworkCore:Sqlite": { "Enabled": "true", - "ConnectionStringName": "Sqlite" + "Options": { + "ConnectionStringName": "Sqlite" + } } }, "WorkflowChannels": { From b452b75666eb79332d8499c9279b67240b5e985e Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 15:01:15 +0300 Subject: [PATCH 05/13] Fix to README.md Fix to README.md --- .../server/Elsa.Samples.Server.Host/README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/samples/server/Elsa.Samples.Server.Host/README.md b/src/samples/server/Elsa.Samples.Server.Host/README.md index 17c9ddee4..1b3b93269 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/README.md +++ b/src/samples/server/Elsa.Samples.Server.Host/README.md @@ -112,14 +112,18 @@ EF Sqlite "Features": { "Persistence:EntityFrameworkCore:Sqlite": { "Enabled": "true", - "ConnectionStringName": "Sqlite" + "Options": { + "ConnectionStringName": "Sqlite" + } }, "Webhooks": { "Enabled": "true" }, "Webhooks:Persistence:EntityFrameworkCore:Sqlite": { "Enabled": "true", - "ConnectionStringName": "Sqlite" + "Options": { + "ConnectionStringName": "Sqlite" + } } ... ``` @@ -130,14 +134,18 @@ EF MongoDB "Features": { "Persistence:MongoDb": { "Enabled": "true", - "ConnectionStringName": "Sqlite" + "Options": { + "ConnectionStringName": "MongoDb" + } }, "Webhooks": { "Enabled": "true" }, "Webhooks:Persistence:MongoDb": { "Enabled": "true", - "ConnectionStringName": "Sqlite" + "Options": { + "ConnectionStringName": "MongoDb" + } } ... ``` From f23227a0e7b5990b4a545a9bc2303d7c7d262156 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 15:07:43 +0300 Subject: [PATCH 06/13] Fix to Monolith Startup after Features functionality changes. Fix to Monolith Startup after Features functionality changes. --- .../ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/samples/dashboard/aspnetcore/ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs b/src/samples/dashboard/aspnetcore/ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs index 0941b4024..2b76a1b07 100644 --- a/src/samples/dashboard/aspnetcore/ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs +++ b/src/samples/dashboard/aspnetcore/ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs @@ -36,7 +36,8 @@ namespace ElsaDashboard.Samples.AspNetCore.Monolith .AddQuartzTemporalActivities() .AddJavaScriptActivities() .AddActivitiesFrom() - .AddFeatures(new[] { typeof(Startup) }, Configuration, elsaSection.GetSection("Features").Get>()) + .ConfigureFeatures(Configuration) + .AddFeatures(new[] { typeof(Startup) }, Configuration) ); services From df5d380a33f495fe5c375890af9f2a42e9e9024c Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 16:21:53 +0300 Subject: [PATCH 07/13] Code and appsettings optimisation for Features Code and appsettings optimisation for Features --- .../EntityFrameworkWebhookStartupBase.cs | 4 +- .../Startup.cs | 4 +- .../Startups.cs | 4 +- src/core/Elsa.Core/ElsaOptions.cs | 1 - src/core/Elsa.Core/ElsaOptionsBuilder.cs | 32 ------------- .../Extensions/ElsaOptionBuilderExtensions.cs | 42 ++++++++++++++-- src/core/Elsa.Core/FeatureOptions.cs | 10 ---- src/core/Elsa.Core/Models/FeatureOption.cs | 11 ----- .../EntityFrameworkCoreStartupBase.cs | 4 +- .../Elsa.Persistence.MongoDb/Startup.cs | 4 +- .../Elsa.Persistence.YesSql/Startups.cs | 4 +- .../Startup.cs | 1 - .../Elsa.Samples.Server.Host/Startup.cs | 1 - .../Elsa.Samples.Server.Host/appsettings.json | 48 +++++-------------- 14 files changed, 61 insertions(+), 109 deletions(-) delete mode 100644 src/core/Elsa.Core/FeatureOptions.cs delete mode 100644 src/core/Elsa.Core/Models/FeatureOption.cs diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs index 91116db56..d5aa71dd8 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/EntityFrameworkWebhookStartupBase.cs @@ -17,8 +17,8 @@ namespace Elsa.Webhooks.Persistence.EntityFramework.Core { var services = elsa.Services; var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:EntityFrameworkCore:{ProviderName}"); - var connectionStringName = section.GetValue("Options:ConnectionStringName"); - var connectionString = section.GetValue("Options:ConnectionString"); + var connectionStringName = section.GetValue("ConnectionStringName"); + var connectionString = section.GetValue("ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs index 93a318ac6..98a249f44 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.MongoDb/Startup.cs @@ -15,8 +15,8 @@ namespace Elsa.Webhooks.Persistence.MongoDb { var services = elsa.Services; var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:MongoDb"); - var connectionStringName = section.GetValue("Options:ConnectionStringName"); - var connectionString = section.GetValue("Options:ConnectionString"); + var connectionStringName = section.GetValue("ConnectionStringName"); + var connectionString = section.GetValue("ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs index cd396dea7..b605ee7bb 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.YesSql/Startups.cs @@ -50,8 +50,8 @@ namespace Elsa.Webhooks.Persistence.YesSql { var services = elsa.Services; var section = configuration.GetSection($"Elsa:Features:Webhooks:Persistence:YesSql:{ProviderName}"); - var connectionStringName = section.GetValue("Options:ConnectionStringName"); - var connectionString = section.GetValue("Options:ConnectionString"); + var connectionStringName = section.GetValue("ConnectionStringName"); + var connectionString = section.GetValue("ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/core/Elsa.Core/ElsaOptions.cs b/src/core/Elsa.Core/ElsaOptions.cs index c80107e2e..e0bd103ac 100644 --- a/src/core/Elsa.Core/ElsaOptions.cs +++ b/src/core/Elsa.Core/ElsaOptions.cs @@ -77,7 +77,6 @@ namespace Elsa public Type DefaultWorkflowStorageProviderType { get; set; } public WorkflowChannelOptions WorkflowChannelOptions { get; set; } = new(); - public FeatureOptions FeatureOptions { get; set; } = new(); internal Func StorageFactory { get; set; } internal Func WorkflowDefinitionStoreFactory { get; set; } diff --git a/src/core/Elsa.Core/ElsaOptionsBuilder.cs b/src/core/Elsa.Core/ElsaOptionsBuilder.cs index 8ee06078a..68ac903fb 100644 --- a/src/core/Elsa.Core/ElsaOptionsBuilder.cs +++ b/src/core/Elsa.Core/ElsaOptionsBuilder.cs @@ -66,38 +66,6 @@ namespace Elsa return this; } - public ElsaOptionsBuilder ConfigureFeatures(IConfiguration configuration) - { - var elsaFeaturesSection = "Elsa:Features"; - - ElsaOptions.FeatureOptions.Features = new List(); - var features = configuration.GetSection(elsaFeaturesSection).AsEnumerable(); - - foreach (var feature in features) - { - if (!configuration.GetSection($"{feature.Key}:Enabled").Exists()) continue; - - var enabled = configuration.GetValue($"{feature.Key}:Enabled"); - if (!enabled) continue; - - var opts = new Dictionary(); - var config = configuration.GetSection($"{feature.Key}:Options"); - config.Bind(opts); - - var name = feature.Key.Replace($"{elsaFeaturesSection}:", string.Empty); - - ElsaOptions.FeatureOptions.Features.Add( - new FeatureOption - { - Name = name, - Enabled = enabled, - Options = opts - }); - } - - return this; - } - public ElsaOptionsBuilder AddActivity() where T : IActivity => AddActivity(typeof(T)); public ElsaOptionsBuilder AddActivity(Type activityType) diff --git a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs index ec1f3dda1..227fd650f 100644 --- a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs @@ -15,17 +15,18 @@ namespace Elsa public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblies, IConfiguration configuration) { - if (builder.ElsaOptions.FeatureOptions.Features == null!) // Null when configuration binding finds an empty array. + ParseFeatures(configuration); + + if (EnabledFeatures == null!) // Null when configuration binding finds an empty array. return builder; - var enabledFeatures = builder.ElsaOptions.FeatureOptions.Features.ToHashSet(); + var enabledFeatures = EnabledFeatures.ToHashSet(); var startupTypesQuery = from assembly in assemblies from type in assembly.GetExportedTypes() where type.IsClass && !type.IsAbstract && typeof(IStartup).IsAssignableFrom(type) let featureAttribute = type.GetCustomAttribute() - let enabledFeature = enabledFeatures.FirstOrDefault(x => x.Name == featureAttribute.FeatureName) - where featureAttribute != null && enabledFeature != null + where featureAttribute != null && enabledFeatures.Contains(featureAttribute.FeatureName) select type; var startupTypes = startupTypesQuery.ToList(); @@ -39,7 +40,38 @@ namespace Elsa return builder; } - + + private static void ParseFeatures(IConfiguration configuration) + { + var elsaFeaturesSection = "Elsa:Features"; + + EnabledFeatures = new List(); + var features = configuration.GetSection(elsaFeaturesSection).AsEnumerable(); + + foreach (var feature in features) + { + var explEnabled = false; + var implEnabled = false; + + if (configuration.GetSection($"{feature.Key}:Enabled").Exists()) + { + bool.TryParse(configuration.GetValue($"{feature.Key}:Enabled"), out explEnabled); + } + else if (!feature.Key.EndsWith(":Enabled")) + { + bool.TryParse(configuration.GetValue($"{feature.Key}"), out implEnabled); + } + + if (!explEnabled && !implEnabled) continue; + + var featureName = feature.Key.Replace($"{elsaFeaturesSection}:", string.Empty); + + EnabledFeatures.Add(featureName); + } + } + private static IEnumerable GetAssemblies(IEnumerable assemblyMarkerTypes) => assemblyMarkerTypes.Select(x => x.Assembly).Distinct(); + + private static ICollection? EnabledFeatures { get; set; } } } \ No newline at end of file diff --git a/src/core/Elsa.Core/FeatureOptions.cs b/src/core/Elsa.Core/FeatureOptions.cs deleted file mode 100644 index fa3ff1213..000000000 --- a/src/core/Elsa.Core/FeatureOptions.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; -using Elsa.Models; - -namespace Elsa -{ - public class FeatureOptions - { - public ICollection? Features { get; set; } - } -} diff --git a/src/core/Elsa.Core/Models/FeatureOption.cs b/src/core/Elsa.Core/Models/FeatureOption.cs deleted file mode 100644 index 976e1cfb0..000000000 --- a/src/core/Elsa.Core/Models/FeatureOption.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Elsa.Models -{ - public class FeatureOption - { - public string Name { get; set; } = default!; - public bool Enabled { get; set; } = default!; - public Dictionary? Options { get; set; } - } -} diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs index d69244c95..6cf381516 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/EntityFrameworkCoreStartupBase.cs @@ -13,8 +13,8 @@ namespace Elsa.Persistence.EntityFramework.Core public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var section = configuration.GetSection($"Elsa:Features:Persistence:EntityFrameworkCore:{ProviderName}"); - var connectionStringName = section.GetValue("Options:ConnectionStringName"); - var connectionString = section.GetValue("Options:ConnectionString"); + var connectionStringName = section.GetValue("ConnectionStringName"); + var connectionString = section.GetValue("ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/persistence/Elsa.Persistence.MongoDb/Startup.cs b/src/persistence/Elsa.Persistence.MongoDb/Startup.cs index a14faa3b1..38eaf73ca 100644 --- a/src/persistence/Elsa.Persistence.MongoDb/Startup.cs +++ b/src/persistence/Elsa.Persistence.MongoDb/Startup.cs @@ -10,8 +10,8 @@ namespace Elsa.Persistence.MongoDb public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var section = configuration.GetSection($"Elsa:Features:Persistence:MongoDb"); - var connectionStringName = section.GetValue("Options:ConnectionStringName"); - var connectionString = section.GetValue("Options:ConnectionString"); + var connectionStringName = section.GetValue("ConnectionStringName"); + var connectionString = section.GetValue("ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/persistence/Elsa.Persistence.YesSql/Startups.cs b/src/persistence/Elsa.Persistence.YesSql/Startups.cs index 58e7763e2..ffcce94d6 100644 --- a/src/persistence/Elsa.Persistence.YesSql/Startups.cs +++ b/src/persistence/Elsa.Persistence.YesSql/Startups.cs @@ -45,8 +45,8 @@ namespace Elsa.Persistence.YesSql public override void ConfigureElsa(ElsaOptionsBuilder elsa, IConfiguration configuration) { var section = configuration.GetSection($"Elsa:Features:Persistence:YesSql:{ProviderName}"); - var connectionStringName = section.GetValue("Options:ConnectionStringName"); - var connectionString = section.GetValue("Options:ConnectionString"); + var connectionStringName = section.GetValue("ConnectionStringName"); + var connectionString = section.GetValue("ConnectionString"); if (string.IsNullOrWhiteSpace(connectionString)) { diff --git a/src/samples/dashboard/aspnetcore/ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs b/src/samples/dashboard/aspnetcore/ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs index 2b76a1b07..1dfd52ca0 100644 --- a/src/samples/dashboard/aspnetcore/ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs +++ b/src/samples/dashboard/aspnetcore/ElsaDashboard.Samples.AspNetCore.Monolith/Startup.cs @@ -36,7 +36,6 @@ namespace ElsaDashboard.Samples.AspNetCore.Monolith .AddQuartzTemporalActivities() .AddJavaScriptActivities() .AddActivitiesFrom() - .ConfigureFeatures(Configuration) .AddFeatures(new[] { typeof(Startup) }, Configuration) ); diff --git a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs index 638ae70dc..ddfbed3f1 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs +++ b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs @@ -66,7 +66,6 @@ namespace Elsa.Samples.Server.Host .AddElsa(elsa => elsa .AddActivitiesFrom() .AddWorkflowsFrom() - .ConfigureFeatures(Configuration) .AddFeatures(startups, Configuration) .ConfigureWorkflowChannels(options => elsaSection.GetSection("WorkflowChannels").Bind(options)) ); diff --git a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json index 6a5d011c3..0ee36a572 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json +++ b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json @@ -21,45 +21,21 @@ "Features": { "Persistence:EntityFrameworkCore:Sqlite": { "Enabled": "true", - "Options": { - "ConnectionStringName": "Sqlite" - } - }, - "Dispatcher:Hangfire": { - "Enabled": "true" - }, - "Console": { - "Enabled": "true" - }, - "Http": { - "Enabled": "true" - }, - "Email": { - "Enabled": "true" - }, - "Temporal:Quartz": { - "Enabled": "true" - }, - "JavaScript:Activities": { - "Enabled": "true" - }, - "UserTask": { - "Enabled": "true" - }, - "Conductor": { - "Enabled": "true" - }, - "Telnyx": { - "Enabled": "true" - }, - "Webhooks": { - "Enabled": "true" + "ConnectionStringName": "Sqlite" }, + "Dispatcher:Hangfire": true, + "Console": true, + "Http": true, + "Email": true, + "Temporal:Quartz": true, + "JavaScript:Activities": true, + "UserTask": true, + "Conductor": true, + "Telnyx": true, + "Webhooks": true, "Webhooks:Persistence:EntityFrameworkCore:Sqlite": { "Enabled": "true", - "Options": { - "ConnectionStringName": "Sqlite" - } + "ConnectionStringName": "Sqlite" } }, "WorkflowChannels": { From 9a3dc76b62a09e32669e9363c7c78c2d31ea7406 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 16:24:30 +0300 Subject: [PATCH 08/13] Update README.md Update README.md --- .../server/Elsa.Samples.Server.Host/README.md | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/samples/server/Elsa.Samples.Server.Host/README.md b/src/samples/server/Elsa.Samples.Server.Host/README.md index 1b3b93269..07879a189 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/README.md +++ b/src/samples/server/Elsa.Samples.Server.Host/README.md @@ -7,7 +7,7 @@ EF Sqlite "Elsa": { "Features": { "Persistence:EntityFrameworkCore:Sqlite": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "Sqlite" }, ... @@ -18,7 +18,7 @@ EF MySQL "Elsa": { "Features": { "Persistence:EntityFrameworkCore:MySql": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "MySql" }, ... @@ -29,7 +29,7 @@ EF SQL Server "Elsa": { "Features": { "Persistence:EntityFrameworkCore:SqlServer": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "SqlServer" }, ... @@ -51,7 +51,7 @@ EF MongoDB "Elsa": { "Features": { "Persistence:MongoDb": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "MongoDb" }, ... @@ -62,7 +62,7 @@ YesSql Sqlite "Elsa": { "Features": { "Persistence:YesSql:Sqlite": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "Sqlite" }, ... @@ -73,7 +73,7 @@ YesSql MySQL "Elsa": { "Features": { "Persistence:YesSql:MySql": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "MySql" }, ... @@ -84,7 +84,7 @@ YesSql SQL Server "Elsa": { "Features": { "Persistence:YesSql:SqlServer": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "SqlServer" }, ... @@ -95,7 +95,7 @@ YesSql Postgre "Elsa": { "Features": { "Persistence:YesSql:PostgreSql": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "PostgreSql" }, ... @@ -111,19 +111,14 @@ EF Sqlite "Elsa": { "Features": { "Persistence:EntityFrameworkCore:Sqlite": { - "Enabled": "true", - "Options": { - "ConnectionStringName": "Sqlite" - } + "Enabled": true, + "ConnectionStringName": "Sqlite" }, - "Webhooks": { - "Enabled": "true" + "Webhooks": true }, "Webhooks:Persistence:EntityFrameworkCore:Sqlite": { - "Enabled": "true", - "Options": { - "ConnectionStringName": "Sqlite" - } + "Enabled": true, + "ConnectionStringName": "Sqlite" } ... ``` @@ -133,19 +128,14 @@ EF MongoDB "Elsa": { "Features": { "Persistence:MongoDb": { - "Enabled": "true", - "Options": { - "ConnectionStringName": "MongoDb" - } + "Enabled": true, + "ConnectionStringName": "MongoDb" }, - "Webhooks": { - "Enabled": "true" + "Webhooks": true }, "Webhooks:Persistence:MongoDb": { - "Enabled": "true", - "Options": { - "ConnectionStringName": "MongoDb" - } + "Enabled": true, + "ConnectionStringName": "MongoDb" } ... ``` From e1cc867117683175c1b03fd5e31449762dd8b2da Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 16:26:37 +0300 Subject: [PATCH 09/13] The appsettings Clean up The appsettings Clean up --- src/samples/server/Elsa.Samples.Server.Host/appsettings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json index 0ee36a572..0b93db473 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/appsettings.json +++ b/src/samples/server/Elsa.Samples.Server.Host/appsettings.json @@ -20,7 +20,7 @@ "Elsa": { "Features": { "Persistence:EntityFrameworkCore:Sqlite": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "Sqlite" }, "Dispatcher:Hangfire": true, @@ -34,7 +34,7 @@ "Telnyx": true, "Webhooks": true, "Webhooks:Persistence:EntityFrameworkCore:Sqlite": { - "Enabled": "true", + "Enabled": true, "ConnectionStringName": "Sqlite" } }, From 7f24d19bc72143546d75640dbcda58e8153f7cc8 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 16:53:27 +0300 Subject: [PATCH 10/13] Code clean up Code clean up --- .../Extensions/ElsaOptionBuilderExtensions.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs index 227fd650f..6aa70edce 100644 --- a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs @@ -15,12 +15,12 @@ namespace Elsa public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblies, IConfiguration configuration) { - ParseFeatures(configuration); + ICollection enabledFeatures = ParseFeatures(configuration); - if (EnabledFeatures == null!) // Null when configuration binding finds an empty array. + if (enabledFeatures == null!) // Null when configuration binding finds an empty array. return builder; - var enabledFeatures = EnabledFeatures.ToHashSet(); + enabledFeatures = enabledFeatures.ToHashSet(); var startupTypesQuery = from assembly in assemblies from type in assembly.GetExportedTypes() @@ -41,11 +41,10 @@ namespace Elsa return builder; } - private static void ParseFeatures(IConfiguration configuration) + private static ICollection ParseFeatures(IConfiguration configuration) { var elsaFeaturesSection = "Elsa:Features"; - - EnabledFeatures = new List(); + var enabledFeatures = new List(); var features = configuration.GetSection(elsaFeaturesSection).AsEnumerable(); foreach (var feature in features) @@ -66,12 +65,12 @@ namespace Elsa var featureName = feature.Key.Replace($"{elsaFeaturesSection}:", string.Empty); - EnabledFeatures.Add(featureName); + enabledFeatures.Add(featureName); } + + return enabledFeatures; } private static IEnumerable GetAssemblies(IEnumerable assemblyMarkerTypes) => assemblyMarkerTypes.Select(x => x.Assembly).Distinct(); - - private static ICollection? EnabledFeatures { get; set; } } } \ No newline at end of file From 85dd7b320280895bea8c0b37e3c5445d683f6b72 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 16:54:17 +0300 Subject: [PATCH 11/13] Code clean up 2 Code clean up 2 --- src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs index 6aa70edce..2020447f8 100644 --- a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using Elsa.Attributes; -using Elsa.Models; using Elsa.Services.Startup; using Microsoft.Extensions.Configuration; From 4fcf541d4d014f81db180893ed4fe14f118650f7 Mon Sep 17 00:00:00 2001 From: axeleron007 Date: Tue, 6 Jul 2021 16:59:35 +0300 Subject: [PATCH 12/13] Some Sipkes' suggested improvements Some Sipkes' suggested improvements --- src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs index 2020447f8..f41f2d58a 100644 --- a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs @@ -14,7 +14,7 @@ namespace Elsa public static ElsaOptionsBuilder AddFeatures(this ElsaOptionsBuilder builder, IEnumerable assemblies, IConfiguration configuration) { - ICollection enabledFeatures = ParseFeatures(configuration); + var enabledFeatures = ParseFeatures(configuration); if (enabledFeatures == null!) // Null when configuration binding finds an empty array. return builder; @@ -40,7 +40,7 @@ namespace Elsa return builder; } - private static ICollection ParseFeatures(IConfiguration configuration) + private static IEnumerable ParseFeatures(IConfiguration configuration) { var elsaFeaturesSection = "Elsa:Features"; var enabledFeatures = new List(); From 3e6abc8b306ebe2d24c369ed81abf8dbc6da594b Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 6 Jul 2021 16:08:22 +0200 Subject: [PATCH 13/13] Make linq --- .../Extensions/ElsaOptionBuilderExtensions.cs | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs index f41f2d58a..081375ee9 100644 --- a/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaOptionBuilderExtensions.cs @@ -18,7 +18,7 @@ namespace Elsa if (enabledFeatures == null!) // Null when configuration binding finds an empty array. return builder; - + enabledFeatures = enabledFeatures.ToHashSet(); var startupTypesQuery = from assembly in assemblies @@ -43,31 +43,30 @@ namespace Elsa private static IEnumerable ParseFeatures(IConfiguration configuration) { var elsaFeaturesSection = "Elsa:Features"; - var enabledFeatures = new List(); var features = configuration.GetSection(elsaFeaturesSection).AsEnumerable(); - foreach (var feature in features) + return + from feature in features + let isEnabled = ParseFeatureFlag(configuration, feature.Key) + where isEnabled + select feature.Key.Replace($"{elsaFeaturesSection}:", string.Empty); + } + + private static bool ParseFeatureFlag(IConfiguration configuration, string feature) + { + if (configuration.GetSection($"{feature}:Enabled").Exists()) { - var explEnabled = false; - var implEnabled = false; - - if (configuration.GetSection($"{feature.Key}:Enabled").Exists()) - { - bool.TryParse(configuration.GetValue($"{feature.Key}:Enabled"), out explEnabled); - } - else if (!feature.Key.EndsWith(":Enabled")) - { - bool.TryParse(configuration.GetValue($"{feature.Key}"), out implEnabled); - } - - if (!explEnabled && !implEnabled) continue; - - var featureName = feature.Key.Replace($"{elsaFeaturesSection}:", string.Empty); - - enabledFeatures.Add(featureName); + bool.TryParse(configuration.GetValue($"{feature}:Enabled"), out var enabled); + return enabled; } - return enabledFeatures; + if (!feature.EndsWith(":Enabled")) + { + bool.TryParse(configuration.GetValue($"{feature}"), out var enabled); + return enabled; + } + + return false; } private static IEnumerable GetAssemblies(IEnumerable assemblyMarkerTypes) => assemblyMarkerTypes.Select(x => x.Assembly).Distinct();