/// <summary> /// Get tree /// </summary> /// <param name="endpointId"></param> /// <param name="id"></param> /// <param name="parentId"></param> /// <param name="discovererId"></param> /// <param name="direction"></param> /// <returns>ListNode</returns> public async Task <PagedResult <ListNode> > GetTreeAsync(string endpointId, string id, List <string> parentId, string discovererId, BrowseDirection direction) { var pageResult = new PagedResult <ListNode>(); var model = new BrowseRequestApiModel { TargetNodesOnly = true }; if (direction == BrowseDirection.Forward) { model.MaxReferencesToReturn = _MAX_REFERENCES; model.NodeId = id; if (id == string.Empty) { Path = string.Empty; } } else { model.NodeId = parentId.ElementAt(parentId.Count - 2); } try { var browseData = await _twinService.NodeBrowseAsync(endpointId, model); var continuationToken = browseData.ContinuationToken; var references = browseData.References; var browseDataNext = new BrowseNextResponseApiModel(); if (direction == BrowseDirection.Forward) { parentId.Add(browseData.Node.NodeId); Path += "/" + browseData.Node.DisplayName; } else { parentId.RemoveAt(parentId.Count - 1); Path = Path.Substring(0, Path.LastIndexOf("/")); } do { if (references != null) { foreach (var nodeReference in references) { pageResult.Results.Add(new ListNode { Id = nodeReference.Target.NodeId.ToString(), NodeClass = nodeReference.Target.NodeClass ?? 0, NodeName = nodeReference.Target.DisplayName.ToString(), Children = (bool)nodeReference.Target.Children, ParentIdList = parentId, DiscovererId = discovererId, AccessLevel = nodeReference.Target.AccessLevel ?? 0, ParentName = browseData.Node.DisplayName, DataType = nodeReference.Target.DataType, Value = string.Empty, Publishing = false, PublishedItem = null }); } } if (!string.IsNullOrEmpty(continuationToken)) { var modelNext = new BrowseNextRequestApiModel { ContinuationToken = continuationToken }; browseDataNext = await _twinService.NodeBrowseNextAsync(endpointId, modelNext); references = browseDataNext.References; continuationToken = browseDataNext.ContinuationToken; } else { browseDataNext.References = null; } } while (!string.IsNullOrEmpty(continuationToken) || browseDataNext.References != null); } catch (Exception e) { // skip this node Trace.TraceError("Can not browse node '{0}'", id); var errorMessage = string.Concat(e.Message, e.InnerException?.Message ?? "--", e?.StackTrace ?? "--"); Trace.TraceError(errorMessage); pageResult.Results.Add(new ListNode { NodeName = e.Message, DiscovererId = discovererId, ParentName = "Root" }); } pageResult.PageSize = 10; pageResult.RowCount = pageResult.Results.Count; pageResult.PageCount = (int)Math.Ceiling((decimal)pageResult.RowCount / 10); return(pageResult); }
/// <summary> /// Get tree /// </summary> /// <param name="endpointId"></param> /// <param name="id"></param> /// <param name="parentId"></param> /// <param name="discovererId"></param> /// <param name="direction"></param> /// <returns>ListNode</returns> public async Task <PagedResult <ListNode> > GetTreeAsync(string endpointId, string id, List <string> parentId, string discovererId, BrowseDirection direction, int index, CredentialModel credential = null) { var pageResult = new PagedResult <ListNode>(); var model = new BrowseRequestApiModel { TargetNodesOnly = true, ReadVariableValues = true }; if (direction == BrowseDirection.Forward) { model.MaxReferencesToReturn = _MAX_REFERENCES; model.NodeId = id; if (id == string.Empty) { Path = new List <string>(); } } else { model.NodeId = parentId.ElementAt(index - 1); } model.Header = Elevate(new RequestHeaderApiModel(), credential); try { var browseData = await _twinService.NodeBrowseAsync(endpointId, model); var continuationToken = browseData.ContinuationToken; var references = browseData.References; var browseDataNext = new BrowseNextResponseApiModel(); if (direction == BrowseDirection.Forward) { parentId.Add(browseData.Node.NodeId); Path.Add(browseData.Node.DisplayName); } else { parentId.RemoveAt(parentId.Count - 1); Path.RemoveRange(index, Path.Count - index); } do { if (references != null) { foreach (var nodeReference in references) { pageResult.Results.Add(new ListNode { Id = nodeReference.Target.NodeId.ToString(), NodeClass = nodeReference.Target.NodeClass ?? 0, NodeName = nodeReference.Target.DisplayName.ToString(), Children = (bool)nodeReference.Target.Children, ParentIdList = parentId, DiscovererId = discovererId, AccessLevel = nodeReference.Target.AccessLevel ?? 0, ParentName = browseData.Node.DisplayName, DataType = nodeReference.Target.DataType, Value = nodeReference.Target.Value?.ToString(), Publishing = false, PublishedItem = null }); } } if (!string.IsNullOrEmpty(continuationToken)) { bool?abort = null; if (pageResult.Results.Count > 5) { // TODO: !!! Implement real paging - need to make ux responsive for large # tags !!! abort = true; } var modelNext = new BrowseNextRequestApiModel { ContinuationToken = continuationToken, Abort = abort }; browseDataNext = await _twinService.NodeBrowseNextAsync(endpointId, modelNext); if (abort == true) { break; } references = browseDataNext.References; continuationToken = browseDataNext.ContinuationToken; } else { browseDataNext.References = null; } } while (!string.IsNullOrEmpty(continuationToken) || browseDataNext.References != null); } catch (Exception e) { // skip this node _logger.Error($"Can not browse node '{id}'"); var errorMessage = string.Concat(e.Message, e.InnerException?.Message ?? "--", e?.StackTrace ?? "--"); _logger.Error(errorMessage); string error = JToken.Parse(e.Message).ToString(Formatting.Indented); if (error.Contains(StatusCodes.Status401Unauthorized.ToString())) { pageResult.Error = "Unauthorized access: Bad User Access Denied."; } else { pageResult.Error = error; } } pageResult.PageSize = 10; pageResult.RowCount = pageResult.Results.Count; pageResult.PageCount = (int)Math.Ceiling((decimal)pageResult.RowCount / 10); return(pageResult); }