using System.Text.Json; using Elsa.Connections.Attributes; using Elsa.Connections.Models; using Elsa.Extensions; using Elsa.Workflows; using Elsa.Workflows.Pipelines.ActivityExecution; using JetBrains.Annotations; using Microsoft.Extensions.Logging; using Elsa.Connections.Core.Extensions; using Elsa.Connections.Converters; using Elsa.Connections.Persistence.Contracts; namespace Elsa.Connections.Middleware; /// /// An activity execution middleware component that injects connection properties from Connection Name. /// [UsedImplicitly] public class ConnectionMiddleware(ActivityMiddlewareDelegate next , IConnectionStore connectionStore ,ILogger logger) : IActivityExecutionMiddleware { private static JsonSerializerOptions? _serializerOptions; private static JsonSerializerOptions SerializerOptions => _serializerOptions ??= new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, }.WithConverters(new Int32Converter()); /// public async ValueTask InvokeAsync(ActivityExecutionContext context) { var activityDescriptor = context.ActivityDescriptor; if (activityDescriptor.Attributes.Any(attr => attr.GetType() == typeof(ConnectionActivityAttribute))) { var inputDescriptors = activityDescriptor.Inputs.Where(x => x.PropertyInfo?.PropertyType.GetGenericTypeDefinition() == typeof(ConnectionProperties<>)).ToList(); if (inputDescriptors.Count > 0) { var input = inputDescriptors[0]; var propertyType = input.PropertyInfo?.PropertyType.GetGenericArguments()[0]; dynamic inputValue = input.ValueGetter(context.Activity)!; var connectionName = (string)inputValue.ConnectionName; if (connectionName == null) LogConnectionExtensions.LogConnectionIsNull(logger); else { // Get connection from store, if exists. var connectionConfiguration = await connectionStore.FindAsync(new() { Name = connectionName }); if (connectionConfiguration != null) { dynamic deserializedJson = connectionConfiguration.ConnectionConfiguration.Deserialize(propertyType, SerializerOptions)!; inputValue.Properties = deserializedJson; input.ValueSetter(context.Activity, inputValue); } else LogConnectionExtensions.LogConnectionNotFound(logger, connectionName); } } } await next(context); } }