Files
lmxopcua/docs/reqs/GalaxyRepositoryReqs.md
Joseph Doherty 48970af416 Doc refresh (task #205) — requirements updated for multi-driver OtOpcUa three-process deploy
Per-file summary:

- docs/reqs/OpcUaServerReqs.md — rewritten driver-agnostic. OPC-001..OPC-013 re-scoped to multi-driver address-space composition + capability dispatch; OPC-014 AuthorizationGate + permission trie; OPC-015 dynamic ServiceLevel via RedundancyCoordinator; OPC-017 surgical generation-apply rebuild; OPC-012 capability dispatch via CapabilityInvoker (decision #143 idempotence-aware retry); OPC-013 per-host Polly isolation (decision #144); OPC-019 OpenTelemetry metrics. Transport-security profile matrix (OPC-010) + UserName/LDAP (OPC-011) preserved.

- docs/reqs/GalaxyRepositoryReqs.md — scope clarified as Galaxy-driver-only (not platform). GR-001..GR-004 tied to ITagDiscovery.DiscoverAsync + IRediscoverable; all SQL runs inside OtOpcUa.Galaxy.Host and streams to Proxy via named pipe. GR-008 capability wrapping via CapabilityInvoker added. Cross-links to docs/v2/driver-specs.md + docs/GalaxyRepository.md.

- docs/reqs/MxAccessClientReqs.md — scope clarified as Galaxy-Host-only. MXA-001..MXA-009 preserved (STA pump, register/unregister, subscription refcount, auto-reconnect, probe, COM cleanup, operation metrics, error translation). MXA-010 Proxy-side capability wrapping + MXA-011 pipe ACL + per-process shared secret (OTOPCUA_ALLOWED_SID / OTOPCUA_GALAXY_SECRET) added.

- docs/reqs/ServiceHostReqs.md — rewritten for three-process deployment. Shared section (SVC-SHARED-001/002) for Serilog + bootstrap-only appsettings. SRV-* for OtOpcUa.Server (net10 x64, Microsoft.Extensions.Hosting + AddWindowsService, in-process driver hosting, redundancy-node bootstrap). ADM-* for OtOpcUa.Admin (Blazor Server, cookie+LDAP auth, CanEdit/CanPublish policies, sole DB writer, Prometheus /metrics, audit logging). GHX-* for OtOpcUa.Galaxy.Host (TopShelf, net48 x86, named-pipe IPC bootstrap, STA backend lifecycle, crash handling tied to supervisor).

- docs/reqs/ClientRequirements.md — restructured as numbered, verifiable requirements. SHR-* for Client.Shared (single IOpcUaClientService, ConnectionSettings, failover, cross-platform certs, type-coercing write, UI-thread neutrality). CLI-001..CLI-011 cover connect/read/write/browse/subscribe/historyread/alarms/redundancy. UI-001..UI-008 cover connection panel, tree browser, each tab, connection-state reflection, cross-platform build. Reference design content (IOpcUaClientService shape, models, view-model map, mock layout) preserved.

- docs/reqs/StatusDashboardReqs.md — retired cleanly. Replaced with a pointer to docs/v2/admin-ui.md + HLR-015 / HLR-016 / HLR-017 / ADM-*. Mapping table shows each retired DASH-001..DASH-009 requirement's replacement (live cluster-node view via SignalR, Prometheus metrics, driver-instance detail views, etc.). Note that a formal AdminUiReqs.md can be written later if needed for cert compliance.

HighLevelReqs.md was already at the target shape (HLR-001..HLR-018 with Revision header noting retired HLR-009) as of commit f217636; verified identical and no additional edit required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 01:31:58 -04:00

7.8 KiB

Galaxy Driver — Galaxy Repository Requirements

Revision — Refreshed 2026-04-19 for the OtOpcUa v2 multi-driver platform (task #205). Scope clarified: this document is Galaxy-driver-specific. Galaxy is one of seven drivers in the OtOpcUa platform; the requirements below describe the SQL-side of the Galaxy driver (hierarchy/attribute/change-detection queries against the ZB database) that backs the Galaxy driver's ITagDiscovery.DiscoverAsync and IRediscoverable implementations. All Galaxy-specific SQL runs inside OtOpcUa.Galaxy.Host (.NET 4.8 x86 Windows service); the in-server Driver.Galaxy.Proxy calls it over a named pipe. For platform-wide tag discovery requirements see OpcUaServerReqs.md OPC-002. For deeper spec see docs/GalaxyRepository.md and docs/v2/driver-specs.md.

Parent: HLR-002, HLR-003, HLR-006

Driver scope: Galaxy only. Namespace kind: SystemPlatform.

GR-001: Hierarchy Extraction

The Galaxy driver's ITagDiscovery.DiscoverAsync implementation shall query the ZB Galaxy Repository database to extract all deployed objects with their parent-child containment relationships, contained names, and tag names.

Acceptance Criteria

  • Executes queries/hierarchy.sql against the ZB database from within OtOpcUa.Galaxy.Host.
  • Returns a list of objects with: gobject_id, tag_name, contained_name, browse_name, parent_gobject_id, is_area.
  • Objects with parent_gobject_id = 0 become children of the root ZB node inside the SystemPlatform namespace.
  • Only deployed, non-template objects matching the category filter (areas, engines, user-defined objects, etc.) are returned.
  • Query completes within 10 seconds on a typical Galaxy (hundreds of objects). Log Warning if it takes longer.

Details

  • Results are ordered by parent_gobject_id, tag_name for deterministic tree building.
  • Empty result → Warning logged (Galaxy may have no deployed objects, or the DB connection may be misconfigured).
  • Orphan detection: a row referencing a non-existent parent_gobject_id (and not 0) is skipped with a Warning.
  • Streamed to the core via IAddressSpaceBuilder.AddFolder / AddObject calls over the Galaxy named pipe; no in-memory full-tree buffering on the Host side.

GR-002: Attribute Extraction

The Galaxy driver shall query user-defined (dynamic) attributes for deployed objects, including data type, array flag, and array dimensions.

Acceptance Criteria

  • Executes queries/attributes.sql using the template chain CTE to resolve inherited attributes.
  • Returns: gobject_id, tag_name, attribute_name, full_tag_reference, mx_data_type, is_array, array_dimension, security_classification.
  • Attributes starting with _ are filtered out by the query.
  • array_dimension is extracted from the mx_value hex bytes (positions 13-16, little-endian uint16).

Details

  • CTE recursion depth is limited to 10 levels.
  • mx_data_type not in the known set (1-8, 13-16) defaults to String.
  • gobject_id that doesn't match a hierarchy object is skipped (object may not be deployed).
  • Each emitted attribute is reported via DriverAttributeInfo to the core through IAddressSpaceBuilder.AddVariable.

GR-003: Change Detection and IRediscoverable

The Galaxy driver shall implement IRediscoverable by polling galaxy.time_of_last_deploy on a configurable interval to detect when a new deployment has occurred.

Acceptance Criteria

  • Polls SELECT time_of_last_deploy FROM galaxy at a configurable interval (Galaxy:ChangeDetectionIntervalSeconds, default 30 seconds).
  • Compares the returned timestamp to the last known value stored in memory.
  • If different, raises the IRediscoverable.RediscoveryNeeded signal so the core re-runs ITagDiscovery.DiscoverAsync and surgically rebuilds the Galaxy namespace subtree (per OPC-017).
  • First poll after startup always triggers an initial discovery.
  • Query failure → Warning logged; no rediscovery triggered; retry at next interval.

Details

  • Polling runs on a background Task inside OtOpcUa.Galaxy.Host, not on the STA message-pump thread.
  • time_of_last_deploy is a datetime column; compared using exact equality (not a range).
  • Signal delivery to the Proxy happens via a server-push message on the Galaxy named pipe.

GR-004: Rediscovery Data Flow

On a deployment change, the Galaxy driver shall re-query hierarchy + attributes and stream the updated structure to the core for surgical namespace rebuild.

Acceptance Criteria

  • On change signal, re-run GR-001 (hierarchy) and GR-002 (attributes) queries.
  • Stream the new tree to the core via IAddressSpaceBuilder over the named pipe.
  • Log at Information level: "Galaxy deployment change detected. Rebuilding. ({ObjectCount} objects, {AttributeCount} attributes)".
  • Log total rediscovery duration at Information level.
  • On re-query failure: Error logged; existing Galaxy subtree is retained.

Details

  • Rediscovery is not atomic from the DB perspective — hierarchy and attributes are two separate queries. Acceptable; Galaxy deployment is an infrequent operation.
  • The core owns the diff/surgical apply per OPC-017; the Galaxy driver only streams the new authoritative tree.

GR-005: Connection Configuration

Galaxy DB connection parameters shall be configurable via environment variables passed from the OtOpcUa.Galaxy.Host supervisor at spawn time.

Acceptance Criteria

  • Connection string via OTOPCUA_GALAXY_ZB_CONN environment variable.
  • Default: Server=localhost;Database=ZB;Integrated Security=True;TrustServerCertificate=True;Encrypt=False; (Windows Auth).
  • ADO.NET SqlConnection used for queries (.NET Framework 4.8).
  • Connection is opened per-query (not kept open). Connection pooling handles efficiency.
  • If the initial connection test at startup fails, log Error with the connection string sanitized and continue attempting (change-detection polls keep retrying).

Details

  • Command timeout: Galaxy:CommandTimeoutSeconds in Config DB driver JSON (default 30 seconds).
  • No ORM. Raw ADO.NET with SqlCommand and SqlDataReader. SQL text embedded as constants.

GR-006: Query Safety

All Galaxy SQL queries shall be static read-only SELECT statements. No writes to the Galaxy Repository database.

Acceptance Criteria

  • All queries are hardcoded SQL strings with no string concatenation or user-supplied parameters.
  • No INSERT, UPDATE, DELETE, or DDL statements are ever executed against the Galaxy database.
  • Queries use only SELECT with read-only intent.

GR-007: Startup Validation

On startup, the Galaxy driver's DB component inside OtOpcUa.Galaxy.Host shall validate database connectivity.

Acceptance Criteria

  • Execute a simple test query (SELECT 1) against the configured Galaxy DB.
  • If the database is unreachable, log Error but do not prevent Host startup.
  • The Galaxy driver runs in degraded mode (empty SystemPlatform namespace) until the database becomes available and the next change-detection poll succeeds.
  • In degraded mode the Galaxy driver instance reports DriverHealth.Unavailable, causing its Polly circuit state to be open until the first successful discovery.

GR-008: Capability Wrapping

All calls into the Galaxy DB component from the Proxy side shall route through CapabilityInvoker.InvokeAsync(DriverCapability.Discover, …).

Acceptance Criteria

  • Driver.Galaxy.Proxy.DiscoverAsync is a thin capability-invoker call that sends a MessagePack request over the named pipe to the Host's DB component.
  • Roslyn analyzer OTOPCUA0001 validates there are no direct discovery calls bypassing the invoker.
  • Polly pipeline for DriverCapability.Discover on the Galaxy driver instance carries Timeout + Retry + CircuitBreaker.