From 00b248f3d8550d693beef9745a3f56f6cb062419 Mon Sep 17 00:00:00 2001 From: master <> Date: Wed, 8 Apr 2026 13:48:27 +0300 Subject: [PATCH 1/3] fix: backport engine fixes from Serdica integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Handle duplicate JSON property names in ToRuntimeValue — GroupBy before ToDictionary prevents crash on case-insensitive duplicates 2. Normalize decimal-valued integers in sub-workflow payloads — recursive NormalizePayloadNumbers converts 201000256548.0 to long 3. Add WorkflowExecutionActorContext — AsyncLocal propagation of actor identity through OnComplete execution chains Co-Authored-By: Claude Opus 4.6 (1M context) --- .../WorkflowCanonicalExpressionRuntime.cs | 10 +++--- .../WorkflowExecutionActorContext.cs | 35 +++++++++++++++++++ .../WorkflowRegistrationAbstractions.cs | 26 +++++++++++++- 3 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowExecutionActorContext.cs diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowCanonicalExpressionRuntime.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowCanonicalExpressionRuntime.cs index fabb7c215..7e53dbb07 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowCanonicalExpressionRuntime.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowCanonicalExpressionRuntime.cs @@ -480,10 +480,12 @@ public static class WorkflowCanonicalExpressionRuntime JsonValueKind.Number when element.TryGetInt64(out var int64Value) => int64Value, JsonValueKind.Number when element.TryGetDecimal(out var decimalValue) => decimalValue, JsonValueKind.Number when element.TryGetDouble(out var doubleValue) => doubleValue, - JsonValueKind.Object => element.EnumerateObject().ToDictionary( - x => x.Name, - x => ToRuntimeValue(x.Value), - StringComparer.OrdinalIgnoreCase), + JsonValueKind.Object => element.EnumerateObject() + .GroupBy(x => x.Name, StringComparer.OrdinalIgnoreCase) + .ToDictionary( + g => g.Key, + g => ToRuntimeValue(g.Last().Value), + StringComparer.OrdinalIgnoreCase), JsonValueKind.Array => element.EnumerateArray().Select(ToRuntimeValue).ToArray(), _ => element.ToString(), }; diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowExecutionActorContext.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowExecutionActorContext.cs new file mode 100644 index 000000000..871ce857f --- /dev/null +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowExecutionActorContext.cs @@ -0,0 +1,35 @@ +using System.Threading; + +namespace StellaOps.Workflow.Abstractions; + +/// +/// Propagates the authenticated actor ID through async workflow execution chains +/// (e.g., OnComplete -> Call -> transport) where the original request context +/// is not available. Implementations set ActorId and CallerUserId during +/// task-complete/start-workflow processing. +/// +public sealed class WorkflowExecutionActorContext +{ + private static readonly AsyncLocal CurrentActorId = new(); + private static readonly AsyncLocal CurrentCallerUserId = new(); + + /// + /// The actor ID from the task operation request (e.g., numeric user account ID). + /// Used for role resolution and task assignment. + /// + public string? ActorId + { + get => CurrentActorId.Value; + set => CurrentActorId.Value = value; + } + + /// + /// The authenticated caller's user ID extracted from the HTTP request context. + /// Used by transport implementations for backend service calls. + /// + public string? CallerUserId + { + get => CurrentCallerUserId.Value; + set => CurrentCallerUserId.Value = value; + } +} diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowRegistrationAbstractions.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowRegistrationAbstractions.cs index 770d41846..77486a4f1 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowRegistrationAbstractions.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowRegistrationAbstractions.cs @@ -78,6 +78,7 @@ public static class WorkflowRegistrationServiceCollectionExtensions private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web) { PropertyNameCaseInsensitive = true, + NumberHandling = global::System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString, }; public static IServiceCollection AddWorkflowRegistration( @@ -190,7 +191,8 @@ public static class WorkflowRegistrationServiceCollectionExtensions return new Dictionary(payload, StringComparer.OrdinalIgnoreCase); } - var json = JsonSerializer.Serialize(payload, SerializerOptions); + var normalized = NormalizePayloadNumbers(payload); + var json = JsonSerializer.Serialize(normalized, SerializerOptions); return JsonSerializer.Deserialize(json, startRequestType, SerializerOptions) ?? throw new InvalidOperationException( $"Unable to bind workflow payload to '{startRequestType.FullName}'."); @@ -291,5 +293,27 @@ public static class WorkflowRegistrationServiceCollectionExtensions }; } + private static IDictionary NormalizePayloadNumbers(IDictionary payload) + { + var result = new Dictionary(payload.Count, StringComparer.OrdinalIgnoreCase); + foreach (var kvp in payload) + { + result[kvp.Key] = NormalizeValue(kvp.Value); + } + return result; + } + + private static object? NormalizeValue(object? value) + { + return value switch + { + decimal d when d == Math.Truncate(d) && d >= long.MinValue && d <= long.MaxValue => (long)d, + double d when d == Math.Truncate(d) && d >= long.MinValue && d <= long.MaxValue => (long)d, + IDictionary dict => NormalizePayloadNumbers(dict), + object[] arr => arr.Select(NormalizeValue).ToArray(), + _ => value, + }; + } + private sealed record WorkflowBusinessReferencePartProperty(PropertyInfo Property, string PartName); } From ca35f6683091487a63fdf524f44e6451f624fff9 Mon Sep 17 00:00:00 2001 From: master <> Date: Wed, 8 Apr 2026 13:59:09 +0300 Subject: [PATCH 2/3] backport: merge Serdica workflow abstractions and contracts improvements Backport generic improvements from Serdica workflow engine to StellaOps: Abstractions: - Add IWorkflowActorRoleResolver interface and NullWorkflowActorRoleResolver default implementation for server-side actor identity resolution - Add expression-based Call overloads to WorkflowFlowBuilder (6 new methods accepting WorkflowExpressionDefinition for payload instead of Func<> factory) - Fix failure handler compilation: preserve empty handlers (0 steps) as empty sequences instead of null, allowing "ignore failure and continue" semantics - Add explanatory comments to WorkflowRegistrationAbstractions for JSON number normalization logic Contracts: - Add NextTasks and WorkflowState to StartWorkflowResponse so callers can see immediate next tasks after starting a workflow - Add WorkflowInstanceId, NextTasks, and WorkflowState to WorkflowTaskCompleteResponse for richer task completion feedback Transport: verified Transport.GraphQL, Transport.Http, Transport.Microservice, and Transport.LegacyRabbit are engine-embedded plugins (no separate directories to add/remove). ElkSharp library confirmed present at src/__Libraries/. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../IWorkflowActorRoleResolver.cs | 45 +++++++++ ...flowCanonicalDefinitionCompiler.Helpers.cs | 6 +- .../WorkflowDeclarativeAbstractions.cs | 98 +++++++++++++++++++ .../WorkflowRegistrationAbstractions.cs | 6 ++ .../WorkflowStartContracts.cs | 2 + .../WorkflowTaskContracts.cs | 3 + 6 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/IWorkflowActorRoleResolver.cs diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/IWorkflowActorRoleResolver.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/IWorkflowActorRoleResolver.cs new file mode 100644 index 000000000..7a9fd0f77 --- /dev/null +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/IWorkflowActorRoleResolver.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace StellaOps.Workflow.Abstractions; + +/// +/// Resolves the authenticated actor's identity (ID + roles) from the server-side +/// request context. Implementations may query a database, read JWT claims, or +/// fall back to client-supplied values. +/// +public interface IWorkflowActorRoleResolver +{ + /// + /// Returns the actor ID for the current request. + /// Implementations should prefer server-side identity over client-supplied values. + /// + string ResolveActorId(string? clientActorId); + + /// + /// Resolves user roles from a trusted source (database, identity provider). + /// Falls back to when no server-side context + /// is available (e.g., during signal pump processing). + /// + Task> ResolveActorRolesAsync( + string actorId, + IReadOnlyCollection? clientRoles, + CancellationToken cancellationToken = default); +} + +/// +/// Default no-op resolver that passes through client-supplied values. +/// Used when no database-backed role resolution is configured. +/// +public sealed class NullWorkflowActorRoleResolver : IWorkflowActorRoleResolver +{ + public string ResolveActorId(string? clientActorId) + => clientActorId ?? string.Empty; + + public Task> ResolveActorRolesAsync( + string actorId, + IReadOnlyCollection? clientRoles, + CancellationToken cancellationToken = default) + => Task.FromResult>(clientRoles ?? []); +} diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowCanonicalDefinitionCompiler.Helpers.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowCanonicalDefinitionCompiler.Helpers.cs index a39bde064..915e74b1e 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowCanonicalDefinitionCompiler.Helpers.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowCanonicalDefinitionCompiler.Helpers.cs @@ -179,8 +179,10 @@ public static partial class WorkflowCanonicalDefinitionCompiler }, ResultKey = resultKey, TimeoutSeconds = timeoutSeconds, - WhenFailure = failureHandlers?.HasFailureBranch == true ? BuildSequence(failureHandlers.WhenFailure) : null, - WhenTimeout = failureHandlers?.HasTimeoutBranch == true ? BuildSequence(failureHandlers.WhenTimeout) : null, + // Preserve empty handlers (0 steps) as empty sequences — they mean "ignore failure and continue". + // Only set to null when no handler was provided at all. + WhenFailure = failureHandlers is not null ? BuildSequence(failureHandlers.WhenFailure) : null, + WhenTimeout = failureHandlers is not null ? BuildSequence(failureHandlers.WhenTimeout) : null, }; } diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowDeclarativeAbstractions.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowDeclarativeAbstractions.cs index 7d373c17f..8ba98212b 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowDeclarativeAbstractions.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowDeclarativeAbstractions.cs @@ -726,6 +726,104 @@ public sealed class WorkflowFlowBuilder null); } + public WorkflowFlowBuilder Call( + string stepName, + Address address, + WorkflowExpressionDefinition payloadExpression, + Action> whenFailure, + Action>? whenTimeout = null) + { + return AddMicroserviceCall( + stepName, + address.MicroserviceName, + address.Command, + context => WorkflowCanonicalExpressionRuntime.Evaluate(payloadExpression, context), + payloadExpression, + null, + whenFailure, + whenTimeout); + } + + public WorkflowFlowBuilder Call( + string stepName, + Address address, + WorkflowExpressionDefinition payloadExpression, + WorkflowHandledBranchAction onFailure, + WorkflowHandledBranchAction onTimeout = WorkflowHandledBranchAction.None) + { + return AddMicroserviceCall( + stepName, + address.MicroserviceName, + address.Command, + context => WorkflowCanonicalExpressionRuntime.Evaluate(payloadExpression, context), + payloadExpression, + null, + null, + null, + onFailure, + onTimeout); + } + + public WorkflowFlowBuilder Call( + string stepName, + Address address, + WorkflowExpressionDefinition payloadExpression, + string? resultKey = null) + { + ArgumentNullException.ThrowIfNull(payloadExpression); + return AddMicroserviceCall( + stepName, + address.MicroserviceName, + address.Command, + context => WorkflowCanonicalExpressionRuntime.Evaluate(payloadExpression, context), + payloadExpression, + resultKey ?? stepName, + null, + null); + } + + public WorkflowFlowBuilder Call( + string stepName, + Address address, + WorkflowExpressionDefinition payloadExpression, + Action> whenFailure, + Action>? whenTimeout = null, + string? resultKey = null) + { + ArgumentNullException.ThrowIfNull(payloadExpression); + return AddMicroserviceCall( + stepName, + address.MicroserviceName, + address.Command, + context => WorkflowCanonicalExpressionRuntime.Evaluate(payloadExpression, context), + payloadExpression, + resultKey, + whenFailure, + whenTimeout); + } + + public WorkflowFlowBuilder Call( + string stepName, + Address address, + WorkflowExpressionDefinition payloadExpression, + WorkflowHandledBranchAction onFailure, + WorkflowHandledBranchAction onTimeout = WorkflowHandledBranchAction.None, + string? resultKey = null) + { + ArgumentNullException.ThrowIfNull(payloadExpression); + return AddMicroserviceCall( + stepName, + address.MicroserviceName, + address.Command, + context => WorkflowCanonicalExpressionRuntime.Evaluate(payloadExpression, context), + payloadExpression, + resultKey, + null, + null, + onFailure, + onTimeout); + } + public WorkflowFlowBuilder Call( string stepName, Address address, diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowRegistrationAbstractions.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowRegistrationAbstractions.cs index 77486a4f1..e0d8cd899 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowRegistrationAbstractions.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Abstractions/WorkflowRegistrationAbstractions.cs @@ -78,6 +78,9 @@ public static class WorkflowRegistrationServiceCollectionExtensions private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web) { PropertyNameCaseInsensitive = true, + // Allow floating-point JSON numbers (e.g., 201000256548.0) to deserialize into integer + // types (long?, int?). This is needed because the workflow state round-trips through + // JSON serialization which may add ".0" to integer values. NumberHandling = global::System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString, }; @@ -191,6 +194,9 @@ public static class WorkflowRegistrationServiceCollectionExtensions return new Dictionary(payload, StringComparer.OrdinalIgnoreCase); } + // Normalize decimal-valued integers (e.g., 201000256548.0 → 201000256548) + // before serialization. This is needed because the workflow state may store + // integer values as decimals after JSON round-trips. var normalized = NormalizePayloadNumbers(payload); var json = JsonSerializer.Serialize(normalized, SerializerOptions); return JsonSerializer.Deserialize(json, startRequestType, SerializerOptions) diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Contracts/WorkflowStartContracts.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Contracts/WorkflowStartContracts.cs index 8c4d3716e..bf9270c83 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.Contracts/WorkflowStartContracts.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Contracts/WorkflowStartContracts.cs @@ -16,4 +16,6 @@ public sealed record StartWorkflowResponse public required string WorkflowName { get; init; } public required string WorkflowVersion { get; init; } public WorkflowBusinessReference? BusinessReference { get; init; } + public IReadOnlyCollection NextTasks { get; init; } = []; + public IDictionary WorkflowState { get; init; } = new Dictionary(); } diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.Contracts/WorkflowTaskContracts.cs b/src/Workflow/__Libraries/StellaOps.Workflow.Contracts/WorkflowTaskContracts.cs index 0df8f01ac..06e080f81 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.Contracts/WorkflowTaskContracts.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.Contracts/WorkflowTaskContracts.cs @@ -87,6 +87,9 @@ public sealed record WorkflowTaskCompleteResponse { public required string WorkflowTaskId { get; init; } public required bool Completed { get; init; } + public string? WorkflowInstanceId { get; init; } + public IReadOnlyCollection NextTasks { get; init; } = []; + public IDictionary WorkflowState { get; init; } = new Dictionary(); } public sealed record WorkflowTaskAssignRequest From ff4c721eda39d258cef26531f88cdcfaf859b695 Mon Sep 17 00:00:00 2001 From: master <> Date: Wed, 8 Apr 2026 14:56:02 +0300 Subject: [PATCH 3/3] feat: port WorkflowStore plugins (Oracle, Mongo, Postgres) from Serdica Ported 3 database backend plugins with namespace adaptation: - Oracle: EF Core-based store with AQ signaling wiring (2 files) - MongoDB: Delegates to DataStore.MongoDB extension method (2 files) - PostgreSQL: Delegates to DataStore.PostgreSQL extension method (2 files) Implementation files already exist in __Libraries DataStore projects (ported in earlier commits). These plugins are thin IDependencyInjectionRoutine wrappers that enable dynamic plugin loading via the workflow plugin system. Also fleshed out the stub OracleWorkflowDataStoreExtensions to register WorkflowDbContext, OracleWorkflowRuntimeStateStore, and OracleWorkflowHostedJobLockService. All namespaces converted from Ablera.Serdica to StellaOps. Plugin interface adapted from IPluginServiceRegistrator to IDependencyInjectionRoutine. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/Workflow/StellaOps.Workflow.slnx | 5 +++ .../OracleWorkflowDataStoreExtensions.cs | 26 +++++++++-- .../ServiceRegistrator.cs | 16 +++++++ ...Workflow.Plugin.WorkflowStore.Mongo.csproj | 37 +++++++++++++++ .../ServiceRegistrator.cs | 45 +++++++++++++++++++ ...orkflow.Plugin.WorkflowStore.Oracle.csproj | 45 +++++++++++++++++++ .../ServiceRegistrator.cs | 16 +++++++ ...kflow.Plugin.WorkflowStore.Postgres.csproj | 37 +++++++++++++++ 8 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/ServiceRegistrator.cs create mode 100644 src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/StellaOps.Workflow.Plugin.WorkflowStore.Mongo.csproj create mode 100644 src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/ServiceRegistrator.cs create mode 100644 src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/StellaOps.Workflow.Plugin.WorkflowStore.Oracle.csproj create mode 100644 src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/ServiceRegistrator.cs create mode 100644 src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/StellaOps.Workflow.Plugin.WorkflowStore.Postgres.csproj diff --git a/src/Workflow/StellaOps.Workflow.slnx b/src/Workflow/StellaOps.Workflow.slnx index 67e2f4912..008e298d5 100644 --- a/src/Workflow/StellaOps.Workflow.slnx +++ b/src/Workflow/StellaOps.Workflow.slnx @@ -14,6 +14,11 @@ + + + + + diff --git a/src/Workflow/__Libraries/StellaOps.Workflow.DataStore.Oracle/OracleWorkflowDataStoreExtensions.cs b/src/Workflow/__Libraries/StellaOps.Workflow.DataStore.Oracle/OracleWorkflowDataStoreExtensions.cs index c39a268a7..792a310dd 100644 --- a/src/Workflow/__Libraries/StellaOps.Workflow.DataStore.Oracle/OracleWorkflowDataStoreExtensions.cs +++ b/src/Workflow/__Libraries/StellaOps.Workflow.DataStore.Oracle/OracleWorkflowDataStoreExtensions.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.EntityFrameworkCore; using StellaOps.Workflow.Abstractions; @@ -10,10 +11,27 @@ public static class OracleWorkflowDataStoreExtensions public static IServiceCollection AddWorkflowOracleDataStore( this IServiceCollection services, IConfiguration configuration) { - // Register WorkflowDbContext with Oracle provider - // Register OracleWorkflowRuntimeStateStore - // Register OracleWorkflowHostedJobLockService - // Register EF-based projection/retention stores + services.AddWorkflowModule("workflow-store.oracle", "1.0.0"); + services.AddSingleton( + new WorkflowBackendRegistrationMarker(WorkflowBackendNames.Oracle)); + + if (!string.Equals(configuration.GetWorkflowBackendProvider(), WorkflowBackendNames.Oracle, StringComparison.OrdinalIgnoreCase)) + { + return services; + } + + services.AddDbContext(options => + { + var connectionString = configuration.GetConnectionString("WorkflowOracle") + ?? configuration.GetConnectionString("Default"); + if (!string.IsNullOrWhiteSpace(connectionString)) + { + options.UseOracle(connectionString); + } + }); + services.Replace(ServiceDescriptor.Scoped()); + services.Replace(ServiceDescriptor.Scoped()); + return services; } } diff --git a/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/ServiceRegistrator.cs b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/ServiceRegistrator.cs new file mode 100644 index 000000000..024b1e762 --- /dev/null +++ b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/ServiceRegistrator.cs @@ -0,0 +1,16 @@ +using StellaOps.DependencyInjection; +using StellaOps.Workflow.Abstractions; +using StellaOps.Workflow.DataStore.MongoDB; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace StellaOps.Workflow.Plugin.WorkflowStore.Mongo; + +public sealed class ServiceRegistrator : IDependencyInjectionRoutine +{ + public IServiceCollection Register(IServiceCollection services, IConfiguration configuration) + { + return services.AddWorkflowMongoDataStore(configuration); + } +} diff --git a/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/StellaOps.Workflow.Plugin.WorkflowStore.Mongo.csproj b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/StellaOps.Workflow.Plugin.WorkflowStore.Mongo.csproj new file mode 100644 index 000000000..84a3614d3 --- /dev/null +++ b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/StellaOps.Workflow.Plugin.WorkflowStore.Mongo.csproj @@ -0,0 +1,37 @@ + + + net10.0 + false + enable + true + enable + false + true + $([System.IO.Path]::Combine($(MSBuildProjectDirectory),'..','..','StellaOps.Workflow.WebService','PluginBinaries','$(MSBuildProjectName)')) + + + + + + + + + + + + + + + false + runtime + + + false + runtime + + + false + runtime + + + diff --git a/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/ServiceRegistrator.cs b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/ServiceRegistrator.cs new file mode 100644 index 000000000..0e29b71ff --- /dev/null +++ b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/ServiceRegistrator.cs @@ -0,0 +1,45 @@ +using StellaOps.DependencyInjection; +using StellaOps.Workflow.Abstractions; +using StellaOps.Workflow.DataStore.Oracle; +using StellaOps.Workflow.Signaling.OracleAq; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace StellaOps.Workflow.Plugin.WorkflowStore.Oracle; + +public sealed class ServiceRegistrator : IDependencyInjectionRoutine +{ + public IServiceCollection Register(IServiceCollection services, IConfiguration configuration) + { + services.AddWorkflowOracleDataStore(configuration); + + if (!string.Equals(configuration.GetWorkflowBackendProvider(), WorkflowBackendNames.Oracle, StringComparison.OrdinalIgnoreCase)) + { + return services; + } + + var useNativeSignalDriver = string.Equals( + configuration.GetWorkflowSignalDriverProvider(), + WorkflowSignalDriverNames.Native, + StringComparison.OrdinalIgnoreCase); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.Replace(ServiceDescriptor.Scoped(sp => sp.GetRequiredService())); + services.Replace(ServiceDescriptor.Scoped(sp => sp.GetRequiredService())); + services.Replace(ServiceDescriptor.Scoped(sp => sp.GetRequiredService())); + services.Replace(ServiceDescriptor.Scoped()); + if (useNativeSignalDriver) + { + services.Replace(ServiceDescriptor.Scoped(sp => sp.GetRequiredService())); + } + + services.AddSingleton( + new WorkflowSignalDriverRegistrationMarker(WorkflowSignalDriverNames.Native)); + + return services; + } +} diff --git a/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/StellaOps.Workflow.Plugin.WorkflowStore.Oracle.csproj b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/StellaOps.Workflow.Plugin.WorkflowStore.Oracle.csproj new file mode 100644 index 000000000..4ae46bed2 --- /dev/null +++ b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/StellaOps.Workflow.Plugin.WorkflowStore.Oracle.csproj @@ -0,0 +1,45 @@ + + + net10.0 + false + enable + true + enable + false + true + $([System.IO.Path]::Combine($(MSBuildProjectDirectory),'..','..','StellaOps.Workflow.WebService','PluginBinaries','$(MSBuildProjectName)')) + + + + + + + + + + + + + + + false + runtime + + + false + runtime + + + false + runtime + + + false + runtime + + + false + runtime + + + diff --git a/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/ServiceRegistrator.cs b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/ServiceRegistrator.cs new file mode 100644 index 000000000..f852fc5b0 --- /dev/null +++ b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/ServiceRegistrator.cs @@ -0,0 +1,16 @@ +using StellaOps.DependencyInjection; +using StellaOps.Workflow.Abstractions; +using StellaOps.Workflow.DataStore.PostgreSQL; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace StellaOps.Workflow.Plugin.WorkflowStore.Postgres; + +public sealed class ServiceRegistrator : IDependencyInjectionRoutine +{ + public IServiceCollection Register(IServiceCollection services, IConfiguration configuration) + { + return services.AddWorkflowPostgresDataStore(configuration); + } +} diff --git a/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/StellaOps.Workflow.Plugin.WorkflowStore.Postgres.csproj b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/StellaOps.Workflow.Plugin.WorkflowStore.Postgres.csproj new file mode 100644 index 000000000..8810d0ddc --- /dev/null +++ b/src/Workflow/__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/StellaOps.Workflow.Plugin.WorkflowStore.Postgres.csproj @@ -0,0 +1,37 @@ + + + net10.0 + false + enable + true + enable + false + true + $([System.IO.Path]::Combine($(MSBuildProjectDirectory),'..','..','StellaOps.Workflow.WebService','PluginBinaries','$(MSBuildProjectName)')) + + + + + + + + + + + + + + + false + runtime + + + false + runtime + + + false + runtime + + +