WIP #738 - Refactor-out a further service
The triggers-for-activity-blueprint functionality is quite complex just on its own, so I have moved this to a new service. Once again the integration test which is left behind proves that it still does the same job.
This commit is contained in:
parent
654f3072d9
commit
d9724e5267
|
|
@ -0,0 +1,27 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.ActivityProviders;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Triggers
|
||||
{
|
||||
/// <summary>
|
||||
/// An object which can get a collection of the <see cref="WorkflowTrigger"/> for a specified activity blueprint and workflow.
|
||||
/// </summary>
|
||||
public interface IGetsTriggersForActivityBlueprintAndWorkflow
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a collection of the workflow triggers for the specified activity blueprint.
|
||||
/// </summary>
|
||||
/// <param name="activityBlueprint">An activity blueprint</param>
|
||||
/// <param name="workflowExecutionContext">A workflow execution context</param>
|
||||
/// <param name="activityTypes">A dictionary of all of the activity types (by name)</param>
|
||||
/// <param name="cancellationToken">An optional cancellation token</param>
|
||||
/// <returns>A task exposing a collection of workflow triggers for the activity and workflow.</returns>
|
||||
Task<IEnumerable<WorkflowTrigger>> GetTriggersForActivityBlueprintAsync(IActivityBlueprint activityBlueprint,
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
IDictionary<string, ActivityType> activityTypes,
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -146,6 +146,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.AddScoped<IBookmarkFinder, BookmarkFinder>()
|
||||
.AddScoped<ITriggerIndexer, TriggerIndexer>()
|
||||
.AddScoped<IGetsTriggersForWorkflowBlueprints, TriggersForBlueprintsProvider>()
|
||||
.AddTransient<IGetsTriggersForActivityBlueprintAndWorkflow, TriggersForActivityBlueprintAndWorkflowProvider>()
|
||||
.AddSingleton<ITriggerStore, TriggerStore>()
|
||||
.AddScoped<ITriggerFinder, TriggerFinder>()
|
||||
.AddBookmarkProvider<SignalReceivedBookmarkProvider>()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.ActivityProviders;
|
||||
using Elsa.Bookmarks;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Triggers
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of <see cref="IGetsTriggersForActivityBlueprintAndWorkflow"/>.
|
||||
/// </summary>
|
||||
public class TriggersForActivityBlueprintAndWorkflowProvider : IGetsTriggersForActivityBlueprintAndWorkflow
|
||||
{
|
||||
readonly IBookmarkHasher bookmarkHasher;
|
||||
readonly IEnumerable<IBookmarkProvider> bookmarkProviders;
|
||||
readonly ICreatesActivityExecutionContextForActivityBlueprint activityExecutionContextFactory;
|
||||
|
||||
public TriggersForActivityBlueprintAndWorkflowProvider(IBookmarkHasher bookmarkHasher,
|
||||
IEnumerable<IBookmarkProvider> bookmarkProviders,
|
||||
ICreatesActivityExecutionContextForActivityBlueprint activityExecutionContextFactory)
|
||||
{
|
||||
this.bookmarkHasher = bookmarkHasher ?? throw new System.ArgumentNullException(nameof(bookmarkHasher));
|
||||
this.bookmarkProviders = bookmarkProviders ?? throw new System.ArgumentNullException(nameof(bookmarkProviders));
|
||||
this.activityExecutionContextFactory = activityExecutionContextFactory ?? throw new System.ArgumentNullException(nameof(activityExecutionContextFactory));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of the workflow triggers for the specified activity blueprint.
|
||||
/// </summary>
|
||||
/// <param name="activityBlueprint">An activity blueprint</param>
|
||||
/// <param name="workflowExecutionContext">A workflow execution context</param>
|
||||
/// <param name="activityTypes">A dictionary of all of the activity types (by name)</param>
|
||||
/// <param name="cancellationToken">An optional cancellation token</param>
|
||||
/// <returns>A task exposing a collection of workflow triggers for the activity and workflow.</returns>
|
||||
public async Task<IEnumerable<WorkflowTrigger>> GetTriggersForActivityBlueprintAsync(IActivityBlueprint activityBlueprint,
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
IDictionary<string, ActivityType> activityTypes,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var bookmarkProviderContext = GetBookmarkProviderContext(activityBlueprint, workflowExecutionContext, cancellationToken, activityTypes);
|
||||
var supportedBookmarkProviders = await GetSupportedBookmarkProvidersForContextAsync(bookmarkProviderContext)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var tasksOfListsOfTriggers = supportedBookmarkProviders
|
||||
.Select(async bookmarkProvider => await GetTriggersForBookmarkProvider(bookmarkProvider,
|
||||
bookmarkProviderContext,
|
||||
activityBlueprint,
|
||||
workflowExecutionContext.WorkflowBlueprint,
|
||||
cancellationToken));
|
||||
return (await Task.WhenAll(tasksOfListsOfTriggers))
|
||||
.SelectMany(x => x)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
BookmarkProviderContext GetBookmarkProviderContext(IActivityBlueprint activity,
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
CancellationToken cancellationToken,
|
||||
IDictionary<string,ActivityType> activityTypes)
|
||||
{
|
||||
var activityExecutionContext = activityExecutionContextFactory.CreateActivityExecutionContext(activity,
|
||||
workflowExecutionContext,
|
||||
cancellationToken);
|
||||
var activityType = activityTypes[activity.Type];
|
||||
return new BookmarkProviderContext(activityExecutionContext, activityType, BookmarkIndexingMode.WorkflowBlueprint);
|
||||
}
|
||||
|
||||
async IAsyncEnumerable<IBookmarkProvider> GetSupportedBookmarkProvidersForContextAsync(BookmarkProviderContext context)
|
||||
{
|
||||
foreach (var provider in bookmarkProviders)
|
||||
if (await provider.SupportsActivityAsync(context))
|
||||
yield return provider;
|
||||
}
|
||||
|
||||
async Task<IList<WorkflowTrigger>> GetTriggersForBookmarkProvider(IBookmarkProvider provider,
|
||||
BookmarkProviderContext context,
|
||||
IActivityBlueprint activityBlueprint,
|
||||
IWorkflowBlueprint workflowBlueprint,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var bookmarks = (await provider.GetBookmarksAsync(context, cancellationToken)).ToList();
|
||||
return bookmarks
|
||||
.Select(x => new WorkflowTrigger(workflowBlueprint, activityBlueprint.Id, activityBlueprint.Type, bookmarkHasher.Hash(x), x))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ using System.Linq;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.ActivityProviders;
|
||||
using Elsa.Bookmarks;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
|
|
@ -17,22 +16,16 @@ namespace Elsa.Triggers
|
|||
public class TriggersForBlueprintsProvider : IGetsTriggersForWorkflowBlueprints
|
||||
{
|
||||
readonly IActivityTypeService activityTypeService;
|
||||
readonly IBookmarkHasher bookmarkHasher;
|
||||
readonly IEnumerable<IBookmarkProvider> bookmarkProviders;
|
||||
readonly ICreatesWorkflowExecutionContextForWorkflowBlueprint workflowExecutionContextFactory;
|
||||
readonly ICreatesActivityExecutionContextForActivityBlueprint activityExecutionContextFactory;
|
||||
readonly IGetsTriggersForActivityBlueprintAndWorkflow triggerProvider;
|
||||
|
||||
public TriggersForBlueprintsProvider(IActivityTypeService activityTypeService,
|
||||
IBookmarkHasher bookmarkHasher,
|
||||
IEnumerable<IBookmarkProvider> bookmarkProviders,
|
||||
ICreatesWorkflowExecutionContextForWorkflowBlueprint workflowExecutionContextFactory,
|
||||
ICreatesActivityExecutionContextForActivityBlueprint activityExecutionContextFactory)
|
||||
IGetsTriggersForActivityBlueprintAndWorkflow triggerProvider)
|
||||
{
|
||||
this.activityTypeService = activityTypeService ?? throw new ArgumentNullException(nameof(activityTypeService));
|
||||
this.bookmarkHasher = bookmarkHasher ?? throw new ArgumentNullException(nameof(bookmarkHasher));
|
||||
this.bookmarkProviders = bookmarkProviders ?? throw new ArgumentNullException(nameof(bookmarkProviders));
|
||||
this.workflowExecutionContextFactory = workflowExecutionContextFactory ?? throw new ArgumentNullException(nameof(workflowExecutionContextFactory));
|
||||
this.activityExecutionContextFactory = activityExecutionContextFactory ?? throw new ArgumentNullException(nameof(activityExecutionContextFactory));
|
||||
this.triggerProvider = triggerProvider ?? throw new ArgumentNullException(nameof(triggerProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -52,56 +45,18 @@ namespace Elsa.Triggers
|
|||
var startingActivityBlueprints = workflowBlueprint.GetStartActivities();
|
||||
var workflowExecutionContext = await workflowExecutionContextFactory.CreateWorkflowExecutionContextAsync(workflowBlueprint,
|
||||
cancellationToken);
|
||||
|
||||
foreach (var activityBlueprint in startingActivityBlueprints)
|
||||
{
|
||||
var bookmarkProviderContext = GetBookmarkProviderContext(activityBlueprint, workflowExecutionContext, cancellationToken, activityTypes);
|
||||
var supportedBookmarkProviders = await GetSupportedBookmarkProvidersForContextAsync(bookmarkProviderContext).ToListAsync(cancellationToken);
|
||||
|
||||
foreach (var bookmarkProvider in supportedBookmarkProviders)
|
||||
{
|
||||
var triggers = await GetTriggersForBookmarkProvider(bookmarkProvider,
|
||||
bookmarkProviderContext,
|
||||
activityBlueprint,
|
||||
workflowBlueprint,
|
||||
cancellationToken);
|
||||
allTriggers.AddRange(triggers);
|
||||
}
|
||||
}
|
||||
var tasksOfCollectionsOfTriggers = startingActivityBlueprints
|
||||
.Select(async activityBlueprint => await triggerProvider.GetTriggersForActivityBlueprintAsync(activityBlueprint,
|
||||
workflowExecutionContext,
|
||||
activityTypes,
|
||||
cancellationToken));
|
||||
var triggers = (await Task.WhenAll(tasksOfCollectionsOfTriggers))
|
||||
.SelectMany(x => x)
|
||||
.ToList();
|
||||
allTriggers.AddRange(triggers);
|
||||
}
|
||||
|
||||
return allTriggers;
|
||||
}
|
||||
|
||||
BookmarkProviderContext GetBookmarkProviderContext(IActivityBlueprint activity,
|
||||
WorkflowExecutionContext workflowExecutionContext,
|
||||
CancellationToken cancellationToken,
|
||||
IDictionary<string,ActivityType> activityTypes)
|
||||
{
|
||||
var activityExecutionContext = activityExecutionContextFactory.CreateActivityExecutionContext(activity,
|
||||
workflowExecutionContext,
|
||||
cancellationToken);
|
||||
var activityType = activityTypes[activity.Type];
|
||||
return new BookmarkProviderContext(activityExecutionContext, activityType, BookmarkIndexingMode.WorkflowBlueprint);
|
||||
}
|
||||
|
||||
async IAsyncEnumerable<IBookmarkProvider> GetSupportedBookmarkProvidersForContextAsync(BookmarkProviderContext context)
|
||||
{
|
||||
foreach (var provider in bookmarkProviders)
|
||||
if (await provider.SupportsActivityAsync(context))
|
||||
yield return provider;
|
||||
}
|
||||
|
||||
async Task<IList<WorkflowTrigger>> GetTriggersForBookmarkProvider(IBookmarkProvider provider,
|
||||
BookmarkProviderContext context,
|
||||
IActivityBlueprint activityBlueprint,
|
||||
IWorkflowBlueprint workflowBlueprint,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var bookmarks = (await provider.GetBookmarksAsync(context, cancellationToken)).ToList();
|
||||
return bookmarks
|
||||
.Select(x => new WorkflowTrigger(workflowBlueprint, activityBlueprint.Id, activityBlueprint.Type, bookmarkHasher.Hash(x), x))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ namespace Elsa.UnitTests.Triggers
|
|||
{
|
||||
public class TriggersForBlueprintsProviderTests
|
||||
{
|
||||
[Theory(DisplayName = "The GetTriggersAsync method should return all triggers for the compatible bookmarks of the start activities of the blueprints"), AutoMoqData]
|
||||
[Theory(DisplayName = "The GetTriggersAsync method should return all triggers for the compatible bookmarks of the start activities of the blueprints. This is actually an integration test."), AutoMoqData]
|
||||
public async Task GetTriggersAsyncGetsAllTriggersForAllBlueprintsStartActivitiesAndCompatibleBookmarks(IActivityTypeService activityTypeService,
|
||||
IBookmarkHasher bookmarkHasher,
|
||||
IBookmarkProvider provider1,
|
||||
|
|
@ -65,13 +65,13 @@ namespace Elsa.UnitTests.Triggers
|
|||
{
|
||||
var workflowExecutionContextFactory = new WorkflowExecutionContextForWorkflowBlueprintFactory(serviceProvider, workflowFactory);
|
||||
var activityExecutionContextFactory = new ActivityExecutionContextForActivityBlueprintFactory(serviceProvider);
|
||||
var triggersForActivityProvider = new TriggersForActivityBlueprintAndWorkflowProvider(bookmarkHasher,
|
||||
new[] { provider1, provider2, provider3 },
|
||||
activityExecutionContextFactory);
|
||||
|
||||
// Unfortunately the SUT can't be created by Autofixture because of the IEnumerable<IBookmarkProvider> in the ctor
|
||||
var sut = new TriggersForBlueprintsProvider(activityTypeService,
|
||||
bookmarkHasher,
|
||||
new[] { provider1, provider2, provider3 },
|
||||
workflowExecutionContextFactory,
|
||||
activityExecutionContextFactory);
|
||||
triggersForActivityProvider);
|
||||
|
||||
Mock.Get(activityTypeService)
|
||||
.Setup(x => x.GetActivityTypesAsync(default))
|
||||
|
|
|
|||
Loading…
Reference in a new issue