Incremental work on GraphQL
This commit is contained in:
parent
34a3872693
commit
b7103188fd
|
|
@ -49,7 +49,7 @@ namespace Elsa.Services
|
|||
Id = Id,
|
||||
Type = Type,
|
||||
State = new JObject(State),
|
||||
Output = JObject.FromObject(Output)
|
||||
Output = Output != null ? JObject.FromObject(Output) : null
|
||||
};
|
||||
|
||||
public Task<IActivityExecutionResult> ResumeAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) => OnResumeAsync(context, cancellationToken);
|
||||
|
|
|
|||
|
|
@ -30,16 +30,16 @@ namespace Elsa.Persistence.DocumentDb.Extensions
|
|||
return new CosmosDbElsaBuilder(builder.Services);
|
||||
}
|
||||
|
||||
public static CosmosDbElsaBuilder AddWorkflowInstanceStore(this CosmosDbElsaBuilder configuration)
|
||||
public static CosmosDbElsaBuilder AddWorkflowInstanceStore(this CosmosDbElsaBuilder builder)
|
||||
{
|
||||
configuration.Services.AddSingleton<IWorkflowInstanceStore, CosmosDbWorkflowInstanceStore>();
|
||||
return configuration;
|
||||
builder.Services.AddSingleton<IWorkflowInstanceStore, CosmosDbWorkflowInstanceStore>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static CosmosDbElsaBuilder AddWorkflowDefinitionStore(this CosmosDbElsaBuilder configuration)
|
||||
public static CosmosDbElsaBuilder AddWorkflowDefinitionStore(this CosmosDbElsaBuilder builder)
|
||||
{
|
||||
configuration.Services.AddSingleton<IWorkflowDefinitionStore, CosmosDbWorkflowDefinitionStore>();
|
||||
return configuration;
|
||||
builder.Services.AddSingleton<IWorkflowDefinitionStore, CosmosDbWorkflowDefinitionStore>();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -49,12 +49,12 @@ namespace Elsa.Persistence.DocumentDb.Services
|
|||
public async Task<int> DeleteAsync(string id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var client = storage.Client;
|
||||
var records = await client.CreateDocumentQuery<WorkflowDefinitionVersionDocument>(storage.CollectionUri).Where(c => c.DefinitionId == id).ToQueryResultAsync();
|
||||
foreach (var record in records)
|
||||
var workflowDefinitionDocuments = await client.CreateDocumentQuery<WorkflowDefinitionVersionDocument>(storage.CollectionUri).Where(c => c.DefinitionId == id).ToQueryResultAsync();
|
||||
foreach (var record in workflowDefinitionDocuments)
|
||||
{
|
||||
await client.DeleteDocumentAsync(record.Id, cancellationToken: cancellationToken);
|
||||
}
|
||||
return records.Count;
|
||||
return workflowDefinitionDocuments.Count;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<WorkflowDefinitionVersion>> ListAsync(VersionOptions version, CancellationToken cancellationToken = default)
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ namespace Elsa.Persistence.MongoDb.Serialization
|
|||
|
||||
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, T value)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(value, serializerSettings);
|
||||
var document = BsonDocument.Parse(json);
|
||||
var json = value != null ? JsonConvert.SerializeObject(value, serializerSettings) : null;
|
||||
var document = json != null ? BsonDocument.Parse(json) : new BsonDocument();
|
||||
BsonDocumentSerializer.Instance.Serialize(context, document);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,74 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
using AutoMapper;
|
||||
using Elsa.Models;
|
||||
using Elsa.Persistence;
|
||||
using Elsa.Server.GraphQL.Models;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using Elsa.Services;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using GraphQL.Types;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Elsa.Server.GraphQL
|
||||
{
|
||||
public class ElsaMutation : ObjectGraphType
|
||||
{
|
||||
public ElsaMutation(IWorkflowDefinitionStore workflowDefinitionStore, IWorkflowPublisher publisher, IIdGenerator idGenerator, IMapper mapper)
|
||||
public ElsaMutation(IEnumerable<IMutationProvider> providers)
|
||||
{
|
||||
FieldAsync<WorkflowDefinitionVersionType>(
|
||||
"defineWorkflow",
|
||||
"Create a new workflow definitions",
|
||||
new QueryArguments(new QueryArgument<NonNullGraphType<DefineWorkflowDefinitionInputType>> { Name = "workflowDefinition" }),
|
||||
async context =>
|
||||
{
|
||||
var model = context.GetArgument<DefineWorkflowDefinitionInputModel>("workflowDefinition");
|
||||
var publish = model.Publish;
|
||||
var workflowDefinitionVersion = mapper.Map<WorkflowDefinitionVersion>(model);
|
||||
|
||||
workflowDefinitionVersion.Id = idGenerator.Generate();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(workflowDefinitionVersion.DefinitionId))
|
||||
workflowDefinitionVersion.DefinitionId = idGenerator.Generate();
|
||||
|
||||
if (publish)
|
||||
await publisher.PublishAsync(workflowDefinitionVersion, context.CancellationToken);
|
||||
else
|
||||
await publisher.SaveDraftAsync(workflowDefinitionVersion, context.CancellationToken);
|
||||
|
||||
return workflowDefinitionVersion;
|
||||
});
|
||||
|
||||
FieldAsync<WorkflowDefinitionVersionType>(
|
||||
"updateWorkflow",
|
||||
"Update an existing workflow definition",
|
||||
new QueryArguments(
|
||||
new QueryArgument<NonNullGraphType<IdGraphType>> { Name = "id" },
|
||||
new QueryArgument<NonNullGraphType<UpdateWorkflowDefinitionInputType>> { Name = "workflowDefinition" }),
|
||||
async context =>
|
||||
{
|
||||
var id = context.GetArgument<string>("id");
|
||||
var workflowDefinitionVersion = await workflowDefinitionStore.GetByIdAsync(id, VersionOptions.Latest, context.CancellationToken);
|
||||
|
||||
if (workflowDefinitionVersion == null)
|
||||
return null;
|
||||
|
||||
var updateModel = context.GetArgument<dynamic>("workflowDefinition");
|
||||
var props = (IDictionary<string, object>)updateModel;
|
||||
var publish = props.ContainsKey("publish") && (bool)props["publish"];
|
||||
|
||||
// "Patch" the existing workflow definition version with the posted model values.
|
||||
var json = JsonConvert.SerializeObject(updateModel);
|
||||
JsonConvert.PopulateObject(json, workflowDefinitionVersion, new JsonSerializerSettings
|
||||
{
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace
|
||||
});
|
||||
|
||||
if (publish)
|
||||
workflowDefinitionVersion = await publisher.PublishAsync(workflowDefinitionVersion, context.CancellationToken);
|
||||
else
|
||||
workflowDefinitionVersion = await publisher.SaveDraftAsync(workflowDefinitionVersion, context.CancellationToken);
|
||||
|
||||
return workflowDefinitionVersion;
|
||||
});
|
||||
foreach (var provider in providers)
|
||||
provider.Setup(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,73 +1,15 @@
|
|||
using System.Threading.Tasks;
|
||||
using AutoMapper;
|
||||
using Elsa.Models;
|
||||
using Elsa.Persistence;
|
||||
using Elsa.Server.GraphQL.Models;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using System.Collections.Generic;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL
|
||||
{
|
||||
public class ElsaQuery : ObjectGraphType
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore workflowDefinitionStore;
|
||||
private readonly IWorkflowInstanceStore workflowInstanceStore;
|
||||
private readonly IMapper mapper;
|
||||
|
||||
public ElsaQuery(IWorkflowDefinitionStore workflowDefinitionStore, IWorkflowInstanceStore workflowInstanceStore, IMapper mapper)
|
||||
public ElsaQuery(IEnumerable<IQueryProvider> providers)
|
||||
{
|
||||
this.workflowDefinitionStore = workflowDefinitionStore;
|
||||
this.workflowInstanceStore = workflowInstanceStore;
|
||||
this.mapper = mapper;
|
||||
|
||||
FieldAsync<ListGraphType<WorkflowDefinitionVersionType>>(
|
||||
"workflowDefinitions",
|
||||
arguments: new QueryArguments(new QueryArgument<NonNullGraphType<VersionOptionsInputType>>{ Name = "version", Description = "Filter workflow definitions by the specified version options."}),
|
||||
resolve: ResolveWorkflowDefinitions);
|
||||
|
||||
FieldAsync<WorkflowDefinitionVersionType>(
|
||||
"workflowDefinition",
|
||||
arguments: new QueryArguments(
|
||||
new QueryArgument<IdGraphType> { Name = "versionId", Description = "Get a specific workflow definition by its version ID."},
|
||||
new QueryArgument<StringGraphType> { Name = "definitionId", Description = "Get a specific workflow definition by ID."},
|
||||
new QueryArgument<VersionOptionsInputType>{ Name = "version", Description = "Filter workflow definitions by the specified version options."}),
|
||||
resolve: ResolveWorkflowDefinition);
|
||||
|
||||
FieldAsync<ListGraphType<WorkflowInstanceType>>(
|
||||
"workflowInstances",
|
||||
arguments: new QueryArguments(
|
||||
new QueryArgument<StringGraphType>{ Name = "definitionId", Description = "Filter workflow instances by the specified workflow definition ID."},
|
||||
new QueryArgument<EnumerationGraphType<WorkflowStatus>>{ Name = "status", Description = "Filter workflow instances by the specified workflow status."}
|
||||
),
|
||||
resolve: ResolveWorkflowInstances);
|
||||
}
|
||||
|
||||
private async Task<object> ResolveWorkflowInstances(ResolveFieldContext<object> context)
|
||||
{
|
||||
return await workflowInstanceStore.ListAllAsync(context.CancellationToken);
|
||||
}
|
||||
|
||||
private async Task<object> ResolveWorkflowDefinitions(ResolveFieldContext<object> context)
|
||||
{
|
||||
var versionOptionsModel = context.GetArgument<VersionOptionsModel>("version");
|
||||
var versionOptions = mapper.Map<VersionOptions>(versionOptionsModel);
|
||||
return await workflowDefinitionStore.ListAsync(versionOptions, context.CancellationToken);
|
||||
}
|
||||
|
||||
private async Task<object> ResolveWorkflowDefinition(ResolveFieldContext<object> context) => await ResolveWorkflowDefinitionInternal(context);
|
||||
|
||||
private async Task<WorkflowDefinitionVersion> ResolveWorkflowDefinitionInternal(ResolveFieldContext<object> context)
|
||||
{
|
||||
var versionId = context.GetArgument<string>("versionId");
|
||||
|
||||
if (versionId != null)
|
||||
return await workflowDefinitionStore.GetByIdAsync(versionId, context.CancellationToken);
|
||||
|
||||
var versionOptionsModel = context.GetArgument<VersionOptionsModel>("version") ?? new VersionOptionsModel { Latest = true };
|
||||
var versionOptions = mapper.Map<VersionOptions>(versionOptionsModel);
|
||||
var definitionId = context.GetArgument<string>("definitionId");
|
||||
|
||||
return await workflowDefinitionStore.GetByIdAsync(definitionId, versionOptions, context.CancellationToken);
|
||||
foreach (var provider in providers)
|
||||
provider.Setup(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using Elsa.Server.GraphQL.Scalars.Json;
|
||||
using Elsa.Server.GraphQL.Types.Scalars.Json;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ using Elsa.AutoMapper.Extensions;
|
|||
using Elsa.Models;
|
||||
using Elsa.Server.GraphQL;
|
||||
using Elsa.Server.GraphQL.Mapping;
|
||||
using Elsa.Server.GraphQL.Mutations;
|
||||
using Elsa.Server.GraphQL.Queries;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using GraphQL.NodaTime;
|
||||
using GraphQL.Server;
|
||||
using GraphQL.Types;
|
||||
|
|
@ -21,6 +24,14 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.AddScoped<ElsaSchema>()
|
||||
.AddSingleton<InstantGraphType>()
|
||||
.AddSingleton<EnumerationGraphType<WorkflowStatus>>()
|
||||
.AddQueryProvider<ListWorkflowDefinitions>()
|
||||
.AddQueryProvider<ListWorkflowInstances>()
|
||||
.AddQueryProvider<GetWorkflowDefinition>()
|
||||
.AddMutationProvider<DefineWorkflow>()
|
||||
.AddMutationProvider<UpdateWorkflowDefinition>()
|
||||
.AddMutationProvider<RunWorkflow>()
|
||||
.AddMutationProvider<PublishWorkflow>()
|
||||
.AddMutationProvider<DeleteWorkflowDefinition>()
|
||||
.AddAutoMapperProfile<GraphQLProfile>(ServiceLifetime.Singleton)
|
||||
.AddLogging();
|
||||
|
||||
|
|
@ -33,5 +44,15 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddMutationProvider<T>(this IServiceCollection services) where T : class, IMutationProvider
|
||||
{
|
||||
return services.AddScoped<IMutationProvider, T>();
|
||||
}
|
||||
|
||||
public static IServiceCollection AddQueryProvider<T>(this IServiceCollection services) where T : class, IQueryProvider
|
||||
{
|
||||
return services.AddScoped<IQueryProvider, T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
51
src/server/Elsa.Server.GraphQL/Mutations/DefineWorkflow.cs
Normal file
51
src/server/Elsa.Server.GraphQL/Mutations/DefineWorkflow.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using AutoMapper;
|
||||
using Elsa.Models;
|
||||
using Elsa.Server.GraphQL.Models;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using Elsa.Server.GraphQL.Types.Input;
|
||||
using Elsa.Services;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Mutations
|
||||
{
|
||||
public class DefineWorkflow : IMutationProvider
|
||||
{
|
||||
private readonly IWorkflowPublisher publisher;
|
||||
private readonly IIdGenerator idGenerator;
|
||||
private readonly IMapper mapper;
|
||||
|
||||
public DefineWorkflow(IWorkflowPublisher publisher, IIdGenerator idGenerator, IMapper mapper)
|
||||
{
|
||||
this.publisher = publisher;
|
||||
this.idGenerator = idGenerator;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public void Setup(ElsaMutation mutation)
|
||||
{
|
||||
mutation.FieldAsync<WorkflowDefinitionVersionType>(
|
||||
"defineWorkflow",
|
||||
"Create a new workflow definitions",
|
||||
new QueryArguments(new QueryArgument<NonNullGraphType<DefineWorkflowDefinitionInputType>> { Name = "workflowDefinition" }),
|
||||
async context =>
|
||||
{
|
||||
var model = context.GetArgument<DefineWorkflowDefinitionInputModel>("workflowDefinition");
|
||||
var publish = model.Publish;
|
||||
var workflowDefinitionVersion = mapper.Map<WorkflowDefinitionVersion>(model);
|
||||
|
||||
workflowDefinitionVersion.Id = idGenerator.Generate();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(workflowDefinitionVersion.DefinitionId))
|
||||
workflowDefinitionVersion.DefinitionId = idGenerator.Generate();
|
||||
|
||||
if (publish)
|
||||
await publisher.PublishAsync(workflowDefinitionVersion, context.CancellationToken);
|
||||
else
|
||||
await publisher.SaveDraftAsync(workflowDefinitionVersion, context.CancellationToken);
|
||||
|
||||
return workflowDefinitionVersion;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
using Elsa.Persistence;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Mutations
|
||||
{
|
||||
public class DeleteWorkflowDefinition : IMutationProvider
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore workflowDefinitionStore;
|
||||
|
||||
public DeleteWorkflowDefinition(IWorkflowDefinitionStore workflowDefinitionStore)
|
||||
{
|
||||
this.workflowDefinitionStore = workflowDefinitionStore;
|
||||
}
|
||||
|
||||
public void Setup(ElsaMutation mutation)
|
||||
{
|
||||
mutation.FieldAsync<IntGraphType>(
|
||||
"deleteWorkflowDefinition",
|
||||
"Delete a specified workflow definition.",
|
||||
new QueryArguments(
|
||||
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "workflowDefinitionId", Description = "The ID of the workflow definition to delete." }
|
||||
),
|
||||
async context =>
|
||||
{
|
||||
var workflowDefinitionId = context.GetArgument<string>("workflowDefinitionId");
|
||||
|
||||
return await workflowDefinitionStore.DeleteAsync(workflowDefinitionId, context.CancellationToken);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/server/Elsa.Server.GraphQL/Mutations/PublishWorkflow.cs
Normal file
33
src/server/Elsa.Server.GraphQL/Mutations/PublishWorkflow.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
using Elsa.Server.GraphQL.Services;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using Elsa.Services;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Mutations
|
||||
{
|
||||
public class PublishWorkflow : IMutationProvider
|
||||
{
|
||||
private readonly IWorkflowPublisher publisher;
|
||||
|
||||
public PublishWorkflow(IWorkflowPublisher publisher)
|
||||
{
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
public void Setup(ElsaMutation mutation)
|
||||
{
|
||||
mutation.FieldAsync<WorkflowDefinitionVersionType>(
|
||||
"publishWorkflow",
|
||||
"Publish a specified workflow.",
|
||||
new QueryArguments(
|
||||
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "workflowDefinitionId", Description = "The ID of the workflow definition to publish." }
|
||||
),
|
||||
async context =>
|
||||
{
|
||||
var workflowDefinitionId = context.GetArgument<string>("workflowDefinitionId");
|
||||
|
||||
return await publisher.PublishAsync(workflowDefinitionId, context.CancellationToken);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/server/Elsa.Server.GraphQL/Mutations/RunWorkflow.cs
Normal file
44
src/server/Elsa.Server.GraphQL/Mutations/RunWorkflow.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using Elsa.Models;
|
||||
using Elsa.Persistence;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using Elsa.Services;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Mutations
|
||||
{
|
||||
public class RunWorkflow : IMutationProvider
|
||||
{
|
||||
private readonly IWorkflowInvoker workflowInvoker;
|
||||
private readonly IWorkflowDefinitionStore workflowDefinitionStore;
|
||||
|
||||
public RunWorkflow(IWorkflowInvoker workflowInvoker, IWorkflowDefinitionStore workflowDefinitionStore)
|
||||
{
|
||||
this.workflowInvoker = workflowInvoker;
|
||||
this.workflowDefinitionStore = workflowDefinitionStore;
|
||||
}
|
||||
|
||||
public void Setup(ElsaMutation mutation)
|
||||
{
|
||||
mutation.FieldAsync<WorkflowInstanceType>(
|
||||
"runWorkflow",
|
||||
"Run a specified workflow.",
|
||||
new QueryArguments(
|
||||
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "workflowDefinitionId", Description = "The ID of the workflow definition to run." },
|
||||
new QueryArgument<StringGraphType> { Name = "correlationId", Description = "The correlation ID to associate the workflow with." }
|
||||
),
|
||||
async context =>
|
||||
{
|
||||
var workflowDefinitionId = context.GetArgument<string>("workflowDefinitionId");
|
||||
var workflowDefinition = await workflowDefinitionStore.GetByIdAsync(workflowDefinitionId, VersionOptions.Published, context.CancellationToken);
|
||||
|
||||
if (workflowDefinition == null)
|
||||
return null;
|
||||
|
||||
var correlationId = context.GetArgument<string>("correlationId");
|
||||
var executionContext = await workflowInvoker.StartAsync(workflowDefinition, correlationId: correlationId, cancellationToken: context.CancellationToken);
|
||||
return executionContext.Workflow.ToInstance();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
using System.Collections.Generic;
|
||||
using Elsa.Models;
|
||||
using Elsa.Persistence;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using Elsa.Server.GraphQL.Types.Input;
|
||||
using Elsa.Services;
|
||||
using GraphQL.Types;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Mutations
|
||||
{
|
||||
public class UpdateWorkflowDefinition : IMutationProvider
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore workflowDefinitionStore;
|
||||
private readonly IWorkflowPublisher publisher;
|
||||
|
||||
public UpdateWorkflowDefinition(IWorkflowDefinitionStore workflowDefinitionStore, IWorkflowPublisher publisher)
|
||||
{
|
||||
this.workflowDefinitionStore = workflowDefinitionStore;
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
public void Setup(ElsaMutation mutation)
|
||||
{
|
||||
mutation.FieldAsync<WorkflowDefinitionVersionType>(
|
||||
"updateWorkflow",
|
||||
"Update an existing workflow definition",
|
||||
new QueryArguments(
|
||||
new QueryArgument<NonNullGraphType<StringGraphType>> { Name = "id" },
|
||||
new QueryArgument<NonNullGraphType<UpdateWorkflowDefinitionInputType>> { Name = "workflowDefinition" }),
|
||||
async context =>
|
||||
{
|
||||
var id = context.GetArgument<string>("id");
|
||||
var workflowDefinitionVersion = await workflowDefinitionStore.GetByIdAsync(id, VersionOptions.Latest, context.CancellationToken);
|
||||
|
||||
if (workflowDefinitionVersion == null)
|
||||
return null;
|
||||
|
||||
var updateModel = context.GetArgument<dynamic>("workflowDefinition");
|
||||
var props = (IDictionary<string, object>)updateModel;
|
||||
var publish = props.ContainsKey("publish") && (bool)props["publish"];
|
||||
|
||||
// "Patch" the existing workflow definition version with the posted model values.
|
||||
var json = JsonConvert.SerializeObject(updateModel);
|
||||
JsonConvert.PopulateObject(json, workflowDefinitionVersion, new JsonSerializerSettings
|
||||
{
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace
|
||||
});
|
||||
|
||||
if (publish)
|
||||
workflowDefinitionVersion = await publisher.PublishAsync(workflowDefinitionVersion, context.CancellationToken);
|
||||
else
|
||||
workflowDefinitionVersion = await publisher.SaveDraftAsync(workflowDefinitionVersion, context.CancellationToken);
|
||||
|
||||
return workflowDefinitionVersion;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using AutoMapper;
|
||||
using Elsa.Models;
|
||||
using Elsa.Persistence;
|
||||
using Elsa.Server.GraphQL.Models;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Queries
|
||||
{
|
||||
public class GetWorkflowDefinition : IQueryProvider
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore workflowDefinitionStore;
|
||||
private readonly IMapper mapper;
|
||||
|
||||
public GetWorkflowDefinition(IWorkflowDefinitionStore workflowDefinitionStore, IMapper mapper)
|
||||
{
|
||||
this.workflowDefinitionStore = workflowDefinitionStore;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public void Setup(ElsaQuery query)
|
||||
{
|
||||
query.FieldAsync<WorkflowDefinitionVersionType>(
|
||||
"workflowDefinition",
|
||||
arguments: new QueryArguments(
|
||||
new QueryArgument<IdGraphType> { Name = "versionId", Description = "Get a specific workflow definition by its version ID."},
|
||||
new QueryArgument<StringGraphType> { Name = "definitionId", Description = "Get a specific workflow definition by ID."},
|
||||
new QueryArgument<VersionOptionsInputType>{ Name = "version", Description = "Filter workflow definitions by the specified version options."}),
|
||||
resolve: async context =>
|
||||
{
|
||||
var versionId = context.GetArgument<string>("versionId");
|
||||
|
||||
if (versionId != null)
|
||||
return await workflowDefinitionStore.GetByIdAsync(versionId, context.CancellationToken);
|
||||
|
||||
var versionOptionsModel = context.GetArgument<VersionOptionsModel>("version") ?? new VersionOptionsModel { Latest = true };
|
||||
var versionOptions = mapper.Map<VersionOptions>(versionOptionsModel);
|
||||
var definitionId = context.GetArgument<string>("definitionId");
|
||||
|
||||
return await workflowDefinitionStore.GetByIdAsync(definitionId, versionOptions, context.CancellationToken);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using AutoMapper;
|
||||
using Elsa.Models;
|
||||
using Elsa.Persistence;
|
||||
using Elsa.Server.GraphQL.Models;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Queries
|
||||
{
|
||||
public class ListWorkflowDefinitions : IQueryProvider
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore workflowDefinitionStore;
|
||||
private readonly IMapper mapper;
|
||||
|
||||
public ListWorkflowDefinitions(IWorkflowDefinitionStore workflowDefinitionStore, IMapper mapper)
|
||||
{
|
||||
this.workflowDefinitionStore = workflowDefinitionStore;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public void Setup(ElsaQuery query)
|
||||
{
|
||||
query.FieldAsync<ListGraphType<WorkflowDefinitionVersionType>>(
|
||||
"workflowDefinitions",
|
||||
arguments: new QueryArguments(new QueryArgument<NonNullGraphType<VersionOptionsInputType>>{ Name = "version", Description = "Filter workflow definitions by the specified version options."}),
|
||||
resolve: async context =>
|
||||
{
|
||||
var versionOptionsModel = context.GetArgument<VersionOptionsModel>("version");
|
||||
var versionOptions = mapper.Map<VersionOptions>(versionOptionsModel);
|
||||
return await workflowDefinitionStore.ListAsync(versionOptions, context.CancellationToken);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using Elsa.Models;
|
||||
using Elsa.Persistence;
|
||||
using Elsa.Server.GraphQL.Services;
|
||||
using Elsa.Server.GraphQL.Types;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Queries
|
||||
{
|
||||
public class ListWorkflowInstances : IQueryProvider
|
||||
{
|
||||
private readonly IWorkflowInstanceStore workflowInstanceStore;
|
||||
|
||||
public ListWorkflowInstances(IWorkflowInstanceStore workflowInstanceStore)
|
||||
{
|
||||
this.workflowInstanceStore = workflowInstanceStore;
|
||||
}
|
||||
|
||||
public void Setup(ElsaQuery query)
|
||||
{
|
||||
query.FieldAsync<ListGraphType<WorkflowInstanceType>>(
|
||||
"workflowInstances",
|
||||
arguments: new QueryArguments(
|
||||
new QueryArgument<StringGraphType>{ Name = "definitionId", Description = "Filter workflow instances by the specified workflow definition ID."},
|
||||
new QueryArgument<EnumerationGraphType<WorkflowStatus>>{ Name = "status", Description = "Filter workflow instances by the specified workflow status."}
|
||||
),
|
||||
resolve: async context => await workflowInstanceStore.ListAllAsync(context.CancellationToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace Elsa.Server.GraphQL.Services
|
||||
{
|
||||
public interface IMutationProvider
|
||||
{
|
||||
void Setup(ElsaMutation mutation);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace Elsa.Server.GraphQL.Services
|
||||
{
|
||||
public interface IQueryProvider
|
||||
{
|
||||
void Setup(ElsaQuery query);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
using Elsa.Models;
|
||||
using Elsa.Server.GraphQL.Scalars.Json;
|
||||
using Elsa.Server.GraphQL.Types.Scalars.Json;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Types
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using Elsa.Models;
|
||||
using Elsa.Server.GraphQL.Scalars.Json;
|
||||
using Elsa.Server.GraphQL.Types.Scalars.Json;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Types
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
using Elsa.Models;
|
||||
using Elsa.Server.GraphQL.Scalars.Json;
|
||||
using Elsa.Server.GraphQL.Types.Scalars.Json;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Types
|
||||
namespace Elsa.Server.GraphQL.Types.Input
|
||||
{
|
||||
public class ActivityDefinitionInputType : InputObjectGraphType<ActivityDefinition>
|
||||
{
|
||||
|
|
@ -10,6 +10,7 @@ namespace Elsa.Server.GraphQL.Types
|
|||
{
|
||||
Name = "ActivityDefinitionInput";
|
||||
|
||||
Field(x => x.Id).Description("The ID of the activity.");
|
||||
Field(x => x.Type).Description("The activity type name.");
|
||||
Field(x => x.Description, true).Description("A description for the activity");
|
||||
Field(x => x.Name, true).Description("A name for the activity. Named activities make it easy to be referenced from workflow expressions.");
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using Elsa.Models;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Types
|
||||
namespace Elsa.Server.GraphQL.Types.Input
|
||||
{
|
||||
public class ConnectionDefinitionInputType : InputObjectGraphType<ConnectionDefinition>
|
||||
{
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using Elsa.Server.GraphQL.Models;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Types
|
||||
namespace Elsa.Server.GraphQL.Types.Input
|
||||
{
|
||||
public class DefineWorkflowDefinitionInputType : InputObjectGraphType<DefineWorkflowDefinitionInputModel>
|
||||
{
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using Elsa.Server.GraphQL.Models;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Types
|
||||
namespace Elsa.Server.GraphQL.Types.Input
|
||||
{
|
||||
public class UpdateWorkflowDefinitionInputType : InputObjectGraphType<UpdateWorkflowDefinitionInputModel>
|
||||
{
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
using GraphQL.Types;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Scalars.Json
|
||||
namespace Elsa.Server.GraphQL.Types.Scalars.Json
|
||||
{
|
||||
public class JsonAstValueConverter : IAstFromValueConverter
|
||||
{
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
using GraphQL.Types;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Scalars.Json
|
||||
namespace Elsa.Server.GraphQL.Types.Scalars.Json
|
||||
{
|
||||
public class JsonType : ScalarGraphType
|
||||
{
|
||||
|
|
@ -11,7 +11,7 @@ namespace Elsa.Server.GraphQL.Scalars.Json
|
|||
Name = "Json";
|
||||
}
|
||||
|
||||
public override object Serialize(object value) => value.ToString();
|
||||
public override object Serialize(object value) => value;
|
||||
|
||||
public override object ParseValue(object value) => JObject.Parse((string)value);
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using GraphQL.Language.AST;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Scalars.Json
|
||||
namespace Elsa.Server.GraphQL.Types.Scalars.Json
|
||||
{
|
||||
public class JsonValue : ValueNode<JObject>
|
||||
{
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
using Elsa.Models;
|
||||
using Elsa.Server.GraphQL.Scalars.Json;
|
||||
using Elsa.Server.GraphQL.Types.Scalars.Json;
|
||||
using GraphQL.Types;
|
||||
|
||||
namespace Elsa.Server.GraphQL.Types
|
||||
|
|
|
|||
|
|
@ -15,18 +15,18 @@ namespace Elsa.Server.GraphQL.Types
|
|||
Field(x => x.DefinitionId).Description("The ID of the workflow definition this workflow is an instance of.");
|
||||
Field(x => x.Version).Description("The version of the workflow definition this workflow is an instance of.");
|
||||
Field(x => x.Status).Description("The status of the workflow.");
|
||||
Field(x => x.CorrelationId).Description("The correlation ID of the workflow.");
|
||||
Field(x => x.Activities, type: typeof(ListGraphType<ActivityInstanceType>)).Description("A hash of activity instances.");
|
||||
Field(x => x.BlockingActivities, type: typeof(ListGraphType<BlockingActivityType>)).Description("A hash of activities that are blocking workflow execution.");
|
||||
Field(x => x.CorrelationId, true).Description("The correlation ID of the workflow.");
|
||||
Field(x => x.Activities, true, typeof(ListGraphType<ActivityInstanceType>)).Description("A hash of activity instances.");
|
||||
Field(x => x.BlockingActivities, true, typeof(ListGraphType<BlockingActivityType>)).Description("A hash of activities that are blocking workflow execution.");
|
||||
Field(x => x.Input, true, typeof(VariablesType)).Description("Holds input variables.");
|
||||
Field(x => x.Scopes, type: typeof(ListGraphType<WorkflowExecutionScopeType>)).Description("Holds workflow variables in a stack of scopes.");
|
||||
Field(x => x.ExecutionLog, type: typeof(ListGraphType<LogEntryType>)).Description("A log of executed activities.");
|
||||
Field(x => x.ExecutionLog, true, typeof(ListGraphType<LogEntryType>)).Description("A log of executed activities.");
|
||||
Field(x => x.Fault, true, typeof(WorkflowFaultType)).Description("If the workflow is in a Faulted state, this property holds details about the fault.");
|
||||
Field(x => x.CreatedAt, type: typeof(InstantGraphType)).Description("The time stamp at which this workflow instance was created.");
|
||||
Field(x => x.StartedAt, type: typeof(InstantGraphType)).Description("The time stamp at which the workflow has started.");
|
||||
Field(x => x.FinishedAt, type: typeof(InstantGraphType)).Description("The time stamp at which the workflow has finished.");
|
||||
Field(x => x.FaultedAt, type: typeof(InstantGraphType)).Description("The time stamp at which the workflow has faulted.");
|
||||
Field(x => x.AbortedAt, type: typeof(InstantGraphType)).Description("The time stamp at which the workflow was aborted.");
|
||||
Field(x => x.StartedAt, true, typeof(InstantGraphType)).Description("The time stamp at which the workflow has started.");
|
||||
Field(x => x.FinishedAt, true, typeof(InstantGraphType)).Description("The time stamp at which the workflow has finished.");
|
||||
Field(x => x.FaultedAt, true, typeof(InstantGraphType)).Description("The time stamp at which the workflow has faulted.");
|
||||
Field(x => x.AbortedAt, true, typeof(InstantGraphType)).Description("The time stamp at which the workflow was aborted.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
using Elsa.Activities.Console.Extensions;
|
||||
using Elsa.Server.GraphQL.Extensions;
|
||||
using GraphQL.Server.Ui.GraphiQL;
|
||||
using GraphQL.Server.Ui.Playground;
|
||||
|
|
@ -31,6 +32,7 @@ namespace Elsa.Server.Host
|
|||
.AddMongoDbStores(Configuration, "ElsaServer", "MongoDb")
|
||||
.AddGraphQL(options => Configuration.GetSection("GraphQL").Bind(options)))
|
||||
|
||||
.AddConsoleActivities()
|
||||
.AddHttpActivities(options => options.Bind(elsaSection.GetSection("Http")))
|
||||
.AddEmailActivities(options => options.Bind(elsaSection.GetSection("Smtp")))
|
||||
.AddTimerActivities(options => options.Bind(elsaSection.GetSection("BackgroundRunner")))
|
||||
|
|
|
|||
Loading…
Reference in a new issue