Skip to content

Let both OnboardingClient generations call the hand-built GDS registrar - #859

Closed
romanett wants to merge 1 commit into
masterfrom
romanett/gds-registrar-onboarding-ns-cc10fc
Closed

romanett wants to merge 1 commit into
masterfrom
romanett/gds-registrar-onboarding-ns-cc10fc

Conversation

@romanett

@romanett romanett commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

The generated OnboardingClient changed how it reaches RegisterTickets/UnregisterTickets after the 2.0.0-preview.4 cut: it now calls the type-declaration MethodId of the Onboarding companion model on the wrapped instance directly (which OPC UA Part 4 §5.12.2.2 permits), and only falls back to a browse path qualified with the Onboarding namespace. The hand-built registrar of the GDS sample carries its Methods under sample-namespace NodeIds with ns=0 BrowseNames - the contract of the earlier client generation - so against the current GitHub Packages builds (verified on 2.0.280.50326-preview) every ticket call answers BadMethodInvalid. On preview.4 it still works, which is why CI does not show it yet; the break surfaces with the next package bump.

The registrar now serves both generations with the same two nodes:

  • the Method NodeIds are the type-declaration ids of the companion model (DeviceRegistrarAdminType_RegisterTickets = 1176, DeviceRegistrarAdminType_UnregisterTickets = 1179, in the Onboarding namespace, which the node manager brings into the server table) - so the current client's direct call lands with no fallback roundtrip, and
  • the BrowseNames stay in namespace 0 - which the earlier client generation's browse resolution expects.

The namespace URI and the two ids are spelled out as constants because the generated model constants (Opc.Ua.Onboarding.*) are not part of the preview.4 packages this repository builds against.

Verified on both package generations: at 2.0.0-preview.4 (this branch as-is) and at 2.0.280.50326-preview (the same file on the #808 branch) the GDS client test registers and unregisters its onboarding ticket; the GDS tier 1 tests stay green.

Extracted from #808 so the fix is in master independently of the feed switch; #808 carries the identical file.

Related Issues

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Enhancement (non-breaking change which adds functionality)
  • Test enhancement (non-breaking change to increase test coverage)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected, requires version increase of Nuget packages)
  • Documentation Update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc.
  • I have signed the CLA.
  • I ran tests locally with my changes, all passed.
  • I fixed all failing tests in the CI pipelines.
  • I fixed all introduced issues with CodeQL and LGTM.
  • I have added tests that prove my fix is effective or that my feature works and increased code coverage.
  • I have added necessary documentation (if appropriate).
  • Any dependent changes have been merged and published in downstream modules.

Further comments

The alternative - qualifying the BrowseNames with the Onboarding namespace to satisfy the new client's fallback - was tried first and breaks the preview.4 client, whose browse resolution expects ns=0 names. Serving the type-declaration ids directly is both backward compatible and one roundtrip cheaper for the new client.

🤖 Generated with Claude Code

romanett added a commit that referenced this pull request Sep 4, 2026
The type-declaration MethodIds of the companion model serve the current
OnboardingClient's direct call - one roundtrip cheaper than the browse
fallback the previous fix on this branch relied on - and the ns=0
BrowseNames keep the earlier client generation working. Same file as
the master fix, so the next merge is conflict free.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The generated OnboardingClient changed how it reaches RegisterTickets /
UnregisterTickets: it now calls the type-declaration MethodId of the
Onboarding companion model on the instance directly - which OPC UA
Part 4 permits - and only falls back to a browse path qualified with the
Onboarding namespace. The hand-built registrar of the GDS sample carried
its Methods under sample-namespace NodeIds with ns=0 BrowseNames, the
contract of the earlier client generation, so newer packages answer
BadMethodInvalid.

The registrar now serves both generations with the same two nodes: the
Method NodeIds are the type-declaration ids of the companion model
(1176/1179 in the Onboarding namespace, which the node manager brings
into the server table), so the current client's direct call lands, and
the BrowseNames stay in namespace 0, which is what the earlier client's
browse resolution expects. Verified against 2.0.0-preview.4 and
2.0.280.50326-preview.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@romanett romanett closed this Sep 4, 2026
romanett added a commit that referenced this pull request Sep 4, 2026
The packages this branch builds against ship the generated model, so
the namespace and the two type-declaration MethodIds come from
Opc.Ua.Onboarding.Namespaces and Opc.Ua.Onboarding.MethodIds instead of
spelled-out literals. The master variant (#859) keeps the literals until
the packages move past 2.0.0-preview.4, which does not contain the
generated model.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
romanett added a commit that referenced this pull request Sep 8, 2026
…L loading (#808)

* Switch the preview feed to GitHub Packages and adopt the DI config-XML loading

The ADO opcua-preview feed is retired: Nuget.Config now points at the
OPC Foundation GitHub Packages feed, the CI pipelines authenticate it
with the GITHUB_PACKAGES_TOKEN secret through
VSS_NUGET_EXTERNAL_FEED_ENDPOINTS, and the README documents the
read:packages token a local restore needs.

Every OPC UA package reference moves from 2.0.0-preview.2 to
2.0.245.28872-preview - the latest set published to GitHub Packages -
and is pinned in one place, the OpcUaNetStandardVersion property in
targets.props.

The server samples hand their *.Config.xml to the hosted server of the
stack (services.AddOpcUa().AddServer(configurationFile), issue #794,
unblocked by OPCFoundation/UA-.NETStandard#4325): AddSampleServer gains
configuration-file overloads which run the container's server instance
through IOpcUaServerFactory, capture the loaded configuration for the
forms, attach the log file the configuration names, and gate the start
of the host on the server actually listening. The client samples and
the ApplicationInstance-centric legacy samples name their configuration
file directly instead of through ConfigSectionName, and the dead OPC UA
sections leave the App.config files. New HostedServerBootstrapTests pin
the bootstrap contract.

Fixes #794

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Authenticate the CodeQL restore and fail the pipelines fast without a feed token

The first CI run answered the GitHub Packages feed switch with a wall of
401s. Three fixes:

The CodeQL workflow authenticates the feed with its own workflow token -
reading a public package needs any authenticated principal, so this job
needs no secret at all. The token is written into the checked-out
Nuget.Config, which both solution restores read.

The Azure pipelines cannot mint a GitHub token themselves, so they still
need the GITHUB_PACKAGES_TOKEN secret pipeline variable. A probe step in
front of every restore now turns a missing or rejected token into one
readable error pointing at the README instead of hundreds of 401 lines.

The endpoint list moves from a nested job variable into a direct env
mapping on each restore step - the form documented for secrets, with one
less expansion to reason about. The first run proved the credential
provider picks the endpoint up either way.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Move to the 2.0.262.32744-preview packages

The latest set the nuget-publish workflow pushed to GitHub Packages from
master, which the whole solution builds against without a source change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Park the StateMachines expectations which need an SDK newer than 2.0.262

The StateMachines sample merged from master was validated against the
nuget.org 2.0.0-preview.4 cut, which contains UA-.NETStandard #4368
(Executable/UserExecutable reporting for state machine causes, and the
CurrentState/Id that goes with it). That change landed one master build
after 2.0.262.32744-preview - the newest set on GitHub Packages, because
every later publish fails on an unrelated signing error in the stack
(Opc.Ua.WotCon.Bindings declares InternalsVisibleTo without a public
key, which only the strong-name-signed publish build rejects).

The three affected expectations go into the known-issue machinery the
suite has for exactly this: the CurrentState/Id asserts of the node
manager fixture into KnownIssue wrappers, the cause-offering client
test into a subscription known-issue list mirroring SampleClientTests.
All of them fail the moment a newer package set makes them pass, which
is the reminder to remove them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Move to the 2.0.280.50326-preview packages and lift the StateMachines park

The stack's signed publish is repaired, so GitHub Packages carries
master builds again; the newest set contains UA-.NETStandard #4368,
which lets the StateMachines known-issue entry and its TESTING.md note
pay out. The onboarding ticket surface moved from byte arrays to
ArrayOf<ByteString> in and ArrayOf<StatusCode> out, which the device
onboarding dialog and the GDS client test follow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Qualify the registrar methods with the Onboarding namespace, re-park StateMachines

Two findings from running the merged tree on the 2.0.280 packages:

The generated OnboardingClient now calls the type-declaration MethodId
first and falls back to a browse path qualified with the Part 21
Onboarding namespace - the ns=0 browse names the hand-built registrar
carried were the old contract, and GetTickets answered BadMethodInvalid.
The node manager now brings the Onboarding namespace into the server
table and creates the two Method BrowseNames in it, which is the shape
the stack's own OnboardingClientTests pin.

The StateMachines cause-offering test fails identically on master's CI
at 2.0.0-preview.4, so the earlier park was removed for the wrong
reason: this is not package lag but a defect in how the sample and the
stack report Executable for causes. The known-issue entry returns with
that corrected reason and pays out when the defect is fixed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Restore the sample table rows the merge dropped from the README

The NodeManagement, RoleManagement and StateMachines rows of the
workshop sample table were lost in an earlier merge resolution; the
table matches master again, and only the preview-feed section differs
on this branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Align the registrar with the dual-generation design of #859

The type-declaration MethodIds of the companion model serve the current
OnboardingClient's direct call - one roundtrip cheaper than the browse
fallback the previous fix on this branch relied on - and the ns=0
BrowseNames keep the earlier client generation working. Same file as
the master fix, so the next merge is conflict free.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Take the registrar ids from the generated Onboarding model constants

The packages this branch builds against ship the generated model, so
the namespace and the two type-declaration MethodIds come from
Opc.Ua.Onboarding.Namespaces and Opc.Ua.Onboarding.MethodIds instead of
spelled-out literals. The master variant (#859) keeps the literals until
the packages move past 2.0.0-preview.4, which does not contain the
generated model.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Use opcfoundation-org for package feed secret

Co-authored-by: romanett <7413710+romanett@users.noreply.github.com>

* Authenticate GitHub Packages via the Github-Feed service connection

Replace the GITHUB_PACKAGES_TOKEN secret pipeline variable with the
Github-Feed NuGet service connection: NuGetAuthenticate@1 now references
the connection in all three pipeline templates, which removes the
per-restore VSS_NUGET_EXTERNAL_FEED_ENDPOINTS endpoint JSON and the
fail-fast token probe steps. The README documents how the service
connection is set up instead of the secret variable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: romanett <7413710+romanett@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant