Skip to content

Commit

Permalink
NetworkIdentifier is missing in generated Model Design for DI model #629
Browse files Browse the repository at this point in the history


- Development in progress
  • Loading branch information
mpostol committed Mar 16, 2022
1 parent 8adb673 commit 045b62d
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 103 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//___________________________________________________________________________________
//__________________________________________________________________________________________________
//
// Copyright (C) 2021, Mariusz Postol LODZ POLAND.
// Copyright (C) 2022, Mariusz Postol LODZ POLAND.
//
// To be in touch join the community at GITTER: https://gitter.im/mpostol/OPC-UA-OOI
//___________________________________________________________________________________
// To be in touch join the community at GitHub: https://github.com/mpostol/OPC-UA-OOI/discussions
//__________________________________________________________________________________________________

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
Expand Down Expand Up @@ -195,8 +195,9 @@ public void CalculateNodeReferencesNullArguments()
Mock<IValidator> _validatorMoc = new Mock<IValidator>();
List<TraceMessage> _traceBuffer = new List<TraceMessage>();
IUANodeBase _first = new UANodeContext(NodeId.Parse("ns=1;i=11"), _addressSpaceMock.Object, x => _traceBuffer.Add(x));
Assert.ThrowsException<ArgumentNullException>(() => _first.CalculateNodeReferences(null, _validatorMoc.Object));
Assert.ThrowsException<ArgumentNullException>(() => _first.CalculateNodeReferences(_mockNodeFactory.Object, null));
Assert.ThrowsException<ArgumentNullException>(() => _first.CalculateNodeReferences(null, _validatorMoc.Object, y => { }));
Assert.ThrowsException<ArgumentNullException>(() => _first.CalculateNodeReferences(_mockNodeFactory.Object, null, y => { }));
Assert.ThrowsException<ArgumentNullException>(() => _first.CalculateNodeReferences(_mockNodeFactory.Object, _validatorMoc.Object, null));
}

[TestMethod]
Expand Down Expand Up @@ -233,14 +234,17 @@ public void CalculateNodeReferencesNullUANodeTest()
Mock<INodeFactory> _mockNodeFactory = new Mock<INodeFactory>();
_mockNodeFactory.Setup(x => x.NewReference()).Returns(referenceFactoryMock.Object);
Mock<IValidator> _validatorMoc = new Mock<IValidator>();
_validatorMoc.Setup(x => x.ValidateExportNode(It.IsAny<IUANodeBase>(), _mockNodeFactory.Object, It.IsAny<UAReferenceContext>()));
_validatorMoc.Setup(x => x.ValidateExportNode(It.IsAny<IUANodeBase>(), _mockNodeFactory.Object, It.IsAny<Action<IUANodeContext>>(), It.IsAny<UAReferenceContext>()));

//testing
((IUANodeBase)node2Test).CalculateNodeReferences(_mockNodeFactory.Object, _validatorMoc.Object);
int counter = 0;
((IUANodeBase)node2Test).CalculateNodeReferences(_mockNodeFactory.Object, _validatorMoc.Object, y => counter++);

//validation
Assert.AreEqual<int>(1, counter);
addressSpaceMock.Verify(x => x.GetMyReferences(It.IsAny<IUANodeBase>()), Times.Once);
addressSpaceMock.Verify(x => x.ExportBrowseName(It.IsAny<NodeId>(), It.IsAny<NodeId>()), Times.Once);
_validatorMoc.Verify(x => x.ValidateExportNode(It.IsAny<IUANodeBase>(), _mockNodeFactory.Object, It.IsAny<UAReferenceContext>()), Times.Never);
_validatorMoc.Verify(x => x.ValidateExportNode(It.Is<IUANodeBase>(z => z == targetMock.Object), _mockNodeFactory.Object, It.IsAny<Action<IUANodeContext>>(), It.Is<UAReferenceContext>(y => y == listOfReferences[0])), Times.Never);
Assert.AreEqual<int>(0, _traceBuffer.Count, _traceBuffer.Count == 0 ? "" : _traceBuffer[0].Message);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//__________________________________________________________________________________________________
//
// Copyright (C) 2021, Mariusz Postol LODZ POLAND.
// Copyright (C) 2022, Mariusz Postol LODZ POLAND.
//
// To be in touch join the community at GitHub: https://github.com/mpostol/OPC-UA-OOI/discussions
//__________________________________________________________________________________________________
Expand Down Expand Up @@ -56,15 +56,15 @@ public void UAMethodTest()
DisplayName = new LocalizedText[] { new LocalizedText() { Value = "Start" } },
References = new Reference[] { }
};
List<TraceMessage> traceBuffer = new List<TraceMessage>();
List<TraceMessage> traceBuffer = new List<TraceMessage>();
UANodeContext nodeContext = new UANodeContext(DataSerialization.NodeId.Parse(method.NodeId), addressSpaceBuildContextMock.Object, x => traceBuffer.Add(x));
nodeContext.Update(method, x => { });
Mock<INodeContainer> nodeContainerMock = new Mock<INodeContainer>();
Mock<IMethodInstanceFactory> methodInstanceFactory = new Mock<IMethodInstanceFactory>();
nodeContainerMock.Setup(x => x.AddNodeFactory<IMethodInstanceFactory>()).Returns(methodInstanceFactory.Object);
//TODO UANodeSetValidation.Extensions.GetObject - object reference not set #624
Assert.Inconclusive("UANodeSetValidation.Extensions.GetObject - object reference not set #624");
_i2t.ValidateExportNode(nodeContext, nodeContainerMock.Object);
_i2t.ValidateExportNode(nodeContext, nodeContainerMock.Object, z => { });
Assert.AreEqual<int>(0, traceBuffer.Count);
}
}
Expand Down
37 changes: 22 additions & 15 deletions SemanticData/UANodeSetValidation/AddressSpaceContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,16 +312,17 @@ private IUANodeContext TryGetUANodeContext(NodeId nodeId)
return _ret;
}

//TODO NetworkIdentifier is missing in generated Model Design for DI model #629
private void ValidateAndExportModel(int nameSpaceIndex)
{
IValidator validator = new Validator(this, m_TraceEvent);
IEnumerable<IUANodeContext> stubs = from _key in m_NodesDictionary.Values where _key.NodeIdContext.NamespaceIndex == nameSpaceIndex select _key;
IEnumerable<IUANodeContext> undefindNodes = from node in stubs
where Object.ReferenceEquals(node.UANode, null)
select node;
foreach (IUANodeContext item in undefindNodes)
IEnumerable<IUANodeBase> stubs = from _key in m_NodesDictionary.Values where _key.NodeIdContext.NamespaceIndex == nameSpaceIndex select _key;
IEnumerable<IUANodeBase> undefindNodes = from node in stubs
where Object.ReferenceEquals(node.UANode, null)
select node;
foreach (IUANodeBase item in undefindNodes)
m_TraceEvent.WriteTraceMessage(TraceMessage.BuildErrorTraceMessage(BuildError.NodeCannotBeNull, $"the node {item.ToString()} is not defined in the UANodeSet model"));
List<IUANodeContext> nodes = (from _node in stubs where _node.UANode != null && (_node.UANode is UAType) select _node).ToList();
List<IUANodeBase> nodes = (from _node in stubs where _node.UANode != null && (_node.UANode is UAType) select _node).ToList();
m_TraceEvent.TraceData(TraceEventType.Verbose, 938023414, $"Selected {nodes.Count} types to be validated.");
IUANodeBase _objects = TryGetUANodeContext(UAInformationModel.ObjectIds.ObjectsFolder);
if (_objects is null)
Expand All @@ -338,18 +339,24 @@ where Object.ReferenceEquals(node.UANode, null)
string _version = modelTableEntry.Version;
InformationModelFactory.CreateNamespace(modelTableEntry.ModelUri.ToString(), _publicationDate, _version);
}
foreach (IUANodeBase item in nodes)
//NetworkIdentifier is missing in generated Model Design for DI model #629
do
{
try
{
validator.ValidateExportNode(item, InformationModelFactory);
}
catch (Exception ex)
NodesCollection embededNodes = new NodesCollection();
foreach (IUANodeBase item in nodes)
{
string msg = string.Format("Error caught while processing the node {0}. The message: {1} at {2}.", item.UANode.NodeId, ex.Message, ex.StackTrace);
m_TraceEvent.WriteTraceMessage(TraceMessage.BuildErrorTraceMessage(BuildError.NonCategorized, msg));
try
{
validator.ValidateExportNode(item, InformationModelFactory, y => { if (y.NodeIdContext.NamespaceIndex == nameSpaceIndex) embededNodes.AddOrReplace(y, false); });
}
catch (Exception ex)
{
string msg = string.Format("Error caught while processing the node {0}. The message: {1} at {2}.", item.UANode.NodeId, ex.Message, ex.StackTrace);
m_TraceEvent.WriteTraceMessage(TraceMessage.BuildErrorTraceMessage(BuildError.NonCategorized, msg));
}
}
}
nodes = embededNodes.ToList();
} while (nodes.Count > 0);
string message = null;
if (m_TraceEvent.Errors == 0)
{
Expand Down
31 changes: 19 additions & 12 deletions SemanticData/UANodeSetValidation/IUANodeBase.cs
Original file line number Diff line number Diff line change
@@ -1,76 +1,84 @@
//___________________________________________________________________________________
//__________________________________________________________________________________________________
//
// Copyright (C) 2021, Mariusz Postol LODZ POLAND.
// Copyright (C) 2022, Mariusz Postol LODZ POLAND.
//
// To be in touch join the community at GITTER: https://gitter.im/mpostol/OPC-UA-OOI
//___________________________________________________________________________________
// To be in touch join the community at GitHub: https://github.com/mpostol/OPC-UA-OOI/discussions
//__________________________________________________________________________________________________

using System;
using System.Collections.Generic;
using System.Xml;
using UAOOI.SemanticData.InformationModelFactory;
using UAOOI.SemanticData.UANodeSetValidation.DataSerialization;
using UAOOI.SemanticData.UANodeSetValidation.XML;

namespace UAOOI.SemanticData.UANodeSetValidation
{

/// <summary>
/// Interface IUANodeBase - if implemented captures all basic information represented by the UA Node
/// </summary>
internal interface IUANodeBase: IEquatable<IUANodeBase>
internal interface IUANodeBase : IEquatable<IUANodeBase>
{

/// <summary>
/// Calculates the node references.
/// </summary>
/// <param name="nodeFactory">The node factory.</param>
/// <param name="validator">The validator.</param>
void CalculateNodeReferences(INodeFactory nodeFactory, IValidator validator);
/// <param name="validateExportNode2Model">It creates the node at the top level of the model. Called if the node has reference to another node that cannot be defined as a child.</param>
void CalculateNodeReferences(INodeFactory nodeFactory, IValidator validator, Action<IUANodeContext> validateExportNode2Model);

/// <summary>
/// Gets the node identifier.
/// </summary>
/// <value>The imported node identifier.</value>
NodeId NodeIdContext { get; }

/// <summary>
/// Gets the wrapped node described by the <see cref="UANode"/> type.
/// </summary>
UANode UANode { get; }

/// <summary>
/// Exports the browse name of the wrapped node by this instance.
/// </summary>
/// <returns>An instance of <see cref="XmlQualifiedName" /> representing the browse name of the node.</returns>
XmlQualifiedName ExportNodeBrowseName();

/// <summary>
/// Gets a value indicating whether this instance is a property.
/// </summary>
/// <value><c>true</c> if this instance is property; otherwise, <c>false</c>.</value>
bool IsProperty { get; }

/// <summary>
/// Gets a value indicating whether this instance is property variable type.
/// </summary>
/// <value><c>true</c> if this instance is property variable type; otherwise, <c>false</c>.</value>
bool IsPropertyVariableType { get; }

/// <summary>
/// Exports the browse name of this node recognized as <see cref="ReferenceKindEnum.HasSubtype"/> or <see cref="ReferenceKindEnum.HasTypeDefinition"/> target.
/// </summary>
/// <param name="traceEvent">The trace event.</param>
/// <returns>An instance of <see cref="XmlQualifiedName"/> representing subtype or type of an instance.</returns>
XmlQualifiedName ExportBrowseNameBaseType(Action<NodeId> traceEvent);

/// <summary>
/// Gets the derived instances.
/// </summary>
Dictionary<string, IUANodeBase> GetDerivedInstances();
NodesCollection GetDerivedInstances();

/// <summary>
/// Exports the BrowseName of the BaseType.
/// </summary>
/// <returns>An instance of <see cref="XmlQualifiedName" /> representing the base type..</returns>
XmlQualifiedName ExportBaseTypeBrowseName();

/// <summary>
/// Gets the modeling rule associated with this node.
/// </summary>
/// <value>The <see cref="ModelingRules"/> associated with the node. Null if valid modeling rule cannot be recognized.</value>
ModelingRules? ModelingRule { get; }

/// <summary>
/// Removes the inherited values.
/// </summary>
Expand All @@ -79,6 +87,5 @@ internal interface IUANodeBase: IEquatable<IUANodeBase>
/// If a member is overridden all inherited values of the node attributes must be removed.
/// </remarks>
void RemoveInheritedValues(IUANodeBase instanceDeclaration);

}
}
}
15 changes: 9 additions & 6 deletions SemanticData/UANodeSetValidation/IValidator.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//___________________________________________________________________________________
//__________________________________________________________________________________________________
//
// Copyright (C) 2021, Mariusz Postol LODZ POLAND.
// Copyright (C) 2022, Mariusz Postol LODZ POLAND.
//
// To be in touch join the community at GITTER: https://gitter.im/mpostol/OPC-UA-OOI
//___________________________________________________________________________________
// To be in touch join the community at GitHub: https://github.com/mpostol/OPC-UA-OOI/discussions
//__________________________________________________________________________________________________

using System;
using UAOOI.SemanticData.InformationModelFactory;

namespace UAOOI.SemanticData.UANodeSetValidation
Expand All @@ -20,13 +21,15 @@ internal interface IValidator
/// <param name="nodeContext">The node context to be validated and exported.</param>
/// <param name="exportFactory">A model export factory.</param>
/// <param name="parentReference">The reference to parent node.</param>
void ValidateExportNode(IUANodeBase nodeContext, INodeContainer exportFactory, UAReferenceContext parentReference);
/// <param name="validateExportNode2Model">It creates the node at the top level of the model. Called if the node has reference to another node that cannot be defined as a child.</param>
void ValidateExportNode(IUANodeBase nodeContext, INodeContainer exportFactory, Action<IUANodeContext> validateExportNode2Model, UAReferenceContext parentReference);

/// <summary>
/// Validates <paramref name="nodeContext" /> and exports it using an object of <see cref="IModelFactory" /> type.
/// </summary>
/// <param name="nodeContext">The node context to be validated and exported.</param>
/// <param name="exportFactory">A model export factory.</param>
void ValidateExportNode(IUANodeBase nodeContext, INodeContainer exportFactory);
/// <param name="validateExportNode2Model">It creates the node at the top level of the model. Called if the node has reference to another node that cannot be defined as a child.</param>
void ValidateExportNode(IUANodeBase nodeContext, INodeContainer exportFactory, Action<IUANodeContext> validateExportNode2Model);
}
}
8 changes: 1 addition & 7 deletions SemanticData/UANodeSetValidation/ReferenceKindEnum.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//__________________________________________________________________________________________________
//
// Copyright (C) 2021, Mariusz Postol LODZ POLAND.
// Copyright (C) 2022, Mariusz Postol LODZ POLAND.
//
// To be in touch join the community at GitHub: https://github.com/mpostol/OPC-UA-OOI/discussions
//__________________________________________________________________________________________________


namespace UAOOI.SemanticData.UANodeSetValidation
{
/// <summary>
Expand Down Expand Up @@ -33,11 +32,6 @@ internal enum ReferenceKindEnum
/// </summary>
HasTypeDefinition,

/// <summary>
/// The HierarchicalReferences
/// </summary>
HierarchicalReferences,

/// <summary>
/// The HasSubtype
/// </summary>
Expand Down
Loading

0 comments on commit 045b62d

Please sign in to comment.