We are calling NodeStateCollection::SaveAsNodeSet2 to save a NodeStateCollection to XML. After the file has been saved to disk we see that all HasSubtypeReferences reference appear exactly twice in the saved XML file.
The cause seems to be that the NodeStateCollection has an object type which has an associated super type and many subtypes. Specifically, the SuperTypeId field is set to a super type and the list of references contains sub types.
Expected Behavior
When the file is saved each exported reference should occur only one time in the XML file. When processing references there should be some check in place to skip references which have already been added.
protected override void PopulateBrowser(ISystemContext context, NodeBrowser browser)
{
base.PopulateBrowser(context, browser); // (a) this adds all references
[...]
// use the type table to find the subtypes.
if (context.TypeTable != null && this.NodeId != null)
{
if (browser.IsRequired(ReferenceTypeIds.HasSubtype, false))
{
IList<NodeId> subtypeIds = context.TypeTable.FindSubTypes(this.NodeId);
for (int ii = 0; ii < subtypeIds.Count; ii++)
{
// (b) this adds subtype references which were already added in step (a) above
browser.Add(ReferenceTypeIds.HasSubtype, false, subtypeIds[ii]);
}
}
}
}
We have only seen this for NodeStateCollections which contain object types that again have subtype references.
Environment
- OS: Linux (based on the code analysis above, this should not be a platform specific issue)
- Environment: not an environment specific issue
- Runtime: Dotnet 6.0.x
- Nuget Version: We are using 1.4.365.48, but since I can trace the same code path in the latest master branch it should not matter.
- Component: Opc.Ua.Core
- Server: Derived from StandardServer
- Client: N/A
Type of issue
Current Behavior
We are calling
NodeStateCollection::SaveAsNodeSet2
to save a NodeStateCollection to XML. After the file has been saved to disk we see that allHasSubtypeReferences
reference appear exactly twice in the saved XML file.The cause seems to be that the
NodeStateCollection
has an object type which has an associated super type and many subtypes. Specifically, theSuperTypeId
field is set to a super type and the list of references contains sub types.Expected Behavior
When the file is saved each exported reference should occur only one time in the XML file. When processing references there should be some check in place to skip references which have already been added.
Steps To Reproduce
We have traced the bug to the
BaseTypeState.PopulateBrowser
method as can be seen in this stack trace:What appears to happen is the following:
NodeStateCollection:SaveAsNodeSet2
we call intoBaseTypeState.Export
, which delegates to the base implementation inUaNodeSet::Export
.UaNodeSet::Export
we create anINodeBrowser
via a call tonode.CreateBrowser
. The node is in our case derived fromObjectType
:Note that the direction is set to
BrowseDirection.Both
and theincludeSubtypes
flag is set totrue
.NodeState::CreateBrowser
we call the virtualPopulateBrowser()
method which is overridden in BaseTypeState::PopulateBrowser: https://github.com/OPCFoundation/UA-.NETStandard/blob/eda38cb6c22d6e7c4cb2e5507cb76f14849215cd/Stack/Opc.Ua.Core/Stack/State/BaseTypeState.cs#L384base.PopulateBrowser
which is implemented inNodeState::PopulateBrowser
. Here we first add all references of the node: https://github.com/OPCFoundation/UA-.NETStandard/blob/eda38cb6c22d6e7c4cb2e5507cb76f14849215cd/Stack/Opc.Ua.Core/Stack/State/NodeState.cs#L3133However, in the overriden PopulateBrowser methods we then find all subtypes and add them again: https://github.com/OPCFoundation/UA-.NETStandard/blob/eda38cb6c22d6e7c4cb2e5507cb76f14849215cd/Stack/Opc.Ua.Core/Stack/State/BaseTypeState.cs#L405
We have only seen this for
NodeStateCollections
which contain object types that again have subtype references.Environment
Anything else?
No response