# Description
Implements the OPC UA Part 12 §7.10.9 contract on the server (fixes
#3562) AND the client-side counterpart for immediate detection of
own-cert / trust-list / CRL changes (fixes#3160).
## Server side (#3562)
Per Part 12 §7.10.9 the server _shall_ "force existing SecureChannels
affected by the changes to renegotiate" once the `ApplyChanges` method
response has been delivered. Previously the server reloaded the
certificate but did not cut affected channels; clients kept using the
old cert until natural rekey, and the code carried an explicit `TODO`
next to a 1-second `Task.Delay` hack in
`ConfigurationNodeManager.ApplyChanges`.
Key server changes:
* **New optional capability interface**
`Opc.Ua.ITransportListenerCertificateRotation` (single method
`CloseChannelsForCertificate(Certificate)`) — implemented by
`TcpTransportListener` and `HttpsTransportListener`. Custom transport
listeners can opt in without breaking `ITransportListener`.
* **TCP path**: new internal
`TcpListenerChannel.TryCloseForCertificateRotation(oldThumbprint, out
globalChannelId)` matches the channel's negotiated `ServerCertificate`
by thumbprint, sends `BadCertificateInvalid`, and calls
`ChannelFaulted()` to actually close the socket.
`TcpTransportListener.CloseChannelsForCertificate` snapshots
`m_channels` outside `m_lock` to avoid lock inversion, invokes the
per-channel helper, returns cut global channel ids. **The listener
socket stays bound** — clients can reconnect immediately.
* **HTTPS path**: HTTPS owns the cert at the Kestrel/HTTP.sys listener
level, so a `Stop()`+`Start()` cycle is the only practical
force-renegotiate. Moved out of `CertificateUpdate` (which now does only
the soft fan-out) into `CloseChannelsForCertificate` so the staging
event no longer disrupts in-flight requests prematurely.
* **`ConfigurationNodeManager.ApplyChanges`** rewritten:
- Captures the per-group pre-transaction certificate (preserved across
multi-stage transactions per Part 12 §7.10.2) and the staged
`UpdateCertificateData`.
- Schedules a deferred apply: waits for the response to flush, re-syncs
the registry via `CertificateManager.UpdateAsync`, then calls
`CloseChannelsForCertificate` on every listener that implements the
capability.
- **Configurable grace period**: new
`IConfigurationNodeManager.ApplyChangesGracePeriod` (default 250 ms,
negative clamped to zero). Hosts running over higher-latency
administrative links can raise it.
- Exposes
`IConfigurationNodeManager.DrainPendingApplyChangesAsync(CancellationToken)`
for tests/hosts to deterministically await rotation.
- Removes the explicit 1-second `Task.Delay` TODO hack.
* **`Opc.Ua.Server.ITransportListenerRegistryProvider`** — narrow opt-in
interface on `ServerInternalData` exposing the live transport listener
list. Lets `ConfigurationNodeManager` drive the fan-out without
expanding `IServerInternal` (binary compat for mocked test fixtures).
* **Sessions are NOT closed**. Per spec, the cut is on the SecureChannel
only; existing `Session.IsSecureChannelValid` + `Session.Activate`
rebind handles transfer over the new channel.
## Client side (#3160)
The client SDK previously had no automatic detection of changes to its
own certificate, trust list, or CRL — users had to call
`Session.ReloadInstanceCertificateAsync` manually and trigger a
reconnect. The spec-mandated `ApplicationCertificateUpdated`,
`TrustListUpdated`, and `CrlUpdated` enum values existed but only the
first was being emitted by `CertificateManager`.
Key client/shared changes:
* **`CertificateManager` now emits `TrustListUpdated` and `CrlUpdated`**
from `WriteTrustListAsync` (per mask) and from
`TrustListTransaction.CommitAsync` (after the atomic apply). The new
internal `NotifyTrustListChanged` also invalidates cached
peer/user/HTTPS validation cores so subsequent validations pick up the
fresh trust state.
* **`ManagedSession.AutoReconnectOnCertificateChange`** opt-in property
(default `false` for backwards compat). When `true`, `ManagedSession`
subscribes to `CertificateManager.CertificateChanges` on construction
and, on the three relevant kinds:
- Calls `Session.ReloadInstanceCertificateAsync` on
`ApplicationCertificateUpdated` so the next ActivateSession is signed
with the rotated client cert.
- Triggers a reconnect via the state machine so the new state is
honoured within milliseconds rather than at the next
`SecurityTokenLifetime` rekey.
* **`ManagedSession.ApplicationCertificateChanged`** event surfaces
every observed change regardless of the auto-reconnect policy for
diagnostics or custom rotation logic.
* Subscription is disposed by the existing `Dispose` / `DisposeAsync`
paths.
```csharp
using var managed = await ManagedSession.CreateAsync(
configuration, endpoint, sessionFactory);
managed.AutoReconnectOnCertificateChange = true;
managed.ApplicationCertificateChanged += (sender, e) =>
{
Console.WriteLine($"observed {e.Kind} on {e.TrustList}");
};
```
## Tests
| Suite | net10.0 | net48 |
|---|---|---|
| `TransportListenerCertificateRotationTests` (new, 6 tests) | ✅ | ✅ |
| `CertificateManagerTests` (4 new event tests) | ✅ 22/22 | ✅ 4/4 |
| `PushCertManagement` | 50/53 ✅ | 50/53 ✅ |
| `GDS PushTest` (focused subset) | 15/15 ✅ | 16/16 ✅ |
| `Opc.Ua.Server.Tests` (focused subset) | 38/38 ✅ | 38/38 ✅ |
| `GDS PushTest` (full) | 313/338 ✅ | — |
Skips are pre-existing (cert-type mismatches, optional methods) — no
regressions.
New integration test
`PushTest.ApplyChangesForcesChannelRenegotiateAsync` positively asserts
the stale channel fails with a recognized channel-invalidation status
after `ApplyChanges`, and that a fresh reconnect succeeds with the
rotated cert.
## Documentation
- `Docs/CertificateManager.md` — new sections:
- "Server-Side Certificate Rotation via Push (OPC UA Part 12 §7.10.9)" —
`ITransportListenerCertificateRotation` contract + custom listener
example.
- "Client-Side Auto-Detection of Certificate Changes (issue #3160)" —
`AutoReconnectOnCertificateChange` + `ApplicationCertificateChanged`
event + the three covered scenarios.
## Related Issues
- Fixes#3562
- Fixes#3160
## 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.
- [x] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce (new) build or
analyzer warnings.
- [x] I ran focused tests locally using the **UA.slnx** projects against
.net **framework 4.8** and .net **10**, and all passed. _(Full UA.slnx
test run delegated to CI.)_
- [ ] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [ ] I have addressed **all** PR feedback received.
# Description
Fixes four CTT (OPC UA Compliance Test Tool) conformance gaps that the
existing NUnit parity suite was silently passing while the CTT JS
scripts kept failing:
| Issue | Area | Failing CTT script |
|---|---|---|
| #3719 | Base Info Core Structure 2 | `001.js` |
| #3720 | Base Info FiniteStateMachine + StateMachine Instance |
`initialize.js` + `001.js` |
| #3723 | Security None | `007.js` (DoS, partially used channels) |
| #3841 | Alarms & Conditions | Acknowledge Test_003, Alarm Test_002,
Confirm Test_001 / Test_003 / Err_004, Enable Test_002, Non-Exclusive
Limit Test_002 |
Across all four, the underlying pattern was the same — the NUnit parity
tests were checking weaker invariants (DataType attribute instead of
encoded Variant BuiltInType; `Assert.Ignore` instead of `Assert.Fail`;
stub `GetEndpoints` instead of the real DoS scenario; method-call + Read
instead of subscribe-and-validate-event-payload). So the suite gave
false confidence on changes that would have failed CTT. Each commit
below both **strengthens the NUnit parity test** to encode the same
invariant CTT verifies, **and** fixes the server/model defect that the
strengthened test surfaces.
## Commits
### `a1db2984c` Fix#3719 (BaseInfoCoreStructure)
- **Test**: `BaseInfoServerTests.ReadConformanceUnitsAsync` now reads
the **value** of `i=24101` and asserts
`WrappedValue.TypeInfo.BuiltInType == BuiltInType.QualifiedName` AND
`ValueRank == ValueRanks.OneDimension` — not just the DataType
attribute.
- **Test**: `BaseInformationTests.BrowseRequiresMandatoryMethodsAsync`
now `Assert.Fail`s (not `Assert.Ignore`) when an expected mandatory
method is missing on `i=15443` / `i=25440`.
- **Server**: `Server_ServerCapabilities_ConformanceUnits` initialised
with `Array.Empty<QualifiedName>().ToArrayOf()` so the encoded Variant
carries QualifiedName type info even when empty.
- **Server**: Added `AddSecurityGroup` / `RemoveSecurityGroup` (on
`i=15443`) and `AddPushTarget` / `RemovePushTarget` (on `i=25440`)
method nodes with input/output argument metadata and in-memory handlers
in `Quickstarts.Servers/ReferenceServerConfigurationNodeManager`.
### `86d3041e5` Fix#3723 (Security None DoS off-by-one)
- **Server**: Correct off-by-one in
`Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs` channel eviction:
- Condition was `MaxChannelCount == channelCount` (only triggered at
exact equality); now `MaxChannelCount > 0 && channelCount >=
MaxChannelCount` with a loop that evicts idle channels until the count
is below the limit or no more idle channels remain.
- **Server**: `UsedBySession` now properly tracks active sessions and
clears on `CloseSession` (`TcpServerChannel`, `TcpListenerChannel`).
- **Note**: the NUnit reproducer for this issue (`SecurityNoneDosTests`)
stays on the `cttunit` branch (PR #3750) because it depends on the
`TestFixture.CloseSharedFixtureSessionAsync` helper that only exists in
`Tests/Opc.Ua.Conformance.Tests/`. The server fix on this branch is
sufficient to make the CTT JS script pass.
### `2c98390c9` Fix#3720 (BaseInfoStateMachine GeneratesEvent)
- **Model**: Add `GeneratesEvent` forward reference on
`StateMachineType` (i=2299) and `FiniteStateMachineType` (i=2771) →
`AuditUpdateStateEventType` (i=2315) in the design XML
(`Tools/Opc.Ua.SourceGeneration.Core/Design/StandardTypes.xml`);
regenerated `Stack/Opc.Ua.Core/Schema/Opc.Ua.NodeSet2.xml`.
- **Server**: Remove the runtime workaround in `DiagnosticsNodeManager`
that previously injected this reference at load time — now redundant
because the reference ships in the NodeSet at compile time.
- **Test**: New
`BaseInfoStateMachineInstanceTests.StateMachineTypeHasGeneratesEventReferenceAsync`
walks the type hierarchy looking for `GeneratesEvent` with
`IncludeSubtypes=true` and asserts the target resolves to a
`BaseEventType` subtype (matches the CTT walk).
- Per OPC UA Part 16 §4.4.5 / Part 5 §6.4.2.
### `09f551449` Strengthen A&C conformance event tests (#3841)
- **Test fixture**: New `AlarmEventCollector` (476 LOC) — subscribes to
events on `i=Server` with a full A&C event filter (`Comment`, `Retain`,
transition times, all condition-state Ids); per-condition event log;
`WaitForEventAsync(conditionId, predicate, timeout)` for
synchronisation. Uses async `IAsyncDisposable` cleanup.
- **Tests rewritten** to subscribe to events and validate event payload
(`Comment.Text`, `Retain`, `TransitionTime`):
- `Acknowledge Test_003` — empty comment + locale propagates to event
payload; `Retain=false` afterwards
- `Alarm Test_002` — full `ActiveState` cycle Active → Normal with
Acknowledge + Confirm; every transition event validated
- `Confirm Test_001` — unique comment reaches event payload;
`ConfirmedState/Id=true`
- `Confirm Test_003` — Acknowledge → wait event → Confirm with empty
comment
- `Confirm Err_004` — **two concurrent sessions**; second Confirm
asserts specifically `BadConditionBranchAlreadyConfirmed` (not a generic
`BadInvalidState`)
- `Enable Test_002` — Disable + Enable via both type method and
discovered instance method; NO events during disabled period;
`TransitionTime` within call window; `Retain` flips
- `Non-Exclusive Limit Test_002` — mirror for
`NonExclusiveLimitAlarmType`
- **Server fixes** in
`Stack/Opc.Ua.Core.Types/State/AcknowledgeableConditionState.cs`,
`Quickstarts.Servers/Alarms/AlarmHolders/*`, and `AlarmNodeManager` for:
Comment propagation, Retain clearing, TransitionTime updates, and a
dedicated ack-only condition instance
(`AcknowledgeableConditionHolder`).
## Verification
- `dotnet build UA.slnx` — **0 errors**, 42 pre-existing warnings.
- `dotnet test Tests/Opc.Ua.InformationModel.Tests` filtered for the new
+ master `StateMachineGeneratesEvent` / `BaseInfoServer` /
`BaseInformation` tests — **6/6 pass**.
- `dotnet test Tests/Opc.Ua.History.Tests --filter AlarmsAndConditions`
— **141/144 pass**; the 3 occasional failures in
`DisableEnableViaTypeAndInstanceMethodNoEventsDuringDisabledAsync` pass
when re-run in isolation, consistent with the known A&C suite CI
flakiness pattern.
## Related Issues
- Fixes#3719
- Fixes#3720
- Fixes#3723
- Fixes#3841
Related: PR #3750 (`cttunit`) carries the same fixes plus the
conformance-test-project versions of the strengthened NUnit tests.
Either this PR or that one will land first; the other should be rebased
afterwards.
## 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.
- [ ] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce (new) build or
analyzer warnings.
- [x] 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.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
# Description
Adopt
[`System.TimeProvider`](https://learn.microsoft.com/dotnet/api/system.timeprovider)
across the stack so that every place that creates timers, runs duration
math, or schedules periodic work is mockable, deterministic in tests,
and immune to wall-clock changes.
The migration touches Core, Core.Types, Server, Client, PubSub,
Configuration, Gds (server + client), Lds, and the Quickstarts/Console
reference apps. Per-component changes follow the same pattern:
1. Add a `private readonly TimeProvider m_timeProvider;` field.
2. Accept a nullable `TimeProvider? timeProvider = null` as the **last**
constructor parameter (new overload; legacy constructor stays for binary
compatibility and delegates with `timeProvider: null`).
3. Initialise the field with `m_timeProvider = timeProvider ??=
TimeProvider.System;`.
4. Replace `new Timer(...)`, `Stopwatch`, `HiResClock.*`,
`DateTime.UtcNow`-based duration math, and `Task.Delay(delay, ct)` in
timing loops with the matching `m_timeProvider` API (`CreateTimer`,
`GetTimestamp` / `GetElapsedTime`, `GetUtcNow().UtcDateTime`,
`Task.Delay(delay, m_timeProvider, ct)`).
5. Wire the provider through DI: `AddOpcUaServerBuilder` /
`AddOpcUaClientBuilder` register `TimeProvider.System` via
`TryAddSingleton<TimeProvider>()` so tests can swap in
`Microsoft.Extensions.Time.Testing.FakeTimeProvider`.
`HiResClock` itself is kept (so the
`ApplicationConfiguration.DisableHiResClock` schema flag still
round-trips), but **every public member** is now `[Obsolete]` with a
single shared message pointing to the new migration-guide section. The
few internal call sites that still need to set/read `HiResClock` are
wrapped with `#pragma warning disable CS0618`.
### Highlights per component
- **Core / Stack** — `Opc.Ua.Core`, `Opc.Ua.Core.Types`, channel
pipeline (`UaSCBinaryClientChannel`, `ChannelToken`,
`UaSCBinaryChannel`), `ApplicationConfiguration`, certificate
validators, `JwksIssuerKeyResolver`, `TimeProviderExtensions` polyfills
(`GetTimestampMilliseconds`, `GetTickCount`,
`CancellationTokenSource(timeout, timeProvider)`, `Task.Delay(delay,
provider, ct)` polyfill for older TFMs).
- **Server** — session lockout, subscription pipeline
(publish/sample/keep-alive/lifetime), `MonitoredItemQueue`, alarm
sampling rate, `IntervalRunner`, server diagnostics, configuration state
machines, hosted services.
- **Client** — `Session`, managed/V2 subscription engines, reconnect
handlers, channel keep-alive, periodic publishing, complex-type
discovery polling.
- **PubSub** — `IntervalRunner` pipeline, message-receive timers,
MQTT/UDP keep-alive, publishers/readers.
- **Gds / Lds** — `LdsServer`, `LinqApplicationsDatabase` expiry
housekeeping, GDS clients (push, pull), `DirectoryCertificateStore`,
`ConnectionStateMachine`, classic subscription engine.
- **Quickstarts / Console samples** — `SampleNodeManager`,
`ReferenceNodeManager`, `AlarmNodeManager`, `BoilerState`,
`MemoryBufferState`, `PublishedValuesWrites`. Samples resolve via
`(Server as ITimeProviderProvider)?.TimeProvider ?? TimeProvider.System`
so existing ctor signatures stay binary-compatible.
- **Tests** — `Opc.Ua.PubSub.Tests` adds `IntervalRunnerTests`; existing
`SubscriptionTests`, `UaPublisherTests`, and `TestDataSystem` move off
`HiResClock`. Added `Microsoft.Extensions.TimeProvider.Testing` package
for `FakeTimeProvider` (project-load warning surfaces on net48/net472
only — runtime is .NET 8+).
### Migration guide
New section [**Time and Timer abstraction
(`TimeProvider`)**](Docs/MigrationGuide.md#time-and-timer-abstraction-timeprovider)
documents:
- The canonical replacement table (`HiResClock.UtcNow` →
`timeProvider.GetUtcNow().UtcDateTime`, `HiResClock.TickCount64` →
`timeProvider.GetTimestamp()`, `new Timer` → `timeProvider.CreateTimer`,
`Task.Delay(delay, ct)` → `Task.Delay(delay, timeProvider, ct)`, …).
- The `TimeProvider? timeProvider = null` + `??=` constructor pattern.
- DI wiring and how to swap in `FakeTimeProvider` in tests.
- Before/after snippets for `HiResClock.TickCount64`,
`HiResClock.UtcNow`, and `new Timer(...)`.
## Related Issues
- Fixes#2458
## Checklist
- [x] 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.
# Description
Introduces a pluggable user-identity provider model covering all OPC UA
Part 6 §6.5 mechanisms (Anonymous, UserName, X509, IssuedToken/JWT) on
both client and server, with full
`Microsoft.Extensions.DependencyInjection` integration, plus the Part 12
§9 `AuthorizationService` two-phase token-request flow **including
refresh-token rotation**, the Part 12 §8 KeyCredential Push model, and a
clean provider model for OPC 10000-12 §7.2 `ApplicationSelfAdmin`. The
work is split across phase-by-phase commits so it can be reviewed
independently; nothing here changes wire-level behaviour or forces
existing applications to migrate.
### Documentation
All under `Docs/`:
- `IdentityProviders.md` — full developer guide: three-layer model,
recipes, configuration reference, "what gets auto-wired" matrix, JWS
algorithm table, identity-augmenters section, **"Implementing your own
provider"** how-to subsections for Entra / OIDC / Windows / AspNetCore
(sibling files merged in per review feedback).
- `DependencyInjection.md` — `Identity` sections with `appsettings.json`
examples, identity-extension matrix, `WithAuthorizationService` +
`WithKeyCredentialPush` + `AddIdentityAugmenter` extensions documented.
- `RoleBasedUserManagement.md` — claim-criteria callout describing
`IIdentityClaims` probe surface.
- `AuthorizationService.md` — Architecture diagram +
`IAccessTokenProvider` conceptual narrative restored from master; modern
`StartRequestToken` / `FinishRequestToken` flow leads; refresh-token
recipe added.
- `KeyCredentialService.md` — Push model + Pull vs Push vs Bridge
decision matrix + Hybrid (Push + Pull) section; explicit experimental
warning for the bridge.
- `GDS.md` — KeyCredential Push, `StartRequestToken`,
`GdsApplicationSelfAdminProvider`, **shipped Refresh-token support with
rotation policy and audit semantics** all documented.
- `MigrationGuide.md` — User Identity Providers section listing
`[Obsolete]` markers + mechanical recipes; SelfAdmin migration via
`IIdentityAugmenter`; `EnableRefreshTokens` default note.
- `README.md` index entries.
## Checklist
- [x] 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.
- [x] I ran **all** tests locally using the **UA.slnx** solution against
at least .net **framework** and .net **10**, and all passed.
- [x] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [x] 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.
## Proposed changes
Implements **OPC UA Part 11 (Historical Access)** end-to-end via a clean
**provider model** that lets servers back historizing variables with any
time-series storage engine. A reference-quality **in-memory engine**
ships in `Opc.Ua.Server` so getting started requires no extra packages.
The implementation replaces the legacy `HistoryArchive` /
`HistoryDataReader` / `HistoryFile` / `IHistoryDataSource` files
(removed from `Quickstarts.Servers/TestData/`) with a stack-level Part
11 surface.
### What's new
- **Server provider model** in `Libraries/Opc.Ua.Server/Historian/`:
- Umbrella `IHistorianProvider` + narrow capability interfaces
(`IHistorianDataProvider`, `IHistorianModifiedProvider`,
`IHistorianAtTimeProvider`, `IHistorianProcessedProvider`,
`IHistorianAnnotationProvider`, `IHistorianEventProvider`,
`IHistorianTransactionalProvider`).
- `HistorianDispatcher` — routes HistoryRead / HistoryUpdate (raw,
modified, at-time, processed, events, annotations) including
event-`WhereClause` evaluation via the framework's `FilterEvaluator`,
audit-event reporting, and continuation-point lifecycle.
- `HistorianProviderRegistry` with Node → Namespace → Default
precedence; surfaced via `IHistorianRegistryProvider` on
`ServerInternalData`.
- Fluent `HistorianBuilder`
(`server.UseHistorian().UseInMemory().Historize(...).RegisterAsDefault()`).
- Lazy `HistoricalDataConfigurationType` companion installer
(`OnPopulateBrowser`-attached).
- `ServerSystemContext` now exposes `IServerInternal Server { get; }` so
infrastructure code stops relying on the per-NM `SystemHandle`.
- **In-memory reference engine** (`InMemoryHistorianProvider`) — raw,
modified, processed via framework fallback, at-time via framework
fallback, annotations, events, transactional batches.
- **Client surface** in `Libraries/Opc.Ua.Client/Historian/`:
- `HistoryClient` with `IAsyncEnumerable<DataValue>`
raw/modified/at-time/processed/annotation reads (transparent
continuation-point handling and `try/finally`-based release on iterator
abandonment).
- `session.Historian()` extension.
- Capability discovery (`GetServerCapabilitiesAsync`,
`GetConfigurationAsync`).
- **Node-manager wiring** through both `AsyncCustomNodeManager` and
`CustomNodeManager2` (sync-via-dispatcher).
- **Capability rollup** — `DiagnosticsNodeManager` populates the
server-wide `HistoryServerCapabilities` as the union of registered
providers' `GetCapabilitiesAsync(NodeId.Null, ...)` (runs whether the
node was loaded from the predefined nodeset or freshly created; fully
async).
- **Audit-event reporting** for HistoryUpdate (gated on
at-least-one-success):
`AuditHistoryValueUpdateEventType`,
`AuditHistoryAnnotationUpdateEventType`,
`AuditHistoryRawModifyDeleteEventType`,
`AuditHistoryAtTimeDeleteEventType`, `AuditHistoryEventUpdateEventType`,
`AuditHistoryEventDeleteEventType`.
- **ReferenceServer + TestData** historize sample variables through the
new pipeline (replaces the deleted legacy `HistoryArchive`).
- **Comprehensive developer documentation** in
`Docs/HistoricalAccess.md` (~657 lines): server-developer guide,
provider-author guide, client-developer guide, capability discovery,
auditing, limitations/roadmap.
### Tests
| Suite | Files | Tests |
| --- | --- | --- |
| Server unit (Opc.Ua.Server.Tests/Historian) | dispatcher,
event-dispatcher, registry, in-memory provider, transactional provider,
concurrency, coverage, event-filter target | **34** passing |
| Client integration (Opc.Ua.Client.Tests/Historian) |
`HistoryClientIntegrationTests` over the live `ReferenceServer` via
`ServerFixture` | **4** passing |
| AOT (Opc.Ua.Aot.Tests/HistoryAotTests) | positive assertions against
historized `Scalar_Static_Int32` (read raw, read processed/Average) |
**2** passing |
### Local validation
- `dotnet build UA.slnx -c Release` → **0 errors**.
- All historian / client integration / AOT history tests **green**.
### Hardening applied post-internal-review
- `DiagnosticsNodeManager.RollUpHistorianCapabilitiesAsync` — true async
(no more `.GetAwaiter().GetResult()` on the startup path).
- `HistoryClient` raw/modified/details readers — `try/finally` releases
the in-flight continuation point on `break`/exception/cancellation; also
detects malformed-server empty-page loops.
- `ReportAudit*` helpers gated on `HasAnyGood(...)` — audit events do
not fire when every per-value op failed.
- `ServerSystemContext` ctors throw
`ArgumentNullException(nameof(server))` at the boundary.
- `HistorianEventFilterTarget.IsTypeOf` logs a one-shot warning when
`IFilterContext.TypeTree` is null (degrades safely instead of silently).
- `InMemoryHistorianProvider.ReadEventsAsync` snapshots under lock,
filters outside (cuts lock-hold time).
- `TryRestoreContinuation` rejects cross-wired continuation points
(different `NodeId`).
- Processed-read framework fallback capped at 100 000 buffered outputs
(`BadTooManyOperations` when exceeded).
- ReferenceServer / TestData seeding is async-awaited /
`Task.Run`-bridged to escape any captured `SynchronizationContext`.
## Related Issues
- Fixes #
## Types of changes
- [x] 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
- [x] Documentation Update
> The deletion of legacy
`Applications/Quickstarts.Servers/TestData/HistoryArchive*` is a
refactor of sample code only; the public stack surface is purely
additive.
## 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 (`Docs/HistoricalAccess.md`).
- [x] Any dependent changes have been merged and published in downstream
modules.
## Further comments
The provider model is intentionally minimal and orthogonal — providers
opt into specific Part 11 features by implementing one or more of the
narrow capability interfaces, and the dispatcher type-tests the concrete
provider at runtime. This keeps the bundled `InMemoryHistorianProvider`
simple while making it trivial for vendors to plug in their own
time-series database.
A few items remain explicitly deferred (documented in
`Docs/HistoricalAccess.md` *Limitations and roadmap*):
`HistoricalEventConfigurationType` auto-install for event notifiers,
audit-event `OldValues` fidelity (would require read-before-write across
update sites), true streaming processed-read continuation (the framework
fallback is bounded by the 100 k cap; native
`IHistorianProcessedProvider` providers already get arbitrary paging).
These are on-demand items, not gaps in the mandatory Part 11 surface.
Drive the solution to zero warnings / zero errors with analyzers on,
promote the consistently-fixed rules to error, and lock in coverage
on the only line of new logic.
* role management compliant with OPC UA Part 18
Server-side:
- New IRoleManager / RoleManager with spec-correct status codes
(Bad_AlreadyExists, Bad_NodeIdUnknown, Bad_RequestNotAllowed,
Bad_NotFound) for every mutator per Part 18 4.2 / 4.4.
- Pre-populate default identities for the three reserved well-known
roles per Part 18 4.3 (Anonymous, AuthenticatedUser,
TrustedApplication).
- Reject mutations on reserved roles with Bad_RequestNotAllowed.
- Validate IdentityMappingRuleType per Part 18 4.4.3 (empty criteria
for Anonymous/AuthenticatedUser/TrustedApplication; upper-case hex
for Thumbprint; Name=Value grammar for X509Subject).
- Honour Part 18 4.4.2 default-field-as-wildcard EndpointType
comparisons; tighten TrustedApplication/Application rules to
require trusted certificate + signed channel.
- Introduce CustomConfiguration flag per Part 18 4.4.1.
- Add IRoleManager.RoleConfigurationChanged event raised after every
successful mutation per Part 18 4.4.1.
- Make RoleEntry an immutable snapshot.
Address-space binding (typed proxies):
- RoleStateBinding switched from stringly-typed OnCallMethod2 plumbing
to the source-generated typed proxies (RoleSetState, RoleState,
AddRoleMethodState, AddIdentityMethodState, ...).
- DiagnosticsNodeManager.AddBehaviourToPredefinedNodeAsync upgrades
passive BaseObjectState nodes of RoleSetType / RoleType to the
typed RoleSetState / RoleState proxies at predefined-node load time.
- New RoleAuthorizationGate.CheckAdmin centralizes SecurityAdmin role
plus SignAndEncrypt enforcement per Part 18 4.2 / 4.4 / 5.2.
- Bound writable ApplicationsExclude / EndpointsExclude /
CustomConfiguration with the same auth gate.
- Raise RoleMappingRuleChangedAuditEventType from every successful
mutator (Part 18 4.5) via the existing AuditEvents helper.
Client library:
- New Opc.Ua.Client.Roles.RoleManagementClient + IRoleManagementClient
+ RoleInfo + SessionRoleExtensions.OpenRoleManagementClient.
- Covers list / read / add / remove role, identity, application,
endpoint operations plus Set*Exclude via Write Service.
Tests:
- New RoleManagerTests.cs - 37 NUnit tests for pre-populated roles,
reserved-role immutability, spec-correct status codes, criteria
validation, ResolveGrantedRoles, exclude semantics,
CustomConfiguration, AddRole well-known NodeId reuse, and
RoleConfigurationChanged event.
Documentation:
- Rewrite Docs/RoleBasedUserManagement.md as a Part 18 compliance
reference (status-code matrix, client examples, known limitations).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add Part 18 5 UserManagement implementation
Server-side:
- New IUserManagement interface (Opc.Ua.Server.UserManagement) modelling
Part 18 5.2.1 surface: PasswordLength, PasswordOptions, PasswordRestrictions,
SnapshotUsers, AddUser, ModifyUser, RemoveUser, ChangePassword,
MustChangePassword, IsUserActive, UserDeactivated event.
- Default UserManagement implementation wraps the existing IUserDatabase
and stores per-user UserConfigurationMask + description in memory.
Validates passwords against PasswordLength + character-class flags
from PasswordOptions; honours Part 18 5.2 result codes
(Bad_AlreadyExists, Bad_NotFound, Bad_OutOfRange, Bad_NotSupported,
Bad_ConfigurationError, Bad_InvalidSelfReference,
Bad_IdentityTokenInvalid).
- ChangePassword clears the MustChangePassword bit on success.
- New UserManagementBinding wires the typed source-generated proxies
(UserManagementState, AddUserMethodState, ModifyUserMethodState,
RemoveUserMethodState, ChangePasswordMethodState) - typed OnCallAsync
delegates everywhere; admin gate via RoleAuthorizationGate.CheckAdmin;
ChangePassword gated via RoleAuthorizationGate.CheckSelfUserName;
closes active sessions for deactivated users via ISessionManager.
- ConfigurationNodeManager.AddBehaviourToPredefinedNodeAsync upgrades
the passive UserManagement object to the typed UserManagementState
proxy at predefined-node load time; CreateServerConfiguration invokes
UserManagementBinding.Bind when an IUserManagement was injected.
- IServerInternal gains UserManagement getter + SetUserManagement
injector.
Tests:
- New Tests/Opc.Ua.Server.Tests/UserManagementTests.cs - 18 NUnit tests
covering AddUser happy path, duplicate / password-length / config-flag
validation, RemoveUser non-existent / self-reference / NoDelete,
ModifyUser self-disable / disable-other UserDeactivated event,
ChangePassword happy path / same-as-old / wrong-old /
MustChangePassword bit clearing / NoChangeByUser rejection,
IsUserActive on disabled vs active users.
Documentation:
- Update Docs/RoleBasedUserManagement.md with a User Management section
including the spec result-code matrix, example wiring code, and
reduce known limitations - UserManagement is no longer a limitation.
* Add OPC UA Part 17 (Alias Names) support
Server-side: pluggable IAliasNameStore + thread-safe InMemoryAliasNameStore, AliasNameStoreRegistry (live dispatcher, surfaces through optional IAliasNameStoreRegistryProvider on ServerInternalData), AliasNameNodeManager (standalone CustomNodeManager2; defaults to SecurityAdmin-only mutations on SignAndEncrypt channels), AliasNameMethodDispatcher bridging generated typed FindAlias/FindAliasVerbose/Add/Delete *MethodState.OnCallAsync handlers, AliasNameWildcardMatcher (Part 4 §7.40 Like operator with proper escape handling), and a DiagnosticsNodeManager partial that late-binds the standard well-known Aliases (i=23470), TagVariables (i=23479) and Topics (i=23488) FindAlias methods plus Aliases.LastChange through the registry.
Client-side: AliasNameClient (OpenStandardAliases/TagVariables/Topics + arbitrary category root) covering all four Part 17 methods, sub-category enumeration and ReadLastChangeAsync. Hardcoded method-id fast-path for standard categories; cached TranslateBrowsePaths resolution for custom ones. Service-level errors map to typed exceptions (UnauthorizedAccessException / NotSupportedException). AliasNameResolver (IAsyncDisposable) gives a name->NodeId cache with forward and reverse lookup; default refresh is Manual with opt-in AutoOnLastChange polling that compares VersionTime on inequality (wrap-safe).
Reference server: registers an InMemoryAliasNameStore for the standard TagVariables + Topics categories with sample seeds (TIC101_Setpoint, TIC101_PV, FIC202_Flow, Pump1_Status, Heater_Power, MultiRefAlias, ServerEvents, AuditEvents) so the standard well-known FindAlias methods return data through the DiagnosticsNodeManager late binder.
Tests: 45 server-side cases (wildcard matcher, in-memory store, registry, node manager) plus 11 mocked-session client cases and 4 end-to-end integration cases against a live ReferenceServer over a real OPC UA channel. All 60 tests pass; full solution builds clean across net472/net48/netstandard2.1/net8.0/net9.0/net10.0.
Docs: Docs/Part17AliasNames.md plus a link from Docs/README.md.
* 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
* 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
* 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.
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.
* 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>
* Enable Durable Subscriptions (#9)
* [Server] Durable Subscriptions (#2683)
* Implement a system test for DurableSubscriptions (#2839)
* Client Side
Co-authored-by: ALTERNATE-DEV\Archie <archie@dreamsandadventures.ca>
* make a static Method CalculateRevisedQueueSize
* Adress review feedback
* fix FilterRetainTests
* Add MonitoredItem Id to Queues
Use NodeIdDictionary where possible
* first proto
* fix reference server
* implement store
* initialize early
* fix issues
* Move to Reference Server & start implementing queue restore
* Persist queues
* Register queues in factory after restore
* Add Docs
* minor fixes
* Test Subscription Restore & Transfer
* fix Durable Subscription Test Browse
* Fix conversion of extension objects
* use CustomConverter for NumericRange
* Adress review Feedback
* Documentation improvements
* Update Readme
* update sampling group manager to work without session
* remove launch settings
* Enable Durable Subscriptions (#9)
* [Server] Durable Subscriptions (#2683)
* Implement a system test for DurableSubscriptions (#2839)
* Client Side
Co-authored-by: ALTERNATE-DEV\Archie <archie@dreamsandadventures.ca>
* make a static Method CalculateRevisedQueueSize
* Adress review feedback
* fix FilterRetainTests
* Add MonitoredItem Id to Queues
Use NodeIdDictionary where possible
Fix server time source timestamp is not updated.
There are duplicate objects in generated code, on of which which holds the last timestamp was not updated.
Move all readerwriter locks outside of try/finally to avoid a SynchronizationLockException when a reader writer lock is disposed or is cancelled.
Currently there is no obvious fundamental bug in how the readerwriter locks are used, but outside the try/finally clause e.g. a disposed lock may not trigger a false exception.
- Port support for ECC NIST/Brainpool profiles from prototyping_ecc branch
- Implement CertProvider to load certs per connection / profile
- Backward compatibility of configuration for existing apps
- SecurityConfiguration specifies app cert types for each profile
- Autodetect the ECC support for brainpool/nist based on platform (mac OS 10 doesn't support brainpool)
- ECC supported on net48 / net5.0 / net 6.0 / netstandard2.1
- ECC supported on windows / linux / macOS (brainpool not < macOS11)
- Self signed certs for each profile are created on start similar to RSA
- RSA only profiles are supported on .NET standard 2.0
Co-authored-by: Martin Regen <mregen@microsoft.com>
- SessionClientBatched doesn't handle the case when diagnosticinfos are requested and the batched calls returns mixed empty or non empty diagnostic infos, then the returned infos did not match the number of requested items.
- write of arrays of analogItemState are not properly checked
- BuildInfo properties were empty because BuildInfoVariableValue is never initialized
- DataType and ReferenceType may return null attributes instead of BadAttributeIdInvalid.
- Add BuildInfo test and fix the NodeCacheTest
- ICloneable was removed from generated code for the first port to .NET Standard 1.x, instead MemberwiseClone was used
- Reenable ICloneable for generated code
- Add ICloneable to built in types
- Fix code where MemberwiseClone is called instead of Clone
-Make the https callbacks fully async / code cleanup.
-Default https client to use MaxConnectionsToServer = 64 for #1550
-Fix https missing reconnect error code
other fixes unrelated to https:
- move trust list audit event to AuditEvents.cs, fix issue that the event is not filtered since reportAuditEvent cannot be used
- fix an issue when BrowseNext for multiple continuation tokens doesn't add the results array properly
- bump up .NET Core 3.1 Nuget dependencies
- improve .NET reference client app for use with https
- Move the auditing flag to server internal
- Hook up new configuration setting to the Auditing node
- A Security Admin can change the Audit setting.
- Refactor audit events to be extensions in one class.
- enable auditing and diagnostics by default for higher test coverage.
- refactor dependency of some events to bindings, e.g. TcpServerChannel should not be used as reportevent parameter
* Audit events; add methods for reporting Add/Delete nodes audit events and call these methods in CreateNode and DeleteNode methods
- fix values for AuditActivateSessionEventState.ClientSoftwareCertificates and AuditWriteUpdateEventState.IndexRange properties that were set to values of wrong type and generated exception when the client used filters for these properties.
* Fixed casting of event snapshot handler.
* Added Server Session property EndpointDescription ;
* Limited reporting and corrected the filtering of Audit events;
- Provide the CTT configuration used for 1.4.9.398: Added tests with arrays except Variant
- Match the Reference server config for CTT run (Console Server was used, others tbd)
- add a few cases in ref server node manager to enable skipped tests
- preset random generators to create deterministic node data
CTT fixes:
- Trigger: fix a regression introduced with the TransferSubscription support, Trigger stopped working, revert change to remove LinkedList in MonitoredItems
- return BadDataEncodingUnsupported creating MonitoredItems
- ensure that MonitoredItem node data reported as required by CTT after initial reading, transfer and SetMonitoring
note: not yet 100% passy, a few uncritical failing tests are still under investigation
Co-authored-by: mrsuciu <Mircea-Adrian.Suciu@softing.com>
- Add Operation limit parameter and fix server. Fixes#1363
- Add client/server test projects
- Add client and server fixture for test runs
- Server tests can test services without client connection
- Client tests can use common services to write tests which can run directly on server on via client server connection
- Increase code coverage > 50%
- Code coverage excludes the generated code
- Improve codecoverage local tests with report (see Tests/codecoverage scripts)
- Add a benchmark framework to client server tests