Merge pull request #6460 from elsa-workflows/enh/workflowinstance-name
Improved support for named workflow instances
This commit is contained in:
commit
85eec228cf
|
|
@ -47,10 +47,12 @@ using Elsa.Tenants.Extensions;
|
|||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Api;
|
||||
using Elsa.Workflows.CommitStates.Strategies;
|
||||
using Elsa.Workflows.IncidentStrategies;
|
||||
using Elsa.Workflows.LogPersistence;
|
||||
using Elsa.Workflows.Management;
|
||||
using Elsa.Workflows.Management.Compression;
|
||||
using Elsa.Workflows.Management.Stores;
|
||||
using Elsa.Workflows.Options;
|
||||
using Elsa.Workflows.Runtime.Distributed.Extensions;
|
||||
using Elsa.Workflows.Runtime.Options;
|
||||
using Elsa.Workflows.Runtime.Stores;
|
||||
|
|
@ -705,7 +707,7 @@ services.Configure<RecurringTaskOptions>(options =>
|
|||
services.Configure<RuntimeOptions>(options => { options.InactivityThreshold = TimeSpan.FromSeconds(15); });
|
||||
services.Configure<BookmarkQueuePurgeOptions>(options => options.Ttl = TimeSpan.FromSeconds(10));
|
||||
services.Configure<CachingOptions>(options => options.CacheDuration = TimeSpan.FromDays(1));
|
||||
|
||||
services.Configure<IncidentOptions>(options => options.DefaultIncidentStrategy = typeof(ContinueWithIncidentsStrategy));
|
||||
services.AddHealthChecks();
|
||||
services.AddControllers();
|
||||
services.AddCors(cors => cors.AddDefaultPolicy(policy => policy.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().WithExposedHeaders("*")));
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Elsa.CSharp.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to global objects, such as the workflow execution context.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public partial class Globals
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -15,9 +17,9 @@ public partial class Globals
|
|||
{
|
||||
ExpressionExecutionContext = expressionExecutionContext;
|
||||
Arguments = arguments;
|
||||
ExecutionContext = new ExecutionContextProxy(expressionExecutionContext);
|
||||
Output = new OutputProxy(expressionExecutionContext);
|
||||
Outcome = new OutcomeProxy(expressionExecutionContext);
|
||||
ExecutionContext = new(expressionExecutionContext);
|
||||
Output = new(expressionExecutionContext);
|
||||
Outcome = new(expressionExecutionContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -48,6 +50,15 @@ public partial class Globals
|
|||
get => ExpressionExecutionContext.GetWorkflowExecutionContext().CorrelationId;
|
||||
set => ExpressionExecutionContext.GetWorkflowExecutionContext().CorrelationId = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the current workflow instance.
|
||||
/// </summary>
|
||||
public string? WorkflowInstanceName
|
||||
{
|
||||
get => ExpressionExecutionContext.GetWorkflowExecutionContext().Name;
|
||||
set => ExpressionExecutionContext.GetWorkflowExecutionContext().Name = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets additional arguments provided by the caller of the evaluator.
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ public class ConfigureEngineWithCommonFunctions(IOptions<JintOptions> options) :
|
|||
engine.SetValue("getWorkflowInstanceId", (Func<string>)(() => context.GetActivityExecutionContext().WorkflowExecutionContext.Id));
|
||||
engine.SetValue("setCorrelationId", (Action<string?>)(value => context.GetActivityExecutionContext().WorkflowExecutionContext.CorrelationId = value));
|
||||
engine.SetValue("getCorrelationId", (Func<string?>)(() => context.GetActivityExecutionContext().WorkflowExecutionContext.CorrelationId));
|
||||
engine.SetValue("setWorkflowInstanceName", (Action<string?>)(value => context.GetWorkflowExecutionContext().Name = value));
|
||||
engine.SetValue("getWorkflowInstanceName", (Func<string?>)(() => context.GetWorkflowExecutionContext().Name));
|
||||
engine.SetValue("setVariable", (Action<string, object>)((name, value) =>
|
||||
{
|
||||
engine.SyncVariablesContainer(options, name, value);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,14 @@ internal class CommonFunctionsDefinitionProvider(ITypeAliasRegistry typeAliasReg
|
|||
yield return CreateFunctionDefinition(builder => builder
|
||||
.Name("setCorrelationId")
|
||||
.Parameter("value", "string"));
|
||||
|
||||
yield return CreateFunctionDefinition(builder => builder
|
||||
.Name("getWorkflowInstanceName")
|
||||
.ReturnType("string"));
|
||||
|
||||
yield return CreateFunctionDefinition(builder => builder
|
||||
.Name("setWorkflowInstanceName")
|
||||
.Parameter("value", "string"));
|
||||
|
||||
yield return CreateFunctionDefinition(builder => builder
|
||||
.Name("setVariable")
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ internal abstract class EndpointBase<T>(
|
|||
{
|
||||
Workflow = workflowGraph.Workflow,
|
||||
CorrelationId = request.CorrelationId,
|
||||
Name = request.Name,
|
||||
Input = request.GetInputAsDictionary(),
|
||||
Variables = request.GetVariablesAsDictionary(),
|
||||
TriggerActivityId = request.TriggerActivityId,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public interface IExecutionRequest
|
|||
{
|
||||
string DefinitionId { get; }
|
||||
string? CorrelationId { get; }
|
||||
string? Name { get; }
|
||||
string? TriggerActivityId { get; }
|
||||
ActivityHandle? ActivityHandle { get; }
|
||||
VersionOptions? VersionOptions { get; }
|
||||
|
|
@ -25,6 +26,7 @@ public class PostRequest : IExecutionRequest
|
|||
{
|
||||
public string DefinitionId { get; set; } = null!;
|
||||
public string? CorrelationId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? TriggerActivityId { get; set; }
|
||||
public ActivityHandle? ActivityHandle { get; set; }
|
||||
public VersionOptions? VersionOptions { get; set; }
|
||||
|
|
@ -43,6 +45,7 @@ public class GetRequest : IExecutionRequest
|
|||
{
|
||||
public string DefinitionId { get; set; } = null!;
|
||||
public string? CorrelationId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? TriggerActivityId { get; set; }
|
||||
public ActivityHandle? ActivityHandle { get; set; }
|
||||
public VersionOptions? VersionOptions { get; set; }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Models;
|
||||
using JetBrains.Annotations;
|
||||
|
|
@ -12,18 +13,13 @@ namespace Elsa.Workflows.Activities;
|
|||
[PublicAPI]
|
||||
public class SetName : CodeActivity
|
||||
{
|
||||
/// <summary>
|
||||
/// The property key name used to store the workflow instance name.
|
||||
/// </summary>
|
||||
public const string WorkflowInstanceNameKey = "WorkflowInstanceName";
|
||||
|
||||
/// <inheritdoc />
|
||||
public SetName([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
|
||||
public SetName([CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : base(source, line)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public SetName(Input<string> value, [CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : this(source, line)
|
||||
public SetName(Input<string> value, [CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : this(source, line)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
|
@ -36,7 +32,7 @@ public class SetName : CodeActivity
|
|||
/// <inheritdoc />
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
{
|
||||
var value = context.Get(Value);
|
||||
context.WorkflowExecutionContext.SetProperty(WorkflowInstanceNameKey, value!);
|
||||
var value = Value.GetOrDefault(context);
|
||||
context.WorkflowExecutionContext.Name = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -71,8 +71,8 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
_activityExecutionContexts = new List<ActivityExecutionContext>();
|
||||
Scheduler = serviceProvider.GetRequiredService<IActivitySchedulerFactory>().CreateScheduler();
|
||||
IdentityGenerator = serviceProvider.GetRequiredService<IIdentityGenerator>();
|
||||
Input = input != null ? new Dictionary<string, object>(input, StringComparer.OrdinalIgnoreCase) : new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
Properties = properties != null ? new Dictionary<string, object>(properties, StringComparer.OrdinalIgnoreCase) : new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
Input = input != null ? new(input, StringComparer.OrdinalIgnoreCase) : new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
Properties = properties != null ? new(properties, StringComparer.OrdinalIgnoreCase) : new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
ExecuteDelegate = executeDelegate;
|
||||
TriggerActivityId = triggerActivityId;
|
||||
CreatedAt = createdAt;
|
||||
|
|
@ -193,7 +193,7 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
MemoryRegister = workflowGraph.Workflow.CreateRegister()
|
||||
};
|
||||
|
||||
workflowExecutionContext.ExpressionExecutionContext = new ExpressionExecutionContext(serviceProvider, workflowExecutionContext.MemoryRegister, cancellationToken: cancellationToken);
|
||||
workflowExecutionContext.ExpressionExecutionContext = new(serviceProvider, workflowExecutionContext.MemoryRegister, cancellationToken: cancellationToken);
|
||||
|
||||
await workflowExecutionContext.SetWorkflowGraphAsync(workflowGraph);
|
||||
return workflowExecutionContext;
|
||||
|
|
@ -264,6 +264,9 @@ public partial class WorkflowExecutionContext : IExecutionContext
|
|||
/// An application-specific identifier associated with the execution context.
|
||||
public string? CorrelationId { get; set; }
|
||||
|
||||
/// Gets or sets the name of the workflow instance.
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// The ID of the workflow instance that triggered this instance.
|
||||
public string? ParentWorkflowInstanceId { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ public class JsonWorkflowStateSerializer : ConfigurableSerializer, IWorkflowStat
|
|||
public override JsonSerializerOptions GetOptions()
|
||||
{
|
||||
var options = base.GetOptions();
|
||||
return new JsonSerializerOptions(options)
|
||||
return new(options)
|
||||
{
|
||||
ReferenceHandler = new CrossScopedReferenceHandler()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class WorkflowStateExtractor : IWorkflowStateExtractor
|
|||
DefinitionVersionId = workflowExecutionContext.Workflow.Identity.Id,
|
||||
DefinitionVersion = workflowExecutionContext.Workflow.Identity.Version,
|
||||
CorrelationId = workflowExecutionContext.CorrelationId,
|
||||
Name = workflowExecutionContext.Name,
|
||||
ParentWorkflowInstanceId = workflowExecutionContext.ParentWorkflowInstanceId,
|
||||
Status = workflowExecutionContext.Status,
|
||||
SubStatus = workflowExecutionContext.SubStatus,
|
||||
|
|
@ -46,6 +47,7 @@ public class WorkflowStateExtractor : IWorkflowStateExtractor
|
|||
{
|
||||
workflowExecutionContext.Id = state.Id;
|
||||
workflowExecutionContext.CorrelationId = state.CorrelationId;
|
||||
workflowExecutionContext.Name = state.Name;
|
||||
workflowExecutionContext.ParentWorkflowInstanceId = state.ParentWorkflowInstanceId;
|
||||
workflowExecutionContext.SubStatus = state.SubStatus;
|
||||
workflowExecutionContext.IsExecuting = state.IsExecuting;
|
||||
|
|
|
|||
|
|
@ -11,17 +11,17 @@ public class WorkflowState
|
|||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
/// </summary>
|
||||
public string Id { get; set; } = default!;
|
||||
public string Id { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The workflow definition ID.
|
||||
/// </summary>
|
||||
public string DefinitionId { get; set; } = default!;
|
||||
public string DefinitionId { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The workflow definition version ID.
|
||||
/// </summary>
|
||||
public string DefinitionVersionId { get; set; } = default!;
|
||||
public string DefinitionVersionId { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The workflow definition version.
|
||||
|
|
@ -37,6 +37,11 @@ public class WorkflowState
|
|||
/// The correlation ID of the workflow, if any.
|
||||
/// </summary>
|
||||
public string? CorrelationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the workflow instance.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The status of the workflow.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Management.Entities;
|
||||
using Elsa.Workflows.State;
|
||||
|
||||
|
|
@ -23,7 +21,7 @@ public class WorkflowStateMapper
|
|||
|
||||
return workflowInstance;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Maps a workflow state to a workflow instance.
|
||||
/// </summary>
|
||||
|
|
@ -39,14 +37,12 @@ public class WorkflowStateMapper
|
|||
target.SubStatus = source.SubStatus;
|
||||
target.IsExecuting = source.IsExecuting;
|
||||
target.CorrelationId = source.CorrelationId;
|
||||
target.Name = source.Name;
|
||||
target.IncidentCount = source.Incidents.Count;
|
||||
target.IsSystem = source.IsSystem;
|
||||
target.UpdatedAt = source.UpdatedAt;
|
||||
target.FinishedAt = source.FinishedAt;
|
||||
target.WorkflowState = source;
|
||||
|
||||
if (source.Properties.TryGetValue<string>(SetName.WorkflowInstanceNameKey, out var name))
|
||||
target.Name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -68,13 +64,11 @@ public class WorkflowStateMapper
|
|||
workflowState.SubStatus = source.SubStatus;
|
||||
workflowState.IsExecuting = source.IsExecuting;
|
||||
workflowState.CorrelationId = source.CorrelationId;
|
||||
workflowState.Name = source.Name;
|
||||
workflowState.UpdatedAt = source.UpdatedAt;
|
||||
workflowState.FinishedAt = source.FinishedAt;
|
||||
workflowState.IsSystem = source.IsSystem;
|
||||
|
||||
if (source.Name != null)
|
||||
workflowState.Properties[SetName.WorkflowInstanceNameKey] = source.Name;
|
||||
|
||||
return workflowState;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,11 @@ public class WorkflowInstanceOptions
|
|||
/// </summary>
|
||||
public string? CorrelationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the workflow instance.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The input to the workflow instance, if any.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public class WorkflowInstanceFactory(IIdentityGenerator identityGenerator, ISyst
|
|||
DefinitionVersionId = workflow.Identity.Id,
|
||||
DefinitionVersion = workflow.Identity.Version,
|
||||
CorrelationId = options?.CorrelationId,
|
||||
Name = options?.Name,
|
||||
Input = options?.Input ?? new Dictionary<string, object>(),
|
||||
Properties = options?.Properties ?? new Dictionary<string, object>(),
|
||||
Status = WorkflowStatus.Running,
|
||||
|
|
@ -45,6 +46,7 @@ public class WorkflowInstanceFactory(IIdentityGenerator identityGenerator, ISyst
|
|||
DefinitionVersionId = workflowState.DefinitionVersionId,
|
||||
Version = workflowState.DefinitionVersion,
|
||||
CorrelationId = workflowState.CorrelationId,
|
||||
Name = workflowState.Name,
|
||||
Status = workflowState.Status,
|
||||
SubStatus = workflowState.SubStatus,
|
||||
IncidentCount = workflowState.Incidents.Count,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public class CreateAndRunWorkflowInstanceRequestMapper(WorkflowDefinitionHandleM
|
|||
WorkflowDefinitionHandle = workflowDefinitionHandleMapper.Map(source.WorkflowDefinitionHandle),
|
||||
WorkflowInstanceId = workflowInstanceId.EmptyIfNull(),
|
||||
CorrelationId = source.CorrelationId.EmptyIfNull(),
|
||||
Name = source.Name.EmptyIfNull(),
|
||||
ParentId = source.ParentId.EmptyIfNull(),
|
||||
Input = source.Input?.SerializeInput() ?? new ProtoInput(),
|
||||
Properties = source.Properties?.SerializeProperties() ?? new ProtoProperties(),
|
||||
|
|
@ -41,8 +42,9 @@ public class CreateAndRunWorkflowInstanceRequestMapper(WorkflowDefinitionHandleM
|
|||
return new()
|
||||
{
|
||||
WorkflowDefinitionHandle = workflowDefinitionHandleMapper.Map(source.WorkflowDefinitionHandle),
|
||||
CorrelationId = source.CorrelationId,
|
||||
ParentId = source.ParentId,
|
||||
CorrelationId = source.CorrelationId.NullIfEmpty(),
|
||||
Name = source.Name.NullIfEmpty(),
|
||||
ParentId = source.ParentId.NullIfEmpty(),
|
||||
Input = source.Input?.DeserializeInput(),
|
||||
Properties = source.Properties?.DeserializeProperties(),
|
||||
ActivityHandle = activityHandleMapper.Map(source.ActivityHandle),
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ public class CreateWorkflowInstanceRequestMapper(WorkflowDefinitionHandleMapper
|
|||
WorkflowDefinitionHandle = workflowDefinitionHandleMapper.Map(source.WorkflowDefinitionHandle),
|
||||
WorkflowInstanceId = workflowInstanceId,
|
||||
CorrelationId = source.CorrelationId.EmptyIfNull(),
|
||||
Name = source.Name.EmptyIfNull(),
|
||||
ParentId = source.ParentId.EmptyIfNull(),
|
||||
Input = source.Input?.SerializeInput() ?? new ProtoInput(),
|
||||
Properties = source.Properties?.SerializeProperties() ?? new ProtoProperties()
|
||||
|
|
@ -40,8 +41,9 @@ public class CreateWorkflowInstanceRequestMapper(WorkflowDefinitionHandleMapper
|
|||
return new()
|
||||
{
|
||||
WorkflowDefinitionHandle = workflowDefinitionHandleMapper.Map(source.WorkflowDefinitionHandle),
|
||||
CorrelationId = source.CorrelationId,
|
||||
ParentId = source.ParentId,
|
||||
CorrelationId = source.CorrelationId.NullIfEmpty(),
|
||||
Name = source.Name.NullIfEmpty(),
|
||||
ParentId = source.ParentId.NullIfEmpty(),
|
||||
Input = source.Input?.DeserializeInput(),
|
||||
Properties = source.Properties?.DeserializeProperties()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,9 +45,10 @@ message CreateWorkflowInstanceRequest{
|
|||
WorkflowDefinitionHandle WorkflowDefinitionHandle = 1;
|
||||
string WorkflowInstanceId = 2;
|
||||
optional string CorrelationId = 3;
|
||||
optional string ParentId = 4;
|
||||
optional Input input = 5;
|
||||
optional Properties properties = 6;
|
||||
optional string Name = 4;
|
||||
optional string ParentId = 5;
|
||||
optional Input input = 6;
|
||||
optional Properties properties = 7;
|
||||
}
|
||||
|
||||
message CreateWorkflowInstanceResponse{
|
||||
|
|
@ -71,11 +72,12 @@ message CreateAndRunWorkflowInstanceRequest{
|
|||
WorkflowDefinitionHandle WorkflowDefinitionHandle = 1;
|
||||
string WorkflowInstanceId = 2;
|
||||
optional string CorrelationId = 3;
|
||||
optional string ParentId = 4;
|
||||
optional Input input = 5;
|
||||
optional Properties properties = 6;
|
||||
optional ActivityHandle ActivityHandle = 7;
|
||||
optional string TriggerActivityId = 8;
|
||||
optional string Name = 4;
|
||||
optional string ParentId = 5;
|
||||
optional Input input = 6;
|
||||
optional Properties properties = 7;
|
||||
optional ActivityHandle ActivityHandle = 8;
|
||||
optional string TriggerActivityId = 9;
|
||||
}
|
||||
|
||||
message ExportWorkflowStateResponse {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ public class CreateAndRunWorkflowInstanceRequest
|
|||
/// The correlation ID of the workflow, if any.
|
||||
/// </summary>
|
||||
public string? CorrelationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the workflow instance to be created.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The input to the workflow instance, if any.
|
||||
|
|
|
|||
|
|
@ -12,13 +12,18 @@ public class CreateWorkflowInstanceRequest
|
|||
/// <summary>
|
||||
/// The ID of the workflow definition version to create an instance of.
|
||||
/// </summary>
|
||||
public WorkflowDefinitionHandle WorkflowDefinitionHandle { get; set; } = default!;
|
||||
public WorkflowDefinitionHandle WorkflowDefinitionHandle { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The correlation ID of the workflow, if any.
|
||||
/// </summary>
|
||||
public string? CorrelationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the workflow instance to be created.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The input to the workflow instance, if any.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ public class StartWorkflowRequest
|
|||
/// </summary>
|
||||
public string? CorrelationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name to use when starting a new workflow instance.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The input to the workflow instance, if any.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ public class DefaultWorkflowStarter(IWorkflowDefinitionService workflowDefinitio
|
|||
{
|
||||
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionVersionId(workflow.Identity.Id),
|
||||
CorrelationId = request.CorrelationId,
|
||||
Name = request.Name,
|
||||
Input = request.Input,
|
||||
Variables = request.Variables,
|
||||
TriggerActivityId = request.TriggerActivityId,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public class LocalWorkflowClient(
|
|||
{
|
||||
WorkflowInstanceId = WorkflowInstanceId,
|
||||
CorrelationId = request.CorrelationId,
|
||||
Name = request.Name,
|
||||
ParentWorkflowInstanceId = request.ParentId,
|
||||
Input = request.Input,
|
||||
Properties = request.Properties
|
||||
|
|
@ -58,6 +59,7 @@ public class LocalWorkflowClient(
|
|||
{
|
||||
Properties = request.Properties,
|
||||
CorrelationId = request.CorrelationId,
|
||||
Name = request.Name,
|
||||
Input = request.Input,
|
||||
WorkflowDefinitionHandle = request.WorkflowDefinitionHandle,
|
||||
ParentId = request.ParentId
|
||||
|
|
@ -150,6 +152,7 @@ public class LocalWorkflowClient(
|
|||
{
|
||||
WorkflowInstanceId = WorkflowInstanceId,
|
||||
CorrelationId = request.CorrelationId,
|
||||
Name = request.Name,
|
||||
ParentWorkflowInstanceId = request.ParentId,
|
||||
Input = request.Input,
|
||||
Properties = request.Properties
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ public class SetNameTests
|
|||
_serviceProvider = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "WriteLine prints the expected line to the console.")]
|
||||
[Fact(DisplayName = "SetName sets the workflow instance name.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
const string expectedName = "Foo";
|
||||
var setName = new SetName(new Input<string>(expectedName));
|
||||
var result = await _serviceProvider.RunActivityAsync(setName);
|
||||
var actualName = result.WorkflowState.Properties[SetName.WorkflowInstanceNameKey];
|
||||
var actualName = result.WorkflowState.Name;
|
||||
Assert.Equal(expectedName, actualName);
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ public class DefaultRuntimeTests
|
|||
|
||||
const string workflowDefinitionId = nameof(SimpleSuspendedWorkflow);
|
||||
var workflowClient = await _workflowRuntime.CreateClientAsync();
|
||||
await workflowClient.CreateInstanceAsync(new CreateWorkflowInstanceRequest
|
||||
await workflowClient.CreateInstanceAsync(new()
|
||||
{
|
||||
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionId(workflowDefinitionId, VersionOptions.Published)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
using Elsa.Common.Models;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.WorkflowInstanceName.Workflows;
|
||||
using Elsa.Workflows.Models;
|
||||
using Elsa.Workflows.Runtime;
|
||||
using Elsa.Workflows.Runtime.Messages;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.WorkflowInstanceName;
|
||||
|
||||
public class WorkflowInstanceNameTests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IWorkflowRuntime _workflowRuntime;
|
||||
|
||||
public WorkflowInstanceNameTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.AddWorkflow<NamedWorkflow>()
|
||||
.Build();
|
||||
|
||||
_workflowRuntime = _services.GetRequiredService<IWorkflowRuntime>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Setting a workflow instance name keeps the workflow instance name when the workflow is executed")]
|
||||
public async Task SuspendedCancelTest()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
const string workflowDefinitionId = nameof(NamedWorkflow);
|
||||
var desiredName = Guid.NewGuid().ToString();
|
||||
var workflowClient = await _workflowRuntime.CreateClientAsync();
|
||||
await workflowClient.CreateInstanceAsync(new()
|
||||
{
|
||||
Name = desiredName,
|
||||
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionId(workflowDefinitionId, VersionOptions.Published)
|
||||
});
|
||||
await workflowClient.RunInstanceAsync(RunWorkflowInstanceRequest.Empty);
|
||||
var workflowState = await workflowClient.ExportStateAsync();
|
||||
|
||||
Assert.Equal([desiredName], _capturingTextWriter.Lines);
|
||||
Assert.Equal(desiredName, workflowState.Name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.WorkflowInstanceName.Workflows;
|
||||
|
||||
public class NamedWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
builder.Root = new WriteLine(x => x.GetWorkflowExecutionContext().Name);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue