From 34ee3b8e84f730838bf4747821f1f9a948879660 Mon Sep 17 00:00:00 2001 From: MPostol Date: Thu, 17 Mar 2022 22:56:01 +0100 Subject: [PATCH] NetworkIdentifier is missing in generated Model Design for DI model #629 - fixes #651 - UT must be fixed - nodes could be duplicated if they are the target of 2+ references --- .../BuildingErrorsHandling/BuildErrors.cs | 8 + .../XML/BuildErrorsCollection.xml | 526 +++++++++--------- .../UANodeSetValidation/UANodeContext.cs | 45 +- SemanticData/UANodeSetValidation/Validator.cs | 3 +- 4 files changed, 299 insertions(+), 283 deletions(-) diff --git a/SemanticData/BuildingErrorsHandling/BuildErrors.cs b/SemanticData/BuildingErrorsHandling/BuildErrors.cs index 7814f7e5..2118ec90 100644 --- a/SemanticData/BuildingErrorsHandling/BuildErrors.cs +++ b/SemanticData/BuildingErrorsHandling/BuildErrors.cs @@ -14,6 +14,14 @@ namespace UAOOI.SemanticData.BuildingErrorsHandling public partial class BuildError { /// + /// Error: P3-0305000000; Focus: Reference; It is not allowed that References are used to create a looping hierarchy. + /// + /// An instance of describing the error P3-0305000000. + public static BuildError NotValidLoopingHierarchy { get { return new BuildError() + { Focus = Focus.Reference, + Identifier = "P3-0305000000", + Descriptor = "It is not allowed that References are used to create a looping hierarchy." }; } } + /// /// Error: P0-0001010000; Focus: Diagnostic; The XML attribute or element is not supported and neglected. /// /// An instance of describing the error P0-0001010000. diff --git a/SemanticData/BuildingErrorsHandling/XML/BuildErrorsCollection.xml b/SemanticData/BuildingErrorsHandling/XML/BuildErrorsCollection.xml index bf968024..ab72cd74 100644 --- a/SemanticData/BuildingErrorsHandling/XML/BuildErrorsCollection.xml +++ b/SemanticData/BuildingErrorsHandling/XML/BuildErrorsCollection.xml @@ -1,263 +1,269 @@ - - - Diagnostic - P0-0001010000 - The XML attribute or element is not supported and neglected. - NotSupportedFeature - - - XML - P0-0001020000 - Node cannot be null - NodeCannotBeNull - - - XML - P0-0001030000 - Models element cannot be null or empty - ModelsCannotBeNull - - - XML - P0-0001040000 - NamespaceUris element cannot be null or empty - NamespaceUrisCannotBeNull - - - XML - P0-0001050000 - Selected model contains errors. - ModelContainsErrors - - - NonCategorized - P0-0002010000 - General processing error see trace for details. - NonCategorized - - - Diagnostic - P0-0003010000 - It is diagnostic information - DiagnosticInformation - - - NodeClass - P0-0605020209 - The syntax of the NodeId is not valid. - NodeIdInvalidSyntax - - - NodeClass - P0-0605020210 - The syntax of the ExpandedNodeId is not valid. - ExpandedNodeIdInvalidSyntax - - - DataEncoding - P6-0503021400 - The syntax of the QualifiedName is not valid. - QualifiedNameInvalidSyntax - - - NodeClass - P3-0403040000 - The reference target doesn't exist. OPC UA does not require that the TargetNode exists, thus References may point to a Node that does not exist. - DanglingReferenceTarget - - - NodeClass - P3-0502020000 - Nodes shall be unambiguously identified using NodeId - NodeIdDuplicated - - - NodeClass - P3-0502020001 - NodeId is not defined. - NodeIdNotDefined - - - NodeClass - P3-0502050000 - The string part of the DisplayName is restricted to 512 characters. - WrongDisplayNameLength - - - NodeClass - P3-0502070000 - The value must be less than 0x200000 for the UAVariable and less than 0x400000 for other node types. - WrongWriteMaskValue - - - NodeClass - P3-0856000000 - The value must be less than 0x7. - WrongAccessRestriction - - - NodeClass - P3-0503020000 - Unexpected value of the InverseName. - WrongInverseName - - - NodeClass - P3-0503020001 - The BrowseName of a ReferenceType shall be unique. - DuplicatedReferenceType - - - NodeClass - P3-0503020002 - The BrowseName of a ReferenceType is defined outside of the model. - BrowseNameReferenceTypeScope - - - Reference - P3-0503030201 - Wrong Reference type targeting the Property component. - WrongReference2Property - - - NodeClass - P3-0505010000 - Object NodeClass: EventNotifier is out of range. - WrongEventNotifier - - - NodeClass - P3-0505010001 - Object NodeClass: Value of the EventNotifier attribute is not supported. - EventNotifierValueNotSupported - - - NodeClass - P3-0506020000 - ValueRank value is out of range. - WrongValueRank - - - NodeClass - P3-0506040000 - AccessLevel value is out of range. - WrongAccessLevel - - - Reference - P3-0707000000 - Wrong Reference type targeting the DataVariable component. - WrongReference2Variable - - - Reference - P3-0707000001 - Wrong Reference type targeting the Method component. - WrongReference2Method - - - Reference - P3-0707000002 - Dangling reference - undefined target of the HasComponent reference. - UndefinedHasComponentTarget - - - Reference - P3-0708000000 - Dangling reference - undefined target of the HasProperty reference. - UndefinedHasPropertyTarget - - - Reference - P3-0710000000 - Each Node shall be the TargetNode of at most one Reference of type HasSubtype. - HasSubtypeMulitarget - - - Reference - P3-0710000001 - Dangling reference - undefined target of the HasSubtype reference. - UndefinedHasSubtypeTarget - - - Reference - P3-0713000000 - Undefined HasTypeDefinition - each Variable and each Object shall be the SourceNode of exactly one HasTypeDefinition Reference. - UndefinedHasTypeDefinition - - - Naming - P3-0802020000 - Undefined namespace index - The numeric values used to identify namespaces correspond to the index into the NamespaceArray. - UndefinedNamespaceIndex - - - NodeClass - P6-0503011400 - BrowseName cannot be null string. - EmptyBrowseName - - - NodeClass - P6-0F03000000 - SymbolicName contains characters that are not allowed. Only letters, digits or the underscore (‘_’) are permitted. - WrongSymbolicName - - - XML - P6-0F02000000 - The required model is missing. - LackOfRequiredModel - - - DataType - P3-XXXXX00000 - Abstract DataType of the field of a concrete structure is not permitted. - FieldAbstractDataType - - - DataType - P3-XXXXX00000 - All fields must be present in derived Structure DataType. - MissingFieldInDerivedStructure - - - DataType - P3-XXXXX00000 - Wrong DataType of field derived from Structure. - WrongDerivedFieldData - - - DataType - P3-0508010000 - It is not permitted for two DataTypes to point to the same DataTypeEncoding. - WrongDataType2DataTypeEncodingReference - - - DataType - P3-0508010000 - The DataTypeEncoding Object shall point to exactly one Variable of type DataTypeDescriptionType - WrongDataTypeEncoding2DataTypeDescriptionReference - - - DataType - P3-0508010000 - The DataTypeDescription Variable shall belong to a DataTypeDictionary Variable. - WrongDataTypeDescription2DataTypeDictionaryReference - - - DataType - P3-0508030000 - Only concrete Structured DataTypes may use HasEncoding References. Abstract, Built-in, Enumeration, and Simple DataTypes are not allowed to be the SourceNode of a HasEncoding Reference. - AbstractDataType2HasEncodingReference - - - DataType - P3-0508030000 - Each concrete Structured DataType shall point to at least one DataTypeEncoding Object with the BrowseName “Default Binary” or “Default XML” having the NamespaceIndex 0. - ConcreteDataType2HasEncodingReference - - + + + Reference + P3-0305000000 + It is not allowed that References are used to create a looping hierarchy. + NotValidLoopingHierarchy + + + Diagnostic + P0-0001010000 + The XML attribute or element is not supported and neglected. + NotSupportedFeature + + + XML + P0-0001020000 + Node cannot be null + NodeCannotBeNull + + + XML + P0-0001030000 + Models element cannot be null or empty + ModelsCannotBeNull + + + XML + P0-0001040000 + NamespaceUris element cannot be null or empty + NamespaceUrisCannotBeNull + + + XML + P0-0001050000 + Selected model contains errors. + ModelContainsErrors + + + NonCategorized + P0-0002010000 + General processing error see trace for details. + NonCategorized + + + Diagnostic + P0-0003010000 + It is diagnostic information + DiagnosticInformation + + + NodeClass + P0-0605020209 + The syntax of the NodeId is not valid. + NodeIdInvalidSyntax + + + NodeClass + P0-0605020210 + The syntax of the ExpandedNodeId is not valid. + ExpandedNodeIdInvalidSyntax + + + DataEncoding + P6-0503021400 + The syntax of the QualifiedName is not valid. + QualifiedNameInvalidSyntax + + + NodeClass + P3-0403040000 + The reference target doesn't exist. OPC UA does not require that the TargetNode exists, thus References may point to a Node that does not exist. + DanglingReferenceTarget + + + NodeClass + P3-0502020000 + Nodes shall be unambiguously identified using NodeId + NodeIdDuplicated + + + NodeClass + P3-0502020001 + NodeId is not defined. + NodeIdNotDefined + + + NodeClass + P3-0502050000 + The string part of the DisplayName is restricted to 512 characters. + WrongDisplayNameLength + + + NodeClass + P3-0502070000 + The value must be less than 0x200000 for the UAVariable and less than 0x400000 for other node types. + WrongWriteMaskValue + + + NodeClass + P3-0856000000 + The value must be less than 0x7. + WrongAccessRestriction + + + NodeClass + P3-0503020000 + Unexpected value of the InverseName. + WrongInverseName + + + NodeClass + P3-0503020001 + The BrowseName of a ReferenceType shall be unique. + DuplicatedReferenceType + + + NodeClass + P3-0503020002 + The BrowseName of a ReferenceType is defined outside of the model. + BrowseNameReferenceTypeScope + + + Reference + P3-0503030201 + Wrong Reference type targeting the Property component. + WrongReference2Property + + + NodeClass + P3-0505010000 + Object NodeClass: EventNotifier is out of range. + WrongEventNotifier + + + NodeClass + P3-0505010001 + Object NodeClass: Value of the EventNotifier attribute is not supported. + EventNotifierValueNotSupported + + + NodeClass + P3-0506020000 + ValueRank value is out of range. + WrongValueRank + + + NodeClass + P3-0506040000 + AccessLevel value is out of range. + WrongAccessLevel + + + Reference + P3-0707000000 + Wrong Reference type targeting the DataVariable component. + WrongReference2Variable + + + Reference + P3-0707000001 + Wrong Reference type targeting the Method component. + WrongReference2Method + + + Reference + P3-0707000002 + Dangling reference - undefined target of the HasComponent reference. + UndefinedHasComponentTarget + + + Reference + P3-0708000000 + Dangling reference - undefined target of the HasProperty reference. + UndefinedHasPropertyTarget + + + Reference + P3-0710000000 + Each Node shall be the TargetNode of at most one Reference of type HasSubtype. + HasSubtypeMulitarget + + + Reference + P3-0710000001 + Dangling reference - undefined target of the HasSubtype reference. + UndefinedHasSubtypeTarget + + + Reference + P3-0713000000 + Undefined HasTypeDefinition - each Variable and each Object shall be the SourceNode of exactly one HasTypeDefinition Reference. + UndefinedHasTypeDefinition + + + Naming + P3-0802020000 + Undefined namespace index - The numeric values used to identify namespaces correspond to the index into the NamespaceArray. + UndefinedNamespaceIndex + + + NodeClass + P6-0503011400 + BrowseName cannot be null string. + EmptyBrowseName + + + NodeClass + P6-0F03000000 + SymbolicName contains characters that are not allowed. Only letters, digits or the underscore (‘_’) are permitted. + WrongSymbolicName + + + XML + P6-0F02000000 + The required model is missing. + LackOfRequiredModel + + + DataType + P3-XXXXX00000 + Abstract DataType of the field of a concrete structure is not permitted. + FieldAbstractDataType + + + DataType + P3-XXXXX00000 + All fields must be present in derived Structure DataType. + MissingFieldInDerivedStructure + + + DataType + P3-XXXXX00000 + Wrong DataType of field derived from Structure. + WrongDerivedFieldData + + + DataType + P3-0508010000 + It is not permitted for two DataTypes to point to the same DataTypeEncoding. + WrongDataType2DataTypeEncodingReference + + + DataType + P3-0508010000 + The DataTypeEncoding Object shall point to exactly one Variable of type DataTypeDescriptionType + WrongDataTypeEncoding2DataTypeDescriptionReference + + + DataType + P3-0508010000 + The DataTypeDescription Variable shall belong to a DataTypeDictionary Variable. + WrongDataTypeDescription2DataTypeDictionaryReference + + + DataType + P3-0508030000 + Only concrete Structured DataTypes may use HasEncoding References. Abstract, Built-in, Enumeration, and Simple DataTypes are not allowed to be the SourceNode of a HasEncoding Reference. + AbstractDataType2HasEncodingReference + + + DataType + P3-0508030000 + Each concrete Structured DataType shall point to at least one DataTypeEncoding Object with the BrowseName “Default Binary” or “Default XML” having the NamespaceIndex 0. + ConcreteDataType2HasEncodingReference + + \ No newline at end of file diff --git a/SemanticData/UANodeSetValidation/UANodeContext.cs b/SemanticData/UANodeSetValidation/UANodeContext.cs index 31c11697..feb03be3 100644 --- a/SemanticData/UANodeSetValidation/UANodeContext.cs +++ b/SemanticData/UANodeSetValidation/UANodeContext.cs @@ -34,7 +34,7 @@ internal class UANodeContext : IUANodeContext, IUANodeBase /// traceMessageCallback internal UANodeContext(NodeId nodeId, IAddressSpaceBuildContext addressSpaceContext, Action traceMessageCallback) { - _TraceEvent = traceMessageCallback ?? throw new ArgumentNullException(nameof(traceMessageCallback)); + TraceEvent = traceMessageCallback ?? throw new ArgumentNullException(nameof(traceMessageCallback)); NodeIdContext = nodeId; this.m_AddressSpaceContext = addressSpaceContext; } @@ -52,7 +52,7 @@ public void BuildSymbolicId(List path) { if (this.UANode == null) { - _TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.DanglingReferenceTarget, $"The target node NodeId={this.NodeIdContext}, current path {string.Join(", ", path)}")); + TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.DanglingReferenceTarget, $"The target node NodeId={this.NodeIdContext}, current path {string.Join(", ", path)}")); return; } IEnumerable _parentConnector = m_AddressSpaceContext.GetReferences2Me(this).Where(x => x.ChildConnector); @@ -82,7 +82,7 @@ public void Update(UANode node, Action addReference) throw new ArgumentException(nameof(node), $"Argument must not be null at {nameof(Update)} "); if (this.UANode != null) { - _TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.NodeIdDuplicated, string.Format("The {0} is already defined and is removed from further processing.", node.NodeId.ToString()))); + TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.NodeIdDuplicated, string.Format("The {0} is already defined and is removed from further processing.", node.NodeId.ToString()))); return; } UANode = node; @@ -116,7 +116,7 @@ public void Update(UANode node, Action addReference) public IUANodeContext CreateUANodeContext(NodeId id) { - return new UANodeContext(id, m_AddressSpaceContext, _TraceEvent); + return new UANodeContext(id, m_AddressSpaceContext, TraceEvent); } #endregion IUANodeContext @@ -152,7 +152,7 @@ void IUANodeBase.CalculateNodeReferences(INodeFactory nodeFactory, IValidator va { if (_rfx.TargetNode.UANode == null) { - _TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.DanglingReferenceTarget, $"The Node {_rfx.TargetNode} has not been defined and is excluded from further model processing.")); + TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.DanglingReferenceTarget, $"The Node {_rfx.TargetNode} has not been defined and is excluded from further model processing.")); continue; } switch (_rfx.ReferenceKind) @@ -162,11 +162,11 @@ void IUANodeBase.CalculateNodeReferences(INodeFactory nodeFactory, IValidator va if (_ReferenceType == XmlQualifiedName.Empty) { BuildError _err = BuildError.DanglingReferenceTarget; - _TraceEvent(TraceMessage.BuildErrorTraceMessage(_err, "Information")); + TraceEvent(TraceMessage.BuildErrorTraceMessage(_err, "Information")); } else if (_ReferenceType == new XmlQualifiedName(BrowseNames.HasEncoding, Namespaces.OpcUa)) { - _TraceEvent(TraceMessage.DiagnosticTraceMessage($"Removed the graph of nodes at {_ReferenceType.ToString()} from the model")); + TraceEvent(TraceMessage.DiagnosticTraceMessage($"Removed the graph of nodes at {_ReferenceType.ToString()} from the model")); return; } IReferenceFactory _or = nodeFactory.NewReference(); @@ -183,7 +183,7 @@ void IUANodeBase.CalculateNodeReferences(INodeFactory nodeFactory, IValidator va break; case NodeClassEnum.UAMethod: - _TraceEvent(TraceMessage.DiagnosticTraceMessage($"Removed the graph of nodes at {_rfx.TargetNode} from the model")); + TraceEvent(TraceMessage.DiagnosticTraceMessage($"{1560148160} - Removed the graph of nodes at {_rfx.TargetNode} from the model")); //validator..ValidateExportNode(_rc.TargetNode, nodeFactory, _rc); break; @@ -195,11 +195,11 @@ void IUANodeBase.CalculateNodeReferences(INodeFactory nodeFactory, IValidator va break; case NodeClassEnum.UAView: - _TraceEvent(TraceMessage.DiagnosticTraceMessage($"Removed the graph of nodes at {_rfx.TargetNode} from the model")); + TraceEvent(TraceMessage.DiagnosticTraceMessage($"Removed the graph of nodes at {_rfx.TargetNode} from the model")); break; case NodeClassEnum.Unknown: - _TraceEvent(TraceMessage.DiagnosticTraceMessage($"Removed the graph of nodes at {_rfx.TargetNode} from the model")); + TraceEvent(TraceMessage.DiagnosticTraceMessage($"Removed the graph of nodes at {_rfx.TargetNode} from the model")); break; default: @@ -226,7 +226,7 @@ void IUANodeBase.CalculateNodeReferences(INodeFactory nodeFactory, IValidator va break; } } - Dictionary _derivedChildren = m_BaseTypeNode == null ? new Dictionary() : m_BaseTypeNode.GetDerivedInstances(); + NodesCollection _derivedChildren = m_BaseTypeNode == null ? new NodesCollection() : m_BaseTypeNode.GetDerivedInstances(); foreach (UAReferenceContext _rc in _children) { try @@ -236,7 +236,7 @@ void IUANodeBase.CalculateNodeReferences(INodeFactory nodeFactory, IValidator va _instanceDeclaration = _derivedChildren.ContainsKey(_rc.TargetNode.UANode.BrowseNameQualifiedName.Name) ? _derivedChildren[_rc.TargetNode.UANode.BrowseNameQualifiedName.Name] : null; if (_rc.TargetNode.Equals(_instanceDeclaration)) { - //_TraceEvent(TraceMessage.DiagnosticTraceMessage($"Removing instance declaration {_rc.TargetNode.ToString()}")); + TraceEvent(TraceMessage.DiagnosticTraceMessage($" {2054200566} - Removing instance declaration {_rc.TargetNode.ToString()}")); continue; } _rc.TargetNode.RemoveInheritedValues(_instanceDeclaration); @@ -271,7 +271,7 @@ void IUANodeBase.CalculateNodeReferences(INodeFactory nodeFactory, IValidator va public XmlQualifiedName ExportBaseTypeBrowseName() { bool type = UANode is UAType; - return m_BaseTypeNode == null ? null : m_BaseTypeNode.ExportBrowseNameBaseType(x => TraceErrorUndefinedBaseType(x, type, _TraceEvent)); + return m_BaseTypeNode == null ? null : m_BaseTypeNode.ExportBrowseNameBaseType(x => TraceErrorUndefinedBaseType(x, type)); } /// @@ -305,14 +305,16 @@ public XmlQualifiedName ExportBrowseNameBaseType(Action traceEvent) /// /// Gets the derived instances. /// - /// Dictionary<System.String, IUANodeBase>. - /// Circular loop in inheritance chain + /// An instance of or null if there is nothing to return //TODO NetworkIdentifier is missing in generated Model Design for DI model #629 public NodesCollection GetDerivedInstances() { if (m_InGetDerivedInstances) - //Improve GetDerivedInstances to log a message instead of throwing exception #651 - throw new ArgumentOutOfRangeException($"Circular loop in {nameof(GetDerivedInstances)}"); //TODO replace by the message - it is just model error. + { + TraceMessage errorToLog = TraceMessage.BuildErrorTraceMessage(BuildError.NotValidLoopingHierarchy, $"Circular loop in {nameof(GetDerivedInstances)}"); + TraceEvent(errorToLog); + return null; + } try { m_InGetDerivedInstances = true; @@ -373,24 +375,23 @@ public override string ToString() private IUANodeBase m_BaseTypeNode; private readonly IAddressSpaceBuildContext m_AddressSpaceContext = null; private bool m_InGetDerivedInstances = false; + private readonly Action TraceEvent = null; //methods - private void TraceErrorUndefinedBaseType(NodeId target, bool type, Action traceEvent) + private void TraceErrorUndefinedBaseType(NodeId target, bool type) { if (type) { string _msg = string.Format("BaseType of Id={0} for node {1}", target, this.UANode.BrowseNameQualifiedName); - traceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.UndefinedHasSubtypeTarget, _msg)); + TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.UndefinedHasSubtypeTarget, _msg)); } else { string _msg = string.Format("TypeDefinition of Id={0} for node {1}", target, this.UANode.BrowseNameQualifiedName); - traceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.UndefinedHasTypeDefinition, _msg)); + TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.UndefinedHasTypeDefinition, _msg)); } } - private readonly Action _TraceEvent = null; - #endregion private } } \ No newline at end of file diff --git a/SemanticData/UANodeSetValidation/Validator.cs b/SemanticData/UANodeSetValidation/Validator.cs index bc00c763..cea4d03a 100644 --- a/SemanticData/UANodeSetValidation/Validator.cs +++ b/SemanticData/UANodeSetValidation/Validator.cs @@ -92,7 +92,7 @@ public void ValidateExportNode(IUANodeBase nodeContext, INodeContainer exportFac break; case NodeClassEnum.UAVariable: - if (parentReference.ReferenceKind == ReferenceKindEnum.HasProperty) + if ((parentReference != null) && (parentReference.ReferenceKind == ReferenceKindEnum.HasProperty)) CreateNode(exportFactory.AddNodeFactory, nodeContext, (x, y) => Update(x, y, nodeContext, parentReference), UpdateInstance, validateExportNode2Model); else CreateNode(exportFactory.AddNodeFactory, nodeContext, (x, y) => Update(x, y, nodeContext, parentReference), UpdateInstance, validateExportNode2Model); @@ -162,6 +162,7 @@ private void Update(IVariableInstanceFactory variableInstance, UAVariable nodeSe Update(variableInstance, nodeSet); variableInstance.ReferenceType = parentReference == null ? null : parentReference.GetReferenceTypeName(); if (nodeContext.IsProperty) + //TODO NetworkIdentifier is missing in generated Model Design for DI model #629 parentReference System.NullReferenceException m_buildErrorsHandling.WriteTraceMessage(TraceMessage.BuildErrorTraceMessage(BuildError.WrongReference2Variable, string.Format("Creating Variable - wrong reference type {0}", parentReference.ReferenceKind.ToString()))); } catch (Exception _ex)