Пример #1
0
        /// <summary>
        /// Handles the Click event of the Conditions_RefreshMI control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Conditions_RefreshMI_Click(object sender, EventArgs e)
        {
            try
            {
                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId = ObjectTypeIds.ConditionType;
                request.MethodId = MethodIds.ConditionType_ConditionRefresh;
                request.InputArguments.Add(new Variant(m_subscription.Id));

                CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();
                methodsToCall.Add(request);

                CallMethodResultCollection results         = null;
                DiagnosticInfoCollection   diagnosticInfos = null;

                m_session.Call(
                    null,
                    methodsToCall,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, methodsToCall);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw ServiceResultException.Create((uint)results[0].StatusCode, "Unexpected error calling RefreshConditions.");
                }
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }
        private bool PublishOneNode(NodeIdInfo nodeIdInfo)
        {
            string logPrefix = $"{_logClassPrefix}:PublishOneNode:";

            try
            {
                int retryCount = 0;
                int maxRetries = 3;
                while (retryCount < maxRetries)
                {
                    VariantCollection inputArguments = new VariantCollection()
                    {
                        nodeIdInfo.Id,
                        TestserverUrl
                    };
                    CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                    CallMethodResultCollection  results         = null;
                    DiagnosticInfoCollection    diagnosticInfos = null;
                    CallMethodRequest           request         = new CallMethodRequest();
                    request.ObjectId       = new NodeId("Methods", 2);
                    request.MethodId       = new NodeId("PublishNode", 2);
                    request.InputArguments = inputArguments;
                    requests.Add(request);
                    ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);

                    if (results[0].StatusCode == StatusCodes.BadSessionNotActivated)
                    {
                        retryCount++;
                        Logger.Warning($"{logPrefix} need to retry to publish node, since session is not yet activated (nodeId: '{nodeIdInfo.Id}', retry: '{retryCount}')");
                        Task.Delay(MaxShortWaitSec * 1000).Wait();
                        continue;
                    }
                    if (!nodeIdInfo.Published && StatusCode.IsBad(results[0].StatusCode))
                    {
                        Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')");
                        return(false);
                    }
                    else
                    {
                        nodeIdInfo.Published = true;
                        Logger.Verbose($"{logPrefix} succeeded (nodeId: '{nodeIdInfo.Id}', error: '{results[0].StatusCode}'");
                        return(true);
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
            Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')");
            return(false);
        }
Пример #3
0
        /// <summary>
        /// Adds a comment to the selected conditions.
        /// </summary>
        /// <param name="methodId">The NodeId for the method to call.</param>
        /// <param name="comment">The comment to pass as an argument.</param>
        private void CallMethod(NodeId methodId, string comment)
        {
            // build list of methods to call.
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < ConditionsLV.SelectedItems.Count; ii++)
            {
                ConditionState condition = (ConditionState)ConditionsLV.SelectedItems[ii].Tag;

                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId = condition.NodeId;
                request.MethodId = methodId;
                request.Handle   = ConditionsLV.SelectedItems[ii];

                if (comment != null)
                {
                    request.InputArguments.Add(new Variant(condition.EventId.Value));
                    request.InputArguments.Add(new Variant((LocalizedText)comment));
                }

                methodsToCall.Add(request);
            }

            if (methodsToCall.Count == 0)
            {
                return;
            }

            // call the methods.
            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            m_session.Call(
                null,
                methodsToCall,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, methodsToCall);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

            for (int ii = 0; ii < results.Count; ii++)
            {
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    ListViewItem item = (ListViewItem)methodsToCall[ii].Handle;
                    item.SubItems[8].Text = Utils.Format("{0}", results[ii].StatusCode);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Responds to the dialog.
        /// </summary>
        private void Respond(int selectedResponse)
        {
            // build list of dialogs to respond to (caller should always make sure that only one is selected).
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < ConditionsLV.SelectedItems.Count; ii++)
            {
                DialogConditionState dialog = ConditionsLV.SelectedItems[ii].Tag as DialogConditionState;

                if (dialog == null)
                {
                    continue;
                }

                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId = dialog.NodeId;
                request.MethodId = MethodIds.DialogConditionType_Respond;
                request.InputArguments.Add(new Variant(selectedResponse));
                request.Handle = ConditionsLV.SelectedItems[ii];

                methodsToCall.Add(request);
            }

            if (methodsToCall.Count == 0)
            {
                return;
            }

            // call the methods.
            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            m_session.Call(
                null,
                methodsToCall,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, methodsToCall);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

            for (int ii = 0; ii < results.Count; ii++)
            {
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    ListViewItem item = (ListViewItem)methodsToCall[ii].Handle;
                    item.SubItems[8].Text = Utils.Format("{0}", results[ii].StatusCode);
                }
            }
        }
        protected override PublishedNodesCollection GetPublishedNodesLegacy(string endpointUrl, CancellationToken ct)
        {
            string logPrefix = $"{_logClassPrefix}:GetPublishedNodesLegacy:";
            PublishedNodesCollection nodeList = null;

            VariantCollection inputArgumentsTestserver = new VariantCollection()
            {
                ""
            };

            try
            {
                CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                CallMethodResultCollection  results         = new CallMethodResultCollection();
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest
                {
                    ObjectId = new NodeId("Methods", 2),
                    MethodId = new NodeId("GetPublishedNodes", 2),
                };
                request.InputArguments = inputArgumentsTestserver;
                requests.Add(request);
                try
                {
                    ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);
                }
                catch (Exception e)
                {
                    Logger.Fatal(e, $"{logPrefix} Exception");
                }
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    Logger.Warning($"{logPrefix} call was not successfull (status: '{results[0].StatusCode}'");
                }
                else
                {
                    if (results?[0]?.OutputArguments.Count == 1)
                    {
                        string stringResult   = results[0].OutputArguments[0].ToString();
                        int    jsonStartIndex = stringResult.IndexOf("[", StringComparison.InvariantCulture);
                        int    jsonEndIndex   = stringResult.LastIndexOf("]", StringComparison.InvariantCulture);
                        nodeList = JsonConvert.DeserializeObject <PublishedNodesCollection>(stringResult.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1));
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
            return(nodeList);
        }
Пример #6
0
        /// <summary>
        /// Invokes the Call service.
        /// </summary>
        public virtual ResponseHeader Call(
            RequestHeader requestHeader,
            CallMethodRequestCollection methodsToCall,
            out CallMethodResultCollection results,
            out DiagnosticInfoCollection diagnosticInfos)
        {
            results         = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return(CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported));
        }
        protected override void CallUnknownMethod(CancellationToken ct)
        {
            string logPrefix = $"{_logClassPrefix}:CallUnknownMethod:";

            VariantCollection inputArgumentsMethodCall = new VariantCollection()
            {
                "UnknownMethod",
            };

            try
            {
                CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                CallMethodResultCollection  results         = new CallMethodResultCollection();
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest
                {
                    ObjectId = new NodeId("Methods", 2),
                    MethodId = new NodeId("IoTHubDirectMethod", 2),
                };
                request.InputArguments = inputArgumentsMethodCall;
                requests.Add(request);
                try
                {
                    ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);
                }
                catch (Exception e)
                {
                    Logger.Fatal(e, $"{logPrefix} Exception");
                }
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    Logger.Warning($"{logPrefix} call was not successfull (status: '{results[0].StatusCode}'");
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
        }
        private bool UnpublishOneNode(NodeIdInfo nodeIdInfo, string endpointUrl = null)
        {
            string logPrefix = $"{_logClassPrefix}:UnpublishOneNode:";

            try
            {
                VariantCollection inputArguments = new VariantCollection()
                {
                    nodeIdInfo.Id,
                    endpointUrl ?? TestserverUrl
                };
                CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                CallMethodResultCollection  results         = null;
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest();
                request.ObjectId       = new NodeId("Methods", 2);
                request.MethodId       = new NodeId("UnpublishNode", 2);
                request.InputArguments = inputArguments;
                requests.Add(request);
                ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);
                if (nodeIdInfo.Published && StatusCode.IsBad(results[0].StatusCode))
                {
                    Logger.Warning($"{logPrefix} failed (nodeId: '{nodeIdInfo.Id}', published: '{nodeIdInfo.Published}')");
                    return(false);
                }
                else
                {
                    nodeIdInfo.Published = false;
                    Logger.Verbose($"{logPrefix} succeeded (nodeId: '{nodeIdInfo.Id}', error: '{results[0].StatusCode}'");
                    return(true);
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
            return(false);
        }
Пример #9
0
        /// <summary>
        /// Invokes the Call service.
        /// </summary>
        public virtual ResponseHeader Call(
            RequestHeader                  requestHeader,
            CallMethodRequestCollection    methodsToCall,
            out CallMethodResultCollection results,
            out DiagnosticInfoCollection   diagnosticInfos)
        {
            results = null;
            diagnosticInfos = null;

            ValidateRequest(requestHeader);

            // Insert implementation.

            return CreateResponse(requestHeader, StatusCodes.BadServiceUnsupported);
        }
Пример #10
0
        /// <summary>
        /// Confirms the selected conditions.
        /// </summary>
        private void Shelve(bool shelving, bool oneShot, double shelvingTime)
        {
            // build list of methods to call.
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < ConditionsLV.SelectedItems.Count; ii++)
            {
                ConditionState condition = (ConditionState)ConditionsLV.SelectedItems[ii].Tag;

                // check if the node supports shelving.
                BaseObjectState shelvingState = condition.FindChild(m_session.SystemContext, BrowseNames.ShelvingState) as BaseObjectState;

                if (shelvingState == null)
                {
                    continue;
                }

                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId = shelvingState.NodeId;
                request.Handle   = ConditionsLV.SelectedItems[ii];

                // select the method to call.
                if (!shelving)
                {
                    request.MethodId = MethodIds.ShelvedStateMachineType_Unshelve;
                }
                else
                {
                    if (oneShot)
                    {
                        request.MethodId = MethodIds.ShelvedStateMachineType_OneShotShelve;
                    }
                    else
                    {
                        request.MethodId = MethodIds.ShelvedStateMachineType_TimedShelve;
                        request.InputArguments.Add(new Variant(shelvingTime));
                    }
                }

                methodsToCall.Add(request);
            }

            if (methodsToCall.Count == 0)
            {
                return;
            }

            // call the methods.
            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            m_session.Call(
                null,
                methodsToCall,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, methodsToCall);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

            for (int ii = 0; ii < results.Count; ii++)
            {
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    ListViewItem item = (ListViewItem)methodsToCall[ii].Handle;
                    item.SubItems[8].Text = Utils.Format("{0}", results[ii].StatusCode);
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Acknowledges one or more events.
        /// </summary>
        public int[] AcknowledgeEvents(
            Session session,
            string comment,
            string acknowledgerId,
            AeAcknowledgeRequest[] requests)
        {
            if (session == null || !session.Connected)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            StringBuilder buffer = new StringBuilder();

            buffer.Append('[');
            buffer.Append(acknowledgerId);
            buffer.Append(']');

            if (!String.IsNullOrEmpty(comment))
            {
                buffer.Append(comment);
            }

            // wrap the comment once.
            Variant commentToWrite = new Variant(new LocalizedText(buffer.ToString()));

            int[] errors = new int[requests.Length];
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; ii < requests.Length; ii++)
            {
                int cookie = requests[ii].Cookie;

                AeEvent e = null;

                lock (m_lock)
                {
                    // look up the event.
                    if (!m_events.TryGetValue(cookie, out e))
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;

                        if (cookie < m_counter)
                        {
                            errors[ii] = ResultIds.S_ALREADYACKED;
                        }

                        continue;
                    }

                    if (e.SourceName != requests[ii].SourceName)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    if (e.ConditionName != requests[ii].ConditionName)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    if (e.ActiveTime != requests[ii].ActiveTime)
                    {
                        errors[ii] = ResultIds.E_INVALIDTIME;
                        continue;
                    }

                    // check that the cookie is still valid.
                    string conditionId    = GetConditionId(e);
                    int    expectedCookie = 0;

                    if (!m_cookies.TryGetValue(conditionId, out expectedCookie))
                    {
                        errors[ii] = ResultIds.S_ALREADYACKED;
                        continue;
                    }

                    // check cookie.
                    if (expectedCookie != cookie)
                    {
                        errors[ii] = ResultIds.E_INVALIDARG;
                        continue;
                    }

                    m_events.Remove(cookie);
                }

                CallMethodRequest request = new CallMethodRequest();
                request.MethodId = Opc.Ua.MethodIds.AcknowledgeableConditionType_Acknowledge;
                request.ObjectId = e.ConditionId;
                request.InputArguments.Add(new Variant(e.EventId));
                request.InputArguments.Add(commentToWrite);
                request.Handle = ii;
                methodsToCall.Add(request);
            }

            if (methodsToCall.Count > 0)
            {
                try
                {
                    // call the server.
                    CallMethodResultCollection results         = null;
                    DiagnosticInfoCollection   diagnosticInfos = null;

                    session.Call(
                        null,
                        methodsToCall,
                        out results,
                        out diagnosticInfos);

                    // verify that the server returned the correct number of results.
                    ClientBase.ValidateResponse(results, methodsToCall);
                    ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

                    // process results.
                    for (int ii = 0; ii < methodsToCall.Count; ii++)
                    {
                        int index = (int)methodsToCall[ii].Handle;

                        if (StatusCode.IsBad(results[ii].StatusCode))
                        {
                            errors[ii] = ResultIds.E_FAIL;
                            continue;
                        }
                    }
                }
                catch (Exception)
                {
                    // report error.
                    for (int ii = 0; ii < methodsToCall.Count; ii++)
                    {
                        int index = (int)methodsToCall[ii].Handle;
                        errors[ii] = ResultIds.E_FAIL;
                    }
                }
            }

            return(errors);
        }
Пример #12
0
        /// <summary>
        /// Reads the attributes, verifies the results and updates the nodes.
        /// </summary>
        private bool Call(CallMethodRequestCollection methodsToCall)
        {
            Opc.Ua.Test.DataComparer comparer = new Opc.Ua.Test.DataComparer(Session.MessageContext);

            bool success = true;

            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            RequestHeader requestHeader = new RequestHeader();

            requestHeader.ReturnDiagnostics = 0;

            try
            {
                Session.Call(
                    requestHeader,
                    methodsToCall,
                    out results,
                    out diagnosticInfos);
            }
            catch (System.ServiceModel.CommunicationException e)
            {
                Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message);
                return(true);
            }
            catch (System.Xml.XmlException e)
            {
                Log("WARNING: XML parsing error (random data may have resulted in a message that is too large). {0}", e.Message);
                return(true);
            }
            catch (ServiceResultException e)
            {
                if (e.StatusCode == StatusCodes.BadEncodingLimitsExceeded)
                {
                    Log("WARNING: Communication error (random data may have resulted in a message that is too large). {0}", e.Message);
                    return(true);
                }

                throw new ServiceResultException(new ServiceResult(e));
            }

            ClientBase.ValidateResponse(results, methodsToCall);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

            // check diagnostics.
            if (diagnosticInfos != null && diagnosticInfos.Count > 0)
            {
                Log("Returned non-empty DiagnosticInfos array during Call.");
                return(false);
            }

            // check results.
            for (int ii = 0; ii < methodsToCall.Count; ii++)
            {
                CallMethodRequest request = methodsToCall[ii];
                TestMethod        method  = (TestMethod)request.Handle;

                if (request.ObjectId != method.Parent.NodeId)
                {
                    if (results[ii].StatusCode != StatusCodes.BadMethodInvalid)
                    {
                        Log(
                            "Invalid result when method called on wrong object '{0}'. NodeId = {1}, Method = {2}, StatusCode = {3}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (results[ii].StatusCode == StatusCodes.BadUserAccessDenied)
                {
                    if (method.Method.UserExecutable)
                    {
                        Log(
                            "Call failed when calling an executable method '{0}'. NodeId = {1}, Method = {2}, StatusCode = {3}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (results[ii].StatusCode == StatusCodes.BadNotImplemented)
                {
                    continue;
                }

                if (request.InputArguments.Count != method.InputArguments.Count)
                {
                    if (results[ii].StatusCode != StatusCodes.BadArgumentsMissing)
                    {
                        Log(
                            "Incorrect error returned when passing method wrong number of arguments '{0}'. NodeId = {1}, Method = {2}, StatusCode = {3}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (results[ii].StatusCode == StatusCodes.BadInvalidArgument || results[ii].StatusCode == StatusCodes.BadOutOfRange)
                {
                    if (results[ii].InputArgumentResults.Count != request.InputArguments.Count)
                    {
                        Log(
                            "Incorrect number of result returned when reporting argument error '{0}'. NodeId = {1}, Method = {2}, Expected = {3}, Actual = {4}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            request.InputArguments.Count,
                            results[ii].InputArgumentResults.Count);

                        success = false;
                        break;
                    }

                    bool errorFound = false;

                    for (int jj = 0; jj < method.InputArguments.Count; jj++)
                    {
                        if (results[ii].InputArgumentResults[jj] != results[ii].StatusCode)
                        {
                            errorFound = true;
                        }

                        Argument argument = method.InputArguments[jj];

                        // check if data type matches.
                        TypeInfo typeInfo = TypeInfo.IsInstanceOfDataType(
                            request.InputArguments[jj].Value,
                            argument.DataType,
                            argument.ValueRank,
                            Session.NamespaceUris,
                            Session.TypeTree);

                        if (typeInfo == null)
                        {
                            if (results[ii].InputArgumentResults[jj] != StatusCodes.BadTypeMismatch)
                            {
                                Log(
                                    "Incorrect error returned for invalid argument '{0}'. NodeId = {1}, Method = {2}, Argument = {3}, StatusCode = {4}",
                                    method.Parent,
                                    method.Parent.NodeId,
                                    method.Method,
                                    method.InputArguments[jj].Name,
                                    results[ii].InputArgumentResults[jj]);

                                success = false;
                            }

                            continue;
                        }

                        if (results[ii].InputArgumentResults[jj] != StatusCodes.Good && results[ii].InputArgumentResults[jj] != StatusCodes.BadOutOfRange)
                        {
                            Log(
                                "Incorrect error returned for valid argument '{0}'. NodeId = {1}, Method = {2}, Argument = {3}, StatusCode = {4}",
                                method.Parent,
                                method.Parent.NodeId,
                                method.Method,
                                method.InputArguments[jj].Name,
                                results[ii].InputArgumentResults[jj]);

                            success = false;
                        }
                    }

                    if (!success)
                    {
                        break;
                    }

                    if (!errorFound)
                    {
                        Log(
                            "No matching argument level error for method '{0}'. NodeId = {1}, Method = {2}, StatusCode = {4}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    if (results[ii].StatusCode != StatusCodes.BadNotImplemented)
                    {
                        Log(
                            "Unexpected error when calling method '{0}'. NodeId = {1}, Method = {2}, StatusCode = {3}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            results[ii].StatusCode);

                        success = false;
                        break;
                    }

                    continue;
                }

                if (results[ii].OutputArguments.Count != method.OutputArguments.Count)
                {
                    Log(
                        "Incorrect number of output arguments '{0}'. NodeId = {1}, Method = {2}, Expected = {3}, Actual = {4}",
                        method.Parent,
                        method.Parent.NodeId,
                        method.Method,
                        method.OutputArguments.Count,
                        results[ii].OutputArguments.Count);

                    success = false;
                    break;
                }

                for (int jj = 0; jj < method.OutputArguments.Count; jj++)
                {
                    Argument argument = method.OutputArguments[jj];

                    // check if data type matches.
                    TypeInfo typeInfo = TypeInfo.IsInstanceOfDataType(
                        results[ii].OutputArguments[jj].Value,
                        argument.DataType,
                        argument.ValueRank,
                        Session.NamespaceUris,
                        Session.TypeTree);

                    if (typeInfo == null)
                    {
                        Log(
                            "Datatype for output argument is invalid '{0}'. NodeId = {1}, Method = {2}, Argument = {3}, Value = {4}",
                            method.Parent,
                            method.Parent.NodeId,
                            method.Method,
                            method.OutputArguments[jj].Name,
                            results[ii].OutputArguments[jj]);

                        success = false;
                        continue;
                    }

                    // check for special test methods that return the input parameters.
                    if (method.Parent.BrowseName.Name == "MethodTest")
                    {
                        if (jj < request.InputArguments.Count)
                        {
                            if (!comparer.CompareVariant(request.InputArguments[jj], results[ii].OutputArguments[jj]))
                            {
                                Log(
                                    "Output argument did not match input '{0}'. NodeId = {1}, Method = {2}, Argument = {3}, Value = {4}, Output = {5}",
                                    method.Parent,
                                    method.Parent.NodeId,
                                    method.Method,
                                    method.OutputArguments[jj].Name,
                                    request.InputArguments[jj],
                                    results[ii].OutputArguments[jj]);

                                success = false;
                                continue;
                            }
                        }
                    }
                }

                if (!success)
                {
                    break;
                }
            }

            return(success);
        }
Пример #13
0
        /// <summary>
        /// Calls a method defined on a object.
        /// </summary>
        public virtual void Call(
            OperationContext               context, 
            CallMethodRequestCollection    methodsToCall,
            out CallMethodResultCollection results,
            out DiagnosticInfoCollection   diagnosticInfos)
        {
            if (context == null)       throw new ArgumentNullException("context");
            if (methodsToCall == null) throw new ArgumentNullException("methodsToCall");
            
            bool diagnosticsExist = false;
            results = new CallMethodResultCollection(methodsToCall.Count);
            diagnosticInfos = new DiagnosticInfoCollection(methodsToCall.Count);
            List<ServiceResult> errors = new List<ServiceResult>(methodsToCall.Count);

            // add placeholder for each result.
            bool validItems = false;

            for (int ii = 0; ii < methodsToCall.Count; ii++)
            {
                results.Add(null);
                errors.Add(null);

                if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                {
                    diagnosticInfos.Add(null);
                }

                // validate request paramaters.
                errors[ii] = ValidateCallRequestItem(methodsToCall[ii]);

                if (ServiceResult.IsBad(errors[ii]))
                {
                    methodsToCall[ii].Processed = true;

                    // add diagnostics if requested.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]);
                        diagnosticsExist = true;
                    }

                    continue;
                }                

                // found at least one valid item.
                validItems = true;
                methodsToCall[ii].Processed = false;
            }
            
            // call each node manager.
            if (validItems)
            {
                foreach (INodeManager nodeManager in m_nodeManagers)
                {
                    nodeManager.Call(
                        context,
                        methodsToCall,
                        results,
                        errors);
                }
            }
                            
            for (int ii = 0; ii < methodsToCall.Count; ii++)
            {
                // set an error code for calls that were not handled by any node manager.
                if (!methodsToCall[ii].Processed)
                {
                    results[ii] = new CallMethodResult();
                    errors[ii] = StatusCodes.BadNodeIdUnknown;
                }

                // update the diagnostic info and ensure the status code in the result is the same as the error code.
                if (errors[ii] != null && errors[ii].Code != StatusCodes.Good)
                {
                    if (results[ii] == null)
                    {
                        results[ii] = new CallMethodResult();
                    }

                    results[ii].StatusCode = errors[ii].Code;
                    
                    // add diagnostics if requested.
                    if ((context.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0)
                    {
                        diagnosticInfos[ii] = ServerUtils.CreateDiagnosticInfo(m_server, context, errors[ii]);
                        diagnosticsExist = true;
                    }
                }
            }

            // clear the diagnostics array if no diagnostics requested or no errors occurred.
            UpdateDiagnostics(context, diagnosticsExist, ref diagnosticInfos);
        }
Пример #14
0
        /// <summary>
        /// Finishes an asynchronous invocation of the Call service.
        /// </summary>
        public ResponseHeader EndCall(
            IAsyncResult                   result,
            out CallMethodResultCollection results,
            out DiagnosticInfoCollection   diagnosticInfos)
        {
            CallResponse response = null;

            try
            {
                if (UseTransportChannel)
                {
                    IServiceResponse genericResponse = TransportChannel.EndSendRequest(result);

                    if (genericResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    ValidateResponse(genericResponse.ResponseHeader);
                    response = (CallResponse)genericResponse;
                }
                else
                {
                    CallResponseMessage responseMessage = InnerChannel.EndCall(result);

                    if (responseMessage == null || responseMessage.CallResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    response = responseMessage.CallResponse;
                    ValidateResponse(response.ResponseHeader);
                }

                results         = response.Results;
                diagnosticInfos = response.DiagnosticInfos;
            }
            finally
            {
                RequestCompleted(null, response, "Call");
            }

            return response.ResponseHeader;
        }
Пример #15
0
        /// <summary>
        /// Invokes the Call service.
        /// </summary>
        public virtual ResponseHeader Call(
            RequestHeader                  requestHeader,
            CallMethodRequestCollection    methodsToCall,
            out CallMethodResultCollection results,
            out DiagnosticInfoCollection   diagnosticInfos)
        {
            CallRequest request = new CallRequest();
            CallResponse response = null;

            request.RequestHeader = requestHeader;
            request.MethodsToCall = methodsToCall;

            UpdateRequestHeader(request, requestHeader == null, "Call");

            try
            {
                if (UseTransportChannel)
                {
                    IServiceResponse genericResponse = TransportChannel.SendRequest(request);

                    if (genericResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    ValidateResponse(genericResponse.ResponseHeader);
                    response = (CallResponse)genericResponse;
                }
                else
                {
                    CallResponseMessage responseMessage = InnerChannel.Call(new CallMessage(request));

                    if (responseMessage == null || responseMessage.CallResponse == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                    }

                    response = responseMessage.CallResponse;
                    ValidateResponse(response.ResponseHeader);
                }

                results         = response.Results;
                diagnosticInfos = response.DiagnosticInfos;
            }
            finally
            {
                RequestCompleted(request, response, "Call");
            }

            return response.ResponseHeader;
        }
        protected override bool UnpublishAllConfiguredNodes(CancellationToken ct)
        {
            string logPrefix = $"{_logClassPrefix}:UnpublishAllConfiguredNodes:";
            List <PublisherConfigurationFileEntryLegacyModel> configFileEntries = null;
            bool result = true;

            VariantCollection inputArgumentsTestserver = new VariantCollection()
            {
                TestserverUrl
            };

            try
            {
                CallMethodRequestCollection requests        = new CallMethodRequestCollection();
                CallMethodResultCollection  results         = new CallMethodResultCollection();
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest
                {
                    ObjectId = new NodeId("Methods", 2),
                    MethodId = new NodeId("GetPublishedNodes", 2),
                };
                request.InputArguments = inputArgumentsTestserver;
                requests.Add(request);
                try
                {
                    ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos);
                }
                catch (Exception e)
                {
                    Logger.Fatal(e, $"{logPrefix} Exception");
                }
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    Logger.Warning($"{logPrefix} call was not successfull (status: '{results[0].StatusCode}'");
                }
                else
                {
                    if (results?[0]?.OutputArguments.Count == 1)
                    {
                        string stringResult   = results[0].OutputArguments[0].ToString();
                        int    jsonStartIndex = stringResult.IndexOf("[", StringComparison.InvariantCulture);
                        int    jsonEndIndex   = stringResult.IndexOf("]", StringComparison.InvariantCulture);

                        configFileEntries = JsonConvert.DeserializeObject <List <PublisherConfigurationFileEntryLegacyModel> >(stringResult.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1));

                        foreach (var configFileEntry in configFileEntries)
                        {
                            if (configFileEntry.OpcNodes == null)
                            {
                                result &= UnpublishOneNode(new NodeIdInfo(configFileEntry.NodeId.ToString()));
                            }
                            else
                            {
                                foreach (var node in configFileEntry.OpcNodes)
                                {
                                    result &= UnpublishOneNode(new NodeIdInfo(node.Id), configFileEntry.EndpointUrl.AbsoluteUri);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Fatal(e, $"{logPrefix} Exception");
            }
            return(result);
        }
        /// <summary>
        /// Calls the method.
        /// </summary>
        public void Call()
        {
            // build list of methods to call.
            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            CallMethodRequest methodToCall = new CallMethodRequest();

            methodToCall.ObjectId = m_objectId;
            methodToCall.MethodId = m_methodId;

            foreach (DataRow row in m_dataset.Tables[0].Rows)
            {
                Argument argument = (Argument)row[0];
                Variant  value    = (Variant)row[4];
                argument.Value = value.Value;
                methodToCall.InputArguments.Add(value);
            }

            methodsToCall.Add(methodToCall);

            // call the method.
            CallMethodResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            ResponseHeader responseHeader = m_session.Call(
                null,
                methodsToCall,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, methodsToCall);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall);

            for (int ii = 0; ii < results.Count; ii++)
            {
                // display any input argument errors.
                if (results[ii].InputArgumentResults != null)
                {
                    for (int jj = 0; jj < results[ii].InputArgumentResults.Count; jj++)
                    {
                        if (StatusCode.IsBad(results[ii].InputArgumentResults[jj]))
                        {
                            DataRow row = m_dataset.Tables[0].Rows[jj];
                            row[5]           = results[ii].InputArgumentResults[jj].ToString();
                            ResultCH.Visible = true;
                        }
                    }
                }

                // throw an exception on error.
                if (StatusCode.IsBad(results[ii].StatusCode))
                {
                    throw ServiceResultException.Create(results[ii].StatusCode, ii, diagnosticInfos, responseHeader.StringTable);
                }

                // display the output arguments
                ResultCH.Visible      = false;
                NoArgumentsLB.Visible = m_outputArguments == null || m_outputArguments.Length == 0;
                NoArgumentsLB.Text    = "Method invoked successfully.\r\nNo output arguments to display.";
                m_dataset.Tables[0].Rows.Clear();

                if (m_outputArguments != null)
                {
                    for (int jj = 0; jj < m_outputArguments.Length; jj++)
                    {
                        DataRow row = m_dataset.Tables[0].NewRow();

                        if (results[ii].OutputArguments.Count > jj)
                        {
                            UpdateRow(row, m_outputArguments[jj], results[ii].OutputArguments[jj], true);
                        }
                        else
                        {
                            UpdateRow(row, m_outputArguments[jj], Variant.Null, true);
                        }

                        m_dataset.Tables[0].Rows.Add(row);
                    }
                }
            }
        }
        /// <summary>
        /// Invokes the Call service.
        /// </summary>
        /// <param name="requestHeader">The request header.</param>
        /// <param name="methodsToCall">The methods to call.</param>
        /// <param name="results">The results.</param>
        /// <param name="diagnosticInfos">The diagnostic information for the results.</param>
        /// <returns>
        /// Returns a <see cref="ResponseHeader"/> object
        /// </returns>
        public override ResponseHeader Call(
            RequestHeader                  requestHeader,
            CallMethodRequestCollection    methodsToCall,
            out CallMethodResultCollection results,
            out DiagnosticInfoCollection   diagnosticInfos)
        {
            OperationContext context = ValidateRequest(requestHeader, RequestType.Call);
                
            try
            {
                if (methodsToCall == null || methodsToCall.Count == 0)
                {
                    throw new ServiceResultException(StatusCodes.BadNothingToDo);
                }         

                m_serverInternal.NodeManager.Call(
                    context,
                    methodsToCall,
                    out results,
                    out diagnosticInfos);

                return CreateResponse(requestHeader, context.StringTable);
            }
            catch (ServiceResultException e)
            {
                lock (ServerInternal.DiagnosticsLock)
                {
                    ServerInternal.ServerDiagnostics.RejectedRequestsCount++;

                    if (IsSecurityError(e.StatusCode))
                    {
                        ServerInternal.ServerDiagnostics.SecurityRejectedRequestsCount++;
                    }
                }

                throw TranslateException(context, e);
            }  
            finally
            {
                OnRequestComplete(context);
            }
        }