Skip to content

Add runtime NodeSet-backed node managers - #3990

Merged
marcschier merged 4 commits into
OPCFoundation:masterfrom
marcschier:marcschier/3974-runtime-nodesets
Jul 12, 2026
Merged

Add runtime NodeSet-backed node managers#3990
marcschier merged 4 commits into
OPCFoundation:masterfrom
marcschier:marcschier/3974-runtime-nodesets

Conversation

@marcschier

Copy link
Copy Markdown
Collaborator

Description

Add a dedicated startup-time runtime NodeSet2 loading path for servers that need to expose information models without source generation.

This introduces:

  • AddRuntimeNodeSet DI extensions for single files, grouped sources, and lazy stream providers.
  • A dedicated RuntimeNodeSetNodeManagerFactory and FluentNodeManagerBase implementation that remain separate from source-generated NodeManagers and typed fluent builders.
  • Model ownership validation, RequiredModel dependency ordering, parent-child linking, external reference handling, and fail-fast diagnostics.
  • Untyped INodeManagerBuilder code-behind wiring for imported variables, methods, events, alarms, and simulations.
  • Reuse of the existing default server-side complex-type loading path after the runtime address space is created.
  • Runtime NodeSet documentation plus NUnit and NativeAOT coverage.

The feature intentionally loads NodeSets only during server startup. Live add, reload, or removal after clients connect remains out of scope because it requires separate MasterNodeManager routing, NamespaceArray, model-change, subscription, and complex-type lifecycle design.

Related Issues

Validation

  • Runtime NodeSet tests: 38 passed on net10.0.
  • Runtime NodeSet tests: 38 passed on net48.
  • NativeAOT publish succeeded and the full 107-test executable passed.
  • Changed C# files pass whitespace verification and the server library builds without new warnings.

Checklist

  • I have signed the CLA and read the CONTRIBUTING doc.
  • I have added tests that prove my fix is effective or that my feature works and increased code coverage.
  • I have added all necessary documentation.
  • I have verified that my changes do not introduce (new) build or analyzer warnings.
  • I ran all tests locally using the UA.slnx solution against at least .net framework and .net 10, and all passed.
  • I fixed all failing and flaky tests in the CI pipelines and all CodeQL warnings.
  • I have addressed all PR feedback received.

@CLAassistant

CLAassistant commented Jul 11, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ marcschier
❌ Copilot
You have signed the CLA already but the status is still pending? Let us recheck it.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.53261% with 79 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.84%. Comparing base (7f40965) to head (3e69877).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
...Server/RuntimeNodeSet/RuntimeNodeSetNodeManager.cs 58.33% 25 Missing and 10 partials ⚠️
...RuntimeNodeSet/RuntimeNodeSetNodeManagerFactory.cs 81.52% 16 Missing and 18 partials ⚠️
...c.Ua.Server/RuntimeNodeSet/RuntimeNodeSetSource.cs 86.48% 5 Missing and 5 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3990      +/-   ##
==========================================
+ Coverage   77.70%   78.84%   +1.14%     
==========================================
  Files        1385     1391       +6     
  Lines      183248   183805     +557     
  Branches    31926    32062     +136     
==========================================
+ Hits       142385   144917    +2532     
+ Misses      29318    27483    -1835     
+ Partials    11545    11405     -140     
Files with missing lines Coverage Δ
.../RuntimeNodeSet/RuntimeNodeSetBuilderExtensions.cs 100.00% <100.00%> (ø)
....Ua.Server/RuntimeNodeSet/RuntimeNodeSetOptions.cs 100.00% <100.00%> (ø)
...c.Ua.Server/RuntimeNodeSet/RuntimeNodeSetSource.cs 86.48% <86.48%> (ø)
...RuntimeNodeSet/RuntimeNodeSetNodeManagerFactory.cs 81.52% <81.52%> (ø)
...Server/RuntimeNodeSet/RuntimeNodeSetNodeManager.cs 58.33% <58.33%> (ø)

... and 150 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@marcschier
marcschier marked this pull request as ready for review July 11, 2026 15:07
Copilot AI review requested due to automatic review settings July 11, 2026 15:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a server startup-time “runtime NodeSet” loading path that imports one or more NodeSet2 XML documents into the server address space without requiring source generation, integrating with the existing fluent INodeManagerBuilder surface and the default server complex-type loading pipeline.

Changes:

  • Introduces RuntimeNodeSet* types (sources/options/factory/node manager) plus AddRuntimeNodeSet(...) DI/hosting extensions for file- and stream-backed NodeSet2 loading.
  • Adds NUnit integration/unit coverage for runtime NodeSet loading, dependency ordering, namespace registration, and fluent callback wiring.
  • Extends documentation (server NuGet README + docs set) and adds an AOT smoke test covering AddRuntimeNodeSet registration.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Tests/Opc.Ua.Server.Tests/RuntimeNodeSet/RuntimeNodeSetTestServer.cs ReferenceServer subclass used to integration-test runtime NodeSet import + fluent wiring.
Tests/Opc.Ua.Server.Tests/RuntimeNodeSet/RuntimeNodeSetSourceTests.cs Unit tests for runtime NodeSet sources (file/stream) and model-URI extraction behavior.
Tests/Opc.Ua.Server.Tests/RuntimeNodeSet/RuntimeNodeSetNodeManagerFactoryTests.cs Unit tests for factory validation, namespace aggregation, and dependency/cycle/duplicate detection.
Tests/Opc.Ua.Server.Tests/RuntimeNodeSet/RuntimeNodeSetIntegrationTests.cs End-to-end address space tests against a real server instance using runtime NodeSet loading.
Tests/Opc.Ua.Aot.Tests/HostingAotTests.cs Adds AOT-safe smoke coverage for AddRuntimeNodeSet stream registration and manager creation.
Libraries/Opc.Ua.Server/RuntimeNodeSet/RuntimeNodeSetSource.cs Adds RuntimeNodeSetSource abstraction and file/stream implementations with model URI metadata.
Libraries/Opc.Ua.Server/RuntimeNodeSet/RuntimeNodeSetOptions.cs Adds options object controlling sources, default namespace inference, and fluent configuration callback.
Libraries/Opc.Ua.Server/RuntimeNodeSet/RuntimeNodeSetNodeManagerFactory.cs Adds public async node-manager factory that parses/sorts/imports NodeSets in dependency order.
Libraries/Opc.Ua.Server/RuntimeNodeSet/RuntimeNodeSetNodeManager.cs Adds internal node manager that imports NodeSets, validates, and applies fluent callbacks.
Libraries/Opc.Ua.Server/RuntimeNodeSet/RuntimeNodeSetBuilderExtensions.cs Adds IOpcUaServerBuilder.AddRuntimeNodeSet(...) DI registration surface.
Libraries/Opc.Ua.Server/NugetREADME.md Documents how to use AddRuntimeNodeSet from the server NuGet package.
Docs/SourceGeneratedNodeManagers.md Adds a “Runtime NodeSet alternative” section pointing readers to the new approach.
Docs/RuntimeNodeSets.md New end-user guide for runtime NodeSet loading semantics, ordering, and complex-type behavior.
Docs/README.md Adds Runtime NodeSets to the docs index.
Docs/DependencyInjection.md Updates DI feature table to include runtime NodeSet registration.
Docs/ComplexTypes.md Notes that runtime NodeSets integrate with the default server complex-type pass.

Comment thread Libraries/Opc.Ua.Server/RuntimeNodeSet/RuntimeNodeSetSource.cs
Comment thread Libraries/Opc.Ua.Server/RuntimeNodeSet/RuntimeNodeSetSource.cs Outdated
Comment thread Libraries/Opc.Ua.Server/RuntimeNodeSet/RuntimeNodeSetSource.cs
Comment thread Tests/Opc.Ua.Server.Tests/RuntimeNodeSet/RuntimeNodeSetNodeManagerFactoryTests.cs Outdated

@romanett romanett left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a follow up item for adding NodeManager instances to a running server.

@marcschier marcschier added the ready Ready to merge once CI Passes label Jul 12, 2026
@marcschier
marcschier merged commit aadba8b into OPCFoundation:master Jul 12, 2026
163 of 164 checks passed
@marcschier
marcschier deleted the marcschier/3974-runtime-nodesets branch July 12, 2026 11:49
marcschier added a commit to marcschier/UA-.NETStandard that referenced this pull request Jul 23, 2026
Large merge bringing in ~60 upstream commits, most notably the
repository layout consolidation (OPCFoundation#4010) that moves the whole tree under
src/, samples/, tests/, tools/, docs/, and fuzzing/. Also includes the
repo-wide source-generated logging migration (OPCFoundation#3908/OPCFoundation#4003), Part 4 6.6
Redundancy (OPCFoundation#3918), runtime NodeSet-backed node managers (OPCFoundation#3990),
MinimalClient sample (OPCFoundation#4006), and many CTT/compliance and security fixes.

Conflict resolution:

 * UA.slnx - took upstream's new-layout solution structure and added
   our branch-only UaLens under the /samples/ folder
   (samples/Opc.Ua.Lens/Opc.Ua.Lens.csproj). Dropped the stale
   Applications/McpServer entry (McpServer already lives under master's
   /tools/ section as tools/Opc.Ua.Mcp).
 * .azurepipelines/preview.yml, signlist{Debug,Release}.txt - took
   upstream's versions wholesale (pure old->new layout path rewrites for
   upstream-managed files; UaLens was never sign-listed).

Relocations for our branch-only files that the consolidation could not
auto-move (they exist only on our side, so upstream's rename didn't
touch them):

 * Applications/Opc.Ua.Lens/ -> samples/Opc.Ua.Lens/ (alongside the
   other sample apps). Updated its csproj ProjectReferences from the old
   Stack/ + Libraries/ paths to the new src/ layout, and dropped the
   obsolete <None Remove ...Docs\NugetREADME.md> line (common.props no
   longer ships a shared root readme; each package owns its local
   NugetREADME.md, which UaLens already has).
 * Libraries/Opc.Ua.Client/UserManagement/{IUserManagementClient,
   UserManagementClient,UserManagementUser}.cs ->
   src/Opc.Ua.Client/UserManagement/ so they compile back into the
   (moved) client project.

Suppressed CA1873 in the UaLens csproj (with comment + TODO): upstream's
source-generated-logging migration enabled this analyzer repo-wide and
it flags UaLens's 146 direct ILogger.Log* call sites. Migrating UaLens
logging to [LoggerMessage] partials is tracked as follow-up.

UaLens build clean (0 warnings / 0 errors).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready Ready to merge once CI Passes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Server] Runtime Complex Types. Add an easy way to expose NodeSet2 Based NodeManagers at runtime

5 participants