/// <inheritdoc/> public IList <INode> FindReferences( ExpandedNodeId nodeId, NodeId referenceTypeId, bool isInverse, bool includeSubtypes) { IList <INode> targets = new List <INode>(); Node source = Find(nodeId) as Node; if (source == null) { return(targets); } IList <IReference> references = source.ReferenceTable.Find( referenceTypeId, isInverse, includeSubtypes, m_typeTree); var targetIds = new ExpandedNodeIdCollection( references.Select(reference => reference.TargetId)); IList <INode> result = Find(targetIds); foreach (INode target in result) { if (target != null) { targets.Add(target); } } return(targets); }
public void NodeCache_BrowseAllVariables() { var result = new List <INode>(); var nodesToBrowse = new ExpandedNodeIdCollection { ObjectIds.ObjectsFolder }; while (nodesToBrowse.Count > 0) { var nextNodesToBrowse = new ExpandedNodeIdCollection(); foreach (var node in nodesToBrowse) { try { var organizers = m_session.NodeCache.FindReferences( node, ReferenceTypeIds.Organizes, false, true); var components = m_session.NodeCache.FindReferences( node, ReferenceTypeIds.HasComponent, false, false); var properties = m_session.NodeCache.FindReferences( node, ReferenceTypeIds.HasProperty, false, false); nextNodesToBrowse.AddRange(organizers .Where(n => n is ObjectNode) .Select(n => n.NodeId).ToList()); nextNodesToBrowse.AddRange(components .Where(n => n is ObjectNode) .Select(n => n.NodeId).ToList()); result.AddRange(organizers.Where(n => n is VariableNode)); result.AddRange(components.Where(n => n is VariableNode)); result.AddRange(properties.Where(n => n is VariableNode)); } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { TestContext.Out.WriteLine($"Access denied: Skip node {node}."); } } } nodesToBrowse = nextNodesToBrowse; if (result.Count > MaxReferences) { break; } } TestContext.Out.WriteLine("Browsed {0} variables", result.Count); }
/// <summary> /// Load all subTypes and optionally nested subtypes of a type definition. /// Filter for all subtypes or only subtypes outside the default namespace. /// </summary> private IList<INode> LoadDataTypes( ExpandedNodeId dataType, bool nestedSubTypes = false, bool addRootNode = false, bool filterUATypes = true) { var result = new List<INode>(); var nodesToBrowse = new ExpandedNodeIdCollection { dataType }; if (addRootNode) { var rootNode = m_session.NodeCache.Find(dataType); if (!(rootNode is DataTypeNode)) { throw new ServiceResultException("Root Node is not a DataType node."); } result.Add(rootNode); } while (nodesToBrowse.Count > 0) { var nextNodesToBrowse = new ExpandedNodeIdCollection(); foreach (var node in nodesToBrowse) { var response = m_session.NodeCache.FindReferences( node, ReferenceTypeIds.HasSubtype, false, false); if (nestedSubTypes) { nextNodesToBrowse.AddRange(response.Select(r => r.NodeId).ToList()); } if (filterUATypes) { // filter out default namespace result.AddRange(response.Where(rd => rd.NodeId.NamespaceIndex != 0)); } else { result.AddRange(response); } } nodesToBrowse = nextNodesToBrowse; } return result; }
/// <summary> /// Browse all variables in the objects folder. /// </summary> private IList <INode> BrowseAllVariables() { var result = new List <INode>(); var nodesToBrowse = new ExpandedNodeIdCollection(); nodesToBrowse.Add(ObjectIds.ObjectsFolder); while (nodesToBrowse.Count > 0) { var nextNodesToBrowse = new ExpandedNodeIdCollection(); foreach (var node in nodesToBrowse) { try { var organizers = _session.NodeCache.FindReferences( node, ReferenceTypeIds.Organizes, false, false); var components = _session.NodeCache.FindReferences( node, ReferenceTypeIds.HasComponent, false, false); var properties = _session.NodeCache.FindReferences( node, ReferenceTypeIds.HasProperty, false, false); nextNodesToBrowse.AddRange(organizers .Where(n => n is ObjectNode) .Select(n => n.NodeId).ToList()); nextNodesToBrowse.AddRange(components .Where(n => n is ObjectNode) .Select(n => n.NodeId).ToList()); result.AddRange(organizers.Where(n => n is VariableNode)); result.AddRange(components.Where(n => n is VariableNode)); result.AddRange(properties.Where(n => n is VariableNode)); } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { Console.WriteLine($"Access denied: Skip node {node}."); } } } nodesToBrowse = nextNodesToBrowse; } return(result); }
public void NodeCache_BrowseAllVariables() { var result = new List <INode>(); var nodesToBrowse = new ExpandedNodeIdCollection { ObjectIds.ObjectsFolder }; Session.NodeCache.Clear(); Session.NodeCache.LoadUaDefinedTypes(Session.SystemContext); while (nodesToBrowse.Count > 0) { var nextNodesToBrowse = new ExpandedNodeIdCollection(); foreach (var node in nodesToBrowse) { try { var organizers = Session.NodeCache.FindReferences( node, ReferenceTypeIds.HierarchicalReferences, false, true); var objectNodes = organizers.Where(n => n is ObjectNode); nextNodesToBrowse.AddRange(objectNodes.Select(n => n.NodeId)); var variableNodes = organizers.Where(n => n is VariableNode); nextNodesToBrowse.AddRange(variableNodes.Select(n => n.NodeId).ToList()); result.AddRange(variableNodes); } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { TestContext.Out.WriteLine($"Access denied: Skip node {node}."); } } } nodesToBrowse = nextNodesToBrowse; if (result.Count > MaxReferences) { break; } } TestContext.Out.WriteLine("Browsed {0} variables", result.Count); }
/// <inheritdoc/> public IList <INode> FindReferences( IList <ExpandedNodeId> nodeIds, IList <NodeId> referenceTypeIds, bool isInverse, bool includeSubtypes) { ExpandedNodeIdCollection targetIds = new ExpandedNodeIdCollection(); IList <INode> sources = Find(nodeIds); foreach (INode source in sources) { if (!(source is Node node)) { continue; } foreach (var referenceTypeId in referenceTypeIds) { IList <IReference> references = node.ReferenceTable.Find( referenceTypeId, isInverse, includeSubtypes, m_typeTree); targetIds.AddRange( references.Select(reference => reference.TargetId)); } } IList <INode> targets = new List <INode>(); IList <INode> result = Find(targetIds); foreach (INode target in result) { if (target != null) { targets.Add(target); } } return(targets); }
public void NodeCache_BrowseAllVariables_MultipleNodes() { var result = new List <INode>(); var nodesToBrowse = new ExpandedNodeIdCollection { ObjectIds.ObjectsFolder }; Session.FetchTypeTree(ReferenceTypeIds.References); var referenceTypeIds = new NodeIdCollection() { ReferenceTypeIds.HierarchicalReferences }; while (nodesToBrowse.Count > 0) { var nextNodesToBrowse = new ExpandedNodeIdCollection(); try { var organizers = Session.NodeCache.FindReferences( nodesToBrowse, referenceTypeIds, false, true); nextNodesToBrowse.AddRange(organizers.Select(n => n.NodeId)); var objectNodes = organizers.Where(n => n is ObjectNode); var variableNodes = organizers.Where(n => n is VariableNode); result.AddRange(variableNodes); } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { TestContext.Out.WriteLine($"Access denied: Skipped node."); } } nodesToBrowse = new ExpandedNodeIdCollection(nextNodesToBrowse.Distinct()); TestContext.Out.WriteLine("Found {0} duplicates", nextNodesToBrowse.Count - nodesToBrowse.Count); } TestContext.Out.WriteLine("Found {0} variables", result.Count); }
/// <summary> /// Reads an ExpandedNodeId array from the stream. /// </summary> public ExpandedNodeIdCollection ReadExpandedNodeIdArray(string fieldName) { bool isNil = false; ExpandedNodeIdCollection values = new ExpandedNodeIdCollection(); if (BeginField(fieldName, true, out isNil)) { PushNamespace(Namespaces.OpcUaXsd); while (MoveToElement("ExpandedNodeId")) { values.Add(ReadExpandedNodeId("ExpandedNodeId")); } // check the length. if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count) { throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded); } PopNamespace(); EndField(fieldName); return values; } if (isNil) { return null; } return values; }
/// <summary> /// Reads an ExpandedNodeId array from the stream. /// </summary> public ExpandedNodeIdCollection ReadExpandedNodeIdArray(string fieldName) { int length = ReadArrayLength(); if (length == -1) { return null; } ExpandedNodeIdCollection values = new ExpandedNodeIdCollection(length); for (int ii = 0; ii < length; ii++) { values.Add(ReadExpandedNodeId(null)); } return values; }
/// <summary> /// Reads an ExpandedNodeId array from the stream. /// </summary> public ExpandedNodeIdCollection ReadExpandedNodeIdArray(string fieldName) { var values = new ExpandedNodeIdCollection(); List<object> token = null; if (!ReadArrayField(fieldName, out token)) { return values; } for (int ii = 0; ii < token.Count; ii++) { try { m_stack.Push(token[ii]); var element = ReadExpandedNodeId(null); values.Add(element); } finally { m_stack.Pop(); } } return values; }
/// <summary> /// Finds a set of nodes in the nodeset, /// fetches missing nodes from server. /// </summary> /// <param name="nodeIds">The node identifier collection.</param> public IList <INode> Find(IList <ExpandedNodeId> nodeIds) { // check for null. if (nodeIds == null || nodeIds.Count == 0) { return(new List <INode>()); } int count = nodeIds.Count; IList <INode> nodes = new List <INode>(count); var fetchNodeIds = new ExpandedNodeIdCollection(); int ii; for (ii = 0; ii < count; ii++) { // check if node already exists. INode node = m_nodes.Find(nodeIds[ii]); // do not return temporary nodes created after a Browse(). if (node != null && node?.GetType() != typeof(Node)) { nodes.Add(node); } else { nodes.Add(null); fetchNodeIds.Add(nodeIds[ii]); } } if (fetchNodeIds.Count == 0) { return(nodes); } // fetch missing nodes from server. IList <Node> fetchedNodes; try { fetchedNodes = FetchNodes(fetchNodeIds); } catch (Exception e) { Utils.LogError("Could not fetch nodes from server: Reason='{1}'.", e.Message); // m_nodes[nodeId] = null; return(nodes); } ii = 0; foreach (Node fetchedNode in fetchedNodes) { while (ii < count && nodes[ii] != null) { ii++; } if (ii < count && nodes[ii] == null) { nodes[ii++] = fetchedNode; } else { Utils.LogError("Inconsistency fetching nodes from server. Not all nodes could be assigned."); break; } } return(nodes); }