Files
lmxopcua/docs/v2/lmx-followups.md

4.8 KiB

LMX Galaxy bridge — remaining follow-ups

State after PR 19: the Galaxy driver is functionally at v1 parity through the IDriver abstraction; the OPC UA server runs with LDAP-authenticated Basic256Sha256 endpoints and alarms are observable through AlarmConditionState.ReportEvent. The items below are what remains LMX- specific before the stack can fully replace the v1 deployment, in rough priority order.

1. Proxy-side IHistoryProvider for ReadAtTime / ReadEvents

Status: Host-side IPC shipped (PR 10 + PR 11). Proxy consumer not written.

PR 10 added HistoryReadAtTimeRequest/Response on the IPC wire and MxAccessGalaxyBackend.HistoryReadAtTimeAsync delegates to HistorianDataSource.ReadAtTimeAsync. PR 11 did the same for events (HistoryReadEventsRequest/Response + GalaxyHistoricalEvent). The Proxy side (GalaxyProxyDriver) doesn't call those yet — Core.Abstractions.IHistoryProvider only exposes ReadRawAsync + ReadProcessedAsync.

To do:

  • Extend IHistoryProvider with ReadAtTimeAsync(string, DateTime[], …) and ReadEventsAsync(string?, DateTime, DateTime, int, …).
  • GalaxyProxyDriver calls the new IPC message kinds.
  • DriverNodeManager wires the new capability methods onto HistoryRead AtTime + Events service handlers.
  • Integration test: OPC UA client calls HistoryReadAtTime / HistoryReadEvents, value flows through IPC to the Host's HistorianDataSource, back to the client.

2. Write-gating by role

Status: RoleBasedIdentity.Roles populated on the session (PR 19) but DriverNodeManager.OnWriteValue doesn't consult it.

CLAUDE.md defines the role set: ReadOnly / WriteOperate / WriteTune / WriteConfigure / AlarmAck. Each DriverAttributeInfo.SecurityClassification maps to a required role for writes.

To do:

  • Add a RoleRequirements table: SecurityClassification → required role.
  • OnWriteValue reads context.UserIdentity → cast to RoleBasedIdentity → check role membership before calling IWritable.WriteAsync. Return BadUserAccessDenied on miss.
  • Unit test against a fake ISystemContext with varying role sets.

3. Admin UI client-cert trust management

Status: Server side auto-accepts untrusted client certs when the AutoAcceptUntrustedClientCertificates option is true (dev default). Production deployments want operator-controlled trust via the Admin UI.

To do:

  • Surface the server's rejected-certificate store in the Admin UI.
  • Page to move certs between rejected / trusted.
  • Flip AutoAcceptUntrustedClientCertificates to false once Admin UI is the trust gate.

4. Live-LDAP integration test

Status: PR 19 unit-tested the auth-flow shape; the live bind path is exercised only by the pre-existing Admin.Tests/LdapLiveBindTests.cs which uses the same Novell library against a running GLAuth at localhost:3893.

To do:

  • Add OpcUaServerIntegrationTests.Valid_username_authenticates_against_live_ldap with the same skip-when-unreachable guard.
  • Assert session.Identity on the server side carries the expected role after bind — requires exposing a test hook or reading identity from a new IHostConnectivityProbe-style "whoami" variable in the address space.

5. Full Galaxy live-service smoke test against the merged v2 stack

Status: Individual pieces have live smoke tests (PR 5 MXAccess, PR 13 probe manager, PR 14 alarm tracker), but the full loop — OPC UA client → OtOpcUaServerGalaxyProxyDriver (in-process) → named-pipe to Galaxy.Host subprocess → live MXAccess runtime → real Galaxy objects — has no single end-to-end smoke test.

To do:

  • Test that spawns the full topology, discovers a deployed Galaxy object, subscribes to one of its attributes, writes a value back, and asserts the write round-tripped through MXAccess. Skip when ArchestrA isn't running.

6. Second driver instance on the same server

Status: DriverHost.RegisterAsync supports multiple drivers; the OPC UA server creates one DriverNodeManager per driver and isolates their subtrees under distinct namespace URIs. Not proven with two active GalaxyProxyDriver instances pointing at different Galaxies.

To do:

  • Integration test that registers two driver instances, each with a distinct DriverInstanceId + endpoint in its own session, asserts nodes from both appear under the correct subtrees, alarm events land on the correct instance's condition nodes.

7. Host-status per-AppEngine granularity → Admin UI dashboard

Status: PR 13 ships per-platform/per-AppEngine ScanState probing; PR 17 surfaces the resulting OnHostStatusChanged events through OPC UA. Admin UI doesn't render a per-host dashboard yet.

To do:

  • SignalR hub push of HostStatusChangedEventArgs to the Admin UI.
  • Dashboard page showing each tracked host, current state, last transition time, failure count.