Skip to content

Commit

Permalink
Merge with latest master
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsuciu committed Aug 27, 2024
2 parents c6b0cc3 + 6dcee7e commit 7d1496d
Show file tree
Hide file tree
Showing 61 changed files with 3,168 additions and 1,339 deletions.
4 changes: 2 additions & 2 deletions .azurepipelines/get-version.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

try {
# Try install tool
# Note: Keep Version 3.6.133, it is known working for 4 digit versioning
& dotnet @("tool", "install", "--tool-path", "./tools", "--version", "3.6.139", "--framework", "net60", "nbgv") 2>&1
# Note: Keep Version 3.6.141, it is known working for 4 digit versioning
& dotnet @("tool", "install", "--tool-path", "./tools", "--version", "3.6.141", "--framework", "net60", "nbgv") 2>&1

$props = (& ./tools/nbgv @("get-version", "-f", "json")) | ConvertFrom-Json
if ($LastExitCode -ne 0) {
Expand Down
174 changes: 174 additions & 0 deletions Applications/ConsoleReferenceClient/ClientSamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,180 @@ public async Task<IList<INode>> FetchAllNodesNodeCacheAsync(
}
#endregion

#region BrowseAddressSpace with ManagedBrowse sample

/// <summary>
/// Browse full address space using the ManagedBrowseMethod, which
/// will take care of not sending to many nodes to the server,
/// calling BrowseNext and dealing with the status codes
/// BadNoContinuationPoint and BadInvalidContinuationPoint.
/// </summary>
/// <param name="uaClient">The UAClient with a session to use.</param>
/// <param name="startingNode">The node where the browse operation starts.</param>
/// <param name="browseDescription">An optional BrowseDescription to use.</param>
public async Task<ReferenceDescriptionCollection> ManagedBrowseFullAddressSpaceAsync(
IUAClient uaClient,
NodeId startingNode = null,
BrowseDescription browseDescription = null,
CancellationToken ct = default)
{
ContinuationPointPolicy policyBackup = uaClient.Session.ContinuationPointPolicy;
uaClient.Session.ContinuationPointPolicy = ContinuationPointPolicy.Default;

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
BrowseDirection browseDirection = BrowseDirection.Forward;
NodeId referenceTypeId = ReferenceTypeIds.HierarchicalReferences;
bool includeSubtypes = true;
uint nodeClassMask = 0;

if (browseDescription != null)
{
startingNode = browseDescription.NodeId;
browseDirection = browseDescription.BrowseDirection;
referenceTypeId = browseDescription.ReferenceTypeId;
includeSubtypes = browseDescription.IncludeSubtypes;
nodeClassMask = browseDescription.NodeClassMask;

if (browseDescription.ResultMask != (uint)BrowseResultMask.All)
{
Utils.LogWarning($"Setting the BrowseResultMask is not supported by the " +
$"ManagedBrowse method. Using '{BrowseResultMask.All}' instead of " +
$"the mask {browseDescription.ResultMask} for the result mask");
}
}

List<NodeId> nodesToBrowse = new List<NodeId> {
startingNode ?? ObjectIds.RootFolder
};

const int kMaxReferencesPerNode = 1000;

// Browse
var referenceDescriptions = new Dictionary<ExpandedNodeId, ReferenceDescription>();

int searchDepth = 0;
uint maxNodesPerBrowse = uaClient.Session.OperationLimits.MaxNodesPerBrowse;

List<ReferenceDescriptionCollection> allReferenceDescriptions = new List<ReferenceDescriptionCollection>();
List<ReferenceDescriptionCollection> newReferenceDescriptions = new List<ReferenceDescriptionCollection>();
List<ServiceResult> allServiceResults = new List<ServiceResult>();

while (nodesToBrowse.Any() && searchDepth < kMaxSearchDepth)
{
searchDepth++;
Utils.LogInfo("{0}: Browse {1} nodes after {2}ms",
searchDepth, nodesToBrowse.Count, stopWatch.ElapsedMilliseconds);

bool repeatBrowse = false;

do
{
if (m_quitEvent?.WaitOne(0) == true)
{
m_output.WriteLine("Browse aborted.");
break;
}

try
{
// the resultMask defaults to "all"
// maybe the API should be extended to
// support it. But that will then also be
// necessary for BrowseAsync
(
IList<ReferenceDescriptionCollection> descriptions,
IList<ServiceResult> errors
) = await uaClient.Session.ManagedBrowseAsync(
null,
null,
nodesToBrowse,
kMaxReferencesPerNode,
browseDirection,
referenceTypeId,
true,
nodeClassMask,
ct
).ConfigureAwait(false);

allReferenceDescriptions.AddRange(descriptions);
newReferenceDescriptions.AddRange(descriptions);
allServiceResults.AddRange(errors);


}
catch (ServiceResultException sre)
{
// the maximum number of nodes per browse is
// set in the ManagedBrowse from the configuration
// and cannot be influenced from the outside.
// if that's desired it would be necessary to provide
// an additional parameter to the method.
m_output.WriteLine("Browse error: {0}", sre.Message);
throw;
}
} while (repeatBrowse);

// Build browse request for next level
List<NodeId> nodesForNextManagedBrowse = new List<NodeId>();
int duplicates = 0;
foreach (ReferenceDescriptionCollection referenceCollection in newReferenceDescriptions)
{
foreach (ReferenceDescription reference in referenceCollection)
{
if (!referenceDescriptions.ContainsKey(reference.NodeId))
{
referenceDescriptions[reference.NodeId] = reference;

if (!reference.ReferenceTypeId.Equals(ReferenceTypeIds.HasProperty))
{
nodesForNextManagedBrowse.Add(ExpandedNodeId.ToNodeId(reference.NodeId, uaClient.Session.NamespaceUris));
}
}
else
{
duplicates++;
}
}

}

newReferenceDescriptions.Clear();

nodesToBrowse = nodesForNextManagedBrowse;

if (duplicates > 0)
{
Utils.LogInfo("Managed Browse Result {0} duplicate nodes were ignored.", duplicates);
}



}

stopWatch.Stop();

var result = new ReferenceDescriptionCollection(referenceDescriptions.Values);

result.Sort((x, y) => (x.NodeId.CompareTo(y.NodeId)));

m_output.WriteLine("ManagedBrowseFullAddressSpace found {0} references on server in {1}ms.",
result.Count, stopWatch.ElapsedMilliseconds);

if (m_verbose)
{
foreach (var reference in result)
{
m_output.WriteLine("NodeId {0} {1} {2}", reference.NodeId, reference.NodeClass, reference.BrowseName);
}
}

uaClient.Session.ContinuationPointPolicy = policyBackup;

return result;
}
#endregion

#region BrowseAddressSpace sample
/// <summary>
/// Browse full address space.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<PackageId>ConsoleReferenceClient</PackageId>
<Company>OPC Foundation</Company>
<Description>.NET Console Reference Client</Description>
<Copyright>Copyright © 2004-2022 OPC Foundation, Inc</Copyright>
<Copyright>Copyright © 2004-2024 OPC Foundation, Inc</Copyright>
<RootNamespace>Quickstarts.ConsoleReferenceClient</RootNamespace>
</PropertyGroup>

Expand Down
25 changes: 24 additions & 1 deletion Applications/ConsoleReferenceClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public static async Task Main(string[] args)
bool appLog = false;
bool renewCertificate = false;
bool loadTypes = false;
bool managedbrowseall = false;
bool browseall = false;
bool fetchall = false;
bool jsonvalues = false;
Expand Down Expand Up @@ -105,6 +106,7 @@ public static async Task Main(string[] args)
{ "t|timeout=", "timeout in seconds to exit application", (int t) => timeout = t * 1000 },
{ "logfile=", "custom file name for log output", l => { if (l != null) { logFile = l; } } },
{ "lt|loadtypes", "Load custom types", lt => { if (lt != null) loadTypes = true; } },
{ "m|managedbrowseall", "Browse all references using the MangedBrowseAsync method", m => { if (m != null) managedbrowseall = true; } },
{ "b|browseall", "Browse all references", b => { if (b != null) browseall = true; } },
{ "f|fetchall", "Fetch all nodes", f => { if (f != null) fetchall = true; } },
{ "j|json", "Output all Values as JSON", j => { if (j != null) jsonvalues = true; } },
Expand Down Expand Up @@ -259,19 +261,40 @@ await FindUserCertificateIdentifierAsync(userCertificateThumbprint,
var complexTypeSystem = await samples.LoadTypeSystemAsync(uaClient.Session).ConfigureAwait(false);
}

if (browseall || fetchall || jsonvalues)
if (browseall || fetchall || jsonvalues || managedbrowseall)
{
NodeIdCollection variableIds = null;
NodeIdCollection variableIdsManagedBrowse = null;
ReferenceDescriptionCollection referenceDescriptions = null;
ReferenceDescriptionCollection referenceDescriptionsFromManagedBrowse = null;

if (browseall)
{
output.WriteLine("Browse the full address space.");
referenceDescriptions =
await samples.BrowseFullAddressSpaceAsync(uaClient, Objects.RootFolder).ConfigureAwait(false);
variableIds = new NodeIdCollection(referenceDescriptions
.Where(r => r.NodeClass == NodeClass.Variable && r.TypeDefinition.NamespaceIndex != 0)
.Select(r => ExpandedNodeId.ToNodeId(r.NodeId, uaClient.Session.NamespaceUris)));
}

if (managedbrowseall)
{
output.WriteLine("ManagedBrowse the full address space.");
referenceDescriptionsFromManagedBrowse =
await samples.ManagedBrowseFullAddressSpaceAsync(uaClient, Objects.RootFolder).ConfigureAwait(false);
variableIdsManagedBrowse = new NodeIdCollection(referenceDescriptionsFromManagedBrowse
.Where(r => r.NodeClass == NodeClass.Variable && r.TypeDefinition.NamespaceIndex != 0)
.Select(r => ExpandedNodeId.ToNodeId(r.NodeId, uaClient.Session.NamespaceUris)));
}

// treat managedBrowseall result like browseall results if the latter is missing
if (!browseall && managedbrowseall)
{
referenceDescriptions = referenceDescriptionsFromManagedBrowse;
browseall = managedbrowseall;
}

IList<INode> allNodes = null;
if (fetchall)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
<SecurityMode>None_1</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</SecurityPolicyUri>
</ServerSecurityPolicy>
<!-- deprecated security policies for reference only -->
<!-- deprecated security policies for reference only
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256</SecurityPolicyUri>
Expand All @@ -196,7 +196,7 @@
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15</SecurityPolicyUri>
</ServerSecurityPolicy>
<!-- -->
-->
</SecurityPolicies>

<MinRequestThreadCount>5</MinRequestThreadCount>
Expand Down
1 change: 1 addition & 0 deletions Fuzzing/Encoders/Fuzz.Tests/EncoderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace Opc.Ua.Fuzzing
{

[TestFixture]
[Category("Fuzzing")]
public class EncoderTests
{
#region DataPointSources
Expand Down
5 changes: 3 additions & 2 deletions Fuzzing/Encoders/Fuzz.Tests/Opc.Ua.Encoders.Fuzz.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit.Console" Version="3.18.1" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0">
Expand All @@ -30,7 +31,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SharpFuzz" Version="2.1.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
</ItemGroup>

<ItemGroup>
Expand Down
8 changes: 6 additions & 2 deletions Libraries/Opc.Ua.Client/DataDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,12 @@ public static async Task<IDictionary<NodeId, byte[]>> ReadDictionaries(
IList<NodeId> dictionaryIds,
CancellationToken ct = default)
{
var result = new Dictionary<NodeId, byte[]>();
if (dictionaryIds.Count == 0)
{
return result;
}

ReadValueIdCollection itemsToRead = new ReadValueIdCollection();
foreach (var nodeId in dictionaryIds)
{
Expand Down Expand Up @@ -269,8 +275,6 @@ public static async Task<IDictionary<NodeId, byte[]>> ReadDictionaries(
ClientBase.ValidateResponse(values, itemsToRead);
ClientBase.ValidateDiagnosticInfos(diagnosticInfos, itemsToRead);

var result = new Dictionary<NodeId, byte[]>();

int ii = 0;
foreach (var nodeId in dictionaryIds)
{
Expand Down
Loading

0 comments on commit 7d1496d

Please sign in to comment.