diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Dispatch.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Dispatch.cs deleted file mode 100644 index 4c35837e1..000000000 --- a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Dispatch.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using Elsa.Server.Api.ActionFilters; -using Elsa.Services; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Swashbuckle.AspNetCore.Annotations; - -namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions -{ - [ApiController] - [ApiVersion("1")] - [Route("v{apiVersion:apiVersion}/workflow-definitions/{workflowDefinitionId}/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(DispatchWorkflowDefinitionResponse))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [SwaggerOperation( - Summary = "Executes the specified workflow definition.", - Description = "Executes the specified workflow definition.", - OperationId = "WorkflowDefinitions.Execute", - Tags = new[] { "WorkflowDefinitions" }) - ] - public async Task Handle(string workflowDefinitionId, DispatchWorkflowDefinitionRequest request, CancellationToken cancellationToken = default) - { - var startableWorkflow = await _workflowLaunchpad.CollectStartableWorkflowAsync(workflowDefinitionId, request.ActivityId, request.CorrelationId, request.ContextId, default, cancellationToken); - - if (startableWorkflow == null) - return NotFound(); - - var result = await _workflowLaunchpad.DispatchStartableWorkflowAsync(startableWorkflow, request.Input, cancellationToken); - return Ok(new DispatchWorkflowDefinitionResponse(result.WorkflowInstanceId, result.ActivityId)); - } - } -} \ No newline at end of file diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Execute.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Execute.cs deleted file mode 100644 index 3a3416bd3..000000000 --- a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Execute.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using Elsa.Server.Api.ActionFilters; -using Elsa.Services; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Swashbuckle.AspNetCore.Annotations; - -namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions -{ - [ApiController] - [ApiVersion("1")] - [Route("v{apiVersion:apiVersion}/workflow-definitions/{workflowDefinitionId}/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(ExecuteWorkflowDefinitionResponse))] - [ProducesResponseType(StatusCodes.Status404NotFound)] - [SwaggerOperation( - Summary = "Executes the specified workflow definition.", - Description = "Executes the specified workflow definition.", - OperationId = "WorkflowDefinitions.Execute", - Tags = new[] { "WorkflowDefinitions" }) - ] - public async Task Handle(string workflowDefinitionId, ExecuteWorkflowDefinitionRequest request, CancellationToken cancellationToken = default) - { - var startableWorkflow = await _workflowLaunchpad.CollectStartableWorkflowAsync(workflowDefinitionId, request.ActivityId, request.CorrelationId, request.ContextId, default, cancellationToken); - - if (startableWorkflow == null) - return NotFound(); - - var result = await _workflowLaunchpad.ExecuteStartableWorkflowAsync(startableWorkflow, request.Input, cancellationToken); - - if (Response.HasStarted) - return new EmptyResult(); - - return Ok(new ExecuteWorkflowDefinitionResponse( - result.Executed, - result.ActivityId, - result.WorkflowInstance - )); - } - } -} \ No newline at end of file diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Models.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Models.cs index e5d2a1859..d35e956fe 100644 --- a/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Models.cs +++ b/src/server/Elsa.Server.Api/Endpoints/WorkflowDefinitions/Models.cs @@ -33,11 +33,12 @@ namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions public record DispatchWorkflowInstanceResponse(); - public record ExecuteWorkflowsRequest(string ActivityType, IBookmark? Bookmark, IBookmark? Trigger, string? CorrelationId, string? WorkflowInstanceId, string? ContextId, object? Input); + public record TriggerWorkflowsRequest(string ActivityType, IBookmark? Bookmark, IBookmark? Trigger, string? CorrelationId, string? WorkflowInstanceId, string? ContextId, object? Input, bool Dispatch); - public record ExecuteWorkflowsResponse(ICollection StartedWorkflows); + public record TriggerWorkflowsResponse(ICollection TriggeredWorkflows); + public record TriggeredWorkflow(string WorkflowInstanceId, string? ActivityId); - public record DispatchWorkflowsRequest(string ActivityType, IBookmark? Bookmark, IBookmark? Trigger, string? CorrelationId, string? WorkflowInstanceId, string? ContextId, object? Input); + public record DispatchTriggerWorkflowsRequest(string ActivityType, IBookmark? Bookmark, IBookmark? Trigger, string? CorrelationId, string? WorkflowInstanceId, string? ContextId, object? Input); - public record DispatchWorkflowsResponse(ICollection PendingWorkflows); + public record DispatchTriggerWorkflowsResponse(ICollection PendingWorkflows); } \ No newline at end of file diff --git a/src/server/Elsa.Server.Api/Endpoints/Workflows/Dispatch.cs b/src/server/Elsa.Server.Api/Endpoints/Workflows/Dispatch.cs index c61518528..37e68263c 100644 --- a/src/server/Elsa.Server.Api/Endpoints/Workflows/Dispatch.cs +++ b/src/server/Elsa.Server.Api/Endpoints/Workflows/Dispatch.cs @@ -5,14 +5,13 @@ using Elsa.Server.Api.Endpoints.WorkflowDefinitions; using Elsa.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Open.Linq.AsyncExtensions; using Swashbuckle.AspNetCore.Annotations; namespace Elsa.Server.Api.Endpoints.Workflows { [ApiController] [ApiVersion("1")] - [Route("v{apiVersion:apiVersion}/workflows/dispatch")] + [Route("v{apiVersion:apiVersion}/workflows/{workflowDefinitionId}/dispatch")] [Produces("application/json")] public class Dispatch : Controller { @@ -25,23 +24,23 @@ namespace Elsa.Server.Api.Endpoints.Workflows [HttpPost] [ElsaJsonFormatter] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(DispatchWorkflowsResponse))] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(DispatchWorkflowDefinitionResponse))] [ProducesResponseType(StatusCodes.Status404NotFound)] [SwaggerOperation( - Summary = "Triggers all workflows matching the specified criteria asynchronously.", - Description = "Triggers all workflows matching the specified criteria asynchronously.", + Summary = "Executes the specified workflow definition.", + Description = "Executes the specified workflow definition.", OperationId = "Workflows.Dispatch", Tags = new[] { "Workflows" }) ] - public async Task Handle(DispatchWorkflowsRequest request, CancellationToken cancellationToken = default) + public async Task Handle(string workflowDefinitionId, DispatchWorkflowDefinitionRequest request, CancellationToken cancellationToken = default) { - var context = new CollectWorkflowsContext(request.ActivityType, request.Bookmark, request.Trigger, request.CorrelationId, request.WorkflowInstanceId, request.ContextId); - var result = await _workflowLaunchpad.CollectAndDispatchWorkflowsAsync(context, request.Input, cancellationToken).ToList(); + var startableWorkflow = await _workflowLaunchpad.CollectStartableWorkflowAsync(workflowDefinitionId, request.ActivityId, request.CorrelationId, request.ContextId, default, cancellationToken); - if (Response.HasStarted) - return new EmptyResult(); - - return Ok(new DispatchWorkflowsResponse(result)); + if (startableWorkflow == null) + return NotFound(); + + var result = await _workflowLaunchpad.DispatchStartableWorkflowAsync(startableWorkflow, request.Input, cancellationToken); + return Ok(new DispatchWorkflowDefinitionResponse(result.WorkflowInstanceId, result.ActivityId)); } } } \ No newline at end of file diff --git a/src/server/Elsa.Server.Api/Endpoints/Workflows/Execute.cs b/src/server/Elsa.Server.Api/Endpoints/Workflows/Execute.cs index 15fb9c42a..54c2d9802 100644 --- a/src/server/Elsa.Server.Api/Endpoints/Workflows/Execute.cs +++ b/src/server/Elsa.Server.Api/Endpoints/Workflows/Execute.cs @@ -5,14 +5,13 @@ using Elsa.Server.Api.Endpoints.WorkflowDefinitions; using Elsa.Services; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Open.Linq.AsyncExtensions; using Swashbuckle.AspNetCore.Annotations; namespace Elsa.Server.Api.Endpoints.Workflows { [ApiController] [ApiVersion("1")] - [Route("v{apiVersion:apiVersion}/workflows/execute")] + [Route("v{apiVersion:apiVersion}/workflows/{workflowDefinitionId}/execute")] [Produces("application/json")] public class Execute : Controller { @@ -25,23 +24,31 @@ namespace Elsa.Server.Api.Endpoints.Workflows [HttpPost] [ElsaJsonFormatter] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ExecuteWorkflowsResponse))] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(ExecuteWorkflowDefinitionResponse))] [ProducesResponseType(StatusCodes.Status404NotFound)] [SwaggerOperation( - Summary = "Triggers all workflows matching the specified criteria synchronously.", - Description = "Triggers all workflows matching the specified criteria synchronously.", - OperationId = "Workflows.Execute", - Tags = new[] { "Workflows" }) + Summary = "Executes the specified workflow definition.", + Description = "Executes the specified workflow definition.", + OperationId = "WorkflowDefinitions.Execute", + Tags = new[] { "WorkflowDefinitions" }) ] - public async Task Handle(ExecuteWorkflowsRequest request, CancellationToken cancellationToken = default) + public async Task Handle(string workflowDefinitionId, ExecuteWorkflowDefinitionRequest request, CancellationToken cancellationToken = default) { - var context = new CollectWorkflowsContext(request.ActivityType, request.Bookmark, request.Trigger, request.CorrelationId, request.WorkflowInstanceId, request.ContextId); - var result = await _workflowLaunchpad.CollectAndExecuteWorkflowsAsync(context, request.Input, cancellationToken).ToList(); + var startableWorkflow = await _workflowLaunchpad.CollectStartableWorkflowAsync(workflowDefinitionId, request.ActivityId, request.CorrelationId, request.ContextId, default, cancellationToken); + + if (startableWorkflow == null) + return NotFound(); + + var result = await _workflowLaunchpad.ExecuteStartableWorkflowAsync(startableWorkflow, request.Input, cancellationToken); if (Response.HasStarted) return new EmptyResult(); - return Ok(new ExecuteWorkflowsResponse(result)); + return Ok(new ExecuteWorkflowDefinitionResponse( + result.Executed, + result.ActivityId, + result.WorkflowInstance + )); } } } \ No newline at end of file diff --git a/src/server/Elsa.Server.Api/Endpoints/Workflows/Trigger.cs b/src/server/Elsa.Server.Api/Endpoints/Workflows/Trigger.cs new file mode 100644 index 000000000..b7b0d6f08 --- /dev/null +++ b/src/server/Elsa.Server.Api/Endpoints/Workflows/Trigger.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using System.Linq; +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 Open.Linq.AsyncExtensions; +using Swashbuckle.AspNetCore.Annotations; + +namespace Elsa.Server.Api.Endpoints.Workflows +{ + [ApiController] + [ApiVersion("1")] + [Route("v{apiVersion:apiVersion}/workflows/trigger")] + [Produces("application/json")] + public class Trigger : Controller + { + private readonly IWorkflowLaunchpad _workflowLaunchpad; + public Trigger(IWorkflowLaunchpad workflowLaunchpad) => _workflowLaunchpad = workflowLaunchpad; + + [HttpPost] + [ElsaJsonFormatter] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(TriggerWorkflowsResponse))] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [SwaggerOperation( + Summary = "Triggers all workflows matching the specified criteria synchronously.", + Description = "Triggers all workflows matching the specified criteria synchronously.", + OperationId = "Workflows.Execute", + Tags = new[] { "Workflows" }) + ] + public async Task Handle(TriggerWorkflowsRequest request, CancellationToken cancellationToken = default) + { + var context = new CollectWorkflowsContext(request.ActivityType, request.Bookmark, request.Trigger, request.CorrelationId, request.WorkflowInstanceId, request.ContextId); + ICollection triggeredWorkflows; + + if (request.Dispatch) + { + var result = await _workflowLaunchpad.CollectAndDispatchWorkflowsAsync(context, request.Input, cancellationToken).ToList(); + triggeredWorkflows = result.Select(x => new TriggeredWorkflow(x.WorkflowInstanceId, x.ActivityId)).ToList(); + } + else + { + var result = await _workflowLaunchpad.CollectAndExecuteWorkflowsAsync(context, request.Input, cancellationToken).ToList(); + triggeredWorkflows = result.Select(x => new TriggeredWorkflow(x.WorkflowInstanceId, x.ActivityId)).ToList(); + } + + if (Response.HasStarted) + return new EmptyResult(); + + return Ok(new TriggerWorkflowsResponse(triggeredWorkflows)); + } + } +} \ No newline at end of file