23 Commits
Author SHA1 Message Date
Marc Schier dbc09b8e22 Adopt System.TimeProvider across the stack (fixes #2458) (#3829)
# 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.
2026-06-03 22:38:32 +02:00
Marc Schier eb40a59566 More format and diagnostic fixes (#3780)
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.
2026-05-26 06:06:09 +02:00
Marc Schier 3e5f129c6f Enable nullable in Stack, Libraries (9), and Applications projects (#3732) 2026-05-17 12:55:24 +02:00
Marc Schier 70b4498db8 Certificate manager and ref counted certificate type (#3688)
* 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
2026-05-12 07:56:38 +02:00
Marc Schier 6c8c1a6d29 Enable dispose analyzers CA2000 and CA2213 and fix all issues (#3670) 2026-04-17 13:39:34 +02:00
romanett 66f44396ff [Server] Improve Request Queue, fix Event handling, add Tests (#3611)
- implement RequestQueue using Channels
- add event load test
- add event integration test verifying event from server object is received
- fix Client Reconnect Test
- fix DiagnosticsNodeManager not creating RootNotifier for Server object
- add Benchmarks for MonitoredItem.QueueEvent
- add serveral UnitTest for DiagnosticsNodeManager
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: romanett <7413710+romanett@users.noreply.github.com>
Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
2026-03-20 08:09:51 +01:00
Marc Schier 03777ecb09 New Json decoder/encoders, array/matrix abstractions, ByteString, and more. (#3619)
- **Collections overhaul** — new/rewritten collection types (`ArrayOf`, `Collections` commits)
- **`Variant` builder/accessor** — new APIs for constructing and accessing Variants
- **`NodeId` operators made explicit** — breaking change for implicit conversions
- **Version bumped to 1.6** with preview build support
- **NumericRange** uses Variant
- **object** type accessors and general usage removed.

### 🏗️ Infrastructure
- Build config updated; `.NET 10` targeting
- InternalsVisibleTo moved to `.csproj`
- Pipeline/CI adjustments
2026-03-18 12:23:30 +01:00
Marc Schier 2960388560 Update headers and license files (#3388)
Update license headers to copy right year 2025, replace RCL/GPL headers with MIT, replace the nuget license with MIT (via license expression).
2025-12-04 19:44:40 +01:00
romanett e63a7ccaff [Server] Make SubscriptionManagement Methods Async & Fix Publishing of GoodSubscriptionTransferred Message (#3350) 2025-11-21 16:15:56 +01:00
romanett 5864964f5b [Server] Refactor SessionPublishQueue for improved throughput by removing locking on Subscription enumeration (#3320)
* Refactor SessionPublishQueue for improved Throughput by removing locking on Subscription Enumeration

* fix Send Keepalive on first publish

* resolve threading issue with same subscription being assigned to multiple publish requests
2025-11-06 19:13:22 +01:00
Marc Schier b5044212f0 Allow sending while connecting in client channel. (#3315)
- Remove ConnectAsync from lock. Useable means m_channel is set, not useable means it is null.
- Add comments on lock behavior during connection.
- Remove callback log from validator
- Change TCS creation to specify run continuations async
- Fix encoder factory reflecting every time it is created.
2025-11-05 15:37:36 +01:00
romanett 820f6a293c [Server] Refactor Publishing to work with TAP (#3289) 2025-10-30 05:36:54 +01:00
Marc Schier 8e7a73c7df Introduce telemetry context and proper use of ILogger (#3213) 2025-09-25 20:25:31 +02:00
Marc Schier 9830e5d53e Enable roslynizer and fix all analyzer issues (#3157)
* Fix warnings and suggestions
* Enable roslynator
2025-08-16 04:10:24 -07:00
romanett 66a4028da5 [Server] Implement new ISession Interface (#3101)
* Implement ISession Interface

* fix ReferenceServer

* remove unused private field from session
2025-08-07 07:25:02 +02:00
romanett 91b068eacb [Server] Extend ISubscription Interface (#3100) 2025-08-06 18:54:11 +02:00
Martin Regen 2b9d8f9de5 Fix warnings, no functional changes. Improve globalization. (#2445)
Fix warnings regarding localization, CLS compliance, performance. No functional changes.

Many but not all adressed:
CA1859
CA1868
CA1305
CA1310
CA1861

- based on the discussion, use IFormatProvider where appropriate in ToString
2024-02-14 17:17:21 +01:00
Martin Regen 4c0880c800 Fix codesmells. No functional changes and bug fixes. (#2368)
Fix many warnings to improve code quality or simplify the code.
2023-11-07 10:34:42 +01:00
Martin Regen b88e2da4d8 Use the request queue to return GoodSubscriptionTransferred immediately (#2280)
Issues:
- The expectation is for a client session to receive a `GoodSubscriptionTransferred` status after a subscription is transferred to another session. However there is a corner case exposed in our tests, when all subscriptions are transferred so that the client subscriptiona has no active subscriptions left, only `BadNoSubscription` is returned by the server for allpending requests, instead of the status. As a workaround, to get the status, the client session has to send an additional publish request which is unexpected after a `BadNoSubscription` error.
- The status message is only returned on the next publish request, which can lead to undesired delay of the notification.

Fix: Return the status message immediately if pending requests are available.

Other fixes:
- Make client subscription class cloneable
- Improve the test which didn't receive the status messages
- Use the publish request queue to return a status message immediately
2023-08-25 11:29:16 +02:00
Martin Regen cfc68eeb10 Use .NET analyzers instead of Roslynator, fix warnings, no bug fixes (#1729)
-use latests analyzers in .NET instead of Roslynator.
-fix warnings and formatting, no bug fixes!
2022-03-14 16:39:09 +01:00
Martin Regen a147eb55c5 Tracing and Logging improvements for the UA Core and libraries (#1631)
- support for Microsoft.Extensions.Logger.ILogger in Opc.Ua.Core as the new logging interface
- backward compatible with config and TraceEvents
- new API Utils.SetLogger allows to set ILogger
- updated Console samples to demonstrate ILogger support with Serilog
- support for EventSource logging
- see Docs/Logging.md for more info
2021-12-16 00:20:08 +01:00
AlinMoldovean 764c481405 Update Copyright year to 2020 2020-10-07 18:04:34 +03:00
Alin Moldovean 195521719e Move SDK folder to "Libraries" (#1013)
* Move Client library

* Move Server library

* Move Configuration library

* Move Complex Types library

* Update paths in project references
2020-06-09 18:46:08 +03:00