[opcuaclient] OpcUaClient — Selective import + namespace remap #359

Merged
dohertj2 merged 1 commits from auto/opcuaclient/7 into auto/driver-gaps 2026-04-25 20:23:16 -04:00
Owner

Summary

Selective import + namespace remap + root-folder alias for OpcUaClient — the curation surface every commercial aggregator ships.

  • OpcUaClientCurationOptions record on OpcUaClientDriverOptions.Curation:
    • IncludePaths / ExcludePaths — glob (* / ? only), translated to a single combined regex via CompileGlobs. Exclude wins over include.
    • NamespaceRemap — URI→URI applied to DriverAttributeInfo.FullName via new BuildRemappedFullName helper (emits nsu=... form via ExpandedNodeId).
    • RootAlias — replaces hard-coded "Remote" root folder name.
  • BrowseRecursiveAsync — threads a slash-joined pathPrefix plus compiled include/exclude regexes. Pruned subtrees are skipped wholesale.
  • PendingVariable — carries pre-computed remapped FullName so EnrichAndRegisterVariablesAsync just stores it.

Empty/null Curation = legacy behaviour (include all, no remap, root = "Remote"). ns=0 nodes always bypass remap.

Test plan

  • dotnet build src/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient — clean (0 / 0)
  • dotnet test tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests147 / 147 passed (14 new in OpcUaClientCurationTests: glob * / ?, exclude-wins-over-include, multi-include OR, regex-metachar escape, remap hit/miss, ns=0 passthrough, defaults)
  • Integration tests — skipped (live UA server required)

🤖 Auto-generated by the Mode-B execution loop. Closes #279.

Closes #279

## Summary Selective import + namespace remap + root-folder alias for OpcUaClient — the curation surface every commercial aggregator ships. - **`OpcUaClientCurationOptions`** record on `OpcUaClientDriverOptions.Curation`: - `IncludePaths` / `ExcludePaths` — glob (`*` / `?` only), translated to a single combined regex via `CompileGlobs`. Exclude wins over include. - `NamespaceRemap` — URI→URI applied to `DriverAttributeInfo.FullName` via new `BuildRemappedFullName` helper (emits `nsu=...` form via `ExpandedNodeId`). - `RootAlias` — replaces hard-coded `"Remote"` root folder name. - **`BrowseRecursiveAsync`** — threads a slash-joined `pathPrefix` plus compiled include/exclude regexes. Pruned subtrees are skipped wholesale. - **`PendingVariable`** — carries pre-computed remapped `FullName` so `EnrichAndRegisterVariablesAsync` just stores it. Empty/null Curation = legacy behaviour (include all, no remap, root = `"Remote"`). `ns=0` nodes always bypass remap. ## Test plan - [x] `dotnet build src/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient` — clean (0 / 0) - [x] `dotnet test tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests` — **147 / 147 passed** (14 new in `OpcUaClientCurationTests`: glob `*` / `?`, exclude-wins-over-include, multi-include OR, regex-metachar escape, remap hit/miss, ns=0 passthrough, defaults) - [ ] Integration tests — skipped (live UA server required) 🤖 Auto-generated by the Mode-B execution loop. Closes #279. Closes #279
dohertj2 added 1 commit 2026-04-25 20:23:11 -04:00
Adds OpcUaClientCurationOptions on OpcUaClientDriverOptions.Curation with:
- IncludePaths/ExcludePaths globs (* and ? only) matched against the
  slash-joined BrowsePath segments collected during BrowseRecursiveAsync.
  Empty Include = include all so existing deployments are unaffected;
  Exclude wins over Include. Pruned folders are skipped wholesale, so
  descendants don't reach the wire.
- NamespaceRemap (URI -> URI) applied to DriverAttributeInfo.FullName when
  registering variables. Index-0 / standard nodes round-trip unchanged;
  remapped nodes serialise via ExpandedNodeId so downstream clients see
  the local-side URI.
- RootAlias replaces the hard-coded "Remote" folder name at the top of
  the mirrored tree.

Closes #279
dohertj2 merged commit 5e164dc965 into auto/driver-gaps 2026-04-25 20:23:16 -04:00
dohertj2 deleted branch auto/opcuaclient/7 2026-04-25 20:23:16 -04:00
Sign in to join this conversation.