* Add per-namespace NodeSet2 export and CLI option
Implemented ExportNodesToNodeSet2PerNamespaceAsync in ClientSamples to export nodes into separate NodeSet2 XML files per namespace, excluding OPC Foundation companion specs. Added a helper for safe filename generation. Introduced a new -e/--export command-line option in Program.cs to trigger this export after node fetching. Also added System.Xml.Linq import for potential XML handling.
* Add NodeSetExportOptions for flexible NodeSet2 export
Introduce NodeSetExportOptions to control which attributes and values are exported to NodeSet2 XML, with Default, Minimal, and Complete presets. Overload ExportNodesToNodeSet2 to accept these options and update internal logic accordingly. Update CreateNodeState to honor export preferences. Add comprehensive unit tests for all export modes and ensure backward compatibility. Update ClientSamples to use Complete export mode.
* Refactor NodeSet export options for minimal default output
- Change ExportValues default to false; values only for Complete option
- Remove ExportUserAccessLevel and ExportMethodDeclarationId options
- Always export MethodDeclarationId; export UserAccessLevel only if different from AccessLevel
- Remove Minimal option; Default now produces minimal schema output
- Update export logic and tests to reflect new option semantics
- Rename and revise unit test to verify new default and complete behaviors
* Remove unused BitVector32 import
* Add ExportUserContext option to NodeSet2 export
Introduce ExportUserContext to NodeSetExportOptions, allowing selective export of user context attributes (UserAccessLevel, UserExecutable, UserWriteMask, UserRolePermissions) in NodeSet2 files. Update export logic to honor this option and add unit tests to verify correct behavior. This enhances flexibility and control over exported user-specific metadata.
---------
Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
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
* 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>
* 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
- 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>
Added a new method ManagedBrowse to the UA client, which takes care of calling browse next after calling browse, when necessary. It also handles the status codes BadNoContinuationPoint and BadInvalidContinuationPoint.
Added support for the new method in ISession, TraceableSession, Session and SessionAsync.
Use the new methods in the NodeCache and other API that use browse (FetchRefrences etc).
Added unit tests which verify correct behavior of the new methods.
- Fix the UserIdentity constructor to load the private key of a provided certificateIdenifier.
- make UserIdentity constructor throw a ServiceResultException when a Certificate with no private key is specified.
- extend console reference client with two new parameters:
-uc Thumbprint of a user certifiate located in the TrustedUserCertificatesStore
-ucp Password of the private key of the user certificate
- add documentation for console reference client
Fix that if a socket is closed, new service calls are queued and a new channel is established without reconnect / activate.
Add some logic which ensures that a BeginConnect operation is only started if a valid service call is queued first.
The activate is prepared by the session reconnect handler which may take some time to respond. Until then, all other service fail immediately with BadNotConnected.
To detect socket failures earlier, the PublishRequest and KeepAlive send are also hooked up to the KeepAliveError to trigger a reconnect. To disable the keep alive timing calcualtion, an additional variable tracks the statuscode of the last error to set KeepAliveStopped to true.
* Added MaxChannelCount and detect and cleanup "stale" channels based on ChannelLifetime
* Add Environment.TickCount as time reference
* Set a socket backlog value to avoid socket open overflow
* Added a ChannelKeepAlive to signal when a session is still active
* Add options to console client to leak channels and run connect loop forever
Co-authored-by: Martin Regen <mregen@microsoft.com>
- improve various log messages, comments etc.
- multiple internal improvements in naming convention handling of async functions
- add FetchSuperTypesAsync
- replace new UTFEncoding() with Encoding.UTF8 singleton
- With exponential backoff enabled, a KeepAlive calling `BeginReconnect` could retrigger the timer in a way that a reconnect would never occur.
- Throttle `ISession.BeginPublish` on `BadTooManyOperations` error.
- Add reverse connect option to console client to test reconnect with reverse connect manager.
- null events in session on dispose to suppress spurious events.
- mark `TransferSubscription` service calls obsolete to avoid accidential use by applications.
- for reverse connection testing of session reconnect handler, add options for no security and reverse connect endpoint to console client
- Deprecate support for Nuget package support of .NET Framework 4.6.2
- Bump sample applications to 4.8
- update some copyright headers / supporting files (editorconfig etc.)
- fix a few warnings
- fix an issue with `SessionReconnectHandler`, in certain combination of reconnect period and exponential backoff the .NET sample app never reconnected.
- due to the new `MinPublishRequestCount` property publish requests are being sent after reconnect even if no subscription is active
- Improve sample code to show how to dispose the old session after reconnect
Currently the session reconnect requires to create and destroy the object and to lock the operation in the client code.
The refactored version is backward compatible but allows for a single instance to handle reconnects during the lifetime of the client. In addition no more locking is necessary in the client code.
- exponential backoff is enabled by using a constructor `new SessionReconnectHandler( true, 30000);` which would set the maxReconnectPeriod` to 30000ms. The backoff period is doubled after every unsuccessful request.
- a 10% random jitter is added to every timer update.
- The `public virtual int JitteredReconnectPeriod(int reconnectPeriod)` and `public virtual int CheckedReconnectPeriod(int reconnectPeriod, bool exponentialBackoff = false)` can be overloaded to implement custom jitter and backoff implementations.
- A new `ISession.MinPublishRequestCount` property can be set to enforce a minimum number of active publish requests. Default behavior is one publish request per subscription. It can help for low latency high frequency publish intervals.
- A new `PublishSequenceNumbersToAcknoledge` event is implemented which allows to defer ack of sequence numbers until fully processed by the client.
All new methods/properties ar not breaking changes and by default there is no behavior change, all existing code should work and compile aginst the update flawlessly.
- A bugfix in the reconnect handler, when a server changed the application certificate the reconnect ends up in an endless loop, because the `EndpointDescription` is not updated. The fix updates the endpoint from the server if a `BadSecurityChecksFailed` error os returned and then tries to reconnect with a new session.
- Add environment variables as parameter to support docker hosting where command line parameter are not available
- bump some Nuget packages
- only warn on cert validation error on startup, e.g. when the CRL becomes outdated allow to start and print warning.
- Let GetEndpoints return endpoints which match the DNS name used. DNS names must be specified as alternate hostnames in the configuration.
Improvements for complex types.
- Support to encode/decode complex type structures with multidimensional arrays.
- Perf improvements for type loader using new NodeCache fetch multiple interfaces.
- DataTypeDictionary validation when dependencies are used.
- interface for complex type resolver, to build custom types in code.
- improvements of console client to demonstrate browse/read of custom values
+++ Breaking changes +++
IDecoder interface change of the `ReadArray` method
- Return type is now `Array` for all types of arrays. Previously the method returned an array for 1-dim and a `Matrix` type for multidimensional arrays. In addition the convention in generated code is to use `Collection` for all 1-dim arrays, and so was built the `BaseComplexType`. The new convention is to expose the native `Array` type from a complex type, in all cases, hence the return type of `ReadArray` was changed to reflect that for a consistent programming model.
- `ReadArray` has a new parameter `systemType` to efficiently read encodeable types. Previously the `Type` of an encodeable was determined by the encodingid and lookup in the type factory, even when the Type is already known by the caller. The 'old' style is still supported.
- `ReadArray` supports to read encodeable type arrays which are directly encoded in structures. These arrays differ from standard encoding of arrays and they are handled when `BuiltInType.Null` is used as parameter.
- set `KeepAliveTimeout` default back to 5s, was unintentionally set to 50s in 368 release
- fix a bug that duplicate subscriptions were created after reconnect when transfer succeeds.
- add a property to enable subscription transfer in reconnect, set `Session.TransferSubscriptionsOnReconnect=true` to enable, IOP issues may not allow to use it with some servers.
- add a `SessionReconnectHandler(true)` constructor to support reconnect abort, if the connection recovers before reconnect timer called. If the new constructor is used, its a breaking change: Needs check of `Session` property in Reconnect handler callback, if aborted `Session==null`.
- Reduce warning log output if server timestamp > client time.
- Add handling when subscriptions can not be transferred, e.g. when false user credentials or no security prevent transfer.
- Improve the reconnect timer handling by using `OperationLimit` in reconnect.
- Add sample for `SessionReconnectHandler` in console client.
- Seperate session sample code from `UAClient`.
- Tested on popular demo servers of various SDK vendors.
- Fix Winforms ref client
- Only an issue if the configuration does not specify the security policy uri for anonymous token
- If the config does not specify the security policy, for anonymous user token the security profile Basic256Sha256 was chosen.
- This setting requires for the client to trust the server certificate if it tries to connect with security None, may cause IOP issues when no security is chosen and encryption is required for the anonymous user token.
- 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
* Adds proper TPL usage, decouples dependencies on Console and ClientBase, and uses string interpolation versus String.Format.
* Renames private members to standard naming convention.
* implement transport binding factory
* split https transport into seperate nuget package
* new Opc.Ua.Binding.Https assembly
* Https binding is loaded on demand, if available
* reduce core dependencies to kestrel and others
fixes#600