Move the samples to preview 2.0.301.4181 and adopt what it added - #879
Merged
Merged
Conversation
Bumps `OpcUaNetStandardVersion` from `2.0.280.50326-preview` (SDK commit
c4960b54) to `2.0.301.4181-preview` (SDK commit 105508bc), 21 commits later.
## Breaking changes the bump forces
**GDS packages lost their `.Common` suffix** (UA-.NETStandard#4438).
`OPCFoundation.NetStandard.Opc.Ua.Gds.{Client,Server}.Common` are now
`…Gds.{Client,Server}`, and so are the assemblies inside them - which the GDS
sample applications were already using as their own assembly names. MSBuild
reported the collision as MSB3243 and picked a winner at random, so the two
apps and the controls library are renamed to `Quickstarts.GlobalDiscovery*`.
Their namespaces are unchanged.
**Part 11 Historical Access completed** (UA-.NETStandard#4390). Every historian
provider interface changed shape: collections are `ArrayOf<T>`, an update
answers a `HistorianUpdateOutcome<T>` (one status per entry plus the values it
displaced), `DeleteRawAsync` answers one of those rather than a bare status,
`InsertBatchAsync` takes `ArrayOf<HistorianDataBatch>`, `ReadAtTimeAsync`
answers `ArrayOf<DataValue>`, and a resume token carries a `ByteString`. The
three sample providers follow. On the client, `ReadRawAsync` and friends grew a
`HistoryReadNodeOptions` parameter before the cancellation token.
**The fluent configure/seal path became awaitable** (UA-.NETStandard#4442).
`NodeManagerBuilder.Configure(…)` and `Seal()` are gone; the two hand-written
fluent managers now run the pipeline the generator emits - `CreateFluentBuilder`,
`Configure`, `RegisterAuthoredNodesAsync`, `CompleteConfigureAsync`,
`SealConfigurationAsync`.
## Patterns adopted
- **Historian capabilities are a gate, not just an advertisement.** The
dispatcher refuses an operation the provider does not claim, and the
diagnostics node manager rolls the event flags up. `WellReportHistorianProvider`
claims its five event operations, `TestDataHistorianProvider` claims the server
timestamps its archive keeps, and `HistoricalEventsCapabilities` no longer sets
five flags by hand - only the Server object's EventNotifier is left to it.
- **`HistorianEventRecord.QualifiedFields`** is filled from the select clauses
beside the flat `Fields`, so two clauses which differ only in their event type
no longer collapse onto one browse path. The sample's own `BuildOperandKey`
gives way to `HistorianEventFieldKey.BuildPath`.
- **NodeManagement mints through the NodeId factory** (UA-.NETStandard#4433)
rather than a `New` override, which the AddNodes path no longer reaches:
`NodeIdFactory.WithMode(NodeIdAssignmentMode.String)` gives it the readable
identifiers it wanted. The other ten samples are tracked in #875.
- **RoleManagement stores one wildcard endpoint filter** instead of copying every
advertised endpoint description: `AddEndpoint` accepts a partial `EndpointType`
now (UA-.NETStandard#4412), and Part 18 §4.4.2 says the empty fields are
ignored anyway.
- **The NodeSet2 `InputArguments` repair is deleted** (UA-.NETStandard#4422): the
importer binds the typed property itself, so `BindInputArguments` and the
README section explaining it are gone.
## Recorded issues which paid out
Three `KnownIssue` wrappers failed because what they recorded now works, and are
replaced by plain assertions: the two structure default values in
`DataTypesNodeManagerTests` (#4401, fixed by #4414) and the audit trail in
`RoleManagementNodeManagerTests` (fixed by #4420). The prose which described
those gaps across four READMEs and three sources is updated.
## Validation
`UA Samples.slnx` builds clean on net48/net8.0/net10.0. `SampleNodeManagers.Tests`:
181 passed, 0 failed, 1 skipped.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`DataTypesClientModel` called `LoadAsync(true, true)` on the complex type system, and the first parameter of that method is `onlyEnumTypes`. The client therefore built no structured type at all, and every structure the server serves arrived as an undecoded extension object - in a sample whose entire point is that "a value of a structure the client has no compiled knowledge of arrives decoded into its fields". Nothing caught it, because the tier 1.7 fixture asserted against `WrappedValue.ToString()` and the generated default value used to arrive as the bare XML of the model design (UA-.NETStandard#4401): the raw text happened to contain "Trek", "Cube" and "10", so the assertions held on an undecoded value. The bump to 2.0.301.4181-preview fixed that generator defect, the body became a binary `ByteString`, and the fixture started reporting `Byte[35]`. Both arguments are named at the call site now, and the `KnownIssue` wrapper recording the null TypeId is removed with the assertion left standing: the value carries a real encoding id and decodes into its fields. The two expectations tier 1.7 still records - a compiled type cannot hand over its own `DataTypeDefinition` (UA-.NETStandard#4424) and the AlarmCondition audit trail records no `AddComment` - stay ignored. The audit note is narrowed: the RoleSet Methods of the RoleManagement sample are audited on this stack, so "no audit event of any type reaches a subscriber" is no longer true. `SampleClientModels.Tests`: 421 passed, 0 failed, 3 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed changes
Moves the samples from
2.0.280.50326-preview(stack commitc4960b54) to2.0.301.4181-preview(stack commit105508bc), 21 commits later, and adopts what thatrange added.
Breaking changes the bump forces
The GDS packages lost their
.Commonsuffix(UA-.NETStandard#4438).
OPCFoundation.NetStandard.Opc.Ua.Gds.{Client,Server}.Commonare now…Gds.{Client,Server}, and so are the assemblies inside them — which the GDS sampleapplications were already using as their own
AssemblyName. MSBuild reported the collisionas
MSB3243and picked a winner at random, not as an error, so the two apps and thecontrols library are renamed to
Quickstarts.GlobalDiscovery{Client,Server,ClientControls}.Their
RootNamespaceand everyusingare untouched; the sample catalog addresses them byproject path, so nothing else moves.
Part 11 Historical Access was completed
(#4390). Every historian
provider interface changed shape: collections are
ArrayOf<T>, an update answers aHistorianUpdateOutcome<T>(one status per entry plus the values it displaced, for the audittrail),
DeleteRawAsyncanswers one of those rather than a bareStatusCode,InsertBatchAsynctakesArrayOf<HistorianDataBatch>,ReadAtTimeAsyncanswersArrayOf<DataValue>, and a resume token carries aByteString. The three sample providersfollow. On the client,
ReadRawAsyncand friends gained aHistoryReadNodeOptionsparameter before the cancellation token, so a positional
ctno longer compiles.The fluent configure/seal path became awaitable
(#4442).
NodeManagerBuilder.Configure(…)andSeal()are gone; the two hand-written fluentmanagers now run the pipeline the generator emits —
CreateFluentBuilder,Configure,RegisterAuthoredNodesAsync,CompleteConfigureAsync,SealConfigurationAsync.Patterns adopted
operation the provider does not claim, and the diagnostics node manager now rolls the event
flags up as well.
WellReportHistorianProviderclaims the five event operations it serves,TestDataHistorianProviderclaims the server timestamps its archive keeps, andHistoricalEventsCapabilitiesno longer sets five flags by hand — only the Server object'sEventNotifier is left to it.
HistorianEventRecord.QualifiedFieldsis filled from the select clauses beside the flatFields, so two clauses which differ only in their event type no longer collapse onto onebrowse path. The sample's own
BuildOperandKeygives way toHistorianEventFieldKey.BuildPath.(#4433) rather than a
Newoverride, which the AddNodes path no longer reaches — a node built from a TypeDefinition
arrives carrying the type's id, so the override's
!node.NodeId.IsNullguard silently sentevery request to the base.
NodeIdFactory.WithMode(NodeIdAssignmentMode.String)gives thesample back the readable identifiers it wanted.
endpoint description.
AddEndpointaccepts a partialEndpointTypenow(#4412), and Part 18 4.4.2
says the fields left at their default are ignored anyway — so
{ SecurityMode = SignAndEncrypt }is the whole rule, and it keeps matching when a hostname is spelled differently.
InputArgumentsrepair is deleted(#4422): the importer binds
the typed property itself, so
BindInputArgumentsand the README section explaining it aregone.
One real bug the bump exposed
DataTypesClientModelcalledLoadAsync(true, true)on the complex type system, and thefirst parameter of that method is
onlyEnumTypes. The client built no structured type atall, so every structure the server serves arrived as an undecoded extension object — in the
sample whose entire point is that "a value of a structure the client has no compiled knowledge
of arrives decoded into its fields".
Nothing caught it, because the tier 1.7 fixture asserted against
WrappedValue.ToString()and the generated default value used to arrive as the bare XML of the model design
(#4401): the raw text happened
to contain
Trek,Cubeand10, so the assertions held on a value that decoded intonothing. #4414 fixed that generator defect, the body became a binary
ByteString, and thefixture started reporting
Byte[35]. Both arguments are named at the call site now.Recorded issues which paid out
Three
KnownIssuewrappers failed because what they recorded now works, and are replaced byplain assertions: the two structure default values in
DataTypesNodeManagerTests(#4401,fixed by #4414) and the audit trail in
RoleManagementNodeManagerTests(fixed by#4420). The prose describing
those gaps across four READMEs,
docs/TESTING.mdand three sources is updated.Two expectations stay ignored because they are still real: a compiled type cannot hand over
its own
DataTypeDefinition(#4424) and no audit event of
an AlarmCondition condition-Method call reaches a subscriber. The second note is narrowed —
the RoleSet Methods of the RoleManagement sample are audited on this stack, so "no audit
event of any type reaches a subscriber" is no longer true.
Related Issues
Nothing to close here. What this bump unblocks or newly exposes is filed rather than crammed
in:
Newevent history from the client)
ImportTypes of changes
The breaking box is ticked for the GDS assembly renames: anything naming
Opc.Ua.Gds.Client.dllorOpc.Ua.Gds.Server.dllfrom these sample projects by file name —a binding redirect, a launch script — has to follow.
Checklist
Further comments
Validation
UA Samples.slnxbuilds clean on net48, net8.0 and net10.0. Every tier was run locally onnet10.0:
SampleConfiguration.TestsSampleServers.TestsSampleNodeManagers.TestsSampleClientModels.TestsSampleClients.Tests(WinForms)1,025 passed, 0 failed, 4 skipped. The four skips are the recorded known issues named
above plus one pre-existing skip unrelated to this change. The build carries no new warnings,
and the
MSB3243assembly conflict the rename fixes is gone.On resolving the version
GitHub Packages needs a token with
read:packageseven for a public feed, which the localghtoken does not carry. The version was resolved and the build validated the way therepository documentation describes for that situation: from the
release-manifest.jsonofthe last successful
nuget-publish.ymlrun on the stack'smaster, whose artifact doublesas a local folder feed. Nothing about that workflow is committed —
Nuget.Configisuntouched and
targets.propschanges only in the pinned version.🤖 Generated with Claude Code