From 5586151bf125e1e4539cdacf6bfd3fc4046232ac Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Thu, 18 Jul 2024 18:57:42 +0200 Subject: [PATCH] Remove IWorkflowExecutionContextStore and related classes Removed the IWorkflowExecutionContextStore interface and its implementations, along with the associated handlers and registrations. This change simplifies the codebase by eliminating unnecessary components and their dependencies. --- .../Extensions/ModuleExtensions.cs | 9 ++-- .../Features/HangfireSchedulerFeature.cs | 1 + .../Extensions/ModuleExtensions.cs | 3 +- .../Features/QuartzSchedulerFeature.cs | 1 + .../ExecutionState/Endpoint.cs | 2 +- .../IWorkflowDefinitionStorePopulator.cs | 1 + .../IWorkflowExecutionContextStore.cs | 24 ---------- .../Features/WorkflowRuntimeFeature.cs | 7 +-- .../Handlers/CancelBackgroundActivities.cs | 1 - .../Handlers/InvalidateWorkflowsCache.cs | 2 +- .../Handlers/RefreshActivityRegistry.cs | 3 +- ...lowExecutionContextNotificationsHandler.cs | 35 -------------- .../MemoryWorkflowExecutionContextStore.cs | 41 ---------------- .../Services/StoreWorkflowExecutionLogSink.cs | 4 +- .../Helpers/Abstractions/AppComponentTest.cs | 9 ++-- .../Helpers/Fixtures/App.cs | 2 - .../Helpers/Fixtures/WorkflowServer.cs | 3 +- .../Materializers/TestWorkflowMaterializer.cs | 6 +-- .../WorkflowProviders/TestWorkflowProvider.cs | 8 ++-- .../Variables/CountdownWorkflowTests.cs | 1 - .../WorkflowActivities/AutoUpdateTests.cs | 48 +++++++++---------- .../WorkflowActivities/DeleteWorkflowTests.cs | 36 +++++++------- .../WorkflowActivities/SaveWorkflowTests.cs | 9 ++-- .../ReloadWorkflowTests.cs | 40 ++++++++-------- 24 files changed, 94 insertions(+), 202 deletions(-) delete mode 100644 src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowExecutionContextStore.cs delete mode 100644 src/modules/Elsa.Workflows.Runtime/Handlers/WorkflowExecutionContextNotificationsHandler.cs delete mode 100644 src/modules/Elsa.Workflows.Runtime/Services/MemoryWorkflowExecutionContextStore.cs diff --git a/src/modules/Elsa.Hangfire/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Hangfire/Extensions/ModuleExtensions.cs index b28069d4e..ab493f267 100644 --- a/src/modules/Elsa.Hangfire/Extensions/ModuleExtensions.cs +++ b/src/modules/Elsa.Hangfire/Extensions/ModuleExtensions.cs @@ -1,5 +1,6 @@ using Elsa.Features.Services; using Elsa.Hangfire.Features; +using Elsa.Scheduling; using Elsa.Scheduling.Features; using Elsa.Workflows.Runtime.Features; using JetBrains.Annotations; @@ -20,7 +21,7 @@ public static class ModuleExtensions { return module.Use(configure); } - + /// /// Configures Hangfire to use SQL Server storage. Only use this feature if you are not configuring Hangfire yourself. /// @@ -29,7 +30,7 @@ public static class ModuleExtensions feature.Module.Use(configure); return feature; } - + /// /// Configures Hangfire to use SQLite storage. Only use this feature if you are not configuring Hangfire yourself. /// @@ -38,7 +39,7 @@ public static class ModuleExtensions feature.Module.Use(configure); return feature; } - + /// /// Installs a Hangfire implementation for . /// @@ -47,7 +48,7 @@ public static class ModuleExtensions feature.Module.Use(configure); return feature; } - + /// /// Installs a Hangfire implementation for . /// diff --git a/src/modules/Elsa.Hangfire/Features/HangfireSchedulerFeature.cs b/src/modules/Elsa.Hangfire/Features/HangfireSchedulerFeature.cs index 6c2c50bd6..ae24e6499 100644 --- a/src/modules/Elsa.Hangfire/Features/HangfireSchedulerFeature.cs +++ b/src/modules/Elsa.Hangfire/Features/HangfireSchedulerFeature.cs @@ -3,6 +3,7 @@ using Elsa.Features.Attributes; using Elsa.Features.Services; using Elsa.Hangfire.Handlers; using Elsa.Hangfire.Services; +using Elsa.Scheduling; using Elsa.Scheduling.Features; using Elsa.Workflows.Contracts; using Microsoft.Extensions.DependencyInjection; diff --git a/src/modules/Elsa.Quartz/Extensions/ModuleExtensions.cs b/src/modules/Elsa.Quartz/Extensions/ModuleExtensions.cs index d1bd0d35e..e3191924e 100644 --- a/src/modules/Elsa.Quartz/Extensions/ModuleExtensions.cs +++ b/src/modules/Elsa.Quartz/Extensions/ModuleExtensions.cs @@ -1,5 +1,6 @@ using Elsa.Features.Services; using Elsa.Quartz.Features; +using Elsa.Scheduling; using Elsa.Scheduling.Features; // ReSharper disable once CheckNamespace @@ -17,7 +18,7 @@ public static class ModuleExtensions { return module.Use(configure); } - + /// /// Installs a Quartz.NET implementation for . /// diff --git a/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs b/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs index fe9030786..dc4a7c0eb 100644 --- a/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs +++ b/src/modules/Elsa.Quartz/Features/QuartzSchedulerFeature.cs @@ -4,6 +4,7 @@ using Elsa.Features.Services; using Elsa.Quartz.Handlers; using Elsa.Quartz.Jobs; using Elsa.Quartz.Services; +using Elsa.Scheduling; using Elsa.Scheduling.Features; using Elsa.Workflows.Contracts; using Microsoft.Extensions.DependencyInjection; diff --git a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Endpoint.cs b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Endpoint.cs index 96ccc853d..b8cbe8623 100644 --- a/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Endpoint.cs +++ b/src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances/ExecutionState/Endpoint.cs @@ -1,6 +1,6 @@ using Elsa.Abstractions; using Elsa.Extensions; -using Elsa.Workflows.Management.Contracts; +using Elsa.Workflows.Management; using JetBrains.Annotations; namespace Elsa.Workflows.Api.Endpoints.WorkflowInstances.ExecutionState; diff --git a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowDefinitionStorePopulator.cs b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowDefinitionStorePopulator.cs index 8b0f93481..1eabb75bd 100644 --- a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowDefinitionStorePopulator.cs +++ b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowDefinitionStorePopulator.cs @@ -1,4 +1,5 @@ using Elsa.Workflows.Management; +using Elsa.Workflows.Management.Entities; namespace Elsa.Workflows.Runtime; diff --git a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowExecutionContextStore.cs b/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowExecutionContextStore.cs deleted file mode 100644 index 0c833861e..000000000 --- a/src/modules/Elsa.Workflows.Runtime/Contracts/IWorkflowExecutionContextStore.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Elsa.Workflows.Runtime; - -/// -/// Stores records. -/// -public interface IWorkflowExecutionContextStore -{ - /// - /// Saves a record of the . - /// - /// The to save. - Task SaveAsync(WorkflowExecutionContext context); - - /// - /// Finds a with the specified ID. - /// - /// The matching entity or null if no match was found. - Task FindAsync(string workflowExecutionContextId); - - /// - /// Deletes the record of the with the specified ID if it exists. - /// - Task DeleteAsync(string workflowExecutionContextId); -} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs index 7359d7236..2fbfb917c 100644 --- a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs +++ b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs @@ -18,6 +18,7 @@ using Elsa.Workflows.Runtime.Handlers; using Elsa.Workflows.Runtime.HostedServices; using Elsa.Workflows.Runtime.Options; using Elsa.Workflows.Runtime.Providers; +using Elsa.Workflows.Runtime.Services; using Elsa.Workflows.Runtime.Stores; using Medallion.Threading; using Medallion.Threading.FileSystem; @@ -67,9 +68,6 @@ public class WorkflowRuntimeFeature : FeatureBase /// A factory that instantiates an . public Func ActivityExecutionLogStore { get; set; } = sp => sp.GetRequiredService(); - /// A factory that instantiates an . - public Func WorkflowExecutionContextStore { get; set; } = sp => sp.GetRequiredService(); - /// A factory that instantiates an . public Func DistributedLockProvider { get; set; } = _ => new FileDistributedSynchronizationProvider(new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, "App_Data/locks"))); @@ -174,7 +172,6 @@ public class WorkflowRuntimeFeature : FeatureBase .AddScoped(WorkflowRuntime) .AddScoped(WorkflowDispatcher) .AddScoped(WorkflowCancellationDispatcher) - .AddScoped(WorkflowExecutionContextStore) .AddScoped(RunTaskDispatcher) .AddScoped(WorkflowExecutionLogSink) .AddSingleton(BackgroundActivityScheduler) @@ -235,7 +232,6 @@ public class WorkflowRuntimeFeature : FeatureBase .AddMemoryStore() .AddMemoryStore() .AddMemoryStore() - .AddMemoryStore() // Distributed locking. .AddSingleton(DistributedLockProvider) @@ -253,7 +249,6 @@ public class WorkflowRuntimeFeature : FeatureBase .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() - .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() diff --git a/src/modules/Elsa.Workflows.Runtime/Handlers/CancelBackgroundActivities.cs b/src/modules/Elsa.Workflows.Runtime/Handlers/CancelBackgroundActivities.cs index f37b9855f..67067e6c9 100644 --- a/src/modules/Elsa.Workflows.Runtime/Handlers/CancelBackgroundActivities.cs +++ b/src/modules/Elsa.Workflows.Runtime/Handlers/CancelBackgroundActivities.cs @@ -1,6 +1,5 @@ using Elsa.Extensions; using Elsa.Mediator.Contracts; -using Elsa.Workflows.Contracts; using Elsa.Workflows.Runtime.Middleware.Activities; using Elsa.Workflows.Runtime.Notifications; using Elsa.Workflows.Runtime.Stimuli; diff --git a/src/modules/Elsa.Workflows.Runtime/Handlers/InvalidateWorkflowsCache.cs b/src/modules/Elsa.Workflows.Runtime/Handlers/InvalidateWorkflowsCache.cs index d2d52613c..34b3ef696 100644 --- a/src/modules/Elsa.Workflows.Runtime/Handlers/InvalidateWorkflowsCache.cs +++ b/src/modules/Elsa.Workflows.Runtime/Handlers/InvalidateWorkflowsCache.cs @@ -1,5 +1,5 @@ using Elsa.Mediator.Contracts; -using Elsa.Workflows.Management.Contracts; +using Elsa.Workflows.Management; using Elsa.Workflows.Runtime.Notifications; using JetBrains.Annotations; diff --git a/src/modules/Elsa.Workflows.Runtime/Handlers/RefreshActivityRegistry.cs b/src/modules/Elsa.Workflows.Runtime/Handlers/RefreshActivityRegistry.cs index 607751270..5d6054534 100644 --- a/src/modules/Elsa.Workflows.Runtime/Handlers/RefreshActivityRegistry.cs +++ b/src/modules/Elsa.Workflows.Runtime/Handlers/RefreshActivityRegistry.cs @@ -2,7 +2,6 @@ using Elsa.Mediator.Contracts; using Elsa.Workflows.Contracts; using Elsa.Workflows.Management.Activities.WorkflowDefinitionActivity; using Elsa.Workflows.Management.Contracts; -using Elsa.Workflows.Management.Entities; using Elsa.Workflows.Runtime.Notifications; using JetBrains.Annotations; @@ -15,7 +14,7 @@ public class RefreshActivityRegistry(IWorkflowDefinitionActivityRegistryUpdater /// public async Task HandleAsync(WorkflowDefinitionsReloaded notification, CancellationToken cancellationToken) { - foreach (var reloadedWorkflowDefinition in notification.ReloadedWorkflowDefinitions) + foreach (var reloadedWorkflowDefinition in notification.ReloadedWorkflowDefinitions) await UpdateDefinition(reloadedWorkflowDefinition.DefinitionVersionId, reloadedWorkflowDefinition.UsableAsActivity); } diff --git a/src/modules/Elsa.Workflows.Runtime/Handlers/WorkflowExecutionContextNotificationsHandler.cs b/src/modules/Elsa.Workflows.Runtime/Handlers/WorkflowExecutionContextNotificationsHandler.cs deleted file mode 100644 index a4bc67d0d..000000000 --- a/src/modules/Elsa.Workflows.Runtime/Handlers/WorkflowExecutionContextNotificationsHandler.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Elsa.Mediator.Contracts; -using Elsa.Workflows.Management.Notifications; -using Elsa.Workflows.Notifications; - -namespace Elsa.Workflows.Runtime.Handlers; - -/// -/// Deletes workflow execution log records in response to the notification. -/// -internal class WorkflowExecutionContextNotificationsHandler : - INotificationHandler, - INotificationHandler -{ - private readonly IWorkflowExecutionContextStore _store; - - /// - /// Initializes a new instance of the class. - /// - public WorkflowExecutionContextNotificationsHandler(IWorkflowExecutionContextStore store) - { - _store = store; - } - - /// - public Task HandleAsync(WorkflowExecuting notification, CancellationToken cancellationToken) - { - return _store.SaveAsync(notification.WorkflowExecutionContext); - } - - /// - public Task HandleAsync(WorkflowExecuted notification, CancellationToken cancellationToken) - { - return _store.DeleteAsync(notification.WorkflowExecutionContext.Id); - } -} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Services/MemoryWorkflowExecutionContextStore.cs b/src/modules/Elsa.Workflows.Runtime/Services/MemoryWorkflowExecutionContextStore.cs deleted file mode 100644 index 139f05e4f..000000000 --- a/src/modules/Elsa.Workflows.Runtime/Services/MemoryWorkflowExecutionContextStore.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Elsa.Common.Services; -using Elsa.Workflows.Runtime.Stores; - -namespace Elsa.Workflows.Runtime; - -/// -/// Stores in memory. -/// -public class MemoryWorkflowExecutionContextStore : IWorkflowExecutionContextStore -{ - private readonly MemoryStore _store; - - /// - /// Initializes a new instance of the class. - /// - public MemoryWorkflowExecutionContextStore(MemoryStore store) - { - _store = store; - } - - /// - public Task SaveAsync(WorkflowExecutionContext context) - { - _store.Save(context, x => x.Id); - return Task.CompletedTask; - } - - /// - public Task FindAsync(string workflowExecutionContextId) - { - var result = _store.Find((context) => context.Id == workflowExecutionContextId); - return Task.FromResult(result); - } - - /// - public Task DeleteAsync(string workflowExecutionContextId) - { - _store.Delete(workflowExecutionContextId); - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Services/StoreWorkflowExecutionLogSink.cs b/src/modules/Elsa.Workflows.Runtime/Services/StoreWorkflowExecutionLogSink.cs index 5aa5f87c7..51011eb52 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/StoreWorkflowExecutionLogSink.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/StoreWorkflowExecutionLogSink.cs @@ -14,7 +14,7 @@ public class StoreWorkflowExecutionLogSink(IWorkflowExecutionLogStore store, IWo public async Task PersistExecutionLogsAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) { var records = extractor.ExtractWorkflowExecutionLogs(context).ToList(); - await store.AddManyAsync(records, context.CancellationTokens.SystemCancellationToken); - await notificationSender.SendAsync(new WorkflowExecutionLogUpdated(context), context.CancellationTokens.SystemCancellationToken); + await store.AddManyAsync(records, context.CancellationToken); + await notificationSender.SendAsync(new WorkflowExecutionLogUpdated(context), context.CancellationToken); } } \ No newline at end of file diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs index 6f43dbb51..3f5d3e35a 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs @@ -1,6 +1,5 @@ using Elsa.Workflows.ComponentTests.Helpers.Fixtures; using Microsoft.Extensions.DependencyInjection; -using Xunit; namespace Elsa.Workflows.ComponentTests; @@ -12,13 +11,13 @@ public abstract class AppComponentTest(App app) : IDisposable protected Infrastructure Infrastructure { get; } = app.Infrastructure; protected IServiceScope Scope { get; } = app.WorkflowServer.Services.CreateScope(); - protected virtual void OnDispose() - { - } - void IDisposable.Dispose() { Scope.Dispose(); OnDispose(); } + + protected virtual void OnDispose() + { + } } \ No newline at end of file diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs index bd6102fae..921f99441 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs @@ -1,7 +1,5 @@ using Elsa.Workflows.ComponentTests.Helpers.Fixtures; using Hangfire.Annotations; -using JetBrains.Annotations; -using Xunit; namespace Elsa.Workflows.ComponentTests; diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs index eb1caed0e..b8515884c 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs @@ -1,7 +1,6 @@ using System.Net.Http.Headers; using System.Reflection; using Elsa.Alterations.Extensions; -using Elsa.Common.Contracts; using Elsa.EntityFrameworkCore.Extensions; using Elsa.EntityFrameworkCore.Modules.Alterations; using Elsa.EntityFrameworkCore.Modules.Identity; @@ -17,6 +16,8 @@ using Elsa.Testing.Shared.Services; using Elsa.Workflows.ComponentTests.Consumers; using Elsa.Workflows.ComponentTests.Helpers.Materializers; using Elsa.Workflows.ComponentTests.Helpers.Services; +using Elsa.Workflows.ComponentTests.Helpers.WorkflowProviders; +using Elsa.Workflows.Management; using Elsa.Workflows.Runtime.Distributed.Extensions; using FluentStorage; using Hangfire.Annotations; diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Materializers/TestWorkflowMaterializer.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Materializers/TestWorkflowMaterializer.cs index e011422c4..eaa7143a8 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Materializers/TestWorkflowMaterializer.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Materializers/TestWorkflowMaterializer.cs @@ -1,13 +1,13 @@ using Elsa.Workflows.Activities; using Elsa.Workflows.ComponentTests.Helpers.WorkflowProviders; -using Elsa.Workflows.Management.Contracts; +using Elsa.Workflows.Management; using Elsa.Workflows.Management.Entities; -using Elsa.Workflows.Runtime.Contracts; +using Elsa.Workflows.Runtime; namespace Elsa.Workflows.ComponentTests.Helpers.Materializers; /// A workflow materializer that deserializes workflows created from . -public class TestWorkflowMaterializer(IEnumerable workflowProviders) : IWorkflowMaterializer +public class TestWorkflowMaterializer(IEnumerable workflowProviders) : IWorkflowMaterializer { /// The name of the materializer. public const string MaterializerName = "Test"; diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/WorkflowProviders/TestWorkflowProvider.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/WorkflowProviders/TestWorkflowProvider.cs index 5473cf8eb..8e0ec4f31 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Helpers/WorkflowProviders/TestWorkflowProvider.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/WorkflowProviders/TestWorkflowProvider.cs @@ -1,12 +1,12 @@ -using Elsa.Workflows.Runtime.Contracts; -using Elsa.Workflows.Runtime.Models; +using Elsa.Workflows.Runtime; namespace Elsa.Workflows.ComponentTests.Helpers.WorkflowProviders; -public class TestWorkflowProvider : IWorkflowProvider +public class TestWorkflowProvider : IWorkflowsProvider { - public string Name => "Test"; public ICollection MaterializedWorkflows { get; set; } = new List(); + public string Name => "Test"; + public ValueTask> GetWorkflowsAsync(CancellationToken cancellationToken = default) { return new(MaterializedWorkflows); diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Variables/CountdownWorkflowTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Variables/CountdownWorkflowTests.cs index d9a5f4d24..b9445855e 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Variables/CountdownWorkflowTests.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Variables/CountdownWorkflowTests.cs @@ -2,7 +2,6 @@ using Elsa.Expressions.Helpers; using Elsa.Extensions; using Elsa.Workflows.ComponentTests.Scenarios.Variables.Workflows; using Elsa.Workflows.Management; -using Elsa.Workflows.Management.Contracts; using Elsa.Workflows.Models; using Elsa.Workflows.Runtime; using Elsa.Workflows.Runtime.Entities; diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/AutoUpdateTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/AutoUpdateTests.cs index d6dcb9d2b..1f337a481 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/AutoUpdateTests.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/AutoUpdateTests.cs @@ -2,7 +2,6 @@ using Elsa.Http.Contracts; using Elsa.Testing.Shared; using Elsa.Workflows.Contracts; using Elsa.Workflows.Management; -using Elsa.Workflows.Management.Contracts; using Elsa.Workflows.Runtime.Filters; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; @@ -11,37 +10,36 @@ namespace Elsa.Workflows.ComponentTests.Scenarios.WorkflowActivities; public class AutoUpdateTests : AppComponentTest { - private readonly IMemoryCache _cache; - private readonly IHasher _hasher; - private readonly IWorkflowDefinitionCacheManager _definitionCacheManager; - private readonly IWorkflowDefinitionPublisher _publisher; - private readonly ISignalManager _signalManager; - private readonly ITriggerChangeTokenSignalEvents _changeTokenEvents; - private readonly IHttpWorkflowsCacheManager _httpCacheManager; - private readonly IWorkflowDefinitionCacheManager _workflowCacheManager; - - private string? _httpChangeToken; - private string? _triggerChangeToken; - private string? _graphChangeToken; - - private static readonly object HttpChangeTokenSignal = new(); - private static readonly object TriggerChangeTokenSignal = new(); - private static readonly object GraphChangeTokenSignal = new(); - private const string ParentDefinitionVersionId = "4b584e249fdca951"; private const string ParentDefinitionId = "878770f04439a55d"; private const string ChildDefinitionId = "f353742a9ef6af4"; + private static readonly object HttpChangeTokenSignal = new(); + private static readonly object TriggerChangeTokenSignal = new(); + private static readonly object GraphChangeTokenSignal = new(); + private readonly IMemoryCache _cache; + private readonly ITriggerChangeTokenSignalEvents _changeTokenEvents; + private readonly IWorkflowDefinitionCacheManager _definitionCacheManager; + private readonly IHasher _hasher; + private readonly IHttpWorkflowsCacheManager _httpCacheManager; + private readonly IWorkflowDefinitionPublisher _publisher; + private readonly ISignalManager _signalManager; + private readonly IWorkflowDefinitionCacheManager _workflowCacheManager; + private string? _graphChangeToken; + + private string? _httpChangeToken; + private string? _triggerChangeToken; + public AutoUpdateTests(App app) : base(app) { _cache = Scope.ServiceProvider.GetRequiredService(); _hasher = Scope.ServiceProvider.GetRequiredService(); _definitionCacheManager = Scope.ServiceProvider.GetRequiredService(); _publisher = Scope.ServiceProvider.GetRequiredService(); - + _httpCacheManager = Scope.ServiceProvider.GetRequiredService(); _workflowCacheManager = Scope.ServiceProvider.GetRequiredService(); - + _signalManager = Scope.ServiceProvider.GetRequiredService(); _changeTokenEvents = Scope.ServiceProvider.GetRequiredService(); _changeTokenEvents.ChangeTokenSignalTriggered += OnChangeTokenSignalTriggered; @@ -53,7 +51,7 @@ public class AutoUpdateTests : AppComponentTest //Run workflow to make sure the all required items for running the workflow are in the cache var client = WorkflowServer.CreateHttpWorkflowClient(); await client.GetStringAsync("test-cache-invalidation"); - + //Make sure the items are in the cache var hash = _httpCacheManager.ComputeBookmarkHash("/test-cache-invalidation", "get"); Assert.True(_cache.TryGetValue($"http-workflow:{hash}", out _)); @@ -67,15 +65,15 @@ public class AutoUpdateTests : AppComponentTest var parentVersionCacheKey = _definitionCacheManager.CreateWorkflowVersionCacheKey(ParentDefinitionVersionId); Assert.True(_cache.TryGetValue(parentVersionCacheKey, out _)); - + //Set change tokens _httpChangeToken = _workflowCacheManager.CreateWorkflowDefinitionChangeTokenKey(ParentDefinitionId); _triggerChangeToken = _httpCacheManager.GetTriggerChangeTokenKey(hash); _graphChangeToken = _workflowCacheManager.CreateWorkflowDefinitionChangeTokenKey(ParentDefinitionId); - + //(Act) Save the draft version of the child workflow and update the references await _publisher.PublishAsync(ChildDefinitionId); - + //Wait till the notifications for updating the cache have been send and check the cache. await _signalManager.WaitAsync(HttpChangeTokenSignal); await _signalManager.WaitAsync(TriggerChangeTokenSignal); @@ -92,10 +90,12 @@ public class AutoUpdateTests : AppComponentTest { _signalManager.Trigger(HttpChangeTokenSignal, args); } + if (args.Key == _triggerChangeToken) { _signalManager.Trigger(TriggerChangeTokenSignal, args); } + if (args.Key == _graphChangeToken) { _signalManager.Trigger(GraphChangeTokenSignal, args); diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/DeleteWorkflowTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/DeleteWorkflowTests.cs index 439a38397..10754e1cd 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/DeleteWorkflowTests.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/DeleteWorkflowTests.cs @@ -1,20 +1,20 @@ using Elsa.Testing.Shared; +using Elsa.Workflows.ComponentTests.Scenarios.WorkflowActivities.Workflows; using Elsa.Workflows.Contracts; using Elsa.Workflows.Management; -using Elsa.Workflows.Management.Contracts; using Microsoft.Extensions.DependencyInjection; namespace Elsa.Workflows.ComponentTests.Scenarios.WorkflowActivities; public class DeleteWorkflowTests : AppComponentTest { - private readonly ISignalManager _signalManager; - private readonly IWorkflowDefinitionEvents _workflowDefinitionEvents; + private static readonly object WorkflowDeletedSignal = new(); private readonly IServiceScope _scope1; private readonly IServiceScope _scope2; private readonly IServiceScope _scope3; - private static readonly object WorkflowDeletedSignal = new(); - + private readonly ISignalManager _signalManager; + private readonly IWorkflowDefinitionEvents _workflowDefinitionEvents; + public DeleteWorkflowTests(App app) : base(app) { _scope1 = app.Cluster.Pod1.Services.CreateScope(); @@ -30,28 +30,28 @@ public class DeleteWorkflowTests : AppComponentTest public async Task DeleteWorkflow() { EnsureWorkflowInRegistry(_scope1, Workflows.DeleteWorkflow.Type); - + var workflowDefinitionManager = _scope1.ServiceProvider.GetRequiredService(); await workflowDefinitionManager.DeleteByDefinitionIdAsync(Workflows.DeleteWorkflow.DefinitionId); - + WorkflowTypeDeletedFromRegistry(_scope1, Workflows.DeleteWorkflow.Type); } - + [Fact(Skip = "Clustered tests are interfering with other event driven tests")] public async Task DeleteWorkflow_Clustered() { - EnsureWorkflowInRegistry(_scope1, Workflows.DeleteWorkflowClustered.Type); - EnsureWorkflowInRegistry(_scope2, Workflows.DeleteWorkflowClustered.Type); - EnsureWorkflowInRegistry(_scope3, Workflows.DeleteWorkflowClustered.Type); - + EnsureWorkflowInRegistry(_scope1, DeleteWorkflowClustered.Type); + EnsureWorkflowInRegistry(_scope2, DeleteWorkflowClustered.Type); + EnsureWorkflowInRegistry(_scope3, DeleteWorkflowClustered.Type); + var workflowDefinitionManager = _scope1.ServiceProvider.GetRequiredService(); - await workflowDefinitionManager.DeleteByDefinitionIdAsync(Workflows.DeleteWorkflowClustered.DefinitionId); - - WorkflowTypeDeletedFromRegistry(_scope1, Workflows.DeleteWorkflowClustered.Type); - + await workflowDefinitionManager.DeleteByDefinitionIdAsync(DeleteWorkflowClustered.DefinitionId); + + WorkflowTypeDeletedFromRegistry(_scope1, DeleteWorkflowClustered.Type); + await _signalManager.WaitAsync(WorkflowDeletedSignal); - WorkflowTypeDeletedFromRegistry(_scope2, Workflows.DeleteWorkflowClustered.Type); - WorkflowTypeDeletedFromRegistry(_scope3, Workflows.DeleteWorkflowClustered.Type); + WorkflowTypeDeletedFromRegistry(_scope2, DeleteWorkflowClustered.Type); + WorkflowTypeDeletedFromRegistry(_scope3, DeleteWorkflowClustered.Type); } private static void EnsureWorkflowInRegistry(IServiceScope scope, string type) diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/SaveWorkflowTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/SaveWorkflowTests.cs index ddfc36918..c5f4b2781 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/SaveWorkflowTests.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/SaveWorkflowTests.cs @@ -1,7 +1,6 @@ using Elsa.Workflows.Contracts; using Elsa.Workflows.Management; using Elsa.Workflows.Management.Activities.WorkflowDefinitionActivity; -using Elsa.Workflows.Management.Contracts; using Elsa.Workflows.Management.Models; using Elsa.Workflows.Models; using Microsoft.Extensions.DependencyInjection; @@ -18,11 +17,11 @@ public class SaveWorkflowTests(App app) : AppComponentTest(app) public async Task ActivityRegistry(string name, bool usableAsActivity, bool publish, bool expectedInRegistry, bool isBrowsable) { var activityRegistry = Scope.ServiceProvider.GetRequiredService(); - + var descriptor = activityRegistry.Find(name); if (descriptor is not null) activityRegistry.Remove(typeof(WorkflowDefinitionActivityProvider), descriptor); - + var importer = Scope.ServiceProvider.GetRequiredService(); var request = new SaveWorkflowDefinitionRequest { @@ -39,7 +38,7 @@ public class SaveWorkflowTests(App app) : AppComponentTest(app) Publish = publish }; await importer.ImportAsync(request); - + descriptor = activityRegistry.Find(name); if (expectedInRegistry) @@ -49,7 +48,7 @@ public class SaveWorkflowTests(App app) : AppComponentTest(app) } else { - Assert.Null(descriptor); + Assert.Null(descriptor); } } } \ No newline at end of file diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionReload/ReloadWorkflowTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionReload/ReloadWorkflowTests.cs index 9a0fea9ca..fff7410ef 100644 --- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionReload/ReloadWorkflowTests.cs +++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionReload/ReloadWorkflowTests.cs @@ -5,10 +5,8 @@ using Elsa.Workflows.ComponentTests.Helpers.Materializers; using Elsa.Workflows.ComponentTests.Helpers.WorkflowProviders; using Elsa.Workflows.Contracts; using Elsa.Workflows.Management; -using Elsa.Workflows.Management.Contracts; -using Elsa.Workflows.Management.Materializers; +using Elsa.Workflows.Runtime; using Elsa.Workflows.Runtime.Contracts; -using Elsa.Workflows.Runtime.Models; using Humanizer; using Microsoft.Extensions.DependencyInjection; @@ -16,12 +14,12 @@ namespace Elsa.Workflows.ComponentTests.Scenarios.WorkflowDefinitionReload; public class ReloadWorkflowTests : AppComponentTest { - private readonly IWorkflowDefinitionManager _workflowDefinitionManager; - private readonly IWorkflowDefinitionsReloader _workflowDefinitionsReloader; - private readonly IWorkflowBuilderFactory _workflowBuilderFactory; - private readonly TestWorkflowProvider _testWorkflowProvider; - private readonly IWorkflowDefinitionService _workflowDefinitionService; private readonly IActivityRegistry _activityRegistry; + private readonly TestWorkflowProvider _testWorkflowProvider; + private readonly IWorkflowBuilderFactory _workflowBuilderFactory; + private readonly IWorkflowDefinitionManager _workflowDefinitionManager; + private readonly IWorkflowDefinitionService _workflowDefinitionService; + private readonly IWorkflowDefinitionsReloader _workflowDefinitionsReloader; public ReloadWorkflowTests(App app) : base(app) { @@ -30,8 +28,8 @@ public class ReloadWorkflowTests : AppComponentTest _workflowBuilderFactory = Scope.ServiceProvider.GetRequiredService(); _workflowDefinitionService = Scope.ServiceProvider.GetRequiredService(); _activityRegistry = Scope.ServiceProvider.GetRequiredService(); - var workflowProviders = Scope.ServiceProvider.GetRequiredService>(); - _testWorkflowProvider = (TestWorkflowProvider)workflowProviders.First(x => x is TestWorkflowProvider); + var workflowsProviders = Scope.ServiceProvider.GetRequiredService>(); + _testWorkflowProvider = (TestWorkflowProvider)workflowsProviders.First(x => x is TestWorkflowProvider); } [Fact] @@ -52,53 +50,53 @@ public class ReloadWorkflowTests : AppComponentTest var definitionId = Guid.NewGuid().ToString(); var definitionVersionId1 = Guid.NewGuid().ToString(); var workflowV1 = await BuildWorkflowAsync(definitionId, definitionVersionId1, 1); - + // Set up the initial workflow version. _testWorkflowProvider.MaterializedWorkflows = [workflowV1]; await _workflowDefinitionsReloader.ReloadWorkflowDefinitionsAsync(); var definitionV1 = await _workflowDefinitionService.FindWorkflowGraphAsync(definitionId, VersionOptions.Latest); Assert.Equal(definitionVersionId1, definitionV1!.Workflow.Identity.Id); - + // Simulate the workflow provider to have a new version available. var definitionVersionId2 = Guid.NewGuid().ToString(); var workflowV2 = await BuildWorkflowAsync(definitionId, definitionVersionId2, 2); _testWorkflowProvider.MaterializedWorkflows = [workflowV1, workflowV2]; - + // Reload the workflow definitions. await _workflowDefinitionsReloader.ReloadWorkflowDefinitionsAsync(); - + // Assert that the workflow definition service finds the updated workflow version. var definitionV2 = await _workflowDefinitionService.FindWorkflowGraphAsync(definitionId, VersionOptions.Latest); Assert.Equal(definitionVersionId2, definitionV2!.Workflow.Identity.Id); } - + [Fact] public async Task Reloading_AfterUpdatingSourceProvider_ShouldRefreshActivityRegistry() { var definitionId = Guid.NewGuid().ToString(); var definitionVersionId1 = Guid.NewGuid().ToString(); var workflowV1 = await BuildWorkflowAsync(definitionId, definitionVersionId1, 1); - + // Set up the initial workflow version. _testWorkflowProvider.MaterializedWorkflows = [workflowV1]; await _workflowDefinitionsReloader.ReloadWorkflowDefinitionsAsync(); var activityTypeName = workflowV1.Workflow.Name.Pascalize(); - var activityV1 = _activityRegistry.Find(activityTypeName); + var activityV1 = _activityRegistry.Find(activityTypeName); Assert.Equal(1, activityV1!.Version); - + // Simulate the workflow provider to have a new version available. var definitionVersionId2 = Guid.NewGuid().ToString(); var workflowV2 = await BuildWorkflowAsync(definitionId, definitionVersionId2, 2); _testWorkflowProvider.MaterializedWorkflows = [workflowV1, workflowV2]; - + // Reload the workflow definitions. await _workflowDefinitionsReloader.ReloadWorkflowDefinitionsAsync(); - + // Assert that the activity registry contains a new activity descriptor representing the new workflow version. var activityV2 = _activityRegistry.Find(activityTypeName)!; Assert.Equal(2, activityV2.Version); } - + private async Task BuildWorkflowAsync(string definitionId, string definitionVersionId, int version) { var builder = _workflowBuilderFactory.CreateBuilder();