Skip to content

Commit 02b91ce

Browse files
Namespace Uri Issues (#105)
* Change NamespaceURI to UpperCamelCase * Added RefAttributeType to NamespaceUri * Address Issue 100 * Fixed Issue 94. * Tests for 94 - Improper BrowseName
1 parent 0934225 commit 02b91ce

File tree

8 files changed

+156
-33
lines changed

8 files changed

+156
-33
lines changed

NodeSetToAML.cs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ public class NodeSetToAML
142142
{ Enumeration , "xs:int" }
143143
};
144144

145+
private bool _runningInstances = false;
146+
145147
public NodeSetToAML(ModelManager modelManager)
146148
{
147149
m_modelManager = modelManager;
@@ -347,6 +349,8 @@ public void CreateAML(string modelPath, string modelName = null)
347349

348350
Utils.LogInfo( "Creating Instances" );
349351

352+
_runningInstances = true;
353+
350354
CreateInstances(); // add the instances for each model
351355

352356
Utils.LogInfo( "Creating Instances Complete" );
@@ -551,42 +555,42 @@ private void AddMetaModelLibraries(CAEXDocument doc)
551555
// Manually add these to simulate what the AddModifyAttribute would do if it were possible
552556
AttributeType browseNameAttributeType = methodNodeClass.Attribute.Append( "BrowseName" );
553557
browseNameAttributeType.RefAttributeType = "[" + ATLPrefix + Opc.Ua.Namespaces.OpcUa + "]/[QualifiedName]";
554-
AttributeType namespaceUriAttributeType = browseNameAttributeType.Attribute.Append( "NamespaceURI" );
558+
AttributeType namespaceUriAttributeType = browseNameAttributeType.Attribute.Append( "NamespaceUri" );
555559
namespaceUriAttributeType.AttributeDataType = "xs:anyURI";
556560
AttributeType nameAttributeType = browseNameAttributeType.Attribute.Append( "Name" );
557561
nameAttributeType.AttributeDataType = "xs:string";
558562

559563
AddLibraryHeaderInfo( suc_meta as CAEXBasicObject);
560564
}
561565

562-
private void AddBaseNodeClassAttributes( AttributeSequence seq, UANode uanode, UANode basenode = null)
566+
private void AddBaseNodeClassAttributes( AttributeSequence seq, UANode uanode)
563567
{
564-
// only set the value if different from the base node
565-
string baseuri = "";
566-
if (basenode != null )
567-
baseuri = m_modelManager.ModelNamespaceIndexes[basenode.DecodedNodeId.NamespaceIndex].NamespaceUri;
568-
string myuri = m_modelManager.ModelNamespaceIndexes[uanode.DecodedNodeId.NamespaceIndex].NamespaceUri;
569-
570568
var nodeId = seq["NodeId"];
571569

572570
if (uanode.DecodedNodeId.IsNullNodeId == false)
573571
{
574-
ExpandedNodeId expandedNodeId = new ExpandedNodeId(uanode.DecodedNodeId, myuri);
572+
ExpandedNodeId expandedNodeId = new ExpandedNodeId(uanode.DecodedNodeId,
573+
m_modelManager.ModelNamespaceIndexes[uanode.DecodedNodeId.NamespaceIndex].NamespaceUri);
575574
Variant variant = new Variant(expandedNodeId);
576575
nodeId = AddModifyAttribute(seq, "NodeId", "NodeId", variant);
577576
}
578577

579-
var browse = seq["BrowseName"];
578+
AttributeType browse = seq["BrowseName"];
580579
if (browse == null)
581580
{
582581
browse = AddModifyAttribute(seq, "BrowseName", "QualifiedName", Variant.Null);
583582
}
584583

585-
if (myuri != baseuri)
586-
{
587-
var uriatt = browse.Attribute["NamespaceURI"];
584+
// Ensure that NamespaceUri is always present #100
585+
AttributeType uriAttribute = browse.Attribute["NamespaceUri"];
586+
uriAttribute.Value =
587+
m_modelManager.ModelNamespaceIndexes[uanode.DecodedBrowseName.NamespaceIndex].NamespaceUri;
588588

589-
uriatt.Value = myuri;
589+
// Remove the name for everything #100
590+
AttributeType nameSubAttribute = browse.Attribute["Name"];
591+
if (nameSubAttribute != null)
592+
{
593+
browse.Attribute.RemoveElement(nameSubAttribute);
590594
}
591595

592596
BuildLocalizedTextAttribute( seq, "DisplayName", uanode.DisplayName,
@@ -965,7 +969,7 @@ private AttributeType AddModifyAttribute(AttributeSequence seq, string name, str
965969
QualifiedName qualifiedName = val.Value as QualifiedName;
966970
if( qualifiedName != null )
967971
{
968-
AttributeType uri = a.Attribute[ "NamespaceURI" ];
972+
AttributeType uri = a.Attribute[ "NamespaceUri" ];
969973
uri.Value = m_modelManager.ModelNamespaceIndexes[ qualifiedName.NamespaceIndex ].NamespaceUri;
970974
AttributeType nameAttribute = a.Attribute[ "Name" ];
971975
nameAttribute.Value = qualifiedName.Name;
@@ -1580,7 +1584,7 @@ static private string BuildLibraryReference(string prefix, string namespaceURI,
15801584

15811585
private string BaseRefFromNodeId(NodeId nodeId, string LibPrefix, bool UseInverseName = false, bool IsArray = false)
15821586
{
1583-
string NamespaceURI = m_modelManager.FindModelUri(nodeId);
1587+
string NamespaceUri = m_modelManager.FindModelUri(nodeId);
15841588
var BaseNode = m_modelManager.FindNode<UANode>(nodeId);
15851589
if (BaseNode != null)
15861590
{
@@ -1590,16 +1594,16 @@ private string BaseRefFromNodeId(NodeId nodeId, string LibPrefix, bool UseInvers
15901594
if (refnode.InverseName != null)
15911595
{
15921596
if (BaseNode.DecodedBrowseName.Name != refnode.InverseName[0].Value)
1593-
return BuildLibraryReference(LibPrefix, NamespaceURI, BaseNode.DecodedBrowseName.Name, refnode.InverseName[0].Value);
1597+
return BuildLibraryReference(LibPrefix, NamespaceUri, BaseNode.DecodedBrowseName.Name, refnode.InverseName[0].Value);
15941598
}
15951599
}
15961600
if (IsArray == true)
15971601
{
1598-
return BuildLibraryReference(LibPrefix, NamespaceURI, ListOf + BaseNode.DecodedBrowseName.Name); //add ListOf
1602+
return BuildLibraryReference(LibPrefix, NamespaceUri, ListOf + BaseNode.DecodedBrowseName.Name); //add ListOf
15991603
}
16001604
else
16011605
{
1602-
return BuildLibraryReference(LibPrefix, NamespaceURI, BaseNode.DecodedBrowseName.Name);
1606+
return BuildLibraryReference(LibPrefix, NamespaceUri, BaseNode.DecodedBrowseName.Name);
16031607
}
16041608
}
16051609
return "";
@@ -2381,7 +2385,7 @@ SystemUnitFamilyType FindOrAddSUC(ref SystemUnitClassLibType scl, ref RoleClassL
23812385
// override any attribute values
23822386

23832387
var basenode = FindNode<NodeSet.UANode>(BaseNodeId);
2384-
AddBaseNodeClassAttributes(rtn.Attribute, refnode, basenode);
2388+
AddBaseNodeClassAttributes(rtn.Attribute, refnode);
23852389
switch (refnode.NodeClass)
23862390
{
23872391
case NodeClass.ObjectType:
@@ -2469,7 +2473,7 @@ SystemUnitFamilyType FindOrAddSUC(ref SystemUnitClassLibType scl, ref RoleClassL
24692473
rtn.AddInstance(ie);
24702474

24712475
var basenode = FindNode<NodeSet.UANode>(TypeDefNodeId);
2472-
AddBaseNodeClassAttributes(ie.Attribute, targetNode, basenode);
2476+
AddBaseNodeClassAttributes(ie.Attribute, targetNode);
24732477
if (targetNode.NodeClass == NodeClass.Variable)
24742478
{ // Set the datatype for Value
24752479
var varnode = targetNode as NodeSet.UAVariable;
@@ -2786,11 +2790,15 @@ private void ProcessOptionSets(ref AttributeTypeType att, NodeId nodeId)
27862790
}
27872791
else if (nodeId == QualifiedNameNodeId)
27882792
{
2793+
string namespaceUriPath = BuildLibraryReference(ATLPrefix, MetaModelName, "NamespaceUri");
2794+
AttributeFamilyType namespaceUriRoot = m_cAEXDocument.FindByPath(namespaceUriPath) as AttributeFamilyType;
2795+
2796+
AttributeType newNamespaceUri = new AttributeType(new System.Xml.Linq.XElement(defaultNS + "Attribute"));
2797+
newNamespaceUri.Name = "NamespaceUri";
2798+
newNamespaceUri.RecreateAttributeInstance(namespaceUriRoot);
2799+
att.Attribute.Insert(newNamespaceUri);
2800+
27892801
att.AttributeDataType = "";
2790-
AttributeType ns = new AttributeType(new System.Xml.Linq.XElement(defaultNS + "Attribute"));
2791-
ns.Name = "NamespaceURI";
2792-
ns.AttributeDataType = "xs:anyURI";
2793-
att.Attribute.Insert(ns);
27942802
AttributeType n = new AttributeType(new System.Xml.Linq.XElement(defaultNS + "Attribute"));
27952803
n.Name = "Name";
27962804
n.AttributeDataType = "xs:string";

SystemTest/NodeSetFiles/AmlFxTest.xml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
<Uri>http://opcfoundation.org/UA/FX/AML/TESTING/AmlFxTest/</Uri>
55
<Uri>http://opcfoundation.org/UA/FX/AC/</Uri>
66
<Uri>http://opcfoundation.org/UA/FX/Data/</Uri>
7-
</NamespaceUris>
7+
<Uri>http://opcfoundation.org/UA/DI/</Uri>
8+
</NamespaceUris>
89
<Models>
910
<Model ModelUri="http://opcfoundation.org/UA/FX/AML/TESTING/AmlFxTest/">
1011
<RequiredModel ModelUri="http://opcfoundation.org/UA/FX/AC/" />
1112
</Model>
1213
</Models>
1314
<Aliases>
14-
<Alias Alias="Organizes">i=35</Alias>
15+
<Alias Alias="LocalizedText">i=21</Alias>
16+
<Alias Alias="Organizes">i=35</Alias>
1517
<Alias Alias="HasTypeDefinition">i=40</Alias>
1618
<Alias Alias="HasProperty">i=46</Alias>
1719
<Alias Alias="HasComponent">i=47</Alias>
@@ -77,7 +79,23 @@
7779
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=5003</Reference>
7880
</References>
7981
</UAObject>
80-
<UAMethod ParentNodeId="ns=1;i=5003" NodeId="ns=1;i=7001" BrowseName="2:CloseConnections" MethodDeclarationId="ns=2;i=293">
82+
83+
<UAObject NodeId="ns=1;i=5008" BrowseName="1:AnAsset" ParentNodeId="ns=1;i=5004">
84+
<DisplayName>AnAsset</DisplayName>
85+
<References>
86+
<Reference ReferenceType="Organizes" IsForward="false">ns=1;i=5004</Reference>
87+
<Reference ReferenceType="HasTypeDefinition">ns=2;i=3</Reference>
88+
</References>
89+
</UAObject>
90+
<UAVariable DataType="LocalizedText" NodeId="ns=1;i=6008" BrowseName="4:Manufacturer" ParentNodeId="ns=1;i=5008" UserAccessLevel="3" AccessLevel="3">
91+
<DisplayName>Manufacturer</DisplayName>
92+
<References>
93+
<Reference ReferenceType="HasProperty" IsForward="false">ns=1;i=5008</Reference>
94+
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
95+
</References>
96+
</UAVariable>
97+
98+
<UAMethod ParentNodeId="ns=1;i=5003" NodeId="ns=1;i=7001" BrowseName="2:CloseConnections" MethodDeclarationId="ns=2;i=293">
8199
<DisplayName>CloseConnections</DisplayName>
82100
<References>
83101
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=5003</Reference>

SystemTest/TestAttributes.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void TestMethodClassAttributes()
7171
AttributeType browseNameAttribute = objectToTest.Attribute[ "BrowseName" ];
7272
Assert.IsNotNull( browseNameAttribute );
7373

74-
AttributeType namespaceUriAttribute = browseNameAttribute.Attribute[ "NamespaceURI" ];
74+
AttributeType namespaceUriAttribute = browseNameAttribute.Attribute[ "NamespaceUri" ];
7575
Assert.IsNotNull( namespaceUriAttribute );
7676
Assert.AreEqual( "xs:anyURI", namespaceUriAttribute.AttributeDataType );
7777

SystemTest/TestComplexNonRootNamespace.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ public void ValidateQualifiedName( AttributeType attribute, string name, string
638638
{
639639
AttributeType qualifiedNameAttribute = GetAttribute( attribute, name, validateSubAttributes: true );
640640
AttributeType nameAttribute = GetAttribute( qualifiedNameAttribute, "Name", validateSubAttributes: false );
641-
AttributeType namespaceUriAttribute = GetAttribute( qualifiedNameAttribute, "NamespaceURI", validateSubAttributes: false );
641+
AttributeType namespaceUriAttribute = GetAttribute( qualifiedNameAttribute, "NamespaceUri", validateSubAttributes: false );
642642

643643
Assert.AreEqual( uri, namespaceUriAttribute.Value );
644644
Assert.AreEqual( "xs:anyURI", namespaceUriAttribute.AttributeDataType );

SystemTest/TestComplexRootNamespace.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ public void ValidateQualifiedName( AttributeType attribute, string name, string
309309
{
310310
AttributeType qualifiedNameAttribute = GetAttribute( attribute, name, validateSubAttributes: true );
311311
AttributeType nameAttribute = GetAttribute( qualifiedNameAttribute, "Name", validateSubAttributes: false );
312-
AttributeType namespaceUriAttribute = GetAttribute( qualifiedNameAttribute, "NamespaceURI", validateSubAttributes: false );
312+
AttributeType namespaceUriAttribute = GetAttribute( qualifiedNameAttribute, "NamespaceUri", validateSubAttributes: false );
313313

314314
Assert.AreEqual( uri, namespaceUriAttribute.Value );
315315
Assert.AreEqual( "xs:anyURI", namespaceUriAttribute.AttributeDataType );

SystemTest/TestDataTypes.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class TestDataTypes
2727
[DataRow( "6192", "2023-09-13T14:39:08-06:00", "xs:dateTime", "SourceTimestamp", DisplayName = "SourceTimestamp" )]
2828

2929
[DataRow( "6191", "d23c82b6-1715-4951-acd1-84fb898d6b6c", "xs:string", DisplayName = "Guid" )]
30-
[DataRow( "6190", "http://opcfoundation.org/UA/FX/AML/TESTING", "xs:anyURI", "NamespaceURI", DisplayName = "Qualified NamespaceURI" )]
30+
[DataRow( "6190", "http://opcfoundation.org/UA/FX/AML/TESTING", "xs:anyURI", "NamespaceUri", DisplayName = "Qualified NamespaceUri" )]
3131
[DataRow( "6190", "MyQualifiedName", "xs:string", "Name", DisplayName = "Qualified Name" )]
3232

3333
[DataRow( "6139", "StringNodeId", "xs:string", "RootNodeId", "StringId", DisplayName = "NodeId String" )]

SystemTest/TestMultiDimensionalArray.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public void TestMethodClassAttributes()
9292
AttributeType browseNameAttribute = objectToTest.Attribute[ "BrowseName" ];
9393
Assert.IsNotNull( browseNameAttribute );
9494

95-
AttributeType namespaceUriAttribute = browseNameAttribute.Attribute[ "NamespaceURI" ];
95+
AttributeType namespaceUriAttribute = browseNameAttribute.Attribute[ "NamespaceUri" ];
9696
Assert.IsNotNull( namespaceUriAttribute );
9797
Assert.AreEqual( "xs:anyURI", namespaceUriAttribute.AttributeDataType );
9898

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using System;
3+
using System.IO;
4+
using Aml.Engine.AmlObjects;
5+
using Aml.Engine.CAEX;
6+
using Aml.Engine.CAEX.Extensions;
7+
using Opc.Ua;
8+
9+
10+
namespace SystemTest
11+
{
12+
[TestClass]
13+
public class TestNamespaceUriAttributes
14+
{
15+
// Test is to address issue 94 -
16+
// The Namespaces of BrowseNames differ between the generated AML file and the original Nodeset file.
17+
// Test Both NodeId NamespaceUris and BrowseNameUris
18+
19+
private const string FxIdPrefix = "nsu%3Dhttp%3A%2F%2Fopcfoundation.org%2FUA%2FFX%2FAC%2F%3Bi%3D";
20+
private const string AmlFxTestPrefix = "nsu%3Dhttp%3A%2F%2Fopcfoundation.org%2FUA%2FFX%2FAML%2FTESTING%2FAmlFxTest%2F%3Bi%3D";
21+
public const string TestAmlUri = "http://opcfoundation.org/UA/FX/AML/TESTING/AmlFxTest/";
22+
private const string FxAcUri = "http://opcfoundation.org/UA/FX/AC/";
23+
private const string DiUri = "http://opcfoundation.org/UA/DI/";
24+
25+
CAEXDocument m_document = null;
26+
27+
#region Tests
28+
29+
[TestMethod, Timeout( TestHelper.UnitTestTimeout )]
30+
[DataRow( false, "3", FxAcUri, DisplayName = "FxAssetType" )]
31+
[DataRow( false, "175", FxAcUri, DisplayName = "Manufacturer" )]
32+
[DataRow( true, "5008", TestAmlUri, DisplayName = "Asset Instance" )]
33+
[DataRow( true, "6008", TestAmlUri, DisplayName = "Manufacturer Instance")]
34+
public void TestNodeIds( bool instance, string nodeIdentifier, string expectedUri)
35+
{
36+
SystemUnitClassType objectToTest = GetTestObject( instance, nodeIdentifier );
37+
AttributeType nodeId = objectToTest.Attribute[ "NodeId" ];
38+
Assert.IsNotNull( nodeId );
39+
AttributeType rootNodeId = nodeId.Attribute[ "RootNodeId" ];
40+
Assert.IsNotNull( rootNodeId );
41+
AttributeType namespaceUri = rootNodeId.Attribute[ "NamespaceUri" ];
42+
Assert.IsNotNull( namespaceUri );
43+
Assert.AreEqual( expectedUri, namespaceUri.Value );
44+
45+
AttributeType identifier = rootNodeId.Attribute[ "NumericId" ];
46+
Assert.IsNotNull( identifier );
47+
Assert.AreEqual( nodeIdentifier, identifier.Value );
48+
}
49+
50+
[TestMethod, Timeout(TestHelper.UnitTestTimeout)]
51+
[DataRow(false, "3", FxAcUri, DisplayName = "FxAssetType")]
52+
[DataRow(false, "175", DiUri, DisplayName = "Manufacturer")]
53+
[DataRow(true, "5008", TestAmlUri, DisplayName = "Asset Instance")]
54+
[DataRow(true, "6008", DiUri, DisplayName = "Manufacturer Instance")]
55+
public void TestBrowseNames(bool instance, string nodeIdentifier, string expectedUri)
56+
{
57+
SystemUnitClassType objectToTest = GetTestObject(instance, nodeIdentifier);
58+
AttributeType browseName = objectToTest.Attribute["BrowseName"];
59+
Assert.IsNotNull(browseName);
60+
AttributeType namespaceUri = browseName.Attribute["NamespaceUri"];
61+
Assert.IsNotNull(namespaceUri);
62+
Assert.AreEqual(expectedUri, namespaceUri.Value);
63+
}
64+
65+
#endregion
66+
67+
#region Helpers
68+
69+
private CAEXDocument GetDocument()
70+
{
71+
if( m_document == null )
72+
{
73+
m_document = TestHelper.GetReadOnlyDocument( "AmlFxTest.xml.amlx" );
74+
}
75+
Assert.IsNotNull( m_document, "Unable to retrieve Document" );
76+
return m_document;
77+
}
78+
79+
public SystemUnitClassType GetTestObject(bool instance, string nodeId)
80+
{
81+
CAEXDocument document = GetDocument();
82+
83+
string rootName = FxIdPrefix;
84+
if ( instance )
85+
{
86+
rootName = AmlFxTestPrefix;
87+
}
88+
CAEXObject initialObject = document.FindByID(rootName + nodeId);
89+
Assert.IsNotNull(initialObject, "Unable to find Initial Object");
90+
SystemUnitClassType theObject = initialObject as SystemUnitClassType;
91+
Assert.IsNotNull(theObject, "Unable to Cast Initial Object");
92+
return theObject;
93+
}
94+
95+
#endregion
96+
}
97+
}

0 commit comments

Comments
 (0)