Incremental work on GraphQL

This commit is contained in:
Sipke Schoorstra 2019-11-24 22:02:14 +01:00
parent 34a3872693
commit b7103188fd
30 changed files with 409 additions and 159 deletions

View file

@ -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);

View file

@ -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;
}
}
}

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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>();
}
}
}

View 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;
});
}
}
}

View file

@ -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);
});
}
}
}

View 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);
});
}
}
}

View 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();
});
}
}
}

View file

@ -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;
});
}
}
}

View file

@ -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);
});
}
}
}

View file

@ -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);
});
}
}
}

View file

@ -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));
}
}
}

View file

@ -0,0 +1,7 @@
namespace Elsa.Server.GraphQL.Services
{
public interface IMutationProvider
{
void Setup(ElsaMutation mutation);
}
}

View file

@ -0,0 +1,7 @@
namespace Elsa.Server.GraphQL.Services
{
public interface IQueryProvider
{
void Setup(ElsaQuery query);
}
}

View file

@ -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

View file

@ -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

View file

@ -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.");

View file

@ -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>
{

View file

@ -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>
{

View file

@ -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>
{

View file

@ -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
{

View file

@ -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);

View file

@ -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>
{

View file

@ -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

View file

@ -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.");
}
}
}

View file

@ -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")))