docs(m7): reflect OPC UA / MxGateway UX (T13-T17) across component docs + CLAUDE/stillpending/completion-design
This commit is contained in:
@@ -195,10 +195,32 @@ These are configured via `DataConnectionOptions` in `appsettings.json`, not per-
|
||||
DCL is a clean data pipe on the hot path. Browse is an **opt-in capability** for protocols that support it, exposed via `IBrowsableDataConnection`. Only consumed by management/UI (the tag picker on the instance configure page); Instance Actors never call it. The browse path is **protocol-agnostic**: the same command/service/dialog serve every browsable protocol.
|
||||
|
||||
- `OpcUaDataConnection` and `MxGatewayDataConnection` both implement `IBrowsableDataConnection`; other/custom protocols do not (and return a `NotBrowsable` failure).
|
||||
- `DataConnectionManagerActor` handles `BrowseNodeCommand` (fields: `ConnectionName`, `ParentNodeId`) and replies with `BrowseNodeResult` (children + `Truncated` + structured `BrowseFailure?`). The Central UI facade is `IBrowseService`/`BrowseService`, backing the `NodeBrowserDialog` tag picker.
|
||||
- `DataConnectionManagerActor` handles `BrowseNodeCommand` (fields: `ConnectionName`, `ParentNodeId`, and an optional opaque `ContinuationToken` for paging) and replies with `BrowseNodeResult` (children + `Truncated` + an optional continuation token + structured `BrowseFailure?`). The Central UI facade is `IBrowseService`/`BrowseService`, backing the `NodeBrowserDialog` tag picker.
|
||||
- **Browse type-info** (OPC UA): each child `BrowseNode` carries optional best-effort type metadata — `DataType` (friendly name), `ValueRank` (scalar/array), and `Writable`. `RealOpcUaClient` batch-reads these attributes for **Variable** nodes during browse and maps built-in data-type node ids to friendly names; non-Variable rows leave them unset.
|
||||
- Node ids are opaque protocol-specific strings: OPC UA uses NodeIds; MxGateway uses Galaxy gobject ids for navigable objects and full tag references for selectable attribute leaves.
|
||||
- Browse runs against the live session; no caching at DCL.
|
||||
- **Frame-size guard**: the reply crosses the site→central Akka frame (default 128 KB) on a temp Ask actor; an oversized reply is silently discarded by remoting, hanging the picker. The child handler caps each `BrowseNodeResult` to a byte budget (~100 KB) before replying, OR-ing the adapter's own truncation signal into `Truncated`. This is protocol-agnostic (every adapter's reply funnels through it). Per-protocol upstream caps narrow the window first: OPC UA requests at most 500 references per node (continuation point → `Truncated`); MxGateway relies on the gateway's `BrowseChildren` page cap. A `Truncated` level prompts manual node-id entry in the picker rather than auto-paging.
|
||||
- **Frame-size guard**: the reply crosses the site→central Akka frame (default 128 KB) on a temp Ask actor; an oversized reply is silently discarded by remoting, hanging the picker. The child handler caps each `BrowseNodeResult` to a byte budget (~100 KB) before replying, OR-ing the adapter's own truncation signal into `Truncated`. This is protocol-agnostic (every adapter's reply funnels through it). Per-protocol upstream caps narrow the window first: OPC UA requests at most 500 references per node (continuation point → `Truncated`); MxGateway relies on the gateway's `BrowseChildren` page cap.
|
||||
- **`BrowseNext` paging** (OPC UA): a `Truncated` level no longer forces manual node-id entry. When the OPC UA browse is truncated, the adapter returns the session's continuation point as the reply's opaque `ContinuationToken`; a follow-up `BrowseNodeCommand` carrying that token calls `Session.BrowseNext` to fetch the next page (the picker exposes this as **"Load more"**). Continuation points are session-bound and can expire — `BadContinuationPointInvalid` is caught and the browse restarts from a fresh first page rather than failing. Manual node-id entry remains as a fallback when the site or its session is offline.
|
||||
|
||||
### Address-space search
|
||||
|
||||
A second opt-in capability seam, `IAddressSpaceSearchable` (in Commons, mirroring the `IBrowsableDataConnection` / `IAlarmSubscribableConnection` pattern; implemented by the OPC UA adapter, consumed by management/UI only):
|
||||
|
||||
```
|
||||
IAddressSpaceSearchable
|
||||
└── SearchAddressSpaceAsync(query, maxDepth, maxResults, ct) → matches
|
||||
```
|
||||
|
||||
- `DataConnectionManagerActor` handles `SearchAddressSpaceCommand` (`ConnectionName`, `Query`, `MaxDepth`, `MaxResults`); the OPC UA adapter does a **bounded recursive browse** (depth + result caps) from the Objects folder, matching a **case-insensitive substring** against each node's DisplayName and root-relative path, and returns matches as `AddressSpaceMatch` (the `BrowseNode` plus its full path). When a cap is hit the result flags it so the UI can prompt "showing first N — refine".
|
||||
- The Central UI facade is `BrowseService.SearchAsync` (Design role), surfaced as the search box in `NodeBrowserDialog`.
|
||||
- `StubOpcUaClient` carries a canned browse/search implementation so the picker and its bUnit/unit tests run without a live OPC UA server.
|
||||
|
||||
## Endpoint verification (OPC UA)
|
||||
|
||||
Before saving or deploying an OPC UA data connection, the Central UI can ask the target site to **probe** the configured endpoint — this exercises connectivity (and TLS trust) against the live config, including edited-but-unsaved values.
|
||||
|
||||
- `DataConnectionManagerActor` handles `VerifyEndpointCommand` (`SiteId`, protocol, config JSON). The site spins up a **temporary** `RealOpcUaClient` from the submitted config, attempts discovery + a session with a short timeout (a few seconds), then disconnects and disposes the client. The reply is a `VerifyEndpointResult` (`Success`, a typed `FailureKind`, an error message, and an optional captured server cert).
|
||||
- The probe forces **`AutoAcceptUntrustedCerts = false`** and hooks the certificate-validation callback so it can **capture** an untrusted server certificate (Subject / Issuer / Thumbprint / NotBefore / NotAfter / DER) for the UI to display. Critically, the probe **never trusts** the cert — the validation callback always rejects (`Accept = false`); trusting is a separate, explicit, Admin-gated action that writes the cert into the site PKI store (see the cert-trust path in Component-SiteRuntime.md). The probe is read-only with respect to the trust boundary.
|
||||
|
||||
## Native Alarm Mirroring
|
||||
|
||||
|
||||
Reference in New Issue
Block a user