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) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-08 14:56:02 +03:00
parent ca35f66830
commit ff4c721eda
8 changed files with 223 additions and 4 deletions

View File

@@ -14,6 +14,11 @@
<Project Path="__Libraries/StellaOps.Workflow.Signaling.Redis/StellaOps.Workflow.Signaling.Redis.csproj" />
</Folder>
<Project Path="../__Libraries/StellaOps.ElkSharp/StellaOps.ElkSharp.csproj" />
<Folder Name="/__Plugins/">
<Project Path="__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Oracle/StellaOps.Workflow.Plugin.WorkflowStore.Oracle.csproj" />
<Project Path="__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Mongo/StellaOps.Workflow.Plugin.WorkflowStore.Mongo.csproj" />
<Project Path="__Plugins/StellaOps.Workflow.Plugin.WorkflowStore.Postgres/StellaOps.Workflow.Plugin.WorkflowStore.Postgres.csproj" />
</Folder>
<Project Path="StellaOps.Workflow.WebService/StellaOps.Workflow.WebService.csproj" />
<Folder Name="/__Tests/">
<Project Path="__Tests/StellaOps.Workflow.Engine.Tests/StellaOps.Workflow.Engine.Tests.csproj" />

View File

@@ -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<IWorkflowBackendRegistrationMarker>(
new WorkflowBackendRegistrationMarker(WorkflowBackendNames.Oracle));
if (!string.Equals(configuration.GetWorkflowBackendProvider(), WorkflowBackendNames.Oracle, StringComparison.OrdinalIgnoreCase))
{
return services;
}
services.AddDbContext<WorkflowDbContext>(options =>
{
var connectionString = configuration.GetConnectionString("WorkflowOracle")
?? configuration.GetConnectionString("Default");
if (!string.IsNullOrWhiteSpace(connectionString))
{
options.UseOracle(connectionString);
}
});
services.Replace(ServiceDescriptor.Scoped<IWorkflowRuntimeStateStore, OracleWorkflowRuntimeStateStore>());
services.Replace(ServiceDescriptor.Scoped<IWorkflowHostedJobLockService, OracleWorkflowHostedJobLockService>());
return services;
}
}

View File

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

View File

@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<ImplicitUsings>enable</ImplicitUsings>
<EnableDynamicLoading>true</EnableDynamicLoading>
<Nullable>enable</Nullable>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
<CopyPluginBinariesToPath Condition="'$(CopyPluginBinariesToPath)' == ''">$([System.IO.Path]::Combine($(MSBuildProjectDirectory),'..','..','StellaOps.Workflow.WebService','PluginBinaries','$(MSBuildProjectName)'))</CopyPluginBinariesToPath>
</PropertyGroup>
<Target Name="CopyPluginBinaries" AfterTargets="Build">
<ItemGroup>
<BuiltFiles Include="$(TargetDir)**\*.*" />
</ItemGroup>
<RemoveDir Directories="$(CopyPluginBinariesToPath)" Condition="Exists('$(CopyPluginBinariesToPath)')" />
<MakeDir Directories="$(CopyPluginBinariesToPath)" />
<Copy SourceFiles="@(BuiltFiles)" DestinationFolder="$(CopyPluginBinariesToPath)" SkipUnchangedFiles="false" />
</Target>
<ItemGroup>
<ProjectReference Include="..\..\__Libraries\StellaOps.Workflow.DataStore.MongoDB\StellaOps.Workflow.DataStore.MongoDB.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\__Libraries\StellaOps.Workflow.Abstractions\StellaOps.Workflow.Abstractions.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\..\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
</ItemGroup>
</Project>

View File

@@ -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<IOracleAqTransport, OracleManagedAqTransport>();
services.AddScoped<OracleAqWorkflowSignalBus>();
services.AddScoped<OracleAqWorkflowScheduleBus>();
services.Replace(ServiceDescriptor.Scoped<IWorkflowSignalStore>(sp => sp.GetRequiredService<OracleAqWorkflowSignalBus>()));
services.Replace(ServiceDescriptor.Scoped<IWorkflowSignalClaimStore>(sp => sp.GetRequiredService<OracleAqWorkflowSignalBus>()));
services.Replace(ServiceDescriptor.Scoped<IWorkflowSignalScheduler>(sp => sp.GetRequiredService<OracleAqWorkflowScheduleBus>()));
services.Replace(ServiceDescriptor.Scoped<IWorkflowSignalDeadLetterStore, OracleAqWorkflowSignalDeadLetterStore>());
if (useNativeSignalDriver)
{
services.Replace(ServiceDescriptor.Scoped<IWorkflowSignalDriver>(sp => sp.GetRequiredService<OracleAqWorkflowSignalBus>()));
}
services.AddSingleton<IWorkflowSignalDriverRegistrationMarker>(
new WorkflowSignalDriverRegistrationMarker(WorkflowSignalDriverNames.Native));
return services;
}
}

View File

@@ -0,0 +1,45 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<ImplicitUsings>enable</ImplicitUsings>
<EnableDynamicLoading>true</EnableDynamicLoading>
<Nullable>enable</Nullable>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
<CopyPluginBinariesToPath Condition="'$(CopyPluginBinariesToPath)' == ''">$([System.IO.Path]::Combine($(MSBuildProjectDirectory),'..','..','StellaOps.Workflow.WebService','PluginBinaries','$(MSBuildProjectName)'))</CopyPluginBinariesToPath>
</PropertyGroup>
<Target Name="CopyPluginBinaries" AfterTargets="Build">
<ItemGroup>
<BuiltFiles Include="$(TargetDir)**\*.*" />
</ItemGroup>
<RemoveDir Directories="$(CopyPluginBinariesToPath)" Condition="Exists('$(CopyPluginBinariesToPath)')" />
<MakeDir Directories="$(CopyPluginBinariesToPath)" />
<Copy SourceFiles="@(BuiltFiles)" DestinationFolder="$(CopyPluginBinariesToPath)" SkipUnchangedFiles="false" />
</Target>
<ItemGroup>
<ProjectReference Include="..\..\__Libraries\StellaOps.Workflow.Engine\StellaOps.Workflow.Engine.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\__Libraries\StellaOps.Workflow.DataStore.Oracle\StellaOps.Workflow.DataStore.Oracle.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\__Libraries\StellaOps.Workflow.Signaling.OracleAq\StellaOps.Workflow.Signaling.OracleAq.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\__Libraries\StellaOps.Workflow.Abstractions\StellaOps.Workflow.Abstractions.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\..\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
</ItemGroup>
</Project>

View File

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

View File

@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<ImplicitUsings>enable</ImplicitUsings>
<EnableDynamicLoading>true</EnableDynamicLoading>
<Nullable>enable</Nullable>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
<CopyPluginBinariesToPath Condition="'$(CopyPluginBinariesToPath)' == ''">$([System.IO.Path]::Combine($(MSBuildProjectDirectory),'..','..','StellaOps.Workflow.WebService','PluginBinaries','$(MSBuildProjectName)'))</CopyPluginBinariesToPath>
</PropertyGroup>
<Target Name="CopyPluginBinaries" AfterTargets="Build">
<ItemGroup>
<BuiltFiles Include="$(TargetDir)**\*.*" />
</ItemGroup>
<RemoveDir Directories="$(CopyPluginBinariesToPath)" Condition="Exists('$(CopyPluginBinariesToPath)')" />
<MakeDir Directories="$(CopyPluginBinariesToPath)" />
<Copy SourceFiles="@(BuiltFiles)" DestinationFolder="$(CopyPluginBinariesToPath)" SkipUnchangedFiles="false" />
</Target>
<ItemGroup>
<ProjectReference Include="..\..\__Libraries\StellaOps.Workflow.DataStore.PostgreSQL\StellaOps.Workflow.DataStore.PostgreSQL.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\__Libraries\StellaOps.Workflow.Abstractions\StellaOps.Workflow.Abstractions.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\..\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj">
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
</ItemGroup>
</Project>