diff --git a/src/core/Elsa.Abstractions/Services/IWorkflowLaunchpad.cs b/src/core/Elsa.Abstractions/Services/IWorkflowLaunchpad.cs index b37712183..0ae5f1def 100644 --- a/src/core/Elsa.Abstractions/Services/IWorkflowLaunchpad.cs +++ b/src/core/Elsa.Abstractions/Services/IWorkflowLaunchpad.cs @@ -57,7 +57,7 @@ namespace Elsa.Services /// /// Executes a pending workflow. /// - Task ExecutePendingWorkflowAsync(string workflowInstanceId, string? activityId, object? input = default, CancellationToken cancellationToken = default); + Task ExecutePendingWorkflowAsync(string workflowInstanceId, string? activityId, object? input = default, CancellationToken cancellationToken = default); /// /// Dispatches a list of pending workflows for execution. @@ -68,6 +68,11 @@ namespace Elsa.Services /// Dispatches a pending workflow for execution. /// Task DispatchPendingWorkflowAsync(PendingWorkflow pendingWorkflow, object? input, CancellationToken cancellationToken = default); + + /// + /// Dispatches a pending workflow for execution. + /// + Task DispatchPendingWorkflowAsync(string workflowInstanceId, string? activityId, object? input, CancellationToken cancellationToken = default); /// /// Executes the specified startable workflow. diff --git a/src/core/Elsa.Core/Services/WorkflowLaunchpad.cs b/src/core/Elsa.Core/Services/WorkflowLaunchpad.cs index d951ab33d..987af7e45 100644 --- a/src/core/Elsa.Core/Services/WorkflowLaunchpad.cs +++ b/src/core/Elsa.Core/Services/WorkflowLaunchpad.cs @@ -193,15 +193,11 @@ namespace Elsa.Services await _workflowInstanceExecutor.ExecuteAsync(pendingWorkflow.WorkflowInstanceId, pendingWorkflow.ActivityId, input, cancellationToken); } - public async Task ExecutePendingWorkflowAsync(PendingWorkflow pendingWorkflow, object? input = default, CancellationToken cancellationToken = default) - { + public async Task ExecutePendingWorkflowAsync(PendingWorkflow pendingWorkflow, object? input = default, CancellationToken cancellationToken = default) => await _workflowInstanceExecutor.ExecuteAsync(pendingWorkflow.WorkflowInstanceId, pendingWorkflow.ActivityId, input, cancellationToken); - } - public async Task ExecutePendingWorkflowAsync(string workflowInstanceId, string? activityId, object? input = default, CancellationToken cancellationToken = default) - { + public async Task ExecutePendingWorkflowAsync(string workflowInstanceId, string? activityId, object? input = default, CancellationToken cancellationToken = default) => await _workflowInstanceExecutor.ExecuteAsync(workflowInstanceId, activityId, input, cancellationToken); - } public async Task DispatchPendingWorkflowsAsync(IEnumerable pendingWorkflows, object? input, CancellationToken cancellationToken = default) { @@ -212,6 +208,8 @@ namespace Elsa.Services public async Task DispatchPendingWorkflowAsync(PendingWorkflow pendingWorkflow, object? input, CancellationToken cancellationToken = default) => await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(pendingWorkflow.WorkflowInstanceId, pendingWorkflow.ActivityId, input), cancellationToken); + public Task DispatchPendingWorkflowAsync(string workflowInstanceId, string? activityId, object? input, CancellationToken cancellationToken = default) => DispatchPendingWorkflowAsync(new PendingWorkflow(workflowInstanceId, activityId), input, cancellationToken); + public async Task ExecuteStartableWorkflowAsync(StartableWorkflow startableWorkflow, object? input, CancellationToken cancellationToken = default) => await _workflowRunner.RunWorkflowAsync(startableWorkflow.WorkflowBlueprint, startableWorkflow.WorkflowInstance, startableWorkflow.ActivityId, input, cancellationToken); public async Task DispatchStartableWorkflowAsync(StartableWorkflow startableWorkflow, object? input, CancellationToken cancellationToken = default) diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Execute.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Execute.cs index f98a23a6a..7ec7a6561 100644 --- a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Execute.cs +++ b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Execute.cs @@ -26,7 +26,7 @@ namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions [HttpPost] [ElsaJsonFormatter] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(WorkflowDefinitionExecuteResponse))] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ExecuteWorkflowDefinitionResponse))] [ProducesResponseType(StatusCodes.Status404NotFound)] [SwaggerOperation( Summary = "Executes the specified workflow definition.", @@ -46,7 +46,7 @@ namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions if (Response.HasStarted) return new EmptyResult(); - return Ok(new WorkflowDefinitionExecuteResponse( + return Ok(new ExecuteWorkflowDefinitionResponse( result.Executed, result.ActivityId, result.WorkflowInstance diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Models.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Models.cs index e423f3d08..8d5f1a2ce 100644 --- a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Models.cs +++ b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Models.cs @@ -13,9 +13,20 @@ namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions WorkflowPersistenceBehavior PersistenceBehavior, bool IsPublished, bool IsLatest); - + public record ExecuteWorkflowDefinitionRequest(string? ActivityId, string? CorrelationId, string? ContextId, object? Input); - public record WorkflowDefinitionExecuteResponse(bool Executed, string? ActivityId, WorkflowInstance? WorkflowInstance); + + public record ExecuteWorkflowDefinitionResponse(bool Executed, string? ActivityId, WorkflowInstance? WorkflowInstance); + public record DispatchWorkflowDefinitionRequest(string? ActivityId, string? CorrelationId, string? ContextId, object? Input); + public record DispatchWorkflowDefinitionResponse(string WorkflowInstanceId, string? ActivityId); + + public record ExecuteWorkflowInstanceRequest(string? ActivityId, object? Input); + + public record ExecuteWorkflowInstanceResponse(bool Executed, string? ActivityId, WorkflowInstance? WorkflowInstance); + + public record DispatchWorkflowInstanceRequest(string? ActivityId, object? Input); + + public record DispatchWorkflowInstanceResponse(); } \ No newline at end of file diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Dispatch.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Dispatch.cs new file mode 100644 index 000000000..fe617bb14 --- /dev/null +++ b/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Dispatch.cs @@ -0,0 +1,42 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Server.Api.ActionFilters; +using Elsa.Server.Api.Endpoints.WorkflowDefinitions; +using Elsa.Services; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Annotations; + +namespace Elsa.Server.Api.Endpoints.WorkflowInstances +{ + [ApiController] + [ApiVersion("1")] + [Route("v{apiVersion:apiVersion}/workflow-instances/{workflowInstanceId}/dispatch")] + [Produces("application/json")] + public class Dispatch : Controller + { + private readonly IWorkflowLaunchpad _workflowLaunchpad; + + public Dispatch(IWorkflowLaunchpad workflowLaunchpad) + { + _workflowLaunchpad = workflowLaunchpad; + } + + [HttpPost] + [ElsaJsonFormatter] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(DispatchWorkflowInstanceResponse))] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [SwaggerOperation( + Summary = "Dispatches the specified workflow instance.", + Description = "Dispatches the specified workflow instance.", + OperationId = "WorkflowInstances.Dispatch", + Tags = new[] { "WorkflowInstances" }) + ] + public async Task Handle(string workflowInstanceId, DispatchWorkflowInstanceRequest request, CancellationToken cancellationToken = default) + { + await _workflowLaunchpad.DispatchPendingWorkflowAsync(workflowInstanceId, request.ActivityId, request.Input, cancellationToken); + + return Ok(new DispatchWorkflowInstanceResponse()); + } + } +} \ No newline at end of file diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Execute.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Execute.cs new file mode 100644 index 000000000..d307fe5b1 --- /dev/null +++ b/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Execute.cs @@ -0,0 +1,45 @@ +using System.Threading; +using System.Threading.Tasks; +using Elsa.Server.Api.ActionFilters; +using Elsa.Server.Api.Endpoints.WorkflowDefinitions; +using Elsa.Services; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Annotations; + +namespace Elsa.Server.Api.Endpoints.WorkflowInstances +{ + [ApiController] + [ApiVersion("1")] + [Route("v{apiVersion:apiVersion}/workflow-instances/{workflowInstanceId}/execute")] + [Produces("application/json")] + public class Execute : Controller + { + private readonly IWorkflowLaunchpad _workflowLaunchpad; + + public Execute(IWorkflowLaunchpad workflowLaunchpad) + { + _workflowLaunchpad = workflowLaunchpad; + } + + [HttpPost] + [ElsaJsonFormatter] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ExecuteWorkflowInstanceResponse))] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [SwaggerOperation( + Summary = "Executes the specified workflow instance.", + Description = "Executes the specified workflow instance.", + OperationId = "WorkflowInstances.Execute", + Tags = new[] { "WorkflowInstances" }) + ] + public async Task Handle(string workflowInstanceId, ExecuteWorkflowInstanceRequest request, CancellationToken cancellationToken = default) + { + var result = await _workflowLaunchpad.ExecutePendingWorkflowAsync(workflowInstanceId, request.ActivityId, request.Input, cancellationToken); + + if (Response.HasStarted) + return new EmptyResult(); + + return Ok(new ExecuteWorkflowInstanceResponse(result.Executed, result.ActivityId, result.WorkflowInstance)); + } + } +} \ No newline at end of file