Implement API to delete specific workflow definition version
This commit is contained in:
parent
06c332389a
commit
07c9783363
|
|
@ -69,10 +69,18 @@ public interface IWorkflowDefinitionsApi
|
|||
/// <summary>
|
||||
/// Deletes a workflow definition.
|
||||
/// </summary>
|
||||
/// <param name="definitionId">The ID of the workflow definition to delete.</param>
|
||||
/// <param name="definitionId">The definition ID of the workflow definition, and all of its versions, to delete.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
[Delete("/workflow-definitions/{definitionId}")]
|
||||
Task DeleteAsync(string definitionId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a workflow definition version.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of a specific workflow definition version to delete.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
[Delete("/workflow-definition-versions/{id}")]
|
||||
Task DeleteVersionAsync(string id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Publishes a workflow definition.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
using Elsa.Abstractions;
|
||||
using Elsa.Workflows.Management.Contracts;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.DeleteVersion;
|
||||
|
||||
[PublicAPI]
|
||||
internal class DeleteVersion : ElsaEndpoint<Request>
|
||||
{
|
||||
private readonly IWorkflowDefinitionManager _workflowDefinitionManager;
|
||||
|
||||
public DeleteVersion(IWorkflowDefinitionManager workflowDefinitionManager)
|
||||
{
|
||||
_workflowDefinitionManager = workflowDefinitionManager;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Delete("/workflow-definition-versions/{id}");
|
||||
ConfigurePermissions("delete:workflow-definitions");
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(Request request, CancellationToken cancellationToken)
|
||||
{
|
||||
var deleted = await _workflowDefinitionManager.DeleteByIdAsync(request.Id, cancellationToken);
|
||||
|
||||
if (!deleted)
|
||||
await SendNotFoundAsync(cancellationToken);
|
||||
else
|
||||
await SendNoContentAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.DeleteVersion;
|
||||
|
||||
internal class Request
|
||||
{
|
||||
public string Id { get; set; } = default!;
|
||||
}
|
||||
|
|
@ -15,6 +15,13 @@ public interface IWorkflowDefinitionManager
|
|||
/// <returns>The number of deleted workflow definitions.</returns>
|
||||
Task<int> DeleteByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a specific version of a workflow definition.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the workflow definition version.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>True if the workflow definition version was deleted, otherwise false.</returns>
|
||||
Task<bool> DeleteByIdAsync(string id, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a specific workflow definition version.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Elsa.Mediator.Contracts;
|
||||
using Elsa.Workflows.Management.Entities;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Elsa.Workflows.Management.Notifications;
|
||||
|
|
@ -6,7 +7,5 @@ namespace Elsa.Workflows.Management.Notifications;
|
|||
/// <summary>
|
||||
/// A notification that is sent when a workflow definition version is deleted.
|
||||
/// </summary>
|
||||
/// <param name="DefinitionId">The ID of the workflow definition.</param>
|
||||
/// <param name="Version">The version number of the workflow definition.</param>
|
||||
[PublicAPI]
|
||||
public record WorkflowDefinitionVersionDeleted(string DefinitionId, int Version) : INotification;
|
||||
public record WorkflowDefinitionVersionDeleted(WorkflowDefinition WorkflowDefinition) : INotification;
|
||||
|
|
@ -48,6 +48,18 @@ public class WorkflowDefinitionManager : IWorkflowDefinitionManager
|
|||
return count;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<bool> DeleteByIdAsync(string id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var filter = new WorkflowDefinitionFilter { Id = id};
|
||||
var definition = await _store.FindAsync(filter, cancellationToken);
|
||||
|
||||
if (definition == null)
|
||||
return false;
|
||||
|
||||
return await DeleteVersionAsync(definition, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<int> BulkDeleteByDefinitionIdsAsync(IEnumerable<string> definitionIds, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
|
@ -61,37 +73,13 @@ public class WorkflowDefinitionManager : IWorkflowDefinitionManager
|
|||
/// <inheritdoc />
|
||||
public async Task<bool> DeleteVersionAsync(string definitionId, int versionToDelete, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var filter = new WorkflowDefinitionFilter { DefinitionId = definitionId, VersionOptions = VersionOptions.LatestAndPublished };
|
||||
var workflows = (await _store.FindManyAsync(filter, cancellationToken)).ToList();
|
||||
var latestVersion = workflows.WithVersion(VersionOptions.Latest).First();
|
||||
var publishedVersion = workflows.WithVersion(VersionOptions.Published).FirstOrDefault();
|
||||
|
||||
if (versionToDelete == publishedVersion?.Version)
|
||||
{
|
||||
throw new Exception("Published version cannot be deleted");
|
||||
}
|
||||
|
||||
filter = new WorkflowDefinitionFilter { DefinitionId = definitionId, VersionOptions = VersionOptions.SpecificVersion(versionToDelete) };
|
||||
var isDeleted = await _store.DeleteAsync(filter, cancellationToken) > 0;
|
||||
|
||||
if (!isDeleted)
|
||||
var filter = new WorkflowDefinitionFilter { DefinitionId = definitionId, VersionOptions = VersionOptions.SpecificVersion(versionToDelete) };
|
||||
var definitionToDelete = await _store.FindAsync(filter, cancellationToken);
|
||||
|
||||
if (definitionToDelete == null)
|
||||
return false;
|
||||
|
||||
await _notificationSender.SendAsync(new WorkflowDefinitionVersionDeleted(definitionId, versionToDelete), cancellationToken);
|
||||
|
||||
if (latestVersion.Version != versionToDelete)
|
||||
return isDeleted;
|
||||
|
||||
filter = new WorkflowDefinitionFilter { DefinitionId = definitionId };
|
||||
var lastVersion = await _store.FindLastVersionAsync(filter, cancellationToken);
|
||||
|
||||
if (lastVersion is null)
|
||||
return isDeleted;
|
||||
|
||||
lastVersion.IsLatest = true;
|
||||
await _store.SaveAsync(lastVersion, cancellationToken);
|
||||
|
||||
return isDeleted;
|
||||
|
||||
return await DeleteVersionAsync(definitionToDelete, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -159,4 +147,37 @@ public class WorkflowDefinitionManager : IWorkflowDefinitionManager
|
|||
|
||||
return updatedWorkflowDefinitions;
|
||||
}
|
||||
|
||||
private async Task<bool> DeleteVersionAsync(WorkflowDefinition definitionToDelete, CancellationToken cancellationToken)
|
||||
{
|
||||
if (definitionToDelete.IsPublished)
|
||||
{
|
||||
throw new Exception("Published version cannot be deleted before retracting it");
|
||||
}
|
||||
|
||||
var filter = new WorkflowDefinitionFilter { Id = definitionToDelete.Id };
|
||||
var isDeleted = await _store.DeleteAsync(filter, cancellationToken) > 0;
|
||||
|
||||
if (!isDeleted)
|
||||
return false;
|
||||
|
||||
await _notificationSender.SendAsync(new WorkflowDefinitionVersionDeleted(definitionToDelete), cancellationToken);
|
||||
|
||||
if (!definitionToDelete.IsLatest)
|
||||
return isDeleted;
|
||||
|
||||
// The deleted version was also the latest version, so we need to update the current latest version to "IsLatest = true".
|
||||
filter = new WorkflowDefinitionFilter { DefinitionId = definitionToDelete.DefinitionId };
|
||||
var lastVersion = await _store.FindLastVersionAsync(filter, cancellationToken);
|
||||
|
||||
// If there are no more versions left, then we're done.
|
||||
if (lastVersion is null)
|
||||
return isDeleted;
|
||||
|
||||
// Otherwise, we need to update the latest version.
|
||||
lastVersion.IsLatest = true;
|
||||
await _store.SaveAsync(lastVersion, cancellationToken);
|
||||
|
||||
return isDeleted;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue