Merge branch 'main' of github.com:elsa-workflows/elsa-core
This commit is contained in:
commit
d3f9d5ef8f
7
Elsa.sln
7
Elsa.sln
|
|
@ -373,6 +373,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.ServerAndStudio.Web",
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Studio.Web", "src\apps\Elsa.Studio.Web\Elsa.Studio.Web.csproj", "{169A82A5-2DB3-40EA-801E-14C08D743DF7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.OpenTelemetry", "src\modules\Elsa.OpenTelemetry\Elsa.OpenTelemetry.csproj", "{2CDF3E1C-267D-4198-B1C7-7E1F548FC120}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -885,6 +887,10 @@ Global
|
|||
{169A82A5-2DB3-40EA-801E-14C08D743DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{169A82A5-2DB3-40EA-801E-14C08D743DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{169A82A5-2DB3-40EA-801E-14C08D743DF7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2CDF3E1C-267D-4198-B1C7-7E1F548FC120}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2CDF3E1C-267D-4198-B1C7-7E1F548FC120}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2CDF3E1C-267D-4198-B1C7-7E1F548FC120}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2CDF3E1C-267D-4198-B1C7-7E1F548FC120}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -1039,6 +1045,7 @@ Global
|
|||
{690B0274-291F-4D9E-BA76-54EFF7D3E4BC} = {D92BEAB2-60D6-4BB4-885A-6BA681C6CCF1}
|
||||
{060FD0BA-BD78-48E1-A8A7-4906A5AD5E39} = {D92BEAB2-60D6-4BB4-885A-6BA681C6CCF1}
|
||||
{169A82A5-2DB3-40EA-801E-14C08D743DF7} = {D92BEAB2-60D6-4BB4-885A-6BA681C6CCF1}
|
||||
{2CDF3E1C-267D-4198-B1C7-7E1F548FC120} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D4B5CEAA-7D70-4FCB-A68E-B03FBE5E0E5E}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set PYTHONNET_PYDLL environment variable
|
||||
ENV PYTHONNET_PYDLL /usr/lib/aarch64-linux-gnu/libpython3.11.so
|
||||
ENV PYTHONNET_PYDLL=/usr/lib/aarch64-linux-gnu/libpython3.11.so
|
||||
|
||||
# Copy the tracer from build target
|
||||
COPY --from=build /tmp/datadog-dotnet-apm.deb /tmp/datadog-dotnet-apm.deb
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set PYTHONNET_PYDLL environment variable
|
||||
ENV PYTHONNET_PYDLL /usr/lib/aarch64-linux-gnu/libpython3.11.so
|
||||
ENV PYTHONNET_PYDLL=/usr/lib/aarch64-linux-gnu/libpython3.11.so
|
||||
|
||||
EXPOSE 80/tcp
|
||||
EXPOSE 443/tcp
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set PYTHONNET_PYDLL environment variable
|
||||
ENV PYTHONNET_PYDLL /usr/lib/aarch64-linux-gnu/libpython3.11.so
|
||||
ENV PYTHONNET_PYDLL=/usr/lib/aarch64-linux-gnu/libpython3.11.so
|
||||
|
||||
EXPOSE 80/tcp
|
||||
EXPOSE 443/tcp
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<ProjectReference Include="..\..\modules\Elsa.Caching.Distributed.MassTransit\Elsa.Caching.Distributed.MassTransit.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa.EntityFrameworkCore.PostgreSql\Elsa.EntityFrameworkCore.PostgreSql.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.MassTransit.AzureServiceBus\Elsa.MassTransit.AzureServiceBus.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.OpenTelemetry\Elsa.OpenTelemetry.csproj" />
|
||||
<ProjectReference Include="..\..\modules\Elsa\Elsa.csproj"/>
|
||||
<ProjectReference Include="..\..\common\Elsa.DropIns\Elsa.DropIns.csproj"/>
|
||||
<ProjectReference Include="..\..\modules\Elsa.Alterations.MassTransit\Elsa.Alterations.MassTransit.csproj"/>
|
||||
|
|
|
|||
|
|
@ -21,13 +21,17 @@ using Elsa.MongoDb.Modules.Alterations;
|
|||
using Elsa.MongoDb.Modules.Identity;
|
||||
using Elsa.MongoDb.Modules.Management;
|
||||
using Elsa.MongoDb.Modules.Runtime;
|
||||
using Elsa.OpenTelemetry.Middleware;
|
||||
using Elsa.Server.Web;
|
||||
using Elsa.Tenants.Extensions;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Api;
|
||||
using Elsa.Workflows.Management.Compression;
|
||||
using Elsa.Workflows.Management.Stores;
|
||||
using Elsa.Workflows.Pipelines.ActivityExecution;
|
||||
using Elsa.Workflows.Pipelines.WorkflowExecution;
|
||||
using Elsa.Workflows.Runtime.Distributed.Extensions;
|
||||
using Elsa.Workflows.Runtime.Extensions;
|
||||
using Elsa.Workflows.Runtime.Stores;
|
||||
using JetBrains.Annotations;
|
||||
using Medallion.Threading.FileSystem;
|
||||
|
|
@ -133,6 +137,11 @@ services
|
|||
identity.UseConfigurationBasedRoleProvider(options => identitySection.Bind(options));
|
||||
})
|
||||
.UseDefaultAuthentication()
|
||||
.UseWorkflows(workflows =>
|
||||
{
|
||||
workflows.WithDefaultWorkflowExecutionPipeline(pipeline => pipeline.UseWorkflowExecutionTracing());
|
||||
workflows.WithDefaultActivityExecutionPipeline(pipeline => pipeline.UseActivityExecutionTracing());
|
||||
})
|
||||
.UseWorkflowManagement(management =>
|
||||
{
|
||||
if (persistenceProvider == PersistenceProvider.MongoDb)
|
||||
|
|
|
|||
18
src/modules/Elsa.OpenTelemetry/Elsa.OpenTelemetry.csproj
Normal file
18
src/modules/Elsa.OpenTelemetry/Elsa.OpenTelemetry.csproj
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>
|
||||
Provides OpenTelemetry sources for tracing workflow and activity execution.
|
||||
</Description>
|
||||
<PackageTags>elsa module open-telemetry</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Elsa.Workflows.Core\Elsa.Workflows.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Extensions\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
using Elsa.Features.Abstractions;
|
||||
using Elsa.Features.Services;
|
||||
|
||||
namespace Elsa.OpenTelemetry.Features;
|
||||
|
||||
public class OpenTelemetryFeature(IModule module) : FeatureBase(module)
|
||||
{
|
||||
public override void Configure()
|
||||
{
|
||||
}
|
||||
}
|
||||
3
src/modules/Elsa.OpenTelemetry/FodyWeavers.xml
Normal file
3
src/modules/Elsa.OpenTelemetry/FodyWeavers.xml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait />
|
||||
</Weavers>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
using System.Diagnostics;
|
||||
|
||||
namespace Elsa.OpenTelemetry.Helpers;
|
||||
|
||||
public class ElsaOpenTelemetry
|
||||
{
|
||||
public static readonly ActivitySource ActivitySource = new("Elsa.Workflows");
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
using System.Diagnostics;
|
||||
using Elsa.OpenTelemetry.Helpers;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Pipelines.ActivityExecution;
|
||||
using Elsa.Workflows.Pipelines.WorkflowExecution;
|
||||
using JetBrains.Annotations;
|
||||
using Activity = System.Diagnostics.Activity;
|
||||
using ActivityKind = System.Diagnostics.ActivityKind;
|
||||
|
||||
namespace Elsa.OpenTelemetry.Middleware;
|
||||
|
||||
[UsedImplicitly]
|
||||
public class OpenTelemetryTracingActivityExecutionMiddleware(ActivityMiddlewareDelegate next) : IActivityExecutionMiddleware
|
||||
{
|
||||
public async ValueTask InvokeAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var activity = context.Activity;
|
||||
using var span = ElsaOpenTelemetry.ActivitySource.StartActivity($"ActivityExecution {context.ActivityDescriptor.TypeName}", ActivityKind.Internal, Activity.Current?.Context ?? default);
|
||||
span?.AddTag("activity.nodeId", activity.NodeId);
|
||||
span?.AddTag("activity.type", activity.Type);
|
||||
span?.AddTag("activity.name", activity.Name);
|
||||
span?.AddTag("activityInstance.id", context.Id);
|
||||
span?.AddTag("activityInstance.originalStatus", context.Status.ToString());
|
||||
span?.AddEvent(new ActivityEvent("Executing"));
|
||||
await next(context);
|
||||
span?.AddEvent(new ActivityEvent("Executed"));
|
||||
span?.AddTag("activityInstance.newStatus", context.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public static class OpenTelemetryTracingActivityExecutionMiddlewareExtensions
|
||||
{
|
||||
/// Installs the <see cref="OpenTelemetryTracingActivityExecutionMiddleware"/> component in the workflow execution pipeline.
|
||||
public static IActivityExecutionPipelineBuilder UseActivityExecutionTracing(this IActivityExecutionPipelineBuilder pipelineBuilder) => pipelineBuilder.Insert<OpenTelemetryTracingActivityExecutionMiddleware>(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using System.Diagnostics;
|
||||
using Elsa.OpenTelemetry.Helpers;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Pipelines.WorkflowExecution;
|
||||
using JetBrains.Annotations;
|
||||
using Activity = System.Diagnostics.Activity;
|
||||
using ActivityKind = System.Diagnostics.ActivityKind;
|
||||
|
||||
namespace Elsa.OpenTelemetry.Middleware;
|
||||
|
||||
[UsedImplicitly]
|
||||
public class OpenTelemetryTracingWorkflowExecutionMiddleware(WorkflowMiddlewareDelegate next) : WorkflowExecutionMiddleware(next)
|
||||
{
|
||||
public override async ValueTask InvokeAsync(WorkflowExecutionContext context)
|
||||
{
|
||||
var workflowInstanceId = context.Id;
|
||||
var workflow = context.Workflow;
|
||||
using var activity = ElsaOpenTelemetry.ActivitySource.StartActivity($"WorkflowExecution {workflow.WorkflowMetadata.Name}", ActivityKind.Internal, Activity.Current?.Context ?? default);
|
||||
activity?.AddTag("workflowInstance.id", workflowInstanceId);
|
||||
activity?.AddTag("workflowDefinition.definitionId", workflow.Identity.DefinitionId);
|
||||
activity?.AddTag("workflowDefinition.version", workflow.Identity.Version);
|
||||
activity?.AddTag("tenantId", workflow.Identity.TenantId);
|
||||
activity?.AddTag("workflowInstance.originalStatus", context.Status.ToString());
|
||||
activity?.AddTag("workflowInstance.originalSubStatus", context.SubStatus.ToString());
|
||||
activity?.AddEvent(new ActivityEvent("Executing"));
|
||||
await Next(context);
|
||||
activity?.AddEvent(new ActivityEvent("Executed"));
|
||||
activity?.AddTag("workflowInstance.newStatus", context.Status.ToString());
|
||||
activity?.AddTag("workflowInstance.newSubStatus", context.SubStatus.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public static class OpenTelemetryWorkflowExecutionMiddlewareExtensions
|
||||
{
|
||||
/// Installs the <see cref="OpenTelemetryTracingWorkflowExecutionMiddleware"/> component in the workflow execution pipeline.
|
||||
public static IWorkflowExecutionPipelineBuilder UseWorkflowExecutionTracing(this IWorkflowExecutionPipelineBuilder pipelineBuilder) => pipelineBuilder.Insert<OpenTelemetryTracingWorkflowExecutionMiddleware>(0);
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using Elsa.WorkflowContexts.Middleware;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Contracts;
|
||||
using Elsa.Workflows.Pipelines.ActivityExecution;
|
||||
using Elsa.Workflows.Pipelines.WorkflowExecution;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Elsa.Workflows.Contracts;
|
||||
namespace Elsa.Workflows;
|
||||
|
||||
public interface IActivityExecutionMiddleware
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Elsa.Workflows.Pipelines.ActivityExecution;
|
||||
|
||||
namespace Elsa.Workflows.Contracts;
|
||||
namespace Elsa.Workflows;
|
||||
|
||||
/// <summary>
|
||||
/// Builds an activity execution pipeline.
|
||||
|
|
@ -19,6 +19,9 @@ public interface IActivityExecutionPipelineBuilder
|
|||
/// <returns>The current <see cref="IActivityExecutionPipelineBuilder"/>.</returns>
|
||||
IActivityExecutionPipelineBuilder Use(Func<ActivityMiddlewareDelegate, ActivityMiddlewareDelegate> middleware);
|
||||
|
||||
/// Inserts the middleware component at the specified index.
|
||||
IActivityExecutionPipelineBuilder Insert(int index, Func<ActivityMiddlewareDelegate, ActivityMiddlewareDelegate> middleware);
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the final <see cref="ActivityMiddlewareDelegate"/> delegate that invokes each installed middleware component.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,41 +1,30 @@
|
|||
using Elsa.Workflows.Pipelines.WorkflowExecution;
|
||||
|
||||
namespace Elsa.Workflows.Contracts;
|
||||
namespace Elsa.Workflows;
|
||||
|
||||
/// <summary>
|
||||
/// Builds a workflow execution pipeline.
|
||||
/// </summary>
|
||||
public interface IWorkflowExecutionPipelineBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// A general-purpose dictionary of values that can be used by middleware components.
|
||||
/// </summary>
|
||||
public IDictionary<object, object?> Properties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The middleware components that have been installed.
|
||||
/// </summary>
|
||||
public IEnumerable<Func<WorkflowMiddlewareDelegate, WorkflowMiddlewareDelegate>> Components { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The current service provider to resolve services from.
|
||||
/// </summary>
|
||||
IServiceProvider ServiceProvider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Installs the specified delegate as a middleware component.
|
||||
/// </summary>
|
||||
IWorkflowExecutionPipelineBuilder Use(Func<WorkflowMiddlewareDelegate, WorkflowMiddlewareDelegate> middleware);
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the final <see cref="WorkflowMiddlewareDelegate"/> delegate that invokes each installed middleware component.
|
||||
/// </summary>
|
||||
public WorkflowMiddlewareDelegate Build();
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// Clears the current pipeline.
|
||||
/// </summary>
|
||||
IWorkflowExecutionPipelineBuilder Reset();
|
||||
|
||||
/// Inserts the middleware component at the specified index.
|
||||
IWorkflowExecutionPipelineBuilder Insert(int index, Func<WorkflowMiddlewareDelegate, WorkflowMiddlewareDelegate> middleware);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the middleware component at the specified index with the specified delegate.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,37 @@
|
|||
using Elsa.Workflows.Contracts;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Workflows.Pipelines.ActivityExecution;
|
||||
|
||||
public static class ActivityExecutionMiddlewareExtensions
|
||||
{
|
||||
public static IActivityExecutionPipelineBuilder UseMiddleware<TMiddleware>(this IActivityExecutionPipelineBuilder pipelineBuilder, params object[] args) where TMiddleware : IActivityExecutionMiddleware
|
||||
public static IActivityExecutionPipelineBuilder UseMiddleware<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TMiddleware>(this IActivityExecutionPipelineBuilder pipelineBuilder, params object[] args) where TMiddleware : IActivityExecutionMiddleware
|
||||
{
|
||||
var delegateFactory = CreateMiddlewareDelegateFactory<TMiddleware>(pipelineBuilder, args);
|
||||
return pipelineBuilder.Use(delegateFactory);
|
||||
}
|
||||
|
||||
public static IActivityExecutionPipelineBuilder Insert<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]TMiddleware>(this IActivityExecutionPipelineBuilder pipelineBuilder, int index, params object[] args) where TMiddleware : IActivityExecutionMiddleware
|
||||
{
|
||||
var delegateFactory = CreateMiddlewareDelegateFactory<TMiddleware>(pipelineBuilder, args);
|
||||
return pipelineBuilder.Insert(index, delegateFactory);
|
||||
}
|
||||
|
||||
/// Creates a middleware delegate for the specified middleware component.
|
||||
public static Func<ActivityMiddlewareDelegate, ActivityMiddlewareDelegate> CreateMiddlewareDelegateFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TMiddleware>(
|
||||
this IActivityExecutionPipelineBuilder pipelineBuilder, params object[] args) where TMiddleware : IActivityExecutionMiddleware
|
||||
{
|
||||
var middleware = typeof(TMiddleware);
|
||||
|
||||
return pipelineBuilder.Use(next =>
|
||||
return next =>
|
||||
{
|
||||
var invokeMethod = MiddlewareHelpers.GetInvokeMethod(middleware);
|
||||
var ctorArgs = new[] { next }.Concat(args).Select(x => x!).ToArray();
|
||||
var ctorArgs = new[]
|
||||
{
|
||||
next
|
||||
}.Concat(args).Select(x => x).ToArray();
|
||||
var instance = ActivatorUtilities.CreateInstance(pipelineBuilder.ServiceProvider, middleware, ctorArgs);
|
||||
return (ActivityMiddlewareDelegate)invokeMethod.CreateDelegate(typeof(ActivityMiddlewareDelegate), instance);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,12 @@
|
|||
using Elsa.Workflows.Contracts;
|
||||
|
||||
namespace Elsa.Workflows.Pipelines.ActivityExecution;
|
||||
|
||||
/// <inheritdoc />
|
||||
public class ActivityExecutionPipelinePipelineBuilder : IActivityExecutionPipelineBuilder
|
||||
public class ActivityExecutionPipelinePipelineBuilder(IServiceProvider serviceProvider) : IActivityExecutionPipelineBuilder
|
||||
{
|
||||
private readonly IList<Func<ActivityMiddlewareDelegate, ActivityMiddlewareDelegate>> _components = new List<Func<ActivityMiddlewareDelegate, ActivityMiddlewareDelegate>>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ActivityExecutionPipelinePipelineBuilder"/> class.
|
||||
/// </summary>
|
||||
public ActivityExecutionPipelinePipelineBuilder(IServiceProvider serviceProvider)
|
||||
{
|
||||
ServiceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IServiceProvider ServiceProvider { get; }
|
||||
public IServiceProvider ServiceProvider { get; } = serviceProvider;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IActivityExecutionPipelineBuilder Use(Func<ActivityMiddlewareDelegate, ActivityMiddlewareDelegate> middleware)
|
||||
|
|
@ -25,6 +15,12 @@ public class ActivityExecutionPipelinePipelineBuilder : IActivityExecutionPipeli
|
|||
return this;
|
||||
}
|
||||
|
||||
public IActivityExecutionPipelineBuilder Insert(int index, Func<ActivityMiddlewareDelegate, ActivityMiddlewareDelegate> middleware)
|
||||
{
|
||||
_components.Insert(index, middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ActivityMiddlewareDelegate Build()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,44 +4,42 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
|
||||
namespace Elsa.Workflows.Pipelines.WorkflowExecution;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extensions to <see cref="IWorkflowExecutionPipelineBuilder"/> that adds support for installing <see cref="IWorkflowExecutionMiddleware"/> components.
|
||||
/// </summary>
|
||||
public static class WorkflowExecutionMiddlewareExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Installs the specified middleware component into the pipeline being built.
|
||||
/// </summary>
|
||||
public static IWorkflowExecutionPipelineBuilder UseMiddleware<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TMiddleware>(
|
||||
this IWorkflowExecutionPipelineBuilder pipelineBuilder, params object[] args) where TMiddleware : IWorkflowExecutionMiddleware
|
||||
{
|
||||
var delegateFactory = CreateMiddlewareDelegateFactory<TMiddleware>(pipelineBuilder, args);
|
||||
return pipelineBuilder.Use(delegateFactory);
|
||||
}
|
||||
|
||||
/// Installs the specified middleware component into the pipeline being built.
|
||||
public static IWorkflowExecutionPipelineBuilder Insert<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TMiddleware>(
|
||||
this IWorkflowExecutionPipelineBuilder pipelineBuilder, int index, params object[] args) where TMiddleware : IWorkflowExecutionMiddleware
|
||||
{
|
||||
var delegateFactory = CreateMiddlewareDelegateFactory<TMiddleware>(pipelineBuilder, args);
|
||||
return pipelineBuilder.Insert(index, delegateFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the terminal middleware component with the specified middleware component.
|
||||
/// </summary>
|
||||
public static IWorkflowExecutionPipelineBuilder ReplaceTerminal<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TMiddleware>(
|
||||
this IWorkflowExecutionPipelineBuilder pipelineBuilder, params object[] args) where TMiddleware : IWorkflowExecutionMiddleware
|
||||
{
|
||||
var index = pipelineBuilder.Components.Count() - 1;
|
||||
return pipelineBuilder.Replace<TMiddleware>(index, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// Replaces the middleware component at the specified index with the specified middleware component.
|
||||
/// </summary>
|
||||
public static IWorkflowExecutionPipelineBuilder Replace<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TMiddleware>(
|
||||
this IWorkflowExecutionPipelineBuilder pipelineBuilder, int index, params object[] args) where TMiddleware : IWorkflowExecutionMiddleware
|
||||
{
|
||||
var delegateFactory = CreateMiddlewareDelegateFactory<TMiddleware>(pipelineBuilder, args);
|
||||
return pipelineBuilder.Replace(index, delegateFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// Creates a middleware delegate for the specified middleware component.
|
||||
/// </summary>
|
||||
public static Func<WorkflowMiddlewareDelegate, WorkflowMiddlewareDelegate> CreateMiddlewareDelegateFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TMiddleware>(
|
||||
this IWorkflowExecutionPipelineBuilder pipelineBuilder, params object[] args) where TMiddleware : IWorkflowExecutionMiddleware
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using Elsa.Workflows.Contracts;
|
||||
|
||||
namespace Elsa.Workflows.Pipelines.WorkflowExecution;
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -54,6 +52,12 @@ public class WorkflowExecutionPipelineBuilder : IWorkflowExecutionPipelineBuilde
|
|||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowExecutionPipelineBuilder Insert(int index, Func<WorkflowMiddlewareDelegate, WorkflowMiddlewareDelegate> middleware)
|
||||
{
|
||||
_components.Insert(index, middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowExecutionPipelineBuilder Replace(int index, Func<WorkflowMiddlewareDelegate, WorkflowMiddlewareDelegate> middleware)
|
||||
{
|
||||
_components[index] = middleware;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Contracts;
|
||||
using Elsa.Workflows.Pipelines.ActivityExecution;
|
||||
using Elsa.Workflows.Runtime.Middleware.Activities;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Features;
|
||||
using Elsa.Workflows.Middleware.Activities;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Elsa.Workflows.Runtime.Extensions;
|
||||
|
||||
/// Adds an extension method to the <see cref="WorkflowsFeature"/> that installs a default workflow runtime execution pipeline.
|
||||
public static class PipelineWorkflowsFeatureExtensions
|
||||
{
|
||||
/// Installs a default workflow runtime execution pipeline.
|
||||
public static WorkflowsFeature WithDefaultWorkflowExecutionPipeline(this WorkflowsFeature workflowsFeature, Action<IWorkflowExecutionPipelineBuilder>? configurePipeline = null)
|
||||
{
|
||||
return workflowsFeature.WithWorkflowExecutionPipeline(pipeline =>
|
||||
{
|
||||
pipeline.UseDefaultPipeline();
|
||||
configurePipeline?.Invoke(pipeline);
|
||||
});
|
||||
}
|
||||
|
||||
/// Installs an activity invoker that can run activities asynchronously in the background.
|
||||
public static WorkflowsFeature WithDefaultActivityExecutionPipeline(this WorkflowsFeature workflowsFeature, Action<IActivityExecutionPipelineBuilder>? configurePipeline = null)
|
||||
{
|
||||
return workflowsFeature.WithActivityExecutionPipeline(pipeline =>
|
||||
{
|
||||
pipeline
|
||||
.UseExceptionHandling()
|
||||
.UseExecutionLogging()
|
||||
.UseNotifications()
|
||||
.UseBackgroundActivityInvoker();
|
||||
|
||||
configurePipeline?.Invoke(pipeline);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
using Elsa.Workflows.Contracts;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Middleware.Workflows;
|
||||
using Elsa.Workflows.Pipelines.WorkflowExecution;
|
||||
using Elsa.Workflows.Runtime.Middleware.Workflows;
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Features;
|
||||
using Elsa.Workflows.Middleware.Activities;
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
namespace Elsa.Workflows.Runtime.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Adds an extension method to the <see cref="WorkflowsFeature"/> that installs a default workflow runtime execution pipeline.
|
||||
/// </summary>
|
||||
public static class WorkflowsFeatureExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Installs a default workflow runtime execution pipeline.
|
||||
/// </summary>
|
||||
public static WorkflowsFeature WithDefaultWorkflowExecutionPipeline(this WorkflowsFeature workflowsFeature) =>
|
||||
workflowsFeature.WithWorkflowExecutionPipeline(pipeline =>
|
||||
pipeline.UseDefaultPipeline());
|
||||
|
||||
/// <summary>
|
||||
/// Installs an activity invoker that can run activities asynchronously in the background.
|
||||
/// </summary>
|
||||
public static WorkflowsFeature WithBackgroundActivityExecutionPipeline(this WorkflowsFeature workflowsFeature) =>
|
||||
workflowsFeature.WithActivityExecutionPipeline(pipeline =>
|
||||
pipeline
|
||||
.UseExceptionHandling()
|
||||
.UseExecutionLogging()
|
||||
.UseNotifications()
|
||||
.UseBackgroundActivityInvoker());
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Contracts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class ElsaFeature : FeatureBase
|
|||
Module
|
||||
.UseWorkflows(workflows => workflows
|
||||
.WithDefaultWorkflowExecutionPipeline()
|
||||
.WithBackgroundActivityExecutionPipeline())
|
||||
.WithDefaultActivityExecutionPipeline())
|
||||
.UseWorkflowManagement(management =>
|
||||
{
|
||||
if (!DisableAutomaticActivityRegistration)
|
||||
|
|
|
|||
Loading…
Reference in a new issue