mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-23 18:39:26 +08:00
fuzzing
10 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a81d981755 |
dotnet format sweep (whitespace, IDE, RCS) + code-style enforcer agent fix (#3865)
# 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>
|
||
|
|
4756e7c245 |
DI (OPC 10000-100) with samples (Pump, SW Update), fluent API gap closures and model dependency implementation (#3808)
This PR implements the **OPC UA Device Integration (DI, OPC 10000-100)** companion-spec library trio (`Opc.Ua.Di` / `Opc.Ua.Di.Server` / `Opc.Ua.Di.Client`) plus a worked example (`Applications/MinimalPumpServer`) demonstrating the OPC 40223 Pumps companion specification end-to-end with full simulation. It also closes 11 fluent-API gaps in `Opc.Ua.Server.Fluent`, three source-generator bugs, integrates the DI layer into the unified `services.AddOpcUa()` Microsoft.Extensions DI hosting pattern, and adds 250+ new tests. **Worked example — `Applications/MinimalPumpServer/`** - AOT-compatible console host using `Host.CreateApplicationBuilder` + `AddOpcUa()`. - `PumpNodeManager` inherits from `DiNodeManager`; multi-namespace (DI + Machinery + Pumps) via runtime NodeSet2 loading and `ModelLoaderBuilder`. - Demonstrates declarative second-pump creation via `.ConfigureDevicesFor<PumpNodeManager>(...)` and software-package seeding from the same configurator. - Full simulation: pressure, temperatures, power, flow, efficiency, level, cavitation/overheat fault injection, alarm setup, NAMUR-style supervision. **Documentation** - `Docs/Opc.Ua.Di/` — README, DeviceBuilder, Hosting, LockService, SoftwareUpdate, ClientHelpers (6 new developer guides). - `Docs/Opc.Ua.Di/ComplianceMatrix.md` — every DI declaration mapped to In-v1 / Generated / Deferred / Excluded. - `Docs/CompanionSpecLibraries.md` — packaging guide for new companion-spec libraries. - `Docs/FluentApiGaps.md` — historical record of G1–G11. - `Docs/SourceGeneratedNodeManagers.md` updated for richer node managers. - `Docs/plans/StateMachineBuilder.md` — deferred state-machine builder design. |
||
|
|
b3518b53df |
[Server]: Queue Events from the Server Node using multiple channel consumers (#3823)
# Description
This pull request introduces a scalable consumer task model for the
`MonitoredNode2` class, optimizing the handling of event notifications
for notifier nodes. Any notifier node can opt into (or out of) dynamic
scaling of consumer tasks based on the number of event monitored items,
improving throughput and responsiveness under high event loads. The
Server node (`ObjectIds.Server`) is always auto-opted-in. The
implementation includes safe scaling up and down of consumers, robust
disposal logic, Fluent API integration, and tests to verify correct
delivery of events.
**Scalable consumer task management:**
* Added an `enableMultipleEventConsumers` constructor parameter to
`MonitoredNode2` that enables dynamic scaling of consumer tasks to match
the number of event monitored items. The Server node
(`ObjectIds.Server`) always auto-opts-in regardless of this parameter.
* Added `AllowMultipleEventConsumers(NodeId, bool enable = true)`
protected method on `AsyncCustomNodeManager` with an internal
`MultiConsumerNodeIds` registry, so any node manager can
programmatically opt in or out specific nodes.
* Added `IsMultipleEventConsumerNode(NodeId)` to the `IAsyncNodeManager`
interface, allowing consumers to query multi-consumer opt-in status
through the interface without casting to `AsyncCustomNodeManager`.
* Both `MonitoredNodeMonitoredItemManager` and
`SamplingGroupMonitoredItemManager` use the `IAsyncNodeManager`
interface method when creating `MonitoredNode2` instances.
**Fluent API integration:**
* Added `AllowMultipleEventConsumers(bool enable = true)` method to
`INodeBuilder` and its `NodeBuilder` implementation, allowing any
notifier node to be opted in or out via the fluent builder pipeline
(e.g. `builder.Node("myNotifier").AllowMultipleEventConsumers()`).
* The `NodeManagerBuilder` routes the registration to the owning
`AsyncCustomNodeManager`'s multi-consumer registry, supporting both
opt-in and opt-out.
**Testing and verification:**
* Added unit tests to verify multi-consumer behavior for both Server
node (auto-opt-in) and non-Server nodes (explicit opt-in), as well as
default single-consumer behavior for nodes without opt-in.
* Fixed race condition in permission cache tests
(`OnMonitoredNodeChanged_DefaultPermissionsChanged_CacheInvalidated` and
`InvalidatePermissionCacheForSession` tests) that caused flaky CI
failures. The tests now signal on `QueueValue` (which fires after the
cache is populated) instead of `ValidateRolePermissionsAsync` (which
fires before), ensuring cache invalidation operates on a populated
cache.
## Related Issues
## 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.
- [ ] 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.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
|
||
|
|
0000513cde |
Pluggable user-identity provider model (#3807)
# 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. |
||
|
|
c89bc92e7c |
Part 11 Historical Access client/server framework (#3797)
## 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.
|
||
|
|
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. |
||
|
|
3e5f129c6f | Enable nullable in Stack, Libraries (9), and Applications projects (#3732) | ||
|
|
5795e50b58 |
Source-generated, NativeAOT-clean fluent server API with event-source publish (#3765)
* Add async read/write hooks to BaseVariableState and AsyncCustomNodeManager
Introduces an end-to-end async path for variable Value-attribute reads
and writes that does not require holding lock(this) while the user
callback executes:
* New AttributeReadResult, AttributeSimpleReadResult and AttributeWriteResult
readonly record structs in NodeState carry the typed result of an async
Value-attribute hook (no ref/out params across await).
* Four new async delegates (NodeValueEventHandlerAsync,
NodeValueSimpleEventHandlerAsync, NodeValueWriteEventHandlerAsync,
NodeValueSimpleWriteEventHandlerAsync) sit alongside the existing sync
hooks.
* NodeState gains virtual ReadAttributeAsync / WriteAttributeAsync methods.
The default implementation wraps the synchronous call in lock(this) so
callers that have not opted into async hooks see bit-identical behaviour.
* BaseVariableState exposes OnReadValueAsync, OnSimpleReadValueAsync,
OnWriteValueAsync and OnSimpleWriteValueAsync slots and overrides the new
virtuals to dispatch to them WITHOUT holding the lock during the await.
On simple-read the framework still applies index range, data encoding and
copy policy; on simple-write the cached value/status/timestamp are
updated under lock after the hook completes.
* AsyncCustomNodeManager.ReadAsync and WriteAsync now await the new
ReadAttributeAsync / WriteAttributeAsync entry points instead of taking
lock(source) around the synchronous call. Existing per-source locking
semantics are preserved by the default async wrappers.
* The fluent INodeBuilder surface gains four new async OnRead/OnWrite
overloads that wire to the new BaseVariableState slots, with the same
ThrowIfSlotOccupied + null-check pattern as the sync overloads.
* Add typed IVariableBuilder<T> fluent surface
Adds typed sub-interfaces and impls so the existing fluent surface
can expose simple Func<T> / Action<T> / Func<CancellationToken,
ValueTask<T>> overloads for variables — without losing the lower-level
Variant-based overloads on INodeBuilder.
* IVariableBuilder<TValue> + VariableBuilder<TValue> derive from
INodeBuilder<BaseVariableState> / NodeBuilder<BaseVariableState>
(NodeBuilder<TState> unsealed).
* Marshalling uses Variant.AsBoxedObject(BoxingBehavior.Legacy) for
reads and Variant(object) for writes; the AOT-unsafe write path is
scoped-suppressed with a TODO pointing at the planned per-type
generated walker.
* INodeManagerBuilder gains Variable<T>(string),
Variable<T>(NodeId), VariableFromTypeId<T>(NodeId),
VariableFromTypeId<T>(NodeId, QualifiedName).
Server library builds clean across all 6 TFMs.
* Add relative-child traversal API on INodeBuilder
Adds INodeBuilder.Child(QualifiedName), Child<TState>(QualifiedName)
and Variable<TValue>(QualifiedName) so source-generated typed
wrappers can walk one segment at a time without re-resolving from
the manager root. Resolution uses NodeState.FindChild and reuses
NodeManagerBuilder.ToVariableBuilder to keep the typed-variable
marshalling story consistent.
Adds 7 NUnit cases (Fluent category) covering the happy path,
type-mismatch, null/missing browse-name, and non-variable
rejection. All 66 fluent tests pass.
* Mix old + new fluent APIs in MinimalBoilerServer demo
BoilerNodeManager.Configure now exercises five wiring styles:
(1) browse-path with the legacy ref-Variant callback
(2) absolute NodeId with the legacy ref-Variant callback
(3) typed Variable<double>(NodeId) + simple Func<double> sync getter
(4) typed Variable<double>(NodeId) + Func<CancellationToken, ValueTask<double>>
async getter — exercises the BaseVariableState.OnReadValueAsync
slot end-to-end through AsyncCustomNodeManager.ReadAsync
(5) NodeFromTypeId with OnNodeAdded lifecycle hook
All five styles compose against the same INodeManagerBuilder, with
the typed and async callbacks pulling in the new IVariableBuilder<T>
surface (committed at
|
||
|
|
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 |
||
|
|
bd4543e961 |
ManagedSession, Pluggable Subscription engine, and fluent builder + DI (#3730)
- Add new managed session, wrapping session and providing connection management and failover handling - Add new Subscription engine that can act as alternative to current engine, but is based on channels with worker tasks - Add a fluent builder for managed session clients - Replace NodeCache with LruNodeCache, rename ILruNodeCache and LruNodeCache to INodeCache and NodeCache - Update migration guide and document new functionality. |