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
IHistoryProviderwithReadAtTimeAsync(string, DateTime[], …)andReadEventsAsync(string?, DateTime, DateTime, int, …). GalaxyProxyDrivercalls the new IPC message kinds.DriverNodeManagerwires the new capability methods ontoHistoryReadAtTime+Eventsservice handlers.- Integration test: OPC UA client calls
HistoryReadAtTime/HistoryReadEvents, value flows through IPC to the Host'sHistorianDataSource, 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
RoleRequirementstable:SecurityClassification→ required role. OnWriteValuereadscontext.UserIdentity→ cast toRoleBasedIdentity→ check role membership before callingIWritable.WriteAsync. ReturnBadUserAccessDeniedon miss.- Unit test against a fake
ISystemContextwith 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
AutoAcceptUntrustedClientCertificatesto 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_ldapwith the same skip-when-unreachable guard. - Assert
session.Identityon the server side carries the expected role after bind — requires exposing a test hook or reading identity from a newIHostConnectivityProbe-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 →
OtOpcUaServer → GalaxyProxyDriver (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
HostStatusChangedEventArgsto the Admin UI. - Dashboard page showing each tracked host, current state, last transition time, failure count.