Include $schema when exporting workflow definition (#6056)

* Refactor AdditionalConvertersConfigurator constructor

Simplify AdditionalConvertersConfigurator by using constructor injection directly in the class declaration. Also, annotate the class with [UsedImplicitly] to improve code clarity and maintainability.

* Update workflow serialization to be asynchronous

Refactor the workflow definition serialization to use asynchronous operations, improving efficiency and handling cancellation tokens. This change ensures the schema is correctly included in the serialized output.
This commit is contained in:
Sipke Schoorstra 2024-10-25 14:51:27 +02:00 committed by GitHub
parent b46d432579
commit fefe36f49a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 24 additions and 17 deletions

View file

@ -74,7 +74,7 @@ internal class Export : ElsaEndpoint<Request>
foreach (var definition in definitions)
{
var model = await CreateWorkflowModelAsync(definition, cancellationToken);
var binaryJson = SerializeWorkflowDefinition(model);
var binaryJson = await SerializeWorkflowDefinitionAsync(model, cancellationToken);
var fileName = GetFileName(model);
var entry = zipArchive.CreateEntry(fileName, CompressionLevel.Optimal);
await using var entryStream = entry.Open();
@ -103,7 +103,7 @@ internal class Export : ElsaEndpoint<Request>
}
var model = await CreateWorkflowModelAsync(definition, cancellationToken);
var binaryJson = SerializeWorkflowDefinition(model);
var binaryJson = await SerializeWorkflowDefinitionAsync(model, cancellationToken);
var fileName = GetFileName(model);
await SendBytesAsync(binaryJson, fileName, cancellation: cancellationToken);
@ -117,10 +117,25 @@ internal class Export : ElsaEndpoint<Request>
return fileName;
}
private byte[] SerializeWorkflowDefinition(WorkflowDefinitionModel model)
private async Task<byte[]> SerializeWorkflowDefinitionAsync(WorkflowDefinitionModel model, CancellationToken cancellationToken)
{
JsonSerializerOptions serializerOptions = _serializer.GetOptions();
var binaryJson = JsonSerializer.SerializeToUtf8Bytes(model, serializerOptions);
var serializerOptions = _serializer.GetOptions();
var document = JsonSerializer.SerializeToDocument(model, serializerOptions);
var rootElement = document.RootElement;
using var output = new MemoryStream();
await using var writer = new Utf8JsonWriter(output);
writer.WriteStartObject();
writer.WriteString("$schema", "https://elsaworkflows.io/schemas/workflow-definition/v3.0.0/schema.json");
foreach (var property in rootElement.EnumerateObject())
property.WriteTo(writer);
writer.WriteEndObject();
await writer.FlushAsync(cancellationToken);
var binaryJson = output.ToArray();
return binaryJson;
}

View file

@ -1,6 +1,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Elsa.Workflows.Serialization.Converters;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Workflows.Serialization.Configurators;
@ -8,23 +9,14 @@ namespace Elsa.Workflows.Serialization.Configurators;
/// <summary>
/// Add additional <see cref="JsonConverter"/> objects.
/// </summary>
public class AdditionalConvertersConfigurator : SerializationOptionsConfiguratorBase
[UsedImplicitly]
public class AdditionalConvertersConfigurator(IServiceProvider serviceProvider) : SerializationOptionsConfiguratorBase
{
private readonly IServiceProvider _serviceProvider;
/// <summary>
/// Initializes a new instance of the <see cref="AdditionalConvertersConfigurator"/> class.
/// </summary>
public AdditionalConvertersConfigurator(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
/// <inheritdoc />
public override void Configure(JsonSerializerOptions options)
{
options.Converters.Add(Create<VariableConverterFactory>());
}
private T Create<T>() => ActivatorUtilities.CreateInstance<T>(_serviceProvider);
private T Create<T>() => ActivatorUtilities.CreateInstance<T>(serviceProvider);
}