V3 Bulk Actions API Endpoints (#3064)
* Add bulk-delete API for workflow instances * Add bulk-cancel API for workflow instances (stub) * Add bulk-delete API for workflow definitions * Add bulk-publish API for workflow definitions * Add bulk-retract API for workflow definitions
This commit is contained in:
parent
48443566b9
commit
750320082c
39
src/api/Elsa.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs
Normal file
39
src/api/Elsa.Api/Endpoints/WorkflowDefinitions/BulkDelete.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.AspNetCore;
|
||||
using Elsa.Persistence.Services;
|
||||
using Elsa.Serialization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Elsa.Api.Endpoints.WorkflowDefinitions;
|
||||
|
||||
[Area(AreaNames.Elsa)]
|
||||
[ApiEndpoint(ControllerNames.WorkflowDefinitions, "BulkDelete")]
|
||||
public class BulkDelete : Controller
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore _store;
|
||||
private readonly WorkflowSerializerOptionsProvider _serializerOptionsProvider;
|
||||
|
||||
public BulkDelete(IWorkflowDefinitionStore store, WorkflowSerializerOptionsProvider serializerOptionsProvider)
|
||||
{
|
||||
_store = store;
|
||||
_serializerOptionsProvider = serializerOptionsProvider;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> HandleAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var serializerOptions = _serializerOptionsProvider.CreateApiOptions();
|
||||
var model = await Request.ReadFromJsonAsync<BulkDeleteWorkflowDefinitionsRequest>(serializerOptions, cancellationToken);
|
||||
var count = await _store.DeleteManyByDefinitionIdsAsync(model!.DefinitionIds, cancellationToken);
|
||||
|
||||
return Json(new BulkDeleteWorkflowDefinitionsResponse(count), serializerOptions);
|
||||
}
|
||||
|
||||
public record BulkDeleteWorkflowDefinitionsRequest(ICollection<string> DefinitionIds);
|
||||
|
||||
public record BulkDeleteWorkflowDefinitionsResponse([property: JsonPropertyName("deleted")] int DeletedCount);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.AspNetCore;
|
||||
using Elsa.Management.Services;
|
||||
using Elsa.Persistence.Models;
|
||||
using Elsa.Persistence.Services;
|
||||
using Elsa.Serialization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Elsa.Api.Endpoints.WorkflowDefinitions;
|
||||
|
||||
[Area(AreaNames.Elsa)]
|
||||
[ApiEndpoint(ControllerNames.WorkflowDefinitions, "BulkPublish")]
|
||||
public class BulkPublish : Controller
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore _store;
|
||||
private readonly IWorkflowPublisher _workflowPublisher;
|
||||
private readonly WorkflowSerializerOptionsProvider _serializerOptionsProvider;
|
||||
|
||||
public BulkPublish(IWorkflowDefinitionStore store, IWorkflowPublisher workflowPublisher, WorkflowSerializerOptionsProvider serializerOptionsProvider)
|
||||
{
|
||||
_store = store;
|
||||
_workflowPublisher = workflowPublisher;
|
||||
_serializerOptionsProvider = serializerOptionsProvider;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> HandleAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var serializerOptions = _serializerOptionsProvider.CreateApiOptions();
|
||||
var model = (await Request.ReadFromJsonAsync<BulkPublishWorkflowDefinitionsRequest>(serializerOptions, cancellationToken))!;
|
||||
var published = new List<string>();
|
||||
var notFound = new List<string>();
|
||||
var alreadyPublished = new List<string>();
|
||||
|
||||
foreach (var definitionId in model.DefinitionIds)
|
||||
{
|
||||
var definition = await _store.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
notFound.Add(definitionId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (definition.IsPublished)
|
||||
{
|
||||
alreadyPublished.Add(definitionId);
|
||||
continue;
|
||||
}
|
||||
|
||||
await _workflowPublisher.PublishAsync(definition, cancellationToken);
|
||||
published.Add(definitionId);
|
||||
}
|
||||
|
||||
return Json(new BulkPublishWorkflowDefinitionsResponse(published, alreadyPublished, notFound), serializerOptions);
|
||||
}
|
||||
|
||||
public record BulkPublishWorkflowDefinitionsRequest(ICollection<string> DefinitionIds);
|
||||
|
||||
public record BulkPublishWorkflowDefinitionsResponse(ICollection<string> Published, ICollection<string> AlreadyPublished, ICollection<string> NotFound);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.AspNetCore;
|
||||
using Elsa.Management.Services;
|
||||
using Elsa.Persistence.Models;
|
||||
using Elsa.Persistence.Services;
|
||||
using Elsa.Serialization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Elsa.Api.Endpoints.WorkflowDefinitions;
|
||||
|
||||
[Area(AreaNames.Elsa)]
|
||||
[ApiEndpoint(ControllerNames.WorkflowDefinitions, "BulkRetract")]
|
||||
public class BulkRetract : Controller
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore _store;
|
||||
private readonly IWorkflowPublisher _workflowPublisher;
|
||||
private readonly WorkflowSerializerOptionsProvider _serializerOptionsProvider;
|
||||
|
||||
public BulkRetract(IWorkflowDefinitionStore store, IWorkflowPublisher workflowPublisher, WorkflowSerializerOptionsProvider serializerOptionsProvider)
|
||||
{
|
||||
_store = store;
|
||||
_workflowPublisher = workflowPublisher;
|
||||
_serializerOptionsProvider = serializerOptionsProvider;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> HandleAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var serializerOptions = _serializerOptionsProvider.CreateApiOptions();
|
||||
var model = (await Request.ReadFromJsonAsync<BulkRetractWorkflowDefinitionsRequest>(serializerOptions, cancellationToken))!;
|
||||
var retracted = new List<string>();
|
||||
var notFound = new List<string>();
|
||||
var notPublished = new List<string>();
|
||||
|
||||
foreach (var definitionId in model.DefinitionIds)
|
||||
{
|
||||
var definition = await _store.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
notFound.Add(definitionId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!definition.IsPublished)
|
||||
{
|
||||
notPublished.Add(definitionId);
|
||||
continue;
|
||||
}
|
||||
|
||||
await _workflowPublisher.RetractAsync(definition, cancellationToken);
|
||||
retracted.Add(definitionId);
|
||||
}
|
||||
|
||||
return Json(new BulkRetractWorkflowDefinitionsResponse(retracted, notPublished, notFound), serializerOptions);
|
||||
}
|
||||
|
||||
public record BulkRetractWorkflowDefinitionsRequest(ICollection<string> DefinitionIds);
|
||||
|
||||
public record BulkRetractWorkflowDefinitionsResponse(ICollection<string> Retracted, ICollection<string> NotPublished, ICollection<string> NotFound);
|
||||
}
|
||||
|
|
@ -36,6 +36,12 @@ public class Retract : Controller
|
|||
|
||||
if (definition == null)
|
||||
return NotFound();
|
||||
|
||||
if (!definition.IsPublished)
|
||||
return BadRequest(new
|
||||
{
|
||||
Message = $"Workflow with id {definitionId} is not published"
|
||||
});
|
||||
|
||||
await _workflowPublisher.RetractAsync(definition, cancellationToken);
|
||||
var serializerOptions = _serializerOptionsProvider.CreateApiOptions();
|
||||
|
|
|
|||
39
src/api/Elsa.Api/Endpoints/WorkflowInstances/BulkCancel.cs
Normal file
39
src/api/Elsa.Api/Endpoints/WorkflowInstances/BulkCancel.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.AspNetCore;
|
||||
using Elsa.Persistence.Services;
|
||||
using Elsa.Serialization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Elsa.Api.Endpoints.WorkflowInstances;
|
||||
|
||||
[Area(AreaNames.Elsa)]
|
||||
[ApiEndpoint(ControllerNames.WorkflowInstances, "BulkCancel")]
|
||||
public class BulkCancel : Controller
|
||||
{
|
||||
private readonly WorkflowSerializerOptionsProvider _serializerOptionsProvider;
|
||||
|
||||
public BulkCancel(WorkflowSerializerOptionsProvider serializerOptionsProvider)
|
||||
{
|
||||
_serializerOptionsProvider = serializerOptionsProvider;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> HandleAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var serializerOptions = _serializerOptionsProvider.CreateApiOptions();
|
||||
var model = await Request.ReadFromJsonAsync<BulkCancelWorkflowInstancesRequest>(serializerOptions, cancellationToken);
|
||||
// TODO: Implement workflow cancellation.
|
||||
var count = -1;
|
||||
|
||||
return Json(new BulkCancelWorkflowInstancesResponse(count), serializerOptions);
|
||||
}
|
||||
|
||||
public record BulkCancelWorkflowInstancesRequest(ICollection<string> Ids);
|
||||
|
||||
public record BulkCancelWorkflowInstancesResponse([property: JsonPropertyName("cancelled")] int CancelledCount);
|
||||
}
|
||||
40
src/api/Elsa.Api/Endpoints/WorkflowInstances/BulkDelete.cs
Normal file
40
src/api/Elsa.Api/Endpoints/WorkflowInstances/BulkDelete.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.AspNetCore;
|
||||
using Elsa.Persistence.Services;
|
||||
using Elsa.Serialization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Elsa.Api.Endpoints.WorkflowInstances;
|
||||
|
||||
[Area(AreaNames.Elsa)]
|
||||
[ApiEndpoint(ControllerNames.WorkflowInstances, "BulkDelete")]
|
||||
public class BulkDelete : Controller
|
||||
{
|
||||
private readonly IWorkflowInstanceStore _store;
|
||||
private readonly WorkflowSerializerOptionsProvider _serializerOptionsProvider;
|
||||
|
||||
public BulkDelete(IWorkflowInstanceStore store, WorkflowSerializerOptionsProvider serializerOptionsProvider)
|
||||
{
|
||||
_store = store;
|
||||
_serializerOptionsProvider = serializerOptionsProvider;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> HandleAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var serializerOptions = _serializerOptionsProvider.CreateApiOptions();
|
||||
var model = await Request.ReadFromJsonAsync<BulkDeleteWorkflowInstancesRequest>(serializerOptions, cancellationToken);
|
||||
var count = await _store.DeleteManyAsync(model!.Ids, cancellationToken);
|
||||
|
||||
return Json(new BulkDeleteWorkflowInstancesResponse(count), serializerOptions);
|
||||
}
|
||||
|
||||
public record BulkDeleteWorkflowInstancesRequest(ICollection<string> Ids);
|
||||
|
||||
public record BulkDeleteWorkflowInstancesResponse([property: JsonPropertyName("deleted")] int DeletedCount);
|
||||
}
|
||||
|
|
@ -30,8 +30,13 @@ public static class EndpointRouteBuilderExtensions
|
|||
Map("WorkflowDefinitions.Dispatch", "workflow-definitions/{definitionId}/dispatch", new { Controller = ControllerNames.WorkflowDefinitions, Action = "Dispatch" });
|
||||
Map("WorkflowDefinitions.Execute", "workflow-definitions/{definitionId}/execute", new { Controller = ControllerNames.WorkflowDefinitions, Action = "Execute" });
|
||||
Map("WorkflowDefinitions.Export", "workflow-definitions/{definitionId}/export", new { Controller = ControllerNames.WorkflowDefinitions, Action = "Export" });
|
||||
Map("WorkflowDefinitions.BulkDelete", "bulk-actions/delete/workflow-definitions/by-definition-id", new { Controller = ControllerNames.WorkflowDefinitions, Action = "BulkDelete" });
|
||||
Map("WorkflowDefinitions.BulkPublish", "bulk-actions/publish/workflow-definitions/by-definition-id", new { Controller = ControllerNames.WorkflowDefinitions, Action = "BulkPublish" });
|
||||
Map("WorkflowDefinitions.BulkRetract", "bulk-actions/retract/workflow-definitions/by-definition-id", new { Controller = ControllerNames.WorkflowDefinitions, Action = "BulkRetract" });
|
||||
|
||||
// Workflow Instances.
|
||||
Map("WorkflowInstances.BulkDelete", "bulk-actions/delete/workflow-instances/by-id", new { Controller = ControllerNames.WorkflowInstances, Action = "BulkDelete" });
|
||||
Map("WorkflowInstances.BulkCancel", "bulk-actions/cancel/workflow-instances/by-id", new { Controller = ControllerNames.WorkflowInstances, Action = "BulkCancel" });
|
||||
Map("WorkflowInstances.Get", "workflow-instances/{id}", new { Controller = ControllerNames.WorkflowInstances, Action = "Get" });
|
||||
Map("WorkflowInstances.Delete", "workflow-instances/{id}", new { Controller = ControllerNames.WorkflowInstances, Action = "Delete" });
|
||||
Map("WorkflowInstances.List", "workflow-instances", new { Controller = ControllerNames.WorkflowInstances, Action = "List" });
|
||||
|
|
@ -42,7 +47,7 @@ public static class EndpointRouteBuilderExtensions
|
|||
Map("Labels.Get", "labels/{id}", new { Controller = ControllerNames.Labels, Action = "Get" });
|
||||
Map("Labels.Delete", "labels/{id}", new { Controller = ControllerNames.Labels, Action = "Delete" });
|
||||
Map("Labels.List", "labels", new { Controller = ControllerNames.Labels, Action = "List" });
|
||||
|
||||
|
||||
// Workflow Definition Labels
|
||||
Map("WorkflowDefinitions.Labels.Update", "workflow-definitions/{id}/labels", new { Controller = ControllerNames.WorkflowDefinitionLabels, Action = "Update" });
|
||||
Map("WorkflowDefinitions.Labels.Get", "workflow-definitions/{id}/labels", new { Controller = ControllerNames.WorkflowDefinitionLabels, Action = "Get" });
|
||||
|
|
|
|||
Loading…
Reference in a new issue