diff --git a/src/core/Elsa.Core/Mapping/CloningProfile.cs b/src/core/Elsa.Core/Mapping/CloningProfile.cs index b132b907e..34d54b89e 100644 --- a/src/core/Elsa.Core/Mapping/CloningProfile.cs +++ b/src/core/Elsa.Core/Mapping/CloningProfile.cs @@ -11,6 +11,7 @@ namespace Elsa.Mapping public CloningProfile() { CreateMap(); + CreateMap(); } } } \ No newline at end of file diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkBookmarkStore.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkBookmarkStore.cs index 37bb92307..d2a64e3a7 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkBookmarkStore.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkBookmarkStore.cs @@ -1,5 +1,6 @@ using System; using System.Linq.Expressions; +using AutoMapper; using Elsa.Models; using Elsa.Persistence.Specifications; using Microsoft.EntityFrameworkCore; @@ -8,7 +9,7 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores { public class EntityFrameworkBookmarkStore : EntityFrameworkStore, IBookmarkStore { - public EntityFrameworkBookmarkStore(IDbContextFactory dbContextFactory) : base(dbContextFactory) + public EntityFrameworkBookmarkStore(IDbContextFactory dbContextFactory, IMapper mapper) : base(dbContextFactory, mapper) { } diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkStore.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkStore.cs index 6faa490fb..7b223a381 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkStore.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkStore.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using AutoMapper; using Elsa.Models; using Elsa.Persistence.Specifications; using Microsoft.EntityFrameworkCore; @@ -12,10 +13,12 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores { public abstract class EntityFrameworkStore : IStore where T : class, IEntity { + private readonly IMapper _mapper; private readonly SemaphoreSlim _semaphore = new(1); - protected EntityFrameworkStore(IDbContextFactory dbContextFactory) + protected EntityFrameworkStore(IDbContextFactory dbContextFactory, IMapper mapper) { + _mapper = mapper; DbContextFactory = dbContextFactory; } @@ -32,10 +35,21 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores var dbSet = dbContext.Set(); var existingEntity = await dbSet.FindAsync(new object[] { entity.Id }, cancellationToken); - if (existingEntity == null!) + if (existingEntity == null) + { await dbSet.AddAsync(entity, cancellationToken); - - OnSaving(dbContext, entity); + existingEntity = entity; + } + else + { + // Can't use the approach on the next line because we explicitly ignore certain properties (in order for them to be stored in the Data shadow property). + // dbContext.Entry(existingEntity).CurrentValues.SetValues(entity); + + // Therefore using AutoMapper to copy properties instead. + existingEntity = _mapper.Map(entity, existingEntity); + } + + OnSaving(dbContext, existingEntity); }, cancellationToken); } finally diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowDefinitionStore.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowDefinitionStore.cs index a92fb41d0..57d5233bd 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowDefinitionStore.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowDefinitionStore.cs @@ -1,5 +1,6 @@ using System; using System.Linq.Expressions; +using AutoMapper; using Elsa.Models; using Elsa.Persistence.Specifications; using Elsa.Serialization; @@ -12,7 +13,7 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores { private readonly IContentSerializer _contentSerializer; - public EntityFrameworkWorkflowDefinitionStore(IDbContextFactory dbContextFactory, IContentSerializer contentSerializer) : base(dbContextFactory) + public EntityFrameworkWorkflowDefinitionStore(IDbContextFactory dbContextFactory, IMapper mapper, IContentSerializer contentSerializer) : base(dbContextFactory, mapper) { _contentSerializer = contentSerializer; } diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowExecutionLogRecordStore.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowExecutionLogRecordStore.cs index 10e5ea79b..a4f6a7048 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowExecutionLogRecordStore.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowExecutionLogRecordStore.cs @@ -1,5 +1,6 @@ using System; using System.Linq.Expressions; +using AutoMapper; using Elsa.Models; using Elsa.Persistence.Specifications; using Microsoft.EntityFrameworkCore; @@ -8,7 +9,7 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores { public class EntityFrameworkWorkflowExecutionLogRecordStore : EntityFrameworkStore, IWorkflowExecutionLogStore { - public EntityFrameworkWorkflowExecutionLogRecordStore(IDbContextFactory dbContextFactory) : base(dbContextFactory) + public EntityFrameworkWorkflowExecutionLogRecordStore(IDbContextFactory dbContextFactory, IMapper mapper) : base(dbContextFactory, mapper) { } diff --git a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowInstanceStore.cs b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowInstanceStore.cs index 88d288e5c..bb82fc8dc 100644 --- a/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowInstanceStore.cs +++ b/src/persistence/Elsa.Persistence.EntityFramework/Elsa.Persistence.EntityFramework.Core/Stores/EntityFrameworkWorkflowInstanceStore.cs @@ -1,6 +1,6 @@ using System; -using System.Collections.Generic; using System.Linq.Expressions; +using AutoMapper; using Elsa.Models; using Elsa.Persistence.Specifications; using Elsa.Serialization; @@ -13,7 +13,7 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores { private readonly IContentSerializer _contentSerializer; - public EntityFrameworkWorkflowInstanceStore(IDbContextFactory dbContextFactory, IContentSerializer contentSerializer) : base(dbContextFactory) + public EntityFrameworkWorkflowInstanceStore(IDbContextFactory dbContextFactory, IMapper mapper, IContentSerializer contentSerializer) : base(dbContextFactory, mapper) { _contentSerializer = contentSerializer; } @@ -69,7 +69,7 @@ namespace Elsa.Persistence.EntityFramework.Core.Stores entity.ActivityOutput = data.ActivityOutput; entity.BlockingActivities = data.BlockingActivities; entity.ScheduledActivities = data.ScheduledActivities; - entity.Scopes = data.Scopes ?? new Stack(); + entity.Scopes = data.Scopes; entity.Fault = data.Fault; entity.CurrentActivity = data.CurrentActivity; } diff --git a/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Retry.cs b/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Retry.cs index eb75fdb6a..8e02c0090 100644 --- a/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Retry.cs +++ b/src/server/Elsa.Server.Api/Endpoints/WorkflowInstances/Retry.cs @@ -25,7 +25,8 @@ namespace Elsa.Server.Api.Endpoints.WorkflowInstances } [HttpPost] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(WorkflowInstance))] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status202Accepted)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [SwaggerOperation( @@ -41,9 +42,19 @@ namespace Elsa.Server.Api.Endpoints.WorkflowInstances if (workflowInstance == null) return NotFound(); - workflowInstance = options?.RunImmediately == true - ? await _reviver.ReviveAndRunAsync(workflowInstance, cancellationToken) - : await _reviver.ReviveAndQueueAsync(workflowInstance, cancellationToken); + if (options?.RunImmediately == false) + { + workflowInstance = await _reviver.ReviveAndQueueAsync(workflowInstance, cancellationToken); + + var model = new + { + WorkflowInstanceId = workflowInstance.Id, + }; + + return Accepted(model); + } + + workflowInstance = await _reviver.ReviveAndRunAsync(workflowInstance, cancellationToken); if (workflowInstance.WorkflowStatus == WorkflowStatus.Faulted) return StatusCode(500, new @@ -52,7 +63,11 @@ namespace Elsa.Server.Api.Endpoints.WorkflowInstances Fault = workflowInstance.Fault }); - return Response.HasStarted ? (IActionResult) new EmptyResult() : Ok(workflowInstance); + return Response.HasStarted ? (IActionResult) new EmptyResult() : Ok(new + { + WorkflowInstanceId = workflowInstance.Id, + WorkflowStatus = workflowInstance.WorkflowStatus + }); } }