Files
lmxopcua/docs/v1/Configuration.md
Joseph Doherty 006af51768 docs: post-PR-7.2 cleanup — audit + three-track scrub
Audit (three parallel agent passes) found 43 markdown files carrying
stale references to the deleted Galaxy.Host/Proxy/Shared projects
after the v2-mxgw merge. This commit lands the prioritized fixes.

Track 1 — high-traffic in-place rewrites (3 files, ~454 lines deleted)
- README.md (202 → 91 lines): drops .NET 4.8 / x86 / TopShelf install
  text; leads with the multi-driver .NET 10 server identity and points
  at scripts/install/Install-Services.ps1 and the parity rig.
- docs/v2/driver-specs.md §1 Galaxy (~289 → ~66 lines): replaces the
  Tier-C out-of-process spec with a Tier-A in-process description
  matching the current GalaxyDriver code, with the four-section
  GalaxyDriverOptions JSON shape pulled verbatim from
  Config/GalaxyDriverOptions.cs.
- docs/drivers/Galaxy.md (211 → 92 lines): full rewrite around the
  current Browse/Runtime/Health/Config sub-folders.

Track 2 — historical banners (5 files)
- lmx_mxgw.md, lmx_mxgw_impl.md, lmx_backend.md,
  docs/v2/Galaxy.ParityMatrix.md,
  docs/v2/implementation/phase-2-galaxy-out-of-process.md each get a
  " Completed 2026-04-30 — historical record" banner block. lmx_mxgw.md
  also fixes two dead links (`docs/Galaxy.Driver.md` and
  `docs/v2/Galaxy.Driver.md`) → `docs/drivers/Galaxy.md`.

Track 3 — v1 archive sweep (10 git mv + 1 new index + 2 in-place scrubs)
- Moved 10 v1 docs under docs/v1/ preserving subpath structure:
  AlarmTracking, Configuration, DataTypeMapping, HistoricalDataAccess,
  Subscriptions (top-level); drivers/Galaxy-Repository,
  drivers/Galaxy-Test-Fixture; reqs/GalaxyRepositoryReqs,
  reqs/MxAccessClientReqs, reqs/ServiceHostReqs.
- New docs/v1/README.md is the shared archive banner + per-file table.
- docs/README.md repointed to the v1 paths and updated to reflect the
  v2 two-process deploy shape (Server + Admin + optional
  OtOpcUaWonderwareHistorian).
- docs/v2/Galaxy.ParityRig.md got a historical banner + four inline
  scrubs marking the OtOpcUaGalaxyHost service / Driver.Galaxy.Host
  EXE / Driver.Galaxy.ParityTests project as deleted-in-PR-7.2.

The repo's live-reading surface (README + CLAUDE.md + docs/v2/) now
describes only the post-PR-7.2 architecture. v1 docs are preserved as
a labelled archive under docs/v1/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 08:59:59 -04:00

9.5 KiB

Configuration

Two-layer model

OtOpcUa configuration is split into two layers:

Layer Where Scope Edited by
Bootstrap appsettings.json per process Enough to start the process and reach the Config DB Local file edit + process restart
Authoritative config Config DB (SQL Server) via OtOpcUaConfigDbContext Clusters, namespaces, UNS hierarchy, equipment, tags, driver instances, ACLs, role grants, poll groups Admin UI draft/publish workflow

The rule: if the setting describes how the process connects to the rest of the world (Config DB connection string, LDAP bind, transport security profile, node identity, logging), it lives in appsettings.json. If it describes what the fleet does (clusters, drivers, tags, UNS, ACLs), it lives in the Config DB and is edited through the Admin UI.


Bootstrap configuration (appsettings.json)

Each of the three processes (Server, Admin, Galaxy.Host) reads its own appsettings.json plus environment overrides.

OtOpcUa Server — src/ZB.MOM.WW.OtOpcUa.Server/appsettings.json

Bootstrap-only. Program.cs reads four top-level sections:

Section Keys Purpose
Node NodeId, ClusterId, ConfigDbConnectionString, LocalCachePath Identity + path to the Config DB + LiteDB offline cache path.
OpcUaServer EndpointUrl, ApplicationName, ApplicationUri, PkiStoreRoot, AutoAcceptUntrustedClientCertificates, SecurityProfile OPC UA endpoint + transport security. See security.md.
OpcUaServer:Ldap Enabled, Server, Port, UseTls, AllowInsecureLdap, SearchBase, ServiceAccountDn, ServiceAccountPassword, GroupToRole, UserNameAttribute, GroupAttribute LDAP auth for OPC UA UserName tokens. See security.md.
Serilog Standard Serilog keys + WriteJson bool Logging verbosity + optional JSON file sink for SIEM ingest.
Authorization StrictMode (bool) Flip true to fail-closed on sessions lacking LDAP group metadata. Default false during ACL rollouts.
Metrics:Prometheus:Enabled bool Toggles the /metrics endpoint.

Minimal example:

{
  "Serilog": { "MinimumLevel": "Information" },
  "Node": {
    "NodeId": "node-dev-a",
    "ClusterId": "cluster-dev",
    "ConfigDbConnectionString": "Server=localhost,14330;Database=OtOpcUaConfig;Integrated Security=True;TrustServerCertificate=True;Encrypt=False;",
    "LocalCachePath": "config_cache.db"
  },
  "OpcUaServer": {
    "EndpointUrl": "opc.tcp://0.0.0.0:4840/OtOpcUa",
    "ApplicationUri": "urn:node-dev-a:OtOpcUa",
    "SecurityProfile": "None",
    "AutoAcceptUntrustedClientCertificates": true,
    "Ldap": { "Enabled": false }
  }
}

OtOpcUa Admin — src/ZB.MOM.WW.OtOpcUa.Admin/appsettings.json

Section Purpose
ConnectionStrings:ConfigDb SQL connection string — must point at the same Config DB every Server reaches.
Authentication:Ldap LDAP bind for the Admin login form (same options shape as the Server's OpcUaServer:Ldap).
CertTrust CertTrustOptions — file-system path under the Server's PkiStoreRoot so the Admin Certificates page can promote rejected client certs.
Metrics:Prometheus:Enabled Toggles the /metrics scrape endpoint (default true).
Serilog Logging.

Galaxy.Host

Environment-variable driven (OTOPCUA_GALAXY_PIPE, OTOPCUA_ALLOWED_SID, OTOPCUA_GALAXY_SECRET, OTOPCUA_GALAXY_BACKEND, OTOPCUA_GALAXY_ZB_CONN, OTOPCUA_HISTORIAN_*). No appsettings.json — the supervisor owns the launch environment. See ServiceHosting.md.

Environment overrides

Standard .NET config layering applies: appsettings.{Environment}.json, then environment variables with Section__Property naming. DOTNET_ENVIRONMENT (or ASPNETCORE_ENVIRONMENT for Admin) selects the overlay.


Authoritative configuration (Config DB)

The Config DB is the single source of truth for every setting that a v1 deployment used to carry in appsettings.json as driver-specific state. OtOpcUaConfigDbContext (src/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs) is the EF Core context used by both the Admin writer and every Server reader.

Top-level sections operators touch

Concept Entity Admin UI surface Purpose
Cluster ServerCluster Clusters pages Fleet unit; owns nodes, generations, UNS, ACLs.
Cluster node ClusterNode + ClusterNodeCredential RedundancyTab, Hosts page Per-node identity, RedundancyRole, ServiceLevelBase, ApplicationUri, service-account credentials.
Generation ConfigGeneration + ClusterNodeGenerationState Generations / DiffViewer Append-only; draft → publish workflow (sp_PublishGeneration).
Namespace Namespace Namespaces tab Per-cluster OPC UA namespace; Kind = Equipment / SystemPlatform / Simulated.
Driver instance DriverInstance Drivers tab Configured driver (Modbus, S7, OpcUaClient, Galaxy, …) + DriverConfig JSON + resilience profile.
Device Device Under each driver instance Per-host settings inside a driver instance (IP, port, unit-id…).
UNS hierarchy UnsArea + UnsLine UnsTab (drag/drop) L3 / L4 of the unified namespace.
Equipment Equipment Equipment pages, CSV import L5; carries MachineCode, ZTag, SAPID, EquipmentUuid, reservation-backed external ids.
Tag Tag Under each equipment Driver-specific tag address + SecurityClassification + poll-group assignment.
Poll group PollGroup Driver-scoped Poll cadence buckets; PollGroupEngine in Core.Abstractions uses this at runtime.
ACL NodeAcl AclsTab + Probe dialog Per-level permission grants, additive only. See security.md.
Role grant LdapGroupRoleMapping RoleGrants page Maps LDAP groups → Admin roles (ConfigViewer / ConfigEditor / FleetAdmin).
External id reservation ExternalIdReservation Reservations page Reservation-backed ZTag and SAPID uniqueness.
Equipment import batch EquipmentImportBatch CSV import flow Staged bulk-add with validation preview.
Audit log ConfigAuditLog Audit page Append-only record of every publish, rollback, credential rotation, role-grant change.

Draft → publish generation model

All edits go into a draft generation scoped to one cluster. DraftValidationService checks invariants (same-cluster FKs, reservation collisions, UNS path consistency, ACL scope validity). When the operator clicks Publish, sp_PublishGeneration atomically promotes the draft, records the audit event, and causes every RedundancyCoordinator.RefreshAsync in the affected cluster to pick up the new topology + ACL set. The Admin UI DiffViewer shows exactly what's changing before publish.

Old generations are retained; rollback is "publish older generation as new". ConfigAuditLog makes every change auditable by principal + timestamp.

Offline cache

Each Server process caches the last-seen published generation in Node:LocalCachePath via LiteDB (LiteDbConfigCache in src/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/). The cache lets a node start without the central DB reachable; once the DB comes back, NodeBootstrap syncs to the current generation.

Full schema reference

For table columns, indexes, stored procedures, the publish-transaction semantics, and the SQL authorization model (per-node SQL principals + SESSION_CONTEXT cluster binding), see docs/v2/config-db-schema.md.

Admin UI flow

For the draft editor, DiffViewer, CSV import, IdentificationFields, RedundancyTab, AclsTab + Probe-this-permission, RoleGrants, and the SignalR real-time surface, see docs/v2/admin-ui.md.


Where did v1 appsettings sections go?

Quick index for operators coming from v1 LmxOpcUa:

v1 appsettings section v2 home
OpcUa.Port / BindAddress / EndpointPath / ServerName Bootstrap OpcUaServer:EndpointUrl + ApplicationName.
OpcUa.ApplicationUri Config DB ClusterNode.ApplicationUri.
OpcUa.MaxSessions / SessionTimeoutMinutes Bootstrap OpcUaServer:* (if exposed) or stack defaults.
OpcUa.AlarmTrackingEnabled / AlarmFilter Per driver instance in Config DB (alarm surface is capability-driven per IAlarmSource).
MxAccess.* Galaxy driver instance DriverConfig JSON + Galaxy.Host env vars (see ServiceHosting.md).
GalaxyRepository.* Galaxy driver instance DriverConfig JSON + OTOPCUA_GALAXY_ZB_CONN env var.
Dashboard.* Retired — Admin UI replaces the dashboard. See StatusDashboard.md.
Historian.* Galaxy driver instance DriverConfig JSON + OTOPCUA_HISTORIAN_* env vars.
Authentication.Ldap.* Bootstrap OpcUaServer:Ldap (same shape) + Admin Authentication:Ldap for the UI login.
Security.* Bootstrap OpcUaServer:SecurityProfile + PkiStoreRoot + AutoAcceptUntrustedClientCertificates.
Redundancy.* Config DB ClusterNode.RedundancyRole + ServiceLevelBase.

Validation

  • Bootstrap: the process fails fast on missing required keys in Program.cs (e.g. Node:NodeId, Node:ClusterId, Node:ConfigDbConnectionString all throw InvalidOperationException if unset).
  • Authoritative: DraftValidationService runs on every save; sp_ValidateDraft runs as part of sp_PublishGeneration so an invalid draft cannot reach any node.