PR 4.0 — Driver.Galaxy project skeleton + factory

New in-process .NET 10 driver project at
src/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/. The Tier-A replacement for
Driver.Galaxy.Host + Driver.Galaxy.Proxy. PR 4.0 ships only the IDriver
shape + factory + options; capability bodies (browse, read, write,
subscribe, deploy-watch, host probes) land in PRs 4.1–4.7.

Files:
- Driver.Galaxy.csproj — net10 x64, AnyCPU+x64 platforms, references
  Core.Abstractions + Core. No MxGatewayClient ProjectReference yet — that
  comes in PR 4.2 once the gw NuGet package is wired (the user is
  shipping mxaccessgw on a parallel track).
- Config/GalaxyDriverOptions.cs — nested record hierarchy
  (Gateway/MxAccess/Repository/Reconnect) mirroring the JSON shape spelled
  out in lmx_mxgw_impl.md PR 4.0 acceptance section.
- GalaxyDriver.cs — minimal IDriver impl. Initialize/Shutdown toggle
  DriverHealth between Healthy/Unknown; Reinitialize bumps the timestamp;
  GetMemoryFootprint=0 (PR 4.4 wires SubscriptionRegistry size);
  FlushOptionalCachesAsync no-op. Logs intent on lifecycle calls so
  partial deployments are diagnosable.
- GalaxyDriverFactoryExtensions.cs — JSON parser, default fill-ins,
  validation throw on missing required fields. Driver type name
  "GalaxyMxGateway" intentionally distinct from legacy "Galaxy" so both
  factories coexist during parity testing (Phase 5). PR 4.W's
  Galaxy:Backend switch picks one or the other.

Tests:
- 10 tests in Driver.Galaxy.Tests covering minimal-config defaults, full
  override path, three required-field error cases, factory registration
  via DriverFactoryRegistry.TryGet, lifecycle health transitions
  (Init → Shutdown → Reinit), Dispose idempotency, and post-disposal
  ObjectDisposedException.

slnx: registers the new Driver.Galaxy + Driver.Galaxy.Tests projects.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-04-29 14:57:31 -04:00
parent 854827090a
commit f6a4f919e2
7 changed files with 516 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Config;
/// <summary>
/// Driver-instance options for the in-process .NET 10 Galaxy driver. Maps to the
/// <c>DriverConfig</c> JSON column on the central config DB. Decomposed into nested
/// records so the JSON structure mirrors the runtime shape and operators can target
/// individual sections (gateway endpoint, mxaccess client identity, reconnect policy)
/// without touching the rest.
/// </summary>
/// <param name="Gateway">Connection details for the MxAccess gateway (mxaccessgw repo).</param>
/// <param name="MxAccess">MXAccess-specific knobs surfaced through gw — client name, publishing interval, write-user.</param>
/// <param name="Repository">Galaxy Repository browse options consumed by the discoverer.</param>
/// <param name="Reconnect">Backoff knobs for the in-driver reconnect supervisor (PR 4.5).</param>
public sealed record GalaxyDriverOptions(
GalaxyGatewayOptions Gateway,
GalaxyMxAccessOptions MxAccess,
GalaxyRepositoryOptions Repository,
GalaxyReconnectOptions Reconnect);
/// <summary>
/// Connection details for the MxAccess gateway. <see cref="ApiKeySecretRef"/> resolves
/// through the server-side secret store (DPAPI for production, environment override for
/// dev) — the API key never appears in cleartext config.
/// </summary>
public sealed record GalaxyGatewayOptions(
string Endpoint,
string ApiKeySecretRef,
bool UseTls = true,
string? CaCertificatePath = null,
int ConnectTimeoutSeconds = 10,
int DefaultCallTimeoutSeconds = 5,
int StreamTimeoutSeconds = 0);
/// <summary>
/// MXAccess-specific knobs the gateway forwards to the worker process.
/// </summary>
/// <param name="ClientName">
/// Wonderware client identity. MUST be unique per OtOpcUa instance — when two instances
/// share a name, the older session loses subscription state. Redundancy pairs (decision
/// #149) enforce uniqueness via install scripts.
/// </param>
/// <param name="PublishingIntervalMs">
/// Hint forwarded as <c>buffered_update_interval_ms</c> on subscribe; lets the worker
/// coalesce updates at the OPC UA publishing cadence rather than every COM tick.
/// </param>
/// <param name="WriteUserId">
/// Reserved for ArchestrA secured-write user mapping; PR 4.3 wires <c>WriteSecured</c>
/// routing against this id. 0 = anonymous.
/// </param>
public sealed record GalaxyMxAccessOptions(
string ClientName,
int PublishingIntervalMs = 1000,
int WriteUserId = 0);
/// <summary>
/// Galaxy Repository browse-side knobs consumed by PR 4.1's <c>GalaxyDiscoverer</c>.
/// </summary>
public sealed record GalaxyRepositoryOptions(
int DiscoverPageSize = 5000,
bool WatchDeployEvents = true);
/// <summary>
/// Backoff knobs for the in-driver reconnect supervisor (PR 4.5). Replay-on-session-lost
/// calls the gw's <c>ReplaySubscriptions</c> RPC after reconnect rather than re-issuing
/// subscribe-bulk for every tag.
/// </summary>
public sealed record GalaxyReconnectOptions(
int InitialBackoffMs = 500,
int MaxBackoffMs = 30_000,
bool ReplayOnSessionLost = true);