/// <summary>
 /// Check whether valid node and return service result if not.
 /// </summary>
 /// <param name="endpoint"></param>
 /// <param name="request"></param>
 /// <returns></returns>
 private Task <ServiceResultModel> TestPublishNodeAsync(EndpointModel endpoint,
                                                        PublishStartRequestModel request)
 {
     // Test whether value exists and fail if not
     return(_opc.ExecuteServiceAsync(endpoint, null,
                                     TimeSpan.FromSeconds(10), async session => {
         var readNode = request.Item.NodeId.ToNodeId(session.MessageContext);
         if (NodeId.IsNull(readNode))
         {
             throw new ArgumentException(nameof(request.Item.NodeId));
         }
         var diagnostics = new List <OperationResultModel>();
         var response = await session.ReadAsync(
             (request.Header?.Diagnostics).ToStackModel(),
             0, TimestampsToReturn.Both, new ReadValueIdCollection {
             new ReadValueId {
                 NodeId = readNode,
                 AttributeId = Attributes.Value
             }
         });
         OperationResultEx.Validate("Publish_" + readNode, diagnostics,
                                    response.Results.Select(r => r.StatusCode),
                                    response.DiagnosticInfos, false);
         SessionClientEx.Validate(response.Results, response.DiagnosticInfos);
         if (response.Results == null || response.Results.Count == 0)
         {
             return diagnostics.ToServiceModel(request.Header?.Diagnostics,
                                               session.MessageContext);
         }
         return null;
     }));
 }
        /// <summary>
        /// Load references
        /// </summary>
        /// <param name="nodeModel"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task FetchReferencesAsync(BaseNodeModel nodeModel, CancellationToken ct)
        {
            try {
                // Read node with value
                var response = await _client.ExecuteServiceAsync(_endpoint, _elevation,
                                                                 _priority, ct, session => {
                    _encoder.Context.UpdateFromSession(session);
                    return(session.BrowseAsync(_diagnostics.ToStackModel(), null,
                                               nodeModel.NodeId, 0u, Opc.Ua.BrowseDirection.Both,
                                               ReferenceTypeIds.References, true, 0u));
                });

                SessionClientEx.Validate(response.Results, response.DiagnosticInfos);
                OperationResultEx.Validate("Browse_" + nodeModel.NodeId, Diagnostics,
                                           response.Results.Select(r => r.StatusCode), null, false);
                while (true)
                {
                    foreach (var reference in response.Results[0].References)
                    {
                        nodeModel.AddReference(reference.ReferenceTypeId,
                                               !reference.IsForward, reference.NodeId);
                        _references++;
                    }
                    if (response.Results[0].ContinuationPoint == null)
                    {
                        break;
                    }
                    response = await _client.ExecuteServiceAsync(_endpoint, _elevation,
                                                                 _priority, ct, session => {
                        _encoder.Context.UpdateFromSession(session);
                        return(session.BrowseNextAsync(_diagnostics.ToStackModel(), false,
                                                       new ByteStringCollection {
                            response.Results[0].ContinuationPoint
                        }));
                    });

                    SessionClientEx.Validate(response.Results, response.DiagnosticInfos);
                    OperationResultEx.Validate("BrowseNext_" + nodeModel.NodeId, Diagnostics,
                                               response.Results.Select(r => r.StatusCode), null, false);
                }
            }
            catch (Exception ex) {
                _logger.Error(ex, "Failed browsing node object for node {nodeId}.",
                              nodeModel.NodeId);
            }
        }
예제 #3
0
        /// <summary>
        /// Validates responses against requests
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="operation"></param>
        /// <param name="results"></param>
        /// <param name="diagnostics"></param>
        /// <param name="requested"></param>
        /// <param name="operations"></param>
        /// <param name="traceOnly"></param>
        public static void Validate <T>(string operation,
                                        List <OperationResultModel> operations, IEnumerable <StatusCode> results,
                                        DiagnosticInfoCollection diagnostics, IEnumerable <T> requested, bool traceOnly)
        {
            if (operations == null)
            {
                SessionClientEx.Validate(results, diagnostics, requested);
                return;
            }
            if (diagnostics == null)
            {
                diagnostics = new DiagnosticInfoCollection();
            }
            var resultsWithStatus = results?.ToList();

            if (resultsWithStatus == null || (resultsWithStatus.Count == 0 &&
                                              diagnostics.Count == 0))
            {
                throw new ServiceResultException(StatusCodes.BadUnexpectedError,
                                                 "The server returned no results or diagnostics information.");
            }
            // Add diagnostics
            var ids = requested?.ToArray() ?? new T[0];

            for (var index = resultsWithStatus.Count; index < diagnostics.Count; index++)
            {
                resultsWithStatus.Add(diagnostics[index] == null ?
                                      StatusCodes.Good : StatusCodes.BadUnexpectedError);
            }
            operations.AddRange(results
                                .Select((status, index) => new OperationResultModel {
                Operation       = index < ids.Length ? $"{operation}_{ids[index]}" : operation,
                DiagnosticsInfo = index < diagnostics.Count ? diagnostics[index] : null,
                StatusCode      = status,
                TraceOnly       = traceOnly
            })
                                .Where(o => o.StatusCode != StatusCodes.Good || o.DiagnosticsInfo != null));
        }