Commit Graph

93 Commits

Author SHA1 Message Date
Martin Regen 33ae8bbec5 Set DefaultEncodingId in DataTypeDefinition, was always null NodeId (#1523)
- DefaultEncodingId is always set to binary encoding id. Helper added to StructureDefinition for other use cases (e.g. PubSub)
- the default encoding id is derived for the encodeable factory, since the typetree does not contain sufficent information to find the proper binary encoding id
- add a few helper functions in core for an upcoming PR that was used for testing with custom types, will simplify to add more nodemanagers to servers with custom types
2021-09-24 16:25:21 +02:00
Elijah Burshtein 92ae1d324e Enable Subscription to invoke callbacks sequentially and synchronously (#1493)
Pertaining to the discussion started in Issue #957, this Pull Request seeks to add capabilities for Subscription to sequentially invoke its MonitoredItem and FastDataChange callbacks to maintain order properly. The key goal is to avoid out-of-order monitored items. To this effect, the Sequential Publishing capability is added to Subscription
Resolves #957 

### SequentialPublishing
A toggle which forces Subscription to raise callbacks only in a sequential order by the SequenceNumber of the incoming message. It limits the number of tasks that can process publish responses to 1, and enforces a strict +1 Sequence Number requirement before releasing a message.

#### Backwards compatibility
The new property has been added as DataMember at the end to maintain backwards compatibility with the DataContract, where such may be used. The relevant copy constructor has also been updated.

The feature is disabled by default, so the existing behavior is the default. Users must explicitly set the property on the Subscription object to enable these new features. 

#### Leveraging existing "time machine" in SaveMessageInCache
There is already a mechanism for re-ordering messages that entered in the wrong order. This change makes use of that existing "time machine" which sorts messages into chronological order (by the sequence number) to only pull off messages with a proper +1 sequence number each time.

#### KeepAlive messages advancing sequence number
KeepAlive messages do not contain notifications, and do not enter the proper branch in the code to be pulled out. They will not interrupt sequential flow. Since the next message in the sequence with data will "re-use" that sequence number, it can be expected to maintain sequence. 

#### Delayed messages
When sequential publishing is enabled, if a message is genuinely missing from the sequence, it will "hold up" the messages until it either arrives or is pulled out of the incoming messages list by being too old. In either case, it is considered "processed" for the sequence purposes at that point and the rest of the messages may proceed. 

The automatic republish request mechanism is also leveraged here for that purpose as well.

#### SequenceNumber roll-over after max value
As specified in the OPC UA spec, at 1ms publishing, this would take almost 50 days of uptime. Naturally at any "reasonable" publishing interval this time is even longer. The matter itself is also not addressed throughout the whole existing code that handled it before this change. (Though some consideration can be seen in some places, such as placing messages at the end of the incoming message linked list if no better place was found) 

#### Locking on m_cache to get the semaphore
I've considered making a separate locking object for the semaphore management, but decided it is not needed. The message worker would need to obtain m_cache lock later anyway, and momentarily obtaining it is not harmful for the overall flow.
Only in cases of serious contention between new PublishResponses coming in and workers attempting to work would this cause any problems.

#### Callbacks that "take a long time"
This change will naturally suffer from callbacks that take a long time to invoke. In our use case, each callback message is passed into an ActionBlock for handling, so our callbacks are fast. But Other clients may invoke much more code on these callbacks.
Sequential publishing means this capacity is possibly bottlenecked. Sequential publishing should be used for its intended purpose and with callbacks that do not hold up their calling thread for a long time. To ensure proper sequential callbacks, they cannot just be started in order, they have to be processed fully in order. 

#### Changing this property while the Subscription is active
There is limited support to on-the-fly changes to this property, and this is not the intended use case. It is meant to be set once and ideally never changed while messages are being processed.

If users need certain items properly sequenced and some items they can accept out-of-order or ignore outdated messages, they can do this by defining two separate Subscription objects, same as they would if they needed different Publishing Intervals. 

#### Why semaphore?
At first I had considered using ActionBlock from TPL DataFlow and limiting its concurrency to the number of desired message workers, but I had opted not to add a dependency on DataFlow only for this purpose. (Referencing all of DataFlow just for ActionBlock's automatic concurrency limiting is wasteful.

I had also considered using a Limited Concurrency Task Scheduler implementation and queueing the message workers on that instead of the normal ThreadPool via Task.Run, but that is similarly more complex than it needs to be.

#### Why async Task? What was wrong with Void?
While being on a new Task from the ThreadPool anyway, the worker would still occupy a task from the ThreadPool if it was using the synchronous Wait() method, which is a blocking call. By using WaitAsync, the ThreadPool task goes "back" to the ThreadPool until the semaphore is released. 

### Disclaimer - I am not an OPC UA expert
Please do not assume I have "done all my homework" with regard to these changes. I have attempted to learn as much as I can in the time I was working on this change, but I fully expect to have missed a few spots and specifics of the OPC UA protocol.

I have done some testing in our application to verify the out-of-order problem is solved, and that no significant delay is introduced by the additional work done to facilitate this.
2021-09-16 18:58:51 +02:00
Martin Regen a67714147d Support supplied keys and RSACng for the cert generator (#1507)
- Allow to call SetRSAPublicKey without Issuer being set
- Support to create self signed CA cert with supplied keys
- Test case for RSACng on .NET framework and .NET Core 3.1

Issue reported by @eoursel
2021-09-13 15:48:27 +02:00
Martin Regen dad6bcd8da Add API for multiple CRL distribution points (#1504)
fixes #1475 
Co-authored-by: symarchand <sylvain.marchand@capgemini.com>
2021-09-13 10:08:34 +02:00
Martin Regen a4bf0ab174 Complex types client can ignore isoptional fields for structure (#1503)
fixes #1476 
 Improve IOP, some recent ModelCompiler versions (starting with errata 1.04.9) produce invalid output and all IsOptional fields have become true by default, causing the complex types client to bail out for Structures created with this ModelCompiler release. However, the IsOptional field can be ignored.
ModelCompiler is fixed in 1.04.10 and greater
2021-09-13 09:18:30 +02:00
Martin Regen 21546b0aba Remove the code which allows to accept CRL (#1502)
fixes #1343

remove a inofficial test code which allowed a CRL to be decoded from the AddCertificate blob

https://mantis.opcfoundation.org/view.php?id=6342
2021-09-13 07:44:37 +02:00
Martin Regen 76afe829b4 Add async versions of subscription API to session client (#1498)
fixes #919 and #921

- enable async client stubs in core
- add async versions for subscription management
- APM versions will not be included...

based on PR #919 from @mibos-kremer

Co-authored-by: Michiel <m.bos@kremer.nl>
2021-09-07 16:23:00 +02:00
opcfoundation-org 9b89bd070f Modelcompiler 1.04.10 (#1492)
* Changes needed for model compiler needed for Errata 1.04.10. 
* Errata 1.04.10.
2021-09-03 19:38:31 +02:00
Martin Regen 73e0e59f98 macOS mono build fix, Https tests, bench improvements (#1486)
- on VS2019 for mac the https lib doesn't build, now get the properties at runtime to set server validation callback
- add client tests for https
- fix an issue with SslProtocol selection, where tools recommend None it only works on all platform combinations if Tls12 is used
- use the benchmark .NET command line parser 
- benchmarks for StreamWriter buffer size
- StreamWriter default buffer size reduced to 1k, according to bench results best compromise
fixes #1443
2021-08-18 11:01:04 +02:00
Alin Moldovean b5421ea391 Compliance fixes for OperationLimits and SetTriggering (#1469) 2021-07-26 11:33:41 +03:00
Martin Regen c435e5844d Improve JsonDecoder StreamWriter dispose (#1448)
- only dispose StreamWriter if owned by JsonEncoder
- only dispose if dispose is called
- on external stream writer, return text by using reflection on basestream, if memorystream is used
- improve benchmark common code
- fixes #1444
2021-07-09 07:44:54 +02:00
Alin Moldovean 08164fe04a MetaData support for PubSub library (#1452)
* Metadata support
* Fixes for UaPubSub.
* Add support for delta frames.
2021-07-08 19:29:24 +03:00
Martin Regen b9ad021e11 Fix Nuget build (#1445)
Client proj lacks definition of SIGNASSEMBLY, bump nuget dependencies
2021-07-07 09:30:06 +02:00
Martin Regen 0236d082b1 Create client and server test projects, increase test coverage (#1434)
- 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
2021-07-06 18:01:54 +02:00
Alin Moldovean a90024b5de Make ApplicationConfiguration.FixupAppConfig() public. (#1431) 2021-06-24 11:33:49 +03:00
Martin Regen 96ecb4dd9c Add a no file fluent API for application configuration. (#1422)
* Add no file configuration fluent API
* ensure secure settings are produced by default
* most if not all settings can be reached by .Set/.Add functions
* switched gds tests to use no file config (also good as starter)
2021-06-15 19:14:09 +02:00
Martin Regen 24f90c410a Add interfaces IServiceMessageContext, IEncodeableFactory (#1407)
* use IServiceMessageContext instead of ServiceMessageContext across the board.
* same for IEncodeableFactory
2021-06-11 16:35:46 +02:00
Martin Regen 9923141e70 Enable .NET analyzers for all projects (#1414)
* Enable .NET analyzers for all projects
* fix all new warnings, mostly security and perf
2021-06-05 07:58:38 +02:00
Martin Regen 8a986f433a Improve server request handler (#1411)
-no need to search request list for every completed request, only if operation deadline is specified
-move timer clean up to timer callback
2021-05-25 17:53:18 +02:00
Suciu Mircea Adrian 2dfedef0bd Fixes brought to the process of validating permissions (#1406)
* Fixed call to ValidatePermissions under TranslateBrowsePath service

* Fixed adding default permission values to the metadata under GetPermissionMetadata method
2021-05-20 17:01:52 +03:00
Nick 6d232726b4 Preferer a higher SecurityMode over SecurityLevel in CoreClientUtils.SelectEndpoint() (#1405) 2021-05-20 17:01:30 +03:00
Alin Moldovean f332d87f5a Change UaPublisher trigger from ManualResetEvent to Timer (#1399)
* Change UaPublisher trigger from ManualResetEvent to Timer
2021-05-12 16:16:07 +03:00
Alin Moldovean a5e1f4c8cd PubSub fixes (#1394) 2021-05-12 13:33:29 +03:00
Martin Regen ab05d09d66 Tag PubSub lib as beta in release builds (#1396)
- in release builds tag PubSub lib as beta until MQTT API surface is finalized
- tag as 'beta' to avoid nuget collision with preview builds from master
- Move PubSub samples to seperate Solution
2021-05-11 14:45:03 +02:00
Alin Moldovean 49909c6b34 Implement logic for ApplyRestrictionsToBrowse flag in AccessRestrictionType (#1395) 2021-05-11 10:10:02 +03:00
Suciu Mircea Adrian 8b9bbe20fc Optimize GetNodeMetadata (#1392)
* Optimized GetNodeMetadata to support reading AccessRestrictions and RolePermission attributes when specified; All service calls use only these attributes on validating AccessRestrictions and RolePermissions. Read and Browse services also cache the values for avoiding unnecessary calls.
2021-05-05 15:10:02 +03:00
Nyphus 244b26e22f Port thread scheduler and servicehost from UA .NET legacy. (#1389)
* Add minThreadCount and maxThreadCount setting for ThreadPool
* Port thread based scheduler back from UA.NET legacy. 
* The UA Expert perf test shows better response times than Task.Run implementation. 
* Old implementation to compare against is ifdefed,
* Port servicehost from UA.NET legacy
* a few minor backports in serverbase e.g. alias names for hostname
* fix editorconfig, as it caused false positives in ref server

Co-Authored-By: macheronte <79026457+macheronte@users.noreply.github.com>
2021-05-04 15:39:17 +02:00
Sebastian Baeumler ea1e2b35db Fixed issue with XML namespace schema while decode an XML nodeset (#1385)
- added protected property XmlNamespace to BaseComplexType class
- use XmlNamespace instead of TypeId.NamespaceUri for PushNamespace of
  encoder/decoder
- adapt Encode/Decode method in OptionalFieldsCompexType and
  UnionComplexType class

Change was needed if Xml schema in Xml nodeset differ from the custom OPC UA namespace. 
Only effects XML encoding and decoding from values of customized structured datatypes.

Example:

The OPC UA Namespace of the nodeset is http://MyTestOfExtensions but the xml namespace for the xml schema is http://MyTestOfExtensions/Types.xsd
These 2 namespaces are not forced to be equal, therefor the XmlDecoder need to Push the XmlNamespace for the schema to the Reader stack. Otherwise the ExtensionObject Body will not be read.

```XML
<?xml version="1.0" encoding="utf-8"?>
<UANodeSet LastModified="2021-04-08T11:57:22.286Z" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns:si="http://www.siemens.com/OPCUA/2017/SimaticNodeSetExtensions" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <NamespaceUris>
        <Uri>http://MyTestOfExtensions</Uri>
    </NamespaceUris>
    <Models>
        <Model ModelUri="http://MyTestOfExtensions" PublicationDate="2020-07-20T00:00:00Z" Version="1.00">
            <RequiredModel ModelUri="http://opcfoundation.org/UA/" PublicationDate="2020-07-15T00:00:00Z" Version="1.04.7"/>
        </Model>
    </Models>
    <Aliases>
        <Alias Alias="Boolean">i=1</Alias>
        <Alias Alias="DateTime">i=13</Alias>
        <Alias Alias="String">i=12</Alias>
        <Alias Alias="NodeId">i=17</Alias>
        <Alias Alias="QualifiedName">i=20</Alias>
        <Alias Alias="HasComponent">i=47</Alias>
        <Alias Alias="HasProperty">i=46</Alias>
        <Alias Alias="Organizes">i=35</Alias>
        <Alias Alias="HasSubtype">i=45</Alias>
        <Alias Alias="HasTypeDefinition">i=40</Alias>
        <Alias Alias="HasModellingRule">i=37</Alias>
        <Alias Alias="HasEncoding">i=38</Alias>
    </Aliases>
    <Extensions>
        <Extension>
            <si:Generator Product="SiOME" Edition="Standard" Version="2.2.3-beta24"/>
        </Extension>
        <Extension>
            <si:GeneratorExtension Hash="cee97a4b7b32c169214c2bbc22b555d2"/>
        </Extension>
    </Extensions>
    <UAObject SymbolicName="http___MyTestOfExtensions" NodeId="ns=1;i=5000" BrowseName="1:http://MyTestOfExtensions" ParentNodeId="i=11715">
        <DisplayName>http://MyTestOfExtensions</DisplayName>
        <References>
            <Reference ReferenceType="HasComponent" IsForward="false">i=11715</Reference>
            <Reference ReferenceType="HasTypeDefinition">i=11616</Reference>
        </References>
    </UAObject>
    <UAVariable DataType="String" NodeId="ns=1;i=6002" BrowseName="NamespaceUri" ParentNodeId="ns=1;i=5000">
        <DisplayName>NamespaceUri</DisplayName>
        <References>
            <Reference ReferenceType="HasProperty" IsForward="false">ns=1;i=5000</Reference>
            <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
        </References>
        <Value>
            <uax:String>http://MyTestOfExtensions</uax:String>
        </Value>
    </UAVariable>
    <UADataType NodeId="ns=1;i=3000" BrowseName="1:MyStructureType">
        <DisplayName>MyStructureType</DisplayName>
        <References>
            <Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
            <Reference ReferenceType="HasEncoding">ns=1;i=5001</Reference>
            <Reference ReferenceType="HasEncoding">ns=1;i=5002</Reference>
        </References>
        <Definition Name="1:MyStructureType">
            <Field DataType="i=17" Name="NodeId"/>
            <Field DataType="i=20" Name="QualifiedName"/>
        </Definition>
    </UADataType>
    <UAObject SymbolicName="DefaultBinary" NodeId="ns=1;i=5001" BrowseName="Default Binary">
        <DisplayName>Default Binary</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=76</Reference>
        </References>
    </UAObject>
    <UAObject SymbolicName="DefaultXML" NodeId="ns=1;i=5002" BrowseName="Default XML">
        <DisplayName>Default XML</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=76</Reference>
        </References>
    </UAObject>
    <UAVariable DataType="ns=1;i=3000" NodeId="ns=1;i=6021" BrowseName="1:StructureTest" ParentNodeId="i=2253" UserAccessLevel="3" AccessLevel="3">
        <DisplayName>StructureTest</DisplayName>
        <References>
            <Reference ReferenceType="Organizes" IsForward="false">i=2253</Reference>
            <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
        </References>
        <Value>
            <uax:ExtensionObject>
                <uax:TypeId>
                    <uax:Identifier>ns=1;i=5002</uax:Identifier>
                </uax:TypeId>
                <uax:Body>
                    <MyStructureType xmlns="http://MyTestOfExtensions/Types.xsd">
                        <NodeId>
                            <uax:Identifier>ns=1;i=42</uax:Identifier>
                        </NodeId>
                        <QualifiedName>
                            <uax:NamespaceIndex>1</uax:NamespaceIndex>
                            <uax:Name>zweiundvierzig</uax:Name>
                        </QualifiedName>
                    </MyStructureType>
                </uax:Body>
            </uax:ExtensionObject>
        </Value>
    </UAVariable>
</UANodeSet>
```
2021-04-30 07:42:53 +02:00
dependabot[bot] 1dd0ef33ee Bump MQTTnet from 3.0.14 to 3.0.15 (#1387)
Bumps [MQTTnet](https://github.com/chkr1011/MQTTnet) from 3.0.14 to 3.0.15.
2021-04-29 14:46:14 +03:00
Martin Regen 631e729787 Fix warnings, improve complex type exception handler (#1384)
- catch exception in complex type system not only for ServiceResultException
- add fast path for single type loader if type already exists
- fix many warnings, no function change
- fix template for legacy nuget packages to include cert lib
2021-04-28 18:34:43 +02:00
Sebastian Baeumler e8df315193 ComplexTypes Improvements (#1383)
- Fixed typo in StructureDefinitionAttribute
- Adapt using of fixed StructureDefinitionAttribute
- Resolve method internal name conflict
- Enable TypeInfo.GetSystemType to support ExpandedNodeId
- Redirect request with absolute NodeIds an directly use the EncodableFactory.GetSystemType method
2021-04-28 15:08:14 +02:00
Alin Moldovean 7a4a22201b MQTT support in PubSub library (#1376)
Implementation of MQTT support in PubSub library
2021-04-28 15:31:06 +03:00
Alin Moldovean f0c467410e Implement AutoAcceptUntrustedCertificates flag for Client side also. Fixes #1228 (#1380) 2021-04-26 17:00:23 +03:00
Martin Regen e34eb9b512 Fix Perf warnings (#1372)
- use Array.Empty
- improve StringBuilder, Where
- use .Equals instead Compare
- use ConfigureAwait
2021-04-21 09:28:25 +02:00
Martin Regen c996e7933d Add ifdef to support Net5.0 build with ECC support (#1367)
- for dev only ifdefs,  but not added to target props
2021-04-19 10:42:26 +02:00
Archie Miller 88b16b3c01 Implement ConditionRefresh2 (#1353)
* Implement ConditionRefresh2
2021-04-19 09:24:06 +03:00
Simon Jäger 0c735eb038 Add interface for NodeCache (#1364)
* feat: add node cache interface
2021-04-16 11:42:09 +03:00
Alin Moldovean f2b5c45bdd Remove obsolete classes from Diagnostics\V10 (#1362) 2021-04-16 09:55:37 +03:00
Alin Moldovean fafc4427bd ActivateSession fix for changing identity from UserName to Anonymous. Fixes #1149 (#1360)
Check for unsupported UserIdentity type in ReferenceServer e.g. IssuedToken identity
2021-04-14 10:09:29 +03:00
Martin Regen 8a8a38287e Format opc.ua.client - no bug fixes / features (#1358)
for upcoming async improvements, changes will not be cluttered with formatting
2021-04-13 13:13:38 +02:00
Martin Regen 1d5e87c784 Remove RSA dispose special handling for Mono (#1347)
-Issue has been fixed in Mono, no more workarounds
-Fixes #1214 
-fix some Roslynator and other warnings
2021-04-01 14:32:20 +02:00
Alin Moldovean d7c7cbc07c Fixes #1181 - Provide underlying error at LoadApplicationConfiguration() (#1346)
* Fixes #1181 - Provide underlying error at LoadApplicationConfiguration()
2021-04-01 10:07:00 +03:00
Martin Regen 25e0998081 Create codeql-analysis.yml (#1345)
-Add CodeQL code scanner
-EnableNetAnalyzers
-small tweak for .editorconfig
2021-04-01 08:55:42 +02:00
opcfoundation-org 0f97945858 Modelcompiler updates, errata 1.04.9 nodeset (#1284)
- Use updated Modelcompiler code generator to produce code which has no dependency on System.Servicemodel
- breaking change, .NET stack which used the NET_STANDARD version have to fix dependencies on System.Servicemodel
- new codegenerator also provides stubs for async client API (NET_STANDARD_ASYNC), currently disabled
- latest V1.04.9 Nodeset
2021-03-29 17:19:49 +02:00
Alin Moldovean 4f861a2067 Add reference to Configuration library in Client and Server project. (#1340)
In this way a single Nuget package reference is required for a UA Client or UA Server application project.
2021-03-26 21:33:15 +01:00
Alin Moldovean 7e501ff416 Fix for duplicated HistoryServerCapabilities node in DiagnosticsNodeManager. Fixes #1320. (#1334) 2021-03-23 13:32:20 +02:00
Tobias Hoff 4014aa646b Stick with EndpointDescription if SecPol is null for the UserToken (#1324)
Co-authored-by: Alin Moldovean <aam@softing.com>
2021-03-23 13:30:50 +02:00
dependabot[bot] f4fd3cc012 Bump Portable.BouncyCastle from 1.8.9 to 1.8.10 (#1294)
Bumps [Portable.BouncyCastle](https://github.com/novotnyllc/bc-csharp) from 1.8.9 to 1.8.10.
- [Release notes](https://github.com/novotnyllc/bc-csharp/releases)
- [Commits](https://github.com/novotnyllc/bc-csharp/compare/pcl-v1.8.9...pcl-v1.8.10)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-25 09:26:57 +02:00
Martin Regen 46ada27179 Add certificate password provider interface to support password protected pfx files. (#1291)
* Add a certificate password provider.
2021-02-23 11:31:42 +02:00
Bill Berry e138777638 fix comment spelling mistakes - 'refernces' to 'references' (#1273) 2021-02-03 11:14:45 +02:00