# Description
Pure code-style sweep across the repo — no behavioral changes. Drives
`dotnet format` info-level diagnostics down on a large slice of the
codebase (Stack, Libraries, Tests, Tools).
Six commits, applied bottom-up in safety order so each batch leaves the
build green:
1. **`style: fix whitespace and final-newline formatting (WHITESPACE,
FINALNEWLINE)`**
197 hits across ~30 files; pure mechanical cleanup.
2. **`style: apply dotnet format style fixes (IDE rules)`**
IDE-rule batch via `dotnet format style --severity info` —
`var`/explicit type, simplify names, collection expressions, expression
bodies, unused usings, etc.
3. **`style: apply dotnet format analyzers fixes (RCS blank-line
formatting)`**
Roslynator formatting (RCS0xxx) blank-line and punctuation rules.
4. **`style: convert comments to doc comments and inline local vars
(RCS1181, RCS1124)`**
24 files. RCS1181 promotes `// summary`-style comments above
public/internal members to `/// <summary>` doc comments; RCS1124 inlines
locals used exactly once. Generated `Tools/` files were reverted to keep
the source-generator outputs deterministic.
5. **`docs(agent): correct --diagnostics flag form and verify Roslynator
4.x code fixers`**
Updates `.github/agents/opc-ua-codestyle-enforcer.agent.md` with two
corrections discovered while running this sweep:
- `dotnet format --diagnostics "RULE1 RULE2"` (single quoted,
space-separated) silently fixes nothing on `dotnet format` 10.x — it
parses as one unknown ID and exits 0. The correct form is `--diagnostics
RULE1 --diagnostics RULE2 …`, repeated per rule.
- Roslynator 4.15.0 **does** ship code fixers for
RCS1078/1118/1124/1140/1142/1181/1221/1260 (the previous "no auto-fixer"
list was outdated). RCS1140/1142 default to `Hidden` so need `--severity
info` to surface and fire; RCS1078 requires
`roslynator_empty_string_style = field` (already set in
`.editorconfig`). Only NUnit4002/2046/2010 genuinely lack auto-fixers in
this stack.
6. **`style: format new code from master merge (dotnet format sweep)`**
After merging master into the branch (commit `e3ebc8742`), re-ran the
same three-phase format sweep on the 151 .cs files brought in by the
merge, scoped per project via repeated `--include`. 81 files changed;
same rule families as commits 1–4.
- Hand-fixed `Tests/Opc.Ua.MigrationAnalyzer.Tests/AnalyzerHarness.cs`
for `RCS1174` (redundant `async`/`await` removal) because the auto-fixer
didn't apply for that specific case.
- Reverted files that the formatter would break:
- `Libraries/Opc.Ua.Server/Server/ServerInternalData.cs` — multi-TFM
analysis disagreement injected `<<<<<<<` / `=======` / `>>>>>>>`
markers.
-
`Tools/Opc.Ua.MigrationAnalyzer.Core/{Core/Stack/Client/ChannelBase.cs,
Core/Stack/Types/IUserIdentityTokenHandler.cs,
Client/Session/Session.cs}` — IDE0005 removed `using
Opc.Ua.Security.Certificates` that IS used (the files are 1.5.378
reference fixtures for the analyzer).
- `Tests/Opc.Ua.Gds.Tests/PushTest.cs` — IDE0002 over-simplified
`OpcUa.ObjectTypeIds` to `ObjectTypeIds`, which then resolves to a
conflicting type.
### What this PR does **not** touch
- No behavioral or semantic logic changes.
- No `.editorconfig` rule promotions (rules stay at their current
severities; this is a backlog-burndown pass, not a rule tightening).
- Generated source under `Tools/` is intentionally excluded.
- Higher-risk rule families (`RCS1090`/`CA2007` `ConfigureAwait`,
`RCS1249` null-forgiving cleanup, `IDE0270`/`IDE0059`) are left for
follow-up sweeps because they need per-TFM build verification or
semantic review.
## Related Issues
_No tracking issue — this is a non-functional style sweep and the
agent-doc correction is a follow-up to the same work. Happy to open one
if the maintainers prefer._
## Checklist
- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage. _(N/A — style-only, no
behavioral change)_
- [x] I have added all necessary documentation. _(agent doc updated with
the two corrections)_
- [x] I have verified that my changes do not introduce (new) build or
analyzer warnings. _(verified clean on `net10.0` and `net48`; only
pre-existing `NETSDK1005`/`NETSDK1207` failures on Tools/AOT projects)_
- [ ] I ran **all** tests locally using the **UA.slnx** solution against
at least .net **framework** and .net **10**, and all passed. _(build
verified on net10 and net48 per batch; full test suite not yet run
locally — relying on CI)_
- [ ] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [ ] I have addressed **all** PR feedback received.
---------
Co-authored-by: agent <agent@local>
# Description
Adds the OPC UA NodeManagement service set (AddNodes / DeleteNodes /
AddReferences / DeleteReferences) to the server SDK and fixes a
long-standing shutdown bug where `NodeState.Delete` callbacks never
fired on address-space teardown.
### NodeManagement service set (#3736)
- New optional `INodeManagementAsyncNodeManager` facet interface (added
to `INodeManager.cs` alongside other facets, discovered via `as`,
**not** part of the `IAsyncNodeManager` composite). Opt-in per
NodeManager via `AllowNodeManagement` — default is `false` so existing
NodeManagers preserve binary compatibility.
- Dispatcher in `MasterNodeManager` routes:
- **AddNodes** by `RequestedNewNodeId.NamespaceIndex` when supplied,
otherwise to the parent's owning NodeManager. When the parent's owner is
read-only (e.g. `ObjectsFolder` owned by `CoreNodeManager`), the
dispatcher falls back to the first opted-in NodeManager so conformance
flows work out of the box.
- **DeleteNodes** / **AddReferences** / **DeleteReferences** to the
owning NodeManager of the target or source node, returning
`BadUserAccessDenied` when that NodeManager has not opted in.
Cross-NodeManager `AddReference` / `DeleteReference` best-effort mirrors
the inverse edge on the target's NodeManager.
- `AsyncCustomNodeManager` provides a default implementation: per-item
validation, `RequestedNewNodeId` honored, browse-name dedup for both
local and cross-NodeManager parents, `DeleteTargetReferences` semantics,
and a NodeId allocator fallback when an `INodeIdFactory.New` override
returns a null `NodeId` (e.g. parent-based hierarchical naming with no
parent attached).
- `StandardServer` adds the four service overrides plumbed through
`OperationLimits.MaxNodesPerNodeManagement`, audit events, and
`OnRequestComplete`; new `ReportAuditAddReferencesEvent` /
`ReportAuditDeleteReferencesEvent` helpers in `AuditEvents`.
- Quickstarts `ReferenceNodeManager` opts in via `AllowNodeManagement =>
true`; the legacy partial-class override in
`ReferenceServer.NodeManagement.cs` is removed.
### `NodeState.Delete` on shutdown (#3762)
- `CustomNodeManager.DeleteAddressSpace` and
`AsyncCustomNodeManager.DeleteAddressSpaceAsync` now snapshot root
`PredefinedNodes` (skipping children whose parent is in the snapshot to
prevent double-fire), invoke `NodeState.Delete(SystemContext)` on each
root (which recurses into children and raises `OnBeforeDelete` /
`OnAfterDelete` / `NodeStateChangeMasks.Deleted`), and then clear the
map.
- Derived overrides in Quickstarts `ReferenceNodeManager`,
`SampleNodeManager`, and `FileSystemNodeManager` chain to `base` so the
callback fires for their nodes too.
### Tests
- **21 new dispatcher unit tests** in
`Tests/Opc.Ua.Server.Tests/NodeManager/AsyncCustomNodeManagerNodeManagementTests.cs`
covering `AllowNodeManagement` default/opt-in, AddNode validation
(`BadBrowseNameInvalid`, `BadParentNodeIdInvalid`, `BadNodeIdRejected`,
`BadNodeIdExists`, `BadBrowseNameDuplicated`, `BadNodeClassInvalid`),
RequestedNewNodeId paths, DeleteNode + `DeleteTargetReferences`,
AddReference duplicate detection (`BadDuplicateReferenceNotAllowed`),
and DeleteReference (`BadNoMatch`).
- **2 new DeleteAddressSpaceAsync tests** in
`AsyncCustomNodeManagerTests` verifying `NodeState.Delete` invocation
and no double-fire on children.
- Updated InformationModel
`NodeManagementAddRefTests.AddReferenceBetweenExistingNodesSucceedsAsync`
to accept `BadUserAccessDenied` / `BadNotSupported` when the source NM
has opted out.
- **Full `Opc.Ua.Server.Tests` on net10.0: 1709 passed, 0 failed.**
- **All 26 InformationModel `Category=NodeManagement` conformance tests
pass** against the reference server (1 skipped where source NM opts
out).
### Docs
- New [`Docs/NodeManagement.md`](Docs/NodeManagement.md) with
architecture, opt-in pattern, dispatch and routing rules,
request-handling table, error-code table, audit events, and
custom-behavior examples.
- `Docs/MigrationGuide.md` gets two new sections — *NodeManagement
service set* (downstream migration steps) and *DeleteAddressSpace
invokes NodeState.Delete (#3762)* (shutdown behavior change) — with TOC
entries.
- `Docs/README.md` links the new `NodeManagement.md`.
## Related Issues
- Fixes#3736
- Fixes#3762
## Checklist
_Put an `x` in the boxes that apply. You can complete these step by step
after opening the PR._
- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added all necessary documentation.
- [x] 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.
## Proposed changes
This PR updates the server monitored-item pipeline to be
`IAsyncNodeManager`-aware and introduces channel-based FIFO queueing in
the monitored-node path to improve behavior under load.
It also includes follow-up fixes from review/CI feedback:
- Adjusted
`AsyncCustomNodeManagerTests.WriteAsync_PublishesValueToMonitoredItemQueueAsync`
to account for channel-based delivery timing/coalescing while still
asserting the written value is observed.
- Merged latest `master` into this branch and resolved merge conflicts
(notably in `ConfigurationNodeManager`), keeping async address-space
lookup behavior intact.
- Applied small compile-safety corrections needed for successful
validation.
## Proposed changes
Reduces sync-over-async in non-obsolete server APIs, removes stale
`#region/#endregion` noise from the test suite, and fixes analyzer/test
fallout from merging the Part 11 Historical Access framework (#3797).
Follow-up review feedback is included: `FileSystemNodeManager` is now
based on `AsyncCustomNodeManager`.
### Sync-over-async reduction (~24 `GetAwaiter().GetResult()` sites)
**Server-side:**
- `TrustList`: async `OnCallAsync` handlers added; sync `OnCall`
handlers retained as compat shims so legacy `CustomNodeManager2`
subclasses that host the TrustList but do not implement
`ICallAsyncNodeManager` keep working through `MethodState.Call`.
- `GDS ApplicationsNodeManager`: `RequestAccessToken`,
`KeyCredentialStart/FinishRequest`, and `Revoke` moved to `OnCallAsync`.
- `IKeyCredentialRequestStore`: interface + in-memory implementation
converted to async; `FinishKeyCredentialRequestResult` record carries
the previous out-set. Tests in `Tests/Opc.Ua.Gds.Tests/` updated to the
new async API.
- `FileSystem`:
- `DirectoryObjectState` methods (`CreateDirectory` / `CreateFile` /
`Delete` / `MoveOrCopy`) use `OnCallAsync`.
- `FileSystemNodeManager` now derives from `AsyncCustomNodeManager` and
overrides async address-space/node-resolution paths
(`CreateAddressSpaceAsync`, `DeleteAddressSpaceAsync`,
`GetManagerHandleAsync`, `ValidateNodeAsync`) to avoid sync-over-async
in dynamic node validation.
- `FileSystemNodeManagerFactory` now supports async creation
(`IAsyncNodeManagerFactory`) while retaining sync factory compatibility.
- Reference server registration of the FileSystem node manager is
aligned to the async node manager list.
- `ConfigurationNodeManager` namespace lookup uses sync
`GetManagerHandle` to keep the remaining `GetResult` inside the
documented `SyncNodeManagerAdapter` bridge.
- `ServerBase`: new `OnServerStartingAsync`; `StartAsync` now awaits it.
- `StandardServer.CreateMasterNodeManagerAsync` added; sync wrapper kept
for backward compatibility.
- `IServerInternal.CloseSession` marked `[Obsolete]`
(`CloseSessionAsync` exists).
- `IMasterNodeManager.RemoveReferences` marked `[Obsolete]`; in-tree
sync callers remain with scoped `CS0618` pragmas + TODO.
**Stack:**
- `EncryptedSecret`: added `VerifyHeaderForEccAsync` / `DecryptAsync` /
`TryDecryptAsync`; `UserNameIdentityTokenHandler.DecryptAsync` awaits
ECC validation.
- `CertificatePasswordProvider` ctor: `GetResult` fallback replaced with
explicit `InvalidOperationException`.
### Code-style and post-merge cleanup
- Removed unused `#region`/`#endregion` directives across test files.
- Restored green build state after Part 11 merge fallout fixes
(production + analyzer + test cleanup from earlier commits in this PR).
### CI / validation notes
- This PR branch surfaced runtime regressions introduced by Part 11
after the build-breaker was fixed (outside scope of this
async/code-style cleanup).
- Follow-up feedback change validation for `FileSystemNodeManager`:
- `dotnet build Libraries/Opc.Ua.Server/Opc.Ua.Server.csproj -f net10.0
--no-restore` ✅
- `dotnet test Tests/Opc.Ua.Server.Tests/Opc.Ua.Server.Tests.csproj -f
net10.0 --filter FileSystemNodeIdTests` ✅
- `dotnet test Tests/Opc.Ua.History.Tests/Opc.Ua.History.Tests.csproj -f
net10.0 --filter FileSystemSmokeTests` ✅ (test skipped in environment)
## Related Issues
- None.
## Types of changes
- [ ] Bugfix (non-breaking change which fixes an issue)
- [x] Enhancement (non-breaking change which adds functionality)
- [x] 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
- [x] I have read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf).
- [x] 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.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added necessary documentation (if appropriate).
- [x] Any dependent changes have been merged and published in downstream
modules.
* Add SessionActivated notification to invalidate permission caches on identity change
* Fix code review: rename test methods to PascalCase, use default instead of new ValueTask()
* Improve comment clarity in AsyncCustomNodeManager.SessionActivatedAsync
* Add integration test for permission re-evaluation after TransferSubscriptions + ActivateSession
* Replace integration test to use restricted RolePermissions node and verify permission denial after re-activation
* Extract HasDataChangeNotificationForClientHandle helper to reduce duplication
* New certificate and secrete abstraction with certificate infrastructure and certificate/secret stores.
* leak testing for certificate resources to validate new ref counting in every test assembly
* Migration guide updated and documentation added for all
* Remove IDisposable from Nodestate and UserIdentity.
* UserCertificateTokenHandler now just points into certificate registry/stores, no dispose required
* Fix CA2000 warnings and cleanup of other diagnostics, increase warning levels in .editorconfig
new DataValue(42) silently resolved to DataValue(StatusCode) instead of
DataValue(Variant) due to C# 'better conversion target' rule — StatusCode
wins because it implicitly converts to Variant, making it 'more specific'.
This caused m_value = Variant.Null and downstream BadTypeMismatch failures.
Changes:
- Add [OverloadResolutionPriority(1)] on DataValue(Variant) constructor
- Obsolete DataValue(StatusCode) and DataValue(StatusCode, DateTimeUtc)
- Add DataValue.FromStatusCode() static factory methods (2 overloads)
- Delete DataValue(DataValue) copy constructor
- Add DataValue.Copy() instance method using base.MemberwiseClone()
- Rewrite Clone()/MemberwiseClone() to delegate to Copy()
- Migrate all call sites across 14 files
- Add tests verifying new DataValue(42) wraps value correctly
- Update MigrationGuide.md
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix missing mandatory children
* Source generator: fix encoding nodes, EventNotifier, and type RBAC
- Emit DataType encoding nodes (Default Binary/XML/JSON) into the
generated address space. CollectEncodingNodes() discovers
DataTypeEncodingType instances and builds synthetic hierarchies
with their HasEncoding/HasDescription references.
- Auto-set EventNotifier=SubscribeToEvents on Object nodes that have
forward HasEventSource or HasNotifier references. The fix works at
two levels: ModelDesignValidator infers SupportsEvents on types with
event references in design XML, and NodeStateGenerator checks the
resolved reference set for merged instances that inherit references
from their type definitions.
- Wrap AccessRestrictions/RolePermissions in if(forInstance) guards
for ObjectType, VariableType, DataType, and ReferenceType templates
so type definition nodes remain accessible to all users.
- Allow ModellingRule=None Object children on type definitions to be
emitted (e.g. state machine states/transitions).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Update missing nodes analysis after source generator fixes
Retest with admin credentials against ConsoleReferenceServer v1.05.07.
Categorize 794 truly missing nodes (after filtering optional/placeholder):
- 384 encoding nodes (NodeSet2.xml-only, not in design XML)
- 172 role instance children
- 84 other nodes
- Remaining: trust list, PubSub, diagnostics, etc.
RBAC and EventNotifier fixes confirmed working.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* update
* plans: detailed analysis of 292 remaining missing nodes
Replaced the two previous analysis files with a single consolidated
validation report. Each of the 292 nodes is classified with a reason:
- 212 type-level children (ObjectType definitions not instantiated)
- 48 instance-level children (diagnostics, HA, FileSystem, PubSub)
- 32 orphan property templates (design-time canonical definitions)
Only 1 fix recommended: Server.Auditing (i=2994) should be exposed
as false per Part 5 section 6.3.3.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: add GDS node manager to ConsoleReferenceServer
Add Global Discovery Server functionality to the reference server:
- Add Opc.Ua.Gds.Server.Common project reference
- Add GdsNodeManagerFactory that creates ApplicationsNodeManager
with JsonApplicationsDatabase and CertificateGroup (auto-approve)
- Add GlobalDiscoveryServerConfiguration extension to config XML
- Add GDS to ServerCapabilities
- Registration is opt-in: only when config extension is present
Also fix pre-existing source generator test failures:
- Add missing CreateOrReplaceTransitionNumber stub method to
StateMachineTransitionState in CompilerUtils.cs (8 tests fixed)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* plans: update missing nodes report with GDS retest results
Retested after adding GDS node manager to ConsoleReferenceServer.
Total missing reduced from 1325 to 1243 (82 fewer).
335 remaining 'other' nodes fully classified with per-node reasons.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* plans: Server.Auditing is present (access-restricted, not missing)
Live validation confirmed i=2994 exists with value=true, visible to
admin users. Returns BadUserAccessDenied for anonymous. No fixes needed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix CttTestRunner build errors for v1.6 API and Jint 4.8.0
- Update System.CommandLine 2.0.7 API: SetHandler->SetAction, InvokeAsync->Parse().InvokeAsync()
- Remove ObjectInstance inheritance from CttAssert, CttServiceRegister, CttIdentifierConstants, CttMonitoredItemHelper; use ToJsObject() factory methods instead
- Replace Jint.Native.JsValueType with .IsObject()/.IsNumber()/.IsString() etc.
- Add missing using directives (Jint.Runtime, Microsoft.Extensions.Logging, etc.)
- Fix NodeId.Identifier obsolete -> TryGetIdentifier<uint>
- Fix DataValue.Value obsolete -> WrappedValue.AsBoxedObject()
- Fix ApplicationInstance() obsolete -> ApplicationInstance(ITelemetryContext)
- Fix LoadApplicationConfiguration -> LoadApplicationConfigurationAsync
- Fix CheckApplicationInstanceCertificate -> CheckApplicationInstanceCertificatesAsync
- Fix CoreClientUtils.SelectEndpointAsync signature (requires telemetry param)
- Fix DefaultSessionFactory() obsolete -> DefaultSessionFactory(ITelemetryContext)
- Fix DiscoveryClient.Create -> DiscoveryClient.CreateAsync
- Fix FindServers/GetEndpoints -> FindServersAsync/GetEndpointsAsync
- Fix StatusCode to uint conversions
- Fix ArrayOf<T> iteration (use foreach instead of LINQ on IConvertableToArray)
- Fix XmlNodeList null coalescing in CttProjectSettings
- Fix JsValue.False -> JsValue.FromObject(engine, false)
- Add --json option to Program.cs for machine-readable output
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: emit type-level children with ModellingRule=None for all node classes
The source generator's GetChildren method only included
ModellingRule=None children when they were ObjectDesign instances
(state machine states/transitions). This excluded Variables and
Methods that are explicitly defined on types without a modelling
rule, such as:
- ConditionType.ConditionRefresh (Method)
- ConditionType.ConditionRefresh2 (Method)
- ConditionType.SupportsFilteredRetain (Variable)
- ProgramStateMachineType.Creatable (Variable)
- Various TrueState/FalseState display-hint properties
Remove the ObjectDesign restriction so all explicitly defined
type-level children with ModellingRule=None are included in the
generated address space. This adds ~52 previously missing nodes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* plans: update report after ModellingRule=None generator fix
Type-level children dropped from 261 to 203 (-58) after fixing the
source generator to emit Variables and Methods with ModellingRule=None.
Total 'other' reduced from 335 to 283. No fixes needed for any
remaining nodes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* plans: all 203 type-level children confirmed present via Read
Verified all 203 'type-level children' exist in the server (none
return BadNodeIdUnknown). They return Good, BadUserAccessDenied,
or BadSecurityModeInsufficient -- all confirming the node exists
but is access-restricted for anonymous users.
All 1,316 export-missing nodes are now accounted for. Zero nodes
are actually missing from the server address space.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix CttTestRunner session service methods for CTT JS script compatibility
- Implement ServiceCreateSession with real Session.CreateAsync connection
- Implement ServiceActivateSession with proper response fields
- Implement ServiceCloseSession with session cleanup
- Fix UaSession constructor to provide service methods via CreateServiceObject
- Convert all type constructors from ClrFunction to JS functions for 'new' support
(Jint 4.x ClrFunction does not support [[Construct]])
- Add UaChannel.connect/disconnect stubs for OpenSecureChannel flow
- Add UaDiscovery with getEndpoints/findServers from discovery session
- Add missing types: UaSubscriptionDiagnosticsDataType, UaHistoryUpdateResult, etc.
- Add missing enums: IdentifierType, Constants (DateTime/numeric limits)
- Add UaPkiCertificate.fromDER, UaByteString.fromStringData, PkiType, UaPkiUtility
- Add UaDateTime.Now constructor, equals/msecsTo methods
- Add UaStatusCode with isGood/isBad/isUncertain as JS constructor
- Fix response headers with Timestamp (UaDateTime), ServiceDiagnostics, StringTable
- Fix endpoint descriptions with Server, UserIdentityTokens, ServerCertificate
- Add CreateResponseHeader helper for consistent response header construction
- Override warnOnce.js loggers to avoid Function.caller incompatibility
- Add stopTest, checkResourceError (lowercase) global functions
- Add UaOpcServer constructor with all method stubs
- Handle JS parse errors in include() for malformed CTT files
- Test.Connect() now calls InstanciateHelpers with DiscoverySession
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add CttTestRunner: .NET replacement for CTT JavaScript host environment
Implements a Jint-based JavaScript engine that can execute the OPC Foundation's
Compliance Test Tool .js test scripts using the OPC UA .NET Standard stack.
Features:
- Parses CTT .ctt.xml project files (Qt AbstractItemModelData format)
- Loads and resolves CTT include() dependency chains (~100 library files)
- Registers ~250 Ua* type constructors for JavaScript
- Implements session.read/write/browse/getEndpoints/findServers
- Provides all OPC UA enumerations, NodeId constants, Assert methods
- CLI with --list, --file, --conformance-unit, --result, --json flags
- Headless operation for agent/CI integration
Current status: Framework connects to OPC UA server and loads CTT test
infrastructure. Session establishment flow needs additional property
compatibility for CreateSession/ActivateSession request objects.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: do not apply DefaultAccessRestrictions/DefaultRolePermissions to type definitions
ObjectType and VariableType nodes should never have access
restrictions or role permissions from DefaultAccessRestrictions/
DefaultRolePermissions. These defaults are meant to apply to
instances of the type, not to the type definition node itself.
Previously, CertificateGroupType, TrustListType, SecurityGroupType
and other types were incorrectly emitted with AccessRestrictions
inherited from their DefaultAccessRestrictions, making them
unreadable without encryption even though the spec defines no
restrictions on these type definitions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* CttTestRunner: fix session establishment flow
- Fix constructor patterns (new/no-new dual call support)
- Fix ResponseHeader with ServiceDiagnostics/StringTable
- Populate ServerNonce, ServerCertificate, ServerEndpoints in CreateSession response
- Add UaVariant setter methods (setNodeId/setString/setBoolean/etc.)
- Add UaCreateSessionRequest/ActivateSessionRequest with proper nested structures
- Fix UaPkiUtility/UaPkiCertificate with Thumbprint/toDERFile/loadCertificateFromFile
- Add missing enums: PerformUpdateType, SecurityPolicy, StructureType, etc.
- Add HostInfo, Bit helper, KeyPairCollection, ExpectedAndAcceptedResults
- Add _error.store(), MessageSecurityMode.toString()
Status: Session creates successfully, CreateSession validation runs,
hits validateCertificate in PKI chain (next to implement).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* plans: update report after DefaultAccessRestrictions type definition fix
ObjectTypes no longer have incorrect access restrictions. Type
children reduced from 203 to 164 (39 now visible). Total export-
missing reduced from 1316 to 1146. Remaining 164 type children are
individual methods/variables with spec-correct access restrictions.
Two source generator fixes applied:
- ModellingRule=None children for Variables/Methods
- DefaultAccessRestrictions not applied to ObjectType/VariableType
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* CttTestRunner: fix PKI, cert validation, warnOnce, session response
- Intercept warnOnce.js with Jint-compatible replacement (no Function.caller)
- Add _log.store() global helper
- Add HOSTNAMES/HostnameFromUrl helpers for cert hostname validation
- Add UaPkiCertificate properties: PublicKey, Issuer, Subject, KeyUsage, Hostnames
- Add UaPkiUtility.validateCertificate stub
- Add UaByteString static helpers: FromByteArray, ToByteArray, fromHexString
- Use JS UaNodeId constructor for proper equals() support
- Fill AuthenticationToken and 32-byte ServerNonce in CreateSession response
- Add clone/append to ByteString objects
Session flow: CreateSession validates, ActivateSession reached, hits
Channel.ServerCertificate.clone() (IsSecure check — next to fix).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* CttTestRunner: complete session establishment, crypto stubs, ByteString helpers
- Add _makeByteString() helper for consistent ByteString objects with clone/append/isEmpty
- Add UaCryptoProvider with asymmetricSign/Verify stubs
- Add UaExtensionObject setter methods (setAnonymousIdentityToken, etc.)
- Fix UaChannel with full properties (RequestedSecurityPolicyUri, IsSecure, etc.)
- Fix duplicate type registrations overriding custom constructors
- Fix ActivateSession response header with ServiceDiagnostics
- Remove UaCreateSessionResponse/ActivateSessionRequest/CloseSessionRequest duplicates
Status: Full session lifecycle works (GetEndpoints → OpenSecureChannel →
CreateSession → ActivateSession). Test scripts execute and hit server
capabilities initialization (MonitoredItem NodeId settings configuration).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* update
* plans: add spec references for access restriction reasoning
Added links to Part 3 sections 5.2.9, 5.2.11, and 6.3.3 explaining
why DefaultRolePermissions are applied to instance children but not
to type definitions. The NodeSet2.xml has no explicit RolePermissions
on these 164 nodes -- restrictions come from model design defaults.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: add GDS project references to ConsoleReferenceServer Dockerfile
Add Opc.Ua.Gds.Common and Opc.Ua.Gds.Server.Common csproj COPY
lines to the Docker restore layer, required since the GDS node
manager was added to the ConsoleReferenceServer.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* update
* feat: add IsPartOfTypeHierarchy flag to bypass access restrictions on types
Type hierarchy nodes (ObjectType/VariableType definitions and their
children) should be universally accessible regardless of
AccessRestrictions and RolePermissions.
Changes:
- Add IsPartOfTypeHierarchy property to NodeState
- Set flag on ObjectType/VariableType in generated code (!forInstance)
- Propagate flag from parent to children in AddPredefinedNode
- Add flag to NodeMetadata, propagate in GetPermissionMetadata
- Bypass ValidateRolePermissions and ValidateAccessRestrictions
when IsPartOfTypeHierarchy is true
- Revert isTypeDefinition guard: AccessRestrictions and
RolePermissions are now emitted on all nodes as metadata,
but enforcement is skipped for type hierarchy nodes
- Fix forInstance propagation in type factories: use
forInstance: forInstance for type children so deep children
(TrueState/FalseState etc.) are included when !forInstance
Type-level missing nodes reduced from 201 to 99. Remaining 99 are
in the server but not reachable by the export tool's browse path.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* plans: update report with final IsPartOfTypeHierarchy results
Missing from export reduced to 998 (from 1325 original).
Type children: 201 -> 99 (forInstance propagation fix).
All nodes verified present via OPC UA Read.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: propagate IsPartOfTypeHierarchy in GetNodeMetadataAsync
The Browse service's per-reference ValidateRolePermissionsAsync
calls GetNodeMetadataAsync (not GetPermissionMetadataAsync). The
IsPartOfTypeHierarchy flag was only set in GetPermissionMetadataAsync,
causing type hierarchy nodes to be filtered out of Browse results.
This fixes 99 ObjectType children that were previously invisible
in Browse from their parent types. Type-level missing: 99 -> 0.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* plans: final report -- 0 type-level children missing (694 total)
Type-level missing: 99 -> 0 after fixing IsPartOfTypeHierarchy
propagation in GetNodeMetadataAsync. Total export-missing: 694
(384 encoding + 236 access-restricted + 74 instance/orphan).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* update
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Enhance role-based access control and add permission tests
- Improve ValidateRolePermissions logic and add ILogger support for detailed access denial logging
- Expand default roles (add AuthenticatedUser, TrustedApplication)
- Refine RoleBasedIdentity to merge roles and avoid duplicates
- Set UserIdentity default GrantedRoleIds to Anonymous
- Fix MasterNodeManager PrepareValidationCache
- Add comprehensive unit tests for role permission validation and logging
* Fix GDS self-admin role: restore NodeId.Null in GrantedRoleIds for ApplicationSelfAdmin
The RoleBasedIdentity constructor was filtering out roles with null RoleIds
(!role.RoleId.IsNull), which broke the GDS ApplicationSelfAdmin mechanism.
The GDS OnAddSelfAdminUserRolePermissions relies on GrantedRoleIds.Contains(NodeId.Null)
to detect self-admin users (since GdsRole.ApplicationSelfAdmin has RoleId = ExpandedNodeId.Null).
Also remove unused System.Data using statement.
Agent-Logs-Url: https://github.com/OPCFoundation/UA-.NETStandard/sessions/3db86efa-c6d6-4e63-947f-156a88210b58
Co-authored-by: romanett <7413710+romanett@users.noreply.github.com>
* fix build
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: romanett <7413710+romanett@users.noreply.github.com>
* Refactor MonitoredItem.ValueChanged & cert validation
Refactored MonitoredItem.ValueChanged for correctness, performance, and comprehensive test coverage, including improved deadband and array handling. Rewrote equality logic for Variants and arrays. Made certificate validation thread-safe using ConcurrentDictionary and proper semaphore usage. Added extensive unit tests and benchmarks for value change detection.
* Implement DiagnosticsNodeManager using AsyncCustomNodeManager
* Implement CoreNodeManager using AsyncCustomNodeManager
* Use Interfaces Introduced with 1.5.378
Refactor to use interfaces for node managers and server
Replaced concrete types with interfaces (e.g., IMasterNodeManager, ICoreNodeManager, IDiagnosticsNodeManager, IConfigurationNodeManager, IServerBase) across method signatures, properties, and internal structures to improve abstraction and flexibility.
* Refactor CoreNodeManager to be Based on CustomNodeManager2
* Add Test
* Add INodeManager3 with role permission validation
Introduce INodeManager3 interface extending INodeManager2, adding synchronous role permission validation methods. Update all node manager interfaces and classes to use INodeManager3. Extend IAsyncNodeManager with async permission validation methods and update adapters for sync/async bridging. Deprecate FindNodeInAddressSpace in favor of new async FindNodeInAddressSpaceAsync. Refactor MonitoredNode2 to use thread-safe collections and locking for monitored items. Enhance event reporting with security and permission checks. Update constructors and documentation to reflect new interfaces and best practices.
* Implement AsyncCustomNodeManager
* fix comment
* fix
* Add tests
* fix
* Implement better locking strategy
* fix
* Add more tests
* Add tests
* Add tests
* Add Tests
* cleanup
* cleanup
* Add tests that verifies for AnalogItemState the instrument range is checked brefore writing
* only assign new NodeID in default factory if NodeId isNull
* Run all tests also with sampling groups
* Add Docs
* cleanup
* Add chaos test
* fix test
* Use AsyncCustomNodeManager for ReferenceNodeManger & imrpove ReadAttributes method of NodeState
* fixes
* fixes and code review comments
* Use Interfaces Introduced with 1.5.378
Refactor to use interfaces for node managers and server
Replaced concrete types with interfaces (e.g., IMasterNodeManager, ICoreNodeManager, IDiagnosticsNodeManager, IConfigurationNodeManager, IServerBase) across method signatures, properties, and internal structures to improve abstraction and flexibility.
* Refactor CoreNodeManager to be Based on CustomNodeManager2
* Add Test
* Add INodeManager3 with role permission validation
Introduce INodeManager3 interface extending INodeManager2, adding synchronous role permission validation methods. Update all node manager interfaces and classes to use INodeManager3. Extend IAsyncNodeManager with async permission validation methods and update adapters for sync/async bridging. Deprecate FindNodeInAddressSpace in favor of new async FindNodeInAddressSpaceAsync. Refactor MonitoredNode2 to use thread-safe collections and locking for monitored items. Enhance event reporting with security and permission checks. Update constructors and documentation to reflect new interfaces and best practices.
* fix comment
* fix
* Use Interfaces Introduced with 1.5.378
Refactor to use interfaces for node managers and server
Replaced concrete types with interfaces (e.g., IMasterNodeManager, ICoreNodeManager, IDiagnosticsNodeManager, IConfigurationNodeManager, IServerBase) across method signatures, properties, and internal structures to improve abstraction and flexibility.
* [Server] Refactor CoreNodeManager to be based on CustomNodeManager2 (#3552)
* Refactor CoreNodeManager to be Based on CustomNodeManager2
* Add Test
* Revert "[Server] Refactor CoreNodeManager to be based on CustomNodeManager2 (#3552)"
This reverts commit bb1d868c81.
Generate stack and application code using source generators
Change built in types to readonly structs
Update localized text implementation to use JSON text serializer
Status code with symbolic names
Immutable node ids
No boxing for all built in types <= 8 bytes in Variant.
Split user identity token and token handling via token handler
Add migration guide for breaking changes
This pull request modernizes the OPC UA .NET codebase and tests, removes .NET Standard 2.0 support from certificate/security code, and updates test code to use C# 12 and .NET 8+ features for clarity and maintainability.
- Certificate and BouncyCastle interop files (e.g., CertificateBuilder.cs, X509Extensions.cs, X509SignatureFactory.cs) are refactored to drop NETSTANDARD2_0 support and use modern .NET APIs and conditional compilation.
- Test code across the codebase is updated to use default, strongly-typed Parse methods, collection expressions, and improved async/await patterns.
- Exception handling and assertions in tests are modernized, and test method naming is made consistent with Async suffixes.
- The project and build files are updated to clarify Roslynator analyzer usage and remove obsolete netstandard tags.
- General code and test cleanup includes improved null safety, type safety, and removal of deprecated or unused code.
Refactor to make OPC UA server subscription and monitored item management fully asynchronous, improving scalability and responsiveness. All key methods in ISubscription, ISubscriptionManager, and related classes are now async, with synchronous counterparts removed.
* Improve thread safety and logging in MonitoredItem
Replaced Queue with ConcurrentQueue in MonitoredItemDataCache
for thread-safe operations. Updated Publish method to use
List<DataValue> for better handling of dequeued values. Enhanced
logging to include SourceTime and added logs for dropped values.
In DurableSubscriptionTest, added try-finally block to ensure
proper session closure and disposal, preventing memory leaks.
Introduced DurableSubscriptionTestLooper for stress testing
under debug mode. Refactored test code for improved readability.
* Improve logging and session management
Updated logging in `Session.cs`, `ServerBase.cs`, and `UaSCBinaryClientChannel.cs` to pass exceptions directly to the logger, enhancing error handling. Added connection state checks in `Session.cs` to prevent operations when the session is closed or never connected. Updated `Subscription.cs` to reflect session disconnection in `PublishingStopped`. Enhanced test outputs and renamed `DurableSubscriptionTestLooper` to `DurableSubscriptionTestDebug` in `DurableSubscriptionTest.cs`, reducing loop count for faster debug testing.
* Fix monitored item id factory producing collisions by first trying to allocate a free monitored item id in the table, then committing.
* Better diffing
* Enhance logging and session management
Added detailed logging in `AlarmNodeManager.cs` for lifecycle events and simulation control. Introduced a `Reconnecting` property in the `ISession` interface and `Session.cs` to manage session reconnection state, replacing the `m_reconnecting` field. Enhanced logging in `Session.cs` for reconnection and publish operations. Updated `DataGenerator.cs` to use `FrozenDictionary` for performance improvements. Replaced `SyncRoot` with `m_syncRoot` in `NamespaceTable.cs` for synchronization. Improved exception message formatting in `ServiceResult.cs`. Added necessary namespaces for new data structures. Made corrections and added debugging in `DurableSubscriptionTest.cs` for better session handling.
* Dispose simulation
* Implement management Methods from INodeManager & INodeManager2 into IAsyncNodeManager
Refactor MasterNodeManager to allow access to IAsyncNodeManager from NodeManagers & NamespaceManagers Properties
* Use Async methods in MasterNodeManager
* Update ReferenceServerWithLimits
* remove obsolete sync code and expose sync nodeManager
---------
Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
* Implement support for async method Call in the server
* Implement Cancellation
* Add new generated async supported Endpoints & Server Methods
* Make SecureChannelContext AsyncLocal
* Implement SubscriptionAsync
* Add Async Request Queue
* Implement sync calls for async NodeManagers. Add Warning
* Use second file for Async Interface