This change adds a **new Opc.Ua.Types** nuget that contains core types that do not rely on generated code. Why the name? Because almost all code that was in the Types subfolder is part of it, and because we do not want to change the name of the Opc.Ua.Core nuget/assembly because code relies on it. Any other name like base or bootstrap felt out of place due to the current structure already defining the name "types". Key design is to depend on only a small set of libraries with limited transitive dependencies, that includes hashcode, logging.abstraction, and for non standard20 builds System.Text.Json (needed for localizedText mul parsing). Also, key is to support .netstd 2.0 to support source generators and to allow removal of EEC_SUPPORT defines by removing std2.0 from core and all libraries.
The changes are mostly restructuring, and thus small but contain some key changes:
- **Status code** struct now comes with a Symbol field, which is used to carry symbols in case the code is not generated. Currently (until generated) the status code struct must be manually created with a symbol or the ToSymbolicId extension must be called in the core project. Future will generate Status code constants just like NodeId that contain the symbol which also removes the reflection-based lookup. Several tests needed to be adjusted as they checked the status code symbol strings instead of the code.
- **Core identifiers** are copied as they were needed for code to compile, that includes attributes, a subset of status codes and node identifiers. These will never change so no need to generate them.
- The types folder now contains **encoders**, except for json which is still in core. Once the json encoder is ported to system.text.json it will also be included and Newtonsoft.Json dropped as dependency (-> #3329).
- Since types relies on **IOperationContext** and **ISystemContext**, and these export IUserIdentity which relies on crypto, these were split and extended in core with ISessionOperationContext and ISessionSystemContext, which mean changes to ServerSystemContext and introduction of SessionOperationContext and SessionSystemContext classes that extend OperationContext and SystemContext. Some runtime checks in the server are therefore needed to get at the session and auth info, however, those are anyway optional fields and are not on the critical paths, and thus a type check is in order (and was done in the past already, but against OperationContext class).
- **Manifest resources** are now split between Core (nodeset zip, some generated resoures) and Types (built in bsd/xsds). This needs to be revisited later if the bsd/xsd need to be regenerated during type generation. Note that the embedded resource names changed as a result. Since these are only used internally and do not constitute public API this feels reasonable vs duplication of resources in 2 assemblies.
- Reflection however now needs to load not just the built in **encodeables** from Opc.Ua.Types assembly, but also the generated encodeables from Opc.Ua.Core assembly. For this a new helper Utils method was added to get the Core assembly when linked against Opc.Ua.Core otherwise null.
- Whatever utils methods needed to be split out into the new Opc.Ua.Types assembly, they are now in **CoreUtils** static class in Opc.Ua.Types, and Utils.xxxx forwards to them to ensure minimal changes. Later we would want to obsolete them in favor of CoreUtils, although it might make sense to split them again into domain specific utilities, such as networking, files, etc
- 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.
Refactored client-side logic to support batching of service requests, ensuring compliance with operation limits and improving scalability. Added telemetry and activity tracing using `ActivityTraceFlags` for better observability, including metrics collection and logging. Enhanced error handling with descriptive exception messages and improved certificate validation.
Introduced a comprehensive suite of unit tests for `SessionClientBatchTests.cs` and `ClientBaseTests.cs`, covering batching, error scenarios, and edge cases. Added helper classes for testing logging, metrics, and activity tracing. Updated tests to align with modern C# practices, including nullable reference types and collection initializers.
Improved code consistency, readability, and maintainability by standardizing method signatures, simplifying redundant patterns, and removing legacy constructs. Updated XML documentation and added conditional compilation for .NET 8.0+ compatibility.
* Initial plan
* Add TryParse methods to NodeId and ExpandedNodeId with comprehensive tests
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
* Address code review feedback: use explicit Exception catch and improve consistency
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
* Refactor TryParse to be core implementation, Parse now calls TryParse
Changed architecture so TryParse contains the parsing logic without throwing exceptions.
Parse methods now call TryParse and throw appropriate exceptions on failure.
This avoids using try-catch for control flow as requested.
All 1643 BuiltInType tests pass.
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
* Refactor ExpandedNodeId InternalTryParse to avoid creating object in try-catch
Reworked the static InternalTryParse method to directly parse ExpandedNodeId
components without creating an ExpandedNodeId object and catching exceptions.
Also refactored the instance InternalParse method to use a new InternalTryParseInstance
helper that implements TryParse pattern, with InternalParse calling it and throwing
appropriate exceptions (ArgumentException or ServiceResultException) on failure.
All 1643 BuiltInType tests pass.
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
* Added RejectCertificateUriMismatch property and explicit ApplicationUri validation after certificates are loaded
* Perform duplicate detection on thumbprint only
* Ported handle multiple ApplictionUri, removed assign ApplictionUri from certificate
* Missing letter
* Fixed LoadPrivateKeyAsync when no applicationUri is passed.
* Add tests for validating certificates with multiple AplicationUris on ApplicationInstance level and server side
* Renamed into CheckOrCreateCertificateAsync, logged Certificate, improved tests
* Added retry logic for transient connect errors in CreateSessionApplicationUriValidationTests
* Added TODO log when telemetry instance available
* Removed unused ValidateServerCertificateApplicationUri(X509Certificate2 serverCertificate)
* Refactor for robustness and async improvements
Refactored code to enhance robustness and maintainability by enabling nullable reference types and using `async`/`await` for asynchronous operations. Updated exception handling to use `BadNotConnected()` for more accurate error states. Removed unused code and improved test files to align with these changes. Introduced `OpenInternalAsync` for better channel management and handled on-demand connection creation in `SendRequestAsync`.
* Obsolete APM
* Remove WCF remainders, channel clean up and initial cut at Channel factory
* Clean up copyright notice formatting
* Make connect async in Socket and abstract bindings for easier testing
* Fix unit tests
These changes enhance robustness, maintainability, and correctness of channel and task management.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Roman Ettlinger <romanett98@gmail.com>
* Fix NodeId.Parse() to reject invalid identifiers without proper prefix
- Modified NodeId.InternalParse() to distinguish between namespace URI (from ExpandedNodeId) and namespace index (from ns=)
- Only allow implicit string identifiers when namespace URI is specified (nsu=), not when namespace index is specified (ns=)
- Added test case NodeIdParseInvalidWithNamespace to verify invalid NodeIds are rejected
- Fixed existing tests that were relying on the buggy behavior
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
* Replace fuzzy search with SimpleName search if comparing DistinguishedName fails.
* Added mandatory Organization Name attribute to SetSuitableDefaults().
Added Test for the special case.
* Added missing O attribute to CompareDistinguishedName call
* Update test
* CertificateIdentifier.Find will pick the certificate with the longest duration
* Find only valid certificates.
* Prioritizes CA-signed certificates over self-signed certificates
* Update Tests/Opc.Ua.Configuration.Tests/ApplicationInstanceTests.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Select longest remaining validity if valid, or least expired if all expired
* Renamings
* Improved comments, improved algo clarity and taken into account more possible cases of prioritization depending on cert validity
* Comment corrected
---------
Co-authored-by: romanett <romanett98@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Allow setting ReturnDiagnostics on the session factory to ensure the diagnostic settings are part of "Create" also. Set them to SymbolicIdAndText by default.
- Better logging in unit tests, now also logs to progress including exception traces, also prefixes SERVER and TEST on console to attach the logs to the server or client side.
- GDS client stability improvements to ensure client reliably reconnects between calls when connection is lost.
- Do not dispose the application certificate when it is updated from GDS client to avoid existing sessions to crash with CryptographicException. This needs more improvements later on because it is rather hacky today.
- Remove the certificate cache in CertificateFactory (as per discussion and agreement) which allowed re-enabling the older UserIdentity API
- Logging improvements here and there to analyze issues in unit tests better
* Add test to test encoding "Null" array and expect empty array or null to be decoded.
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Set a default TimeoutHint in all request based on the OperationTimeout
* simplify calculation
* Add new TimeOutHintProperty and bounds checks
* fix build
* fix build
* Refactor string usage for secrets (#394)
Strings are immutable and the lifetime of secrets can not be controlled.
Use byte[] or char[] instead of strings for secrets, which can be erased
after use.
* Clear pw
---------
Co-authored-by: Martin Regen <7962757+mregen@users.noreply.github.com>
* 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
* Update GDS Client to use async Client API
* Make GDS Tests use ECC for connection. Update Certifiacte wait check to use polling mechanism
* Use Async Server Methods
* Add specialized ECC Test procdure
* Add Exception handling to allow errors during server application certificate exchange
---------
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