Update packages and incremental work on API

This commit is contained in:
Sipke Schoorstra 2020-11-18 22:31:16 +01:00
parent 57003d487a
commit 757fde7e6e
28 changed files with 86 additions and 128 deletions

View file

@ -1,20 +0,0 @@
using System.Collections.Generic;
namespace Elsa.Client.Models
{
public class PostWorkflowDefinitionRequest
{
public string? Name { get; set; }
public string? DisplayName { get; set; }
public string? Description { get; set; }
public Variables? Variables { get; set; }
public WorkflowContextOptions? ContextOptions { get; set; }
public bool IsSingleton { get; set; }
public WorkflowPersistenceBehavior PersistenceBehavior { get; set; }
public bool DeleteCompletedInstances { get; set; }
public bool Enabled { get; set; }
public bool Publish { get; set; }
public ICollection<ActivityDefinition> Activities { get; set; } = new System.Collections.Generic.List<ActivityDefinition>();
public ICollection<ConnectionDefinition> Connections { get; set; } = new System.Collections.Generic.List<ConnectionDefinition>();
}
}

View file

@ -17,9 +17,6 @@ namespace Elsa.Client.Services
Task<PagedList<WorkflowDefinition>> ListAsync(int? page = default, int? pageSize = default, VersionOptions? versionOptions = default, CancellationToken cancellationToken = default);
[Post("/v1/workflow-definitions")]
Task<WorkflowDefinition> PostAsync([Body(BodySerializationMethod.Serialized)] PostWorkflowDefinitionRequest request, CancellationToken cancellationToken = default);
[Post("/v1/workflow-definitions/{workflowDefinitionId}")]
Task<WorkflowDefinition> PostAsync(string workflowDefinitionId, [Body(BodySerializationMethod.Serialized)] PostWorkflowDefinitionRequest request, CancellationToken cancellationToken = default);
Task<WorkflowDefinition> PostAsync([Body(BodySerializationMethod.Serialized)] WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default);
}
}

View file

@ -40,7 +40,7 @@
<PackageReference Include="System.Linq.Async" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.0" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageReference Include="YesSql.Abstractions" Version="2.0.0-beta-1580" />
<PackageReference Include="YesSql.Abstractions" Version="2.0.0-beta-1583" />
</ItemGroup>
</Project>

View file

@ -12,6 +12,6 @@ namespace Elsa.Models
public bool PersistWorkflow { get; set; }
public bool LoadWorkflowContext { get; set; }
public bool SaveWorkflowContext { get; set; }
public ActivityDefinitionProperties Properties { get; set; } = new ActivityDefinitionProperties();
public ActivityDefinitionProperties Properties { get; set; } = new();
}
}

View file

@ -3,7 +3,7 @@ using Elsa.Services;
namespace Elsa.Models
{
public class CompositeActivityDefinition : ActivityDefinition
public class CompositeActivityDefinition : ActivityDefinition, ICompositeActivityDefinition
{
public CompositeActivityDefinition()
{

View file

@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace Elsa.Models
{
public interface ICompositeActivityDefinition
{
public ICollection<ActivityDefinition> Activities { get; set; }
public ICollection<ConnectionDefinition> Connections { get; set; }
}
}

View file

@ -1,15 +1,25 @@
namespace Elsa.Models
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Elsa.Models
{
public class WorkflowDefinition : CompositeActivityDefinition
public class WorkflowDefinition : ICompositeActivityDefinition
{
public WorkflowDefinition()
{
Variables = new Variables();
Activities = new List<ActivityDefinition>();
Connections = new List<ConnectionDefinition>();
}
[Newtonsoft.Json.JsonIgnore]
[JsonIgnore]
public int Id { get; set; }
public string WorkflowDefinitionId { get; set; } = default!;
public string WorkflowDefinitionVersionId { get; set; } = default!;
public string? Name { get; set; }
public string? DisplayName { get; set; }
public string? Description { get; set; }
public int Version { get; set; }
public Variables? Variables { get; set; }
public WorkflowContextOptions? ContextOptions { get; set; }
@ -19,5 +29,7 @@
public bool IsEnabled { get; set; }
public bool IsPublished { get; set; }
public bool IsLatest { get; set; }
public ICollection<ActivityDefinition> Activities { get; set; }
public ICollection<ConnectionDefinition> Connections { get; set; }
}
}

View file

@ -22,5 +22,6 @@ namespace Elsa.Services
where TIndex : class, IIndex;
IQuery<WorkflowDefinition> ExecuteQuery(ICompiledQuery<WorkflowDefinition> query);
WorkflowDefinition Initialize(WorkflowDefinition workflowDefinition);
}
}

View file

@ -51,7 +51,7 @@
<PackageReference Include="System.Linq.Async" Version="5.0.0" />
<PackageReference Include="YamlDotNet" Version="8.1.2" />
<PackageReference Include="Rebus.ServiceProvider" Version="5.0.6" />
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1580" />
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1583" />
</ItemGroup>
<ItemGroup>

View file

@ -38,10 +38,10 @@ namespace Elsa.Services
);
}
private static ActivityPropertyProviders CreatePropertyProviders(CompositeActivityDefinition workflowDefinition)
private static ActivityPropertyProviders CreatePropertyProviders(ICompositeActivityDefinition compositeActivityDefinition)
{
var propertyProviders = new ActivityPropertyProviders();
var activityDefinitions = workflowDefinition.Activities;
var activityDefinitions = compositeActivityDefinition.Activities;
foreach (var activityDefinition in activityDefinitions)
{

View file

@ -14,14 +14,17 @@ namespace Elsa.Services
public class WorkflowDefinitionManager : IWorkflowDefinitionManager
{
private readonly ISession _session;
private readonly IIdGenerator _idGenerator;
public WorkflowDefinitionManager(ISession session)
public WorkflowDefinitionManager(ISession session, IIdGenerator idGenerator)
{
_session = session;
_idGenerator = idGenerator;
}
public Task SaveAsync(WorkflowDefinition workflowDefinition, CancellationToken cancellationToken = default)
{
workflowDefinition = Initialize(workflowDefinition);
_session.Save(workflowDefinition, CollectionNames.WorkflowDefinitions);
return Task.CompletedTask;
}
@ -54,5 +57,19 @@ namespace Elsa.Services
public IQuery<WorkflowDefinition, TIndex> Query<TIndex>() where TIndex : class, IIndex => _session.Query<WorkflowDefinition, TIndex>(CollectionNames.WorkflowDefinitions);
public IQuery<WorkflowDefinition, TIndex> Query<TIndex>(Expression<Func<TIndex, bool>> predicate) where TIndex : class, IIndex => _session.Query<WorkflowDefinition, TIndex>(predicate, CollectionNames.WorkflowDefinitions);
public IQuery<WorkflowDefinition> ExecuteQuery(ICompiledQuery<WorkflowDefinition> query) => _session.ExecuteQuery(query, CollectionNames.WorkflowDefinitions);
public WorkflowDefinition Initialize(WorkflowDefinition workflowDefinition)
{
if (string.IsNullOrWhiteSpace(workflowDefinition.WorkflowDefinitionId))
workflowDefinition.WorkflowDefinitionId = _idGenerator.Generate();
if (workflowDefinition.Version == 0)
workflowDefinition.Version = 1;
if (string.IsNullOrWhiteSpace(workflowDefinition.WorkflowDefinitionVersionId))
workflowDefinition.WorkflowDefinitionVersionId = _idGenerator.Generate();
return workflowDefinition;
}
}
}

View file

@ -7,7 +7,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="5.0.0" />
<PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.123" />
<PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.136" />
</ItemGroup>
<ItemGroup>

View file

@ -1,4 +1,4 @@
namespace ElsaDashboard.Application.Models
{
public sealed record ConnectionModel(string SourceId, string? TargetId, string Outcome);
public sealed record ConnectionModel(string SourceId, string TargetId, string Outcome);
}

View file

@ -17,6 +17,7 @@ namespace ElsaDashboard.Application.Pages
[Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = default!;
[Inject] private IActivityService ActivityService { get; set; } = default!;
private IDictionary<string, ActivityDescriptor> ActivityDescriptors { get; set; } = default!;
private WorkflowDefinition WorkflowDefinition { get; set; } = default!;
private WorkflowModel WorkflowModel { get; set; } = WorkflowModel.Blank();
private BackgroundWorker BackgroundWorker { get; } = new();
@ -26,8 +27,8 @@ namespace ElsaDashboard.Application.Pages
if (WorkflowDefinitionVersionId != null)
{
var workflowDefinition = await WorkflowDefinitionService.GetByVersionIdAsync(WorkflowDefinitionVersionId);
WorkflowModel = CreateWorkflowModel(workflowDefinition);
WorkflowDefinition = await WorkflowDefinitionService.GetByVersionIdAsync(WorkflowDefinitionVersionId);
WorkflowModel = CreateWorkflowModel(WorkflowDefinition);
}
else
{
@ -60,7 +61,8 @@ namespace ElsaDashboard.Application.Pages
private async ValueTask SaveWorkflowAsync()
{
WorkflowDefinition.Connections = WorkflowModel.Connections.Select(x => new ConnectionDefinition(x.SourceId, x.TargetId, x.Outcome)).ToList();
WorkflowDefinition = await WorkflowDefinitionService.SaveAsync(WorkflowDefinition);
}
private async Task OnWorkflowChanged(WorkflowModelChangedEventArgs e)

View file

@ -10,10 +10,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.29.0" />
<PackageReference Include="Grpc.AspNetCore.Web" Version="2.32.0" />
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.33.1" />
<PackageReference Include="Grpc.AspNetCore.Web" Version="2.33.1" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.123" />
<PackageReference Include="protobuf-net.Grpc.AspNetCore" Version="1.0.136" />
</ItemGroup>
</Project>

View file

@ -18,6 +18,7 @@ namespace ElsaDashboard.Backend.Rpc
public async Task<PagedList<WorkflowDefinition>> ListAsync(ListWorkflowDefinitionsRequest request, CallContext context) =>
await _elsaClient.WorkflowDefinitions.ListAsync(request.Page, request.PageSize, request.VersionOptions, context.CancellationToken);
public Task<WorkflowDefinition> GetByVersionIdAsync(string workflowDefinitionVersionId, CallContext context = default) => _elsaClient.WorkflowDefinitions.GetByVersionIdAsync(workflowDefinitionVersionId, context.CancellationToken);
public Task<WorkflowDefinition> GetByVersionIdAsync(string workflowDefinitionVersionId, CallContext context) => _elsaClient.WorkflowDefinitions.GetByVersionIdAsync(workflowDefinitionVersionId, context.CancellationToken);
public async Task<WorkflowDefinition> SaveAsync(WorkflowDefinition workflowDefinition, CallContext context) => await _elsaClient.WorkflowDefinitions.PostAsync(workflowDefinition, context.CancellationToken);
}
}

View file

@ -6,11 +6,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Api.CommonProtos" Version="2.1.0" />
<PackageReference Include="Google.Api.CommonProtos" Version="2.2.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.33.1" />
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.33.1" />
<PackageReference Include="protobuf-net" Version="3.0.52" />
<PackageReference Include="protobuf-net.Grpc" Version="1.0.123" />
<PackageReference Include="protobuf-net" Version="3.0.62" />
<PackageReference Include="protobuf-net.Grpc" Version="1.0.136" />
</ItemGroup>
<ItemGroup>

View file

@ -1,17 +1,14 @@
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading.Tasks;
using Elsa.Client.Models;
using ProtoBuf;
using ProtoBuf.Grpc;
using ProtoBuf.ServiceModel;
using ProtoBuf.Grpc.Configuration;
namespace ElsaDashboard.Shared.Rpc
{
[ServiceContract]
[Service]
public interface IActivityService
{
[ProtoBehavior]
Task<IEnumerable<ActivityDescriptor>> GetActivitiesAsync(CallContext context = default);
}
}

View file

@ -3,14 +3,16 @@ using System.Threading.Tasks;
using Elsa.Client.Models;
using ProtoBuf;
using ProtoBuf.Grpc;
using ProtoBuf.Grpc.Configuration;
namespace ElsaDashboard.Shared.Rpc
{
[ServiceContract]
[Service]
public interface IWorkflowDefinitionService
{
Task<PagedList<WorkflowDefinition>> ListAsync(ListWorkflowDefinitionsRequest request, CallContext context = default);
Task<WorkflowDefinition> GetByVersionIdAsync(string workflowDefinitionVersionId, CallContext context = default);
Task<WorkflowDefinition> SaveAsync(WorkflowDefinition workflowDefinition, CallContext context = default);
}
[ProtoContract]

View file

@ -19,7 +19,7 @@ namespace Elsa.Samples.CustomActivities
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context)
{
var query = _httpContextAccessor.HttpContext.Request.Query;
var query = _httpContextAccessor.HttpContext!.Request.Query;
return Done(query);
}

View file

@ -34,12 +34,6 @@
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.6.3" />
</ItemGroup>
<ItemGroup>
<Compile Update="Endpoints\WorkflowDefinitions\Post.Request.cs">
<DependentUpon>Post.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
</ItemGroup>

View file

@ -1,21 +0,0 @@
using System.Collections.Generic;
using Elsa.Models;
namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions
{
public class PostWorkflowDefinitionRequest
{
public string? Name { get; set; }
public string? DisplayName { get; set; }
public string? Description { get; set; }
public Variables? Variables { get; set; }
public WorkflowContextOptions? ContextOptions { get; set; }
public bool IsSingleton { get; set; }
public WorkflowPersistenceBehavior PersistenceBehavior { get; set; }
public bool DeleteCompletedInstances { get; set; }
public bool Enabled { get; set; }
public bool Publish { get; set; }
public ICollection<ActivityDefinition> Activities { get; set; } = new List<ActivityDefinition>();
public ICollection<ConnectionDefinition> Connections { get; set; } = new List<ConnectionDefinition>();
}
}

View file

@ -13,15 +13,14 @@ namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions
[ApiController]
[ApiVersion("1")]
[Route("v{apiVersion:apiVersion}/workflow-definitions")]
[Route("v{apiVersion:apiVersion}/workflow-definitions/{workflowDefinitionId}")]
[Produces("application/json")]
public class Post : ControllerBase
{
private readonly IWorkflowPublisher _workflowPublisher;
private readonly IWorkflowDefinitionManager _workflowDefinitionManager;
public Post(IWorkflowPublisher workflowPublisher)
public Post(IWorkflowDefinitionManager workflowDefinitionManager)
{
_workflowPublisher = workflowPublisher;
_workflowDefinitionManager = workflowDefinitionManager;
}
[HttpPost]
@ -29,43 +28,13 @@ namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions
[SwaggerResponseExample(StatusCodes.Status200OK, typeof(WorkflowDefinitionExample))]
[SwaggerOperation(
Summary = "Creates a new workflow definition or updates an existing one.",
Description =
"Creates a new workflow definition or updates an existing one. If the workflow already exists, a new draft is created and updated with the specified values. Use the Publish field to automatically publish the workflow.",
Description = "Creates a new workflow definition or updates an existing one.",
OperationId = "WorkflowDefinitions.Post",
Tags = new[] {"WorkflowDefinitions"})
]
public async Task<ActionResult<WorkflowDefinition>> Handle(string? workflowDefinitionId, PostWorkflowDefinitionRequest request, ApiVersion apiVersion, CancellationToken cancellationToken)
public async Task<ActionResult<WorkflowDefinition>> Handle(WorkflowDefinition workflowDefinition, ApiVersion apiVersion, CancellationToken cancellationToken)
{
workflowDefinitionId = workflowDefinitionId?.Trim();
var workflowDefinition = !string.IsNullOrWhiteSpace(workflowDefinitionId) ? await _workflowPublisher.GetDraftAsync(workflowDefinitionId, cancellationToken) : default;
if (workflowDefinition == null)
{
workflowDefinition = _workflowPublisher.New();
if (!string.IsNullOrWhiteSpace(workflowDefinitionId))
workflowDefinition.WorkflowDefinitionId = workflowDefinitionId;
}
workflowDefinition.Activities = request.Activities;
workflowDefinition.Connections = request.Connections;
workflowDefinition.Description = request.Description?.Trim();
workflowDefinition.Name = request.Name?.Trim();
workflowDefinition.Variables = request.Variables;
workflowDefinition.IsEnabled = request.Enabled;
workflowDefinition.IsSingleton = request.IsSingleton;
workflowDefinition.PersistenceBehavior = request.PersistenceBehavior;
workflowDefinition.DeleteCompletedInstances = request.DeleteCompletedInstances;
workflowDefinition.ContextOptions = request.ContextOptions;
workflowDefinition.Type = "Workflow";
workflowDefinition.ActivityId = workflowDefinition.WorkflowDefinitionId;
workflowDefinition.DisplayName = request.DisplayName?.Trim();
if (request.Publish)
await _workflowPublisher.PublishAsync(workflowDefinition, cancellationToken);
else
await _workflowPublisher.SaveDraftAsync(workflowDefinition, cancellationToken);
await _workflowDefinitionManager.SaveAsync(workflowDefinition, cancellationToken);
return CreatedAtAction("Handle", "GetByVersionId", new {workflowDefinitionVersionId = workflowDefinition.WorkflowDefinitionVersionId, apiVersion = apiVersion.ToString()}, workflowDefinition);
}
}

View file

@ -19,7 +19,6 @@ namespace Elsa.Server.Api.Swagger
IsPublished = true,
WorkflowDefinitionId = Guid.NewGuid().ToString("N"),
WorkflowDefinitionVersionId = Guid.NewGuid().ToString("N"),
Type = "Workflow",
ContextOptions = new WorkflowContextOptions
{
ContextFidelity = WorkflowContextFidelity.Burst,

View file

@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1580" />
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1583" />
</ItemGroup>
<ItemGroup>

View file

@ -17,12 +17,12 @@ namespace Elsa.ComponentTests.Clients.RestClient.WorkflowDefinitions
[Fact(DisplayName = "Posting a new workflow definition returns HTTP 201.")]
public async Task Post01()
{
var request = CreateWorkflowDefinitionRequest();
var request = CreateWorkflowDefinition();
var workflowDefinition = await ElsaClient.WorkflowDefinitions.PostAsync(request);
Assert.Equal(request.Name, workflowDefinition.Name);
}
private PostWorkflowDefinitionRequest CreateWorkflowDefinitionRequest()
private WorkflowDefinition CreateWorkflowDefinition()
{
var writeLine = new ActivityDefinition
{
@ -38,7 +38,7 @@ namespace Elsa.ComponentTests.Clients.RestClient.WorkflowDefinitions
var activities = new[] {writeLine, readLine};
var connections = new[] {new ConnectionDefinition(writeLine.ActivityId, readLine.ActivityId, OutcomeNames.Done)};
return Fixture.Build<PostWorkflowDefinitionRequest>()
return Fixture.Build<WorkflowDefinition>()
.With(x => x.Activities, activities)
.With(x => x.Connections, connections)
.Create();

View file

@ -18,14 +18,12 @@ namespace Elsa.ComponentTests.Endpoints.WorkflowDefinitions
{
private readonly IFixture _fixture;
private readonly TemporaryFolder _tempFolder;
private readonly ElsaHostApplicationFactory _hostApplicationFactory;
private readonly HttpClient _httpClient;
public PostTests(ElsaHostApplicationFactory hostApplicationFactory)
{
_fixture = new Fixture().Customize(new NodaTimeCustomization());
_tempFolder = new TemporaryFolder();
_hostApplicationFactory = hostApplicationFactory;
hostApplicationFactory.SetDbConnectionString($@"Data Source={_tempFolder.Folder}elsa.db;Cache=Shared");
_httpClient = hostApplicationFactory.CreateClient();
}
@ -39,7 +37,7 @@ namespace Elsa.ComponentTests.Endpoints.WorkflowDefinitions
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
}
private PostWorkflowDefinitionRequest CreateWorkflowDefinitionRequest()
private WorkflowDefinition CreateWorkflowDefinitionRequest()
{
var writeLine = new ActivityDefinition
{
@ -55,7 +53,7 @@ namespace Elsa.ComponentTests.Endpoints.WorkflowDefinitions
var activities = new[] { writeLine, readLine };
var connections = new[] { new ConnectionDefinition(writeLine.ActivityId, readLine.ActivityId, OutcomeNames.Done) };
return _fixture.Build<PostWorkflowDefinitionRequest>()
return _fixture.Build<WorkflowDefinition>()
.With(x => x.Activities, activities)
.With(x => x.Connections, connections)
.Create();

View file

@ -20,8 +20,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="YesSql.Core" Version="2.0.0-beta-1580" />
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1580" />
<PackageReference Include="YesSql.Core" Version="2.0.0-beta-1583" />
<PackageReference Include="YesSql.Provider.Sqlite" Version="1.0.0-beta-1583" />
</ItemGroup>
<ItemGroup>