Example #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);
            }
        }
Example #2
0
        private CallMethodRequestCollection ResendDataCall(StatusCode expectedStatus, UInt32Collection subscriptionIds)
        {
            // Find the ResendData method
            var nodesToCall = new CallMethodRequestCollection();

            foreach (var subscriptionId in subscriptionIds)
            {
                nodesToCall.Add(new CallMethodRequest()
                {
                    ObjectId       = ObjectIds.Server,
                    MethodId       = MethodIds.Server_ResendData,
                    InputArguments = new VariantCollection()
                    {
                        new Variant(subscriptionId)
                    }
                });
            }

            //call ResendData method with subscription ids
            m_requestHeader.Timestamp = DateTime.UtcNow;
            var response = m_server.Call(m_requestHeader,
                                         nodesToCall,
                                         out var results,
                                         out var diagnosticInfos);

            Assert.AreEqual(expectedStatus, results[0].StatusCode.Code);
            ServerFixtureUtils.ValidateResponse(response);

            return(nodesToCall);
        }
        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);
        }
Example #4
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);
                }
            }
        }
        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);
        }
Example #6
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);
                }
            }
        }
Example #7
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));
        }
Example #8
0
 /// <inheritdoc/>
 public async Task <(ServiceResultModel, string)> CallMethodAsync(
     string method, string request, DiagnosticsModel diagnostics)
 {
     if (string.IsNullOrEmpty(request))
     {
         throw new ArgumentNullException(nameof(request));
     }
     if (string.IsNullOrEmpty(method))
     {
         throw new ArgumentNullException(nameof(method));
     }
     return(await _client.ExecuteServiceAsync(_endpoint,
                                              null, async session => {
         var results = new List <OperationResultModel>();
         var methodCalls = new CallMethodRequestCollection {
             new CallMethodRequest {
                 ObjectId = new NodeId(kMethodCallObject, 2),
                 MethodId = new NodeId(kMethodCallMethod, 2),
                 InputArguments = new VariantCollection {
                     new Variant(method),
                     new Variant(request)
                 }
             }
         };
         var result = await session.CallAsync(diagnostics.ToStackModel(),
                                              methodCalls);
         OperationResultEx.Validate("CallMethod", results,
                                    result.Results.Select(r => r.StatusCode), result.DiagnosticInfos,
                                    methodCalls, false);
         var diagResult = results.ToServiceModel(diagnostics,
                                                 session.MessageContext);
         if (!StatusCode.IsGood(result.Results[0].StatusCode))
         {
             _logger.Error("Call returned with error {status}",
                           result.Results[0].StatusCode);
             return (diagResult, null);
         }
         if (result.Results[0].OutputArguments?.Count == 1)
         {
             var response = result.Results[0].OutputArguments[0].ToString();
             return (diagResult, response);
         }
         return (diagResult, null);
     }));
 }
Example #9
0
        /// <summary>
        /// Applies custom settings to quickstart servers for CTT run.
        /// </summary>
        /// <param name="server"></param>
        public static void ApplyCTTMode(TextWriter output, StandardServer server)
        {
            var methodsToCall = new CallMethodRequestCollection();
            var index         = server.CurrentInstance.NamespaceUris.GetIndex(Alarms.Namespaces.Alarms);

            if (index > 0)
            {
                try
                {
                    methodsToCall.Add(
                        // Start the Alarms with infinite runtime
                        new CallMethodRequest {
                        MethodId       = new NodeId("Alarms.Start", (ushort)index),
                        ObjectId       = new NodeId("Alarms", (ushort)index),
                        InputArguments = new VariantCollection()
                        {
                            new Variant((UInt32)UInt32.MaxValue)
                        }
                    });
                    var requestHeader = new RequestHeader()
                    {
                        Timestamp   = DateTime.UtcNow,
                        TimeoutHint = 10000
                    };
                    var context = new OperationContext(requestHeader, RequestType.Call);
                    server.CurrentInstance.NodeManager.Call(context, methodsToCall, out CallMethodResultCollection results, out DiagnosticInfoCollection diagnosticInfos);
                    foreach (var result in results)
                    {
                        if (ServiceResult.IsBad(result.StatusCode))
                        {
                            Opc.Ua.Utils.LogError("Error calling method {0}.", result.StatusCode);
                        }
                    }
                    output.WriteLine("The Alarms for CTT mode are active.");
                    return;
                }
                catch (Exception ex)
                {
                    Opc.Ua.Utils.LogError(ex, "Failed to start alarms for CTT.");
                }
            }
            output.WriteLine("The alarms could not be enabled for CTT, the namespace does not exist.");
        }
Example #10
0
        /// <summary>
        /// Tells the server to refresh all conditions being monitored by the subscription.
        /// </summary>
        public async Task ConditionRefreshAsync(CancellationToken ct = default(CancellationToken))
        {
            VerifySubscriptionState(true);

            var methodsToCall = new CallMethodRequestCollection();

            methodsToCall.Add(new CallMethodRequest()
            {
                MethodId       = MethodIds.ConditionType_ConditionRefresh,
                InputArguments = new VariantCollection()
                {
                    new Variant(m_id)
                }
            });

            var response = await m_session.CallAsync(
                null,
                methodsToCall,
                ct).ConfigureAwait(false);
        }
Example #11
0
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                VariantCollection inputArguments = InputArgumentsCTRL.GetValues();

                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId       = m_objectId;
                request.MethodId       = m_methodId;
                request.InputArguments = inputArguments;

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

                CallMethodResultCollection results;
                DiagnosticInfoCollection   diagnosticInfos;

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

                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw new ServiceResultException(new ServiceResult(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable));
                }

                OutputArgumentsCTRL.SetValues(results[0].OutputArguments);

                if (results[0].OutputArguments.Count == 0)
                {
                    MessageBox.Show(this, "Method executed successfully.");
                }
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
Example #12
0
 public static Entry For(CallMethodRequestCollection methodsToCall)
 {
     if (methodsToCall == null)
     {
         return(new NullEntry());
     }
     else
     {
         ArrayEntry array = new ArrayEntry();
         CallMethodRequestCollection.Enumerator e = methodsToCall.GetEnumerator();
         while (e.MoveNext())
         {
             ObjectEntry methodEntry = new ObjectEntry();
             methodEntry.Add("ObjectId", For(e.Current.ObjectId));
             methodEntry.Add("MethodId", For(e.Current.MethodId));
             methodEntry.Add("InputArguments", For(e.Current.InputArguments));
             array.Add(methodEntry);
         }
         return(array);
     }
 }
        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);
        }
Example #15
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);
            }
        }
Example #16
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);
                }
            }
        }
Example #17
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);
                }
            }
        }
Example #18
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;
        }
        /// <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);
            }
        }
Example #20
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);
        }
Example #21
0
        /// <summary>
        /// Adds random parameters
        /// </summary>
        private void AddMethodCall(
            TestMethod method, 
            CallMethodRequestCollection methodsToCall,
            bool testErrors)
        {            
            VariantCollection inputArguments = new VariantCollection();

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

                object value = m_generator.GetRandom(
                    argument.DataType,
                    argument.ValueRank,
                    argument.ArrayDimensions,
                    Session.TypeTree);
                
                inputArguments.Add(new Variant(value));
            }
         
            CallMethodRequest request = null;

            // add valid method.
            if (!testErrors)
            {
                request = new CallMethodRequest();

                request.ObjectId = method.Parent.NodeId;
                request.MethodId = method.Method.NodeId;
                request.Handle = method;
                request.InputArguments = new VariantCollection(inputArguments);

                methodsToCall.Add(request);

                return;
            }
                     
            // add invalid object.
            request = new CallMethodRequest();

            request.ObjectId = Objects.RootFolder;
            request.MethodId = method.Method.NodeId;
            request.Handle = method;
            request.InputArguments = new VariantCollection(inputArguments);

            methodsToCall.Add(request);
                                 
            if (inputArguments.Count > 0)
            {
                // add too few parameters.
                request = new CallMethodRequest();

                request.ObjectId = method.Parent.NodeId;
                request.MethodId = method.Method.NodeId;
                request.Handle = method;
                request.InputArguments = new VariantCollection(inputArguments);
                request.InputArguments.RemoveAt(request.InputArguments.Count-1);

                methodsToCall.Add(request);
                
                // add invalid parameter.
                request = new CallMethodRequest();

                request.ObjectId = method.Parent.NodeId;
                request.MethodId = method.Method.NodeId;
                request.Handle = method;
                request.InputArguments = new VariantCollection(inputArguments);
                
                Argument argument = method.InputArguments[inputArguments.Count/2];      
          
                if (TypeInfo.GetBuiltInType(argument.DataType, Session.TypeTree) != BuiltInType.Variant)
                {
                    TypeInfo typeInfo = null;

                    do
                    { 
                        Variant arg = (Variant)m_generator.GetRandom(BuiltInType.Variant);

                        typeInfo = TypeInfo.IsInstanceOfDataType(
                            arg.Value,
                            argument.DataType,
                            argument.ValueRank,
                            Session.NamespaceUris,
                            Session.TypeTree);

                        if (typeInfo == null)
                        {
                            request.InputArguments[inputArguments.Count/2] = arg;
                            methodsToCall.Add(request);
                            break;
                        }
                    }
                    while (typeInfo != null);
                }
            }

            // add extra parameters.
            request = new CallMethodRequest();

            request.ObjectId = method.Parent.NodeId;
            request.MethodId = method.Method.NodeId;
            request.Handle = method;
            request.InputArguments = new VariantCollection(inputArguments);
            request.InputArguments.Add(new Variant(m_generator.GetRandom(BuiltInType.Variant)));

            methodsToCall.Add(request);
        }
Example #22
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);
        }
Example #23
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);
        }
Example #24
0
        private string CallOpcMethod(string appUri, string parentNode, string methodNode)
        {
            string            result         = null;
            VariantCollection inputArguments = new VariantCollection();

            try
            {
                string  sessionID = Guid.NewGuid().ToString();
                Session session   = OpcSessionHelper.Instance.GetSessionWithImplicitTrust(sessionID, appUri).Result;
                if (session == null)
                {
                    result = $"Could not establish session to OPC UA server with appUri '{appUri}'";
                    Trace.TraceError(result);
                    return(result);
                }

                CallMethodRequestCollection requests = new CallMethodRequestCollection();
                CallMethodResultCollection  results;
                DiagnosticInfoCollection    diagnosticInfos = null;
                CallMethodRequest           request         = new CallMethodRequest();
                request.ObjectId       = new NodeId(parentNode);
                request.MethodId       = new NodeId(methodNode);
                request.InputArguments = inputArguments;
                requests.Add(request);
                ResponseHeader responseHeader = session.Call(null, requests, out results, out diagnosticInfos);
                OpcSessionHelper.Instance.Disconnect(sessionID);
                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    result = Strings.BrowserOpcMethodCallFailed + "`n" +
                             Strings.BrowserOpcMethodStatusCode + ": " + results[0].StatusCode + "`n";
                    if (diagnosticInfos.Count > 0)
                    {
                        result += "`n" + Strings.BrowserOpcDataDiagnosticInfoLabel + ": " + diagnosticInfos;
                    }
                    Trace.TraceInformation($"OPC UA method call to OPC UA server '{appUri}' method '{methodNode}' under parent node '{parentNode}' failed.");
                    Trace.TraceInformation($"Details: {result}'");
                }
                else
                {
                    if (results[0].OutputArguments.Count == 0)
                    {
                        result = Strings.BrowserOpcMethodCallSucceeded;
                    }
                    else
                    {
                        result = Strings.BrowserOpcMethodCallSucceededWithResults + "`n";
                        for (int ii = 0; ii < results[0].OutputArguments.Count; ii++)
                        {
                            result += results[0].OutputArguments[ii] + "`n";
                        }
                    }
                    Trace.TraceInformation($"OPC UA method call to OPC UA server '{appUri}' method '{methodNode}' under parent node '{parentNode}' succeeded.");
                    Trace.TraceInformation($"Details: {result}'");
                }
            }
            catch (Exception exception)
            {
                result = $"Exception while calling OPC UA method: {exception.Message}";
            }
            return(result);
        }
        public async Task <ActionResult> MethodCall(string jstreeNode, string parameterData, string parameterValues, Session session = null)
        {
            string[] delimiter       = { "__$__" };
            string[] jstreeNodeSplit = jstreeNode.Split(delimiter, 3, StringSplitOptions.None);
            string   node;
            string   parentNode = null;

            if (jstreeNodeSplit.Length == 1)
            {
                node       = jstreeNodeSplit[0];
                parentNode = null;
            }
            else
            {
                node       = jstreeNodeSplit[1];
                parentNode = (jstreeNodeSplit[0].Replace(delimiter[0], "")).Replace("__", "");
            }

            string actionResult = "";
            List <MethodCallParameterData> originalData = JsonConvert.DeserializeObject <List <MethodCallParameterData> >(parameterData);
            List <Variant>    values         = JsonConvert.DeserializeObject <List <Variant> >(parameterValues);
            int               count          = values.Count;
            VariantCollection inputArguments = new VariantCollection();

            bool retry = true;

            while (true)
            {
                try
                {
                    if (session == null)
                    {
                        session = await OpcSessionHelper.Instance.GetSessionAsync(Session.SessionID, (string)Session["EndpointUrl"]);
                    }

                    for (int i = 0; i < count; i++)
                    {
                        Variant value          = new Variant();
                        NodeId  dataTypeNodeId = "i=" + originalData[i].Datatype;
                        string  dataTypeName   = originalData[i].TypeName;
                        Int32   valueRank      = Convert.ToInt32(originalData[i].ValueRank, CultureInfo.InvariantCulture);
                        string  newValue       = values[i].Value.ToString();

                        try
                        {
                            OpcSessionHelper.Instance.BuildDataValue(ref session, ref value, dataTypeNodeId, valueRank, newValue);
                            inputArguments.Add(value);
                        }
                        catch (Exception exception)
                        {
                            actionResult = string.Format(Strings.BrowserOpcWriteConversionProblem, newValue,
                                                         dataTypeName, exception.Message);
                            return(Content(actionResult));
                        }
                    }

                    CallMethodRequestCollection requests = new CallMethodRequestCollection();
                    CallMethodResultCollection  results;
                    DiagnosticInfoCollection    diagnosticInfos = null;
                    CallMethodRequest           request         = new CallMethodRequest();
                    request.ObjectId       = new NodeId(parentNode);
                    request.MethodId       = new NodeId(node);
                    request.InputArguments = inputArguments;
                    requests.Add(request);
                    ResponseHeader responseHeader = session.Call(null, requests, out results, out diagnosticInfos);
                    if (StatusCode.IsBad(results[0].StatusCode))
                    {
                        actionResult = Strings.BrowserOpcMethodCallFailed + @"<br/><br/>" +
                                       Strings.BrowserOpcMethodStatusCode + ": " + results[0].StatusCode;
                        if (diagnosticInfos.Count > 0)
                        {
                            actionResult += @"<br/><br/>" + Strings.BrowserOpcDataDiagnosticInfoLabel + ": " + diagnosticInfos;
                        }
                    }
                    else
                    {
                        if (results[0].OutputArguments.Count == 0)
                        {
                            actionResult = Strings.BrowserOpcMethodCallSucceeded;
                        }
                        else
                        {
                            actionResult = Strings.BrowserOpcMethodCallSucceededWithResults + @"<br/><br/>";
                            for (int ii = 0; ii < results[0].OutputArguments.Count; ii++)
                            {
                                actionResult += results[0].OutputArguments[ii] + "@<br/>";
                            }
                        }
                    }
                    return(Content(actionResult));
                }
                catch (Exception exception)
                {
                    if (!retry)
                    {
                        return(Content(CreateOpcExceptionActionString(exception)));
                    }
                    retry = false;
                }
            }
        }
Example #26
0
        public async Task <ActionResult> VariablePublishUnpublish(string jstreeNode, string method)
        {
            string[] delimiter       = { "__$__" };
            string[] jstreeNodeSplit = jstreeNode.Split(delimiter, 3, StringSplitOptions.None);
            string   node;
            string   actionResult = "";
            Session  publisherSession;
            string   publisherSessionId = Guid.NewGuid().ToString();

            if (jstreeNodeSplit.Length == 1)
            {
                node = jstreeNodeSplit[0];
            }
            else
            {
                node = jstreeNodeSplit[1];
            }

            try
            {
                try
                {
                    publisherSession = await ConnectToPublisher(publisherSessionId);
                }
                catch
                {
                    return(Content(CreateOpcExceptionActionString(new Exception(Strings.Error))));
                }

                if (publisherSession != null)
                {
                    VariantCollection inputArguments = new VariantCollection();
                    Variant           nodeIdValue;
                    Variant           endpointUrlValue;
                    try
                    {
                        OpcSessionHelper.Instance.BuildDataValue(ref publisherSession, ref nodeIdValue, TypeInfo.GetDataTypeId(string.Empty), ValueRanks.Scalar, node);
                        OpcSessionHelper.Instance.BuildDataValue(ref publisherSession, ref endpointUrlValue, TypeInfo.GetDataTypeId(string.Empty), ValueRanks.Scalar, (string)Session["EndpointUrl"]);
                    }
                    catch (Exception exception)
                    {
                        actionResult = string.Format(Strings.BrowserOpcWriteConversionProblem, exception.Message);
                        return(Content(actionResult));
                    }
                    inputArguments.Add(nodeIdValue);
                    inputArguments.Add(endpointUrlValue);

                    bool retry = true;
                    while (true)
                    {
                        try
                        {
                            CallMethodRequestCollection requests = new CallMethodRequestCollection();
                            CallMethodResultCollection  results;
                            DiagnosticInfoCollection    diagnosticInfos = null;
                            CallMethodRequest           request         = new CallMethodRequest();
                            request.ObjectId = new NodeId("Methods", 2);
                            if (method == "unpublish")
                            {
                                request.MethodId = new NodeId("UnpublishNode", 2);
                            }
                            else
                            {
                                request.MethodId = new NodeId("PublishNode", 2);
                            }
                            request.InputArguments = inputArguments;
                            requests.Add(request);
                            ResponseHeader responseHeader = publisherSession.Call(null, requests, out results, out diagnosticInfos);
                            if (StatusCode.IsBad(results[0].StatusCode))
                            {
                                actionResult = Strings.BrowserOpcMethodCallFailed + @"<br/><br/>" +
                                               Strings.BrowserOpcMethodStatusCode + ": " + results[0].StatusCode;
                                if (diagnosticInfos.Count > 0)
                                {
                                    actionResult += @"<br/><br/>" + Strings.BrowserOpcDataDiagnosticInfoLabel + ": " + diagnosticInfos;
                                }
                            }
                            else
                            {
                                if (results[0].OutputArguments.Count == 0)
                                {
                                    actionResult = Strings.BrowserOpcMethodCallSucceeded;
                                }
                                else
                                {
                                    actionResult = Strings.BrowserOpcMethodCallSucceededWithResults + @"<br/><br/>";
                                    for (int ii = 0; ii < results[0].OutputArguments.Count; ii++)
                                    {
                                        actionResult += results[0].OutputArguments[ii] + "@<br/>";
                                    }
                                }
                            }
                            return(Content(actionResult));
                        }
                        catch (Exception exception)
                        {
                            if (!retry)
                            {
                                try
                                {
                                    OpcSessionHelper.Instance.Disconnect(publisherSessionId);
                                }
                                catch
                                {
                                }
                                return(Content(CreateOpcExceptionActionString(exception)));
                            }
                            retry = false;
                        }
                    }
                }
                else
                {
                    throw new Exception(Strings.SessionNull);
                }
            }
            catch (Exception exception)
            {
                return(Content(CreateOpcExceptionActionString(exception)));
            }
            finally
            {
                if (publisherSessionId != null)
                {
                    OpcSessionHelper.Instance.Disconnect(publisherSessionId);
                }
            }
        }
Example #27
0
        /// <summary>
        /// Returns the list of published nodes of the OPC UA server with the given endpointUrl
        /// </summary>
        private async Task <string[]> GetPublishedNodes(string endpointUrl)
        {
            List <string> publishedNodes     = new List <string>();
            Session       publisherSession   = null;
            string        publisherSessionId = Guid.NewGuid().ToString();

            // read the published nodes from the publisher
            try
            {
                try
                {
                    publisherSession = await ConnectToPublisher(publisherSessionId);
                }
                catch
                {
                    return(null);
                }

                if (publisherSession != null)
                {
                    VariantCollection inputArguments = new VariantCollection();
                    Variant           endpointUrlValue;
                    try
                    {
                        OpcSessionHelper.Instance.BuildDataValue(ref publisherSession, ref endpointUrlValue, TypeInfo.GetDataTypeId(string.Empty), ValueRanks.Scalar, endpointUrl);
                    }
                    catch (Exception e)
                    {
                        return(null);
                    }
                    inputArguments.Add(endpointUrlValue);

                    bool retry = true;
                    while (true)
                    {
                        try
                        {
                            CallMethodRequestCollection requests = new CallMethodRequestCollection();
                            CallMethodResultCollection  results;
                            DiagnosticInfoCollection    diagnosticInfos = null;
                            CallMethodRequest           request         = new CallMethodRequest();
                            request.ObjectId       = new NodeId("Methods", 2);
                            request.MethodId       = new NodeId("GetPublishedNodes", 2);
                            request.InputArguments = inputArguments;
                            requests.Add(request);
                            ResponseHeader responseHeader = publisherSession.Call(null, requests, out results, out diagnosticInfos);
                            if (StatusCode.IsBad(results[0].StatusCode))
                            {
                                return(null);
                            }
                            else
                            {
                                if (results?[0]?.OutputArguments.Count == 1)
                                {
                                    string stringResult = results[0].OutputArguments[0].ToString();

                                    int jsonStartIndex = stringResult.IndexOf("[");
                                    int jsonEndIndex   = stringResult.IndexOf("]");
                                    PublishedNodesCollection nodelist = JsonConvert.DeserializeObject <PublishedNodesCollection>(stringResult.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1));
                                    foreach (NodeLookup node in nodelist)
                                    {
                                        publishedNodes.Add(node.NodeID.ToString());
                                    }

                                    return(publishedNodes.ToArray());
                                }
                                else
                                {
                                    return(null);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            if (!retry)
                            {
                                return(null);
                            }
                            retry = false;
                        }
                    }
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception e)
            {
                return(null);
            }
            finally
            {
                if (publisherSession != null)
                {
                    OpcSessionHelper.Instance.Disconnect(publisherSessionId);
                }
            }
        }
Example #28
0
        /// <summary>
        /// Reads an verifies all of the nodes.
        /// </summary>
        private bool DoCallTest(bool testErrors)
        {
            // follow tree from each starting node.
            bool success = true;
                                 
            // collection writeable variables that don't change during the test.
            List<TestMethod> methods = new List<TestMethod>();

            foreach (Node node in AvailableNodes.Values)
            {
                if (!CollectMethods(node, testErrors, methods))
                {
                    return false;
                }
            }

            Log("Starting CallTest for {0} Methods", methods.Count);
            
            double increment = MaxProgress/(10*methods.Count);
            double position  = 0;

            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();
            
            for (int ii = 0; success && ii < 10; ii++)
            {
                int nodes = 0;
                int operations = 0;

                foreach (TestMethod method in methods)
                {               
                    nodes++;

                    AddMethodCall(method, methodsToCall, testErrors);

                    // process batch.
                    if (methodsToCall.Count > 100)
                    {
                        operations += methodsToCall.Count;

                        if (!Call(methodsToCall))
                        {
                            success = false;
                            break;
                        }

                        if (nodes > (10*methods.Count)/5)
                        {
                            Log("Called {1} methods {0} times.", operations, nodes);
                            nodes = 0;
                            operations = 0;
                        }

                        methodsToCall.Clear();
                    }

                    position += increment;
                    ReportProgress(position);
                }   
             
                // process final batch.
                if (success)
                {
                    if (methodsToCall.Count > 0)
                    {
                        operations += methodsToCall.Count;

                        if (!Call(methodsToCall))
                        {
                            success = false;
                        }
                        else
                        {
                            Log("Called {1} methods {0} times.", operations, nodes);
                        }

                        methodsToCall.Clear();
                    }
                }

                if (testErrors)
                {
                    break;
                }
            }

            return success;
        }
Example #29
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;
        }
        public void ResendData()
        {
            var serverTestServices = new ServerTestServices(m_server);
            // save old security context, test fixture can only work with one session
            var securityContext = SecureChannelContext.Current;

            try
            {
                var      namespaceUris = m_server.CurrentInstance.NamespaceUris;
                NodeId[] testSet       = CommonTestWorkers.NodeIdTestSetStatic.Select(n => ExpandedNodeId.ToNodeId(n, namespaceUris)).ToArray();
                //Re-use method CreateSubscriptionForTransfer to create a subscription
                CommonTestWorkers.CreateSubscriptionForTransfer(serverTestServices, m_requestHeader,
                                                                testSet, out var subscriptionIds);

                RequestHeader resendDataRequestHeader   = m_server.CreateAndActivateSession("ResendData");
                var           resendDataSecurityContext = SecureChannelContext.Current;

                // After the ResendData call there will be data to publish again
                MethodState methodStateInstance = (MethodState)m_server.CurrentInstance.
                                                  DiagnosticsNodeManager.FindPredefinedNode(MethodIds.Server_ResendData, typeof(MethodState));
                var nodesToCall = new CallMethodRequestCollection();
                nodesToCall.Add(new CallMethodRequest()
                {
                    ObjectId       = ObjectIds.Server,
                    MethodId       = MethodIds.Server_ResendData,
                    InputArguments = new VariantCollection()
                    {
                        new Variant(subscriptionIds.Last())
                    }
                });

                //call ResendData method from the same session context
                m_requestHeader.Timestamp = DateTime.UtcNow;
                var response = m_server.Call(m_requestHeader,
                                             nodesToCall,
                                             out var results,
                                             out var diagnosticInfos);

                Assert.IsTrue(StatusCode.IsGood(results[0].StatusCode));
                ServerFixtureUtils.ValidateResponse(response);

                Thread.Sleep(1000);

                // Make sure publish queue becomes empty by consuming it
                Assert.AreEqual(1, subscriptionIds.Count);
                // Issue a Publish request
                m_requestHeader.Timestamp = DateTime.UtcNow;
                var acknoledgements = new SubscriptionAcknowledgementCollection();
                response = serverTestServices.Publish(m_requestHeader, acknoledgements,
                                                      out uint publishedId, out UInt32Collection availableSequenceNumbers,
                                                      out bool moreNotifications, out NotificationMessage notificationMessage,
                                                      out StatusCodeCollection _, out diagnosticInfos);

                Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code);
                ServerFixtureUtils.ValidateResponse(response);
                ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
                Assert.AreEqual(subscriptionIds[0], publishedId);
                Assert.AreEqual(1, notificationMessage.NotificationData.Count);

                // Validate nothing to publish a few times
                const int timesToCallPublish = 3;
                for (int i = 0; i < timesToCallPublish; i++)
                {
                    m_requestHeader.Timestamp = DateTime.UtcNow;
                    response = serverTestServices.Publish(m_requestHeader, acknoledgements,
                                                          out publishedId, out availableSequenceNumbers,
                                                          out moreNotifications, out notificationMessage,
                                                          out StatusCodeCollection _, out diagnosticInfos);

                    Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code);
                    ServerFixtureUtils.ValidateResponse(response);
                    ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
                    Assert.AreEqual(subscriptionIds[0], publishedId);
                    Assert.AreEqual(0, notificationMessage.NotificationData.Count);
                }

                // Validate ResendData method call from same and different session contexts

                // call ResendData method from different session context
                resendDataRequestHeader.Timestamp = DateTime.UtcNow;
                response = m_server.Call(resendDataRequestHeader,
                                         nodesToCall,
                                         out results,
                                         out diagnosticInfos);

                Assert.AreEqual(StatusCodes.BadUserAccessDenied, results[0].StatusCode.Code);
                ServerFixtureUtils.ValidateResponse(response);

                // Still nothing to publish since previous ResendData call did not execute
                m_requestHeader.Timestamp = DateTime.UtcNow;
                response = serverTestServices.Publish(m_requestHeader, acknoledgements,
                                                      out publishedId, out availableSequenceNumbers,
                                                      out moreNotifications, out notificationMessage,
                                                      out StatusCodeCollection _, out diagnosticInfos);

                Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code);
                ServerFixtureUtils.ValidateResponse(response);
                ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
                Assert.AreEqual(subscriptionIds[0], publishedId);
                Assert.AreEqual(0, notificationMessage.NotificationData.Count);

                //call ResendData method from the same session context
                m_requestHeader.Timestamp = DateTime.UtcNow;
                response = m_server.Call(m_requestHeader,
                                         nodesToCall,
                                         out results,
                                         out diagnosticInfos);

                Assert.IsTrue(StatusCode.IsGood(results[0].StatusCode));
                ServerFixtureUtils.ValidateResponse(response);

                // Data should be available for publishing now
                m_requestHeader.Timestamp = DateTime.UtcNow;
                response = serverTestServices.Publish(m_requestHeader, acknoledgements,
                                                      out publishedId, out availableSequenceNumbers,
                                                      out moreNotifications, out notificationMessage,
                                                      out StatusCodeCollection _, out diagnosticInfos);

                Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code);
                ServerFixtureUtils.ValidateResponse(response);
                ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
                Assert.AreEqual(subscriptionIds[0], publishedId);
                Assert.AreEqual(1, notificationMessage.NotificationData.Count);

                // Call ResendData method with invalid subscription Id
                nodesToCall = new CallMethodRequestCollection();
                nodesToCall.Add(new CallMethodRequest()
                {
                    ObjectId       = ObjectIds.Server,
                    MethodId       = MethodIds.Server_ResendData,
                    InputArguments = new VariantCollection()
                    {
                        new Variant(subscriptionIds.Last() + 20)
                    }
                });
                m_requestHeader.Timestamp = DateTime.UtcNow;
                response = m_server.Call(m_requestHeader,
                                         nodesToCall,
                                         out results,
                                         out diagnosticInfos);

                Assert.AreEqual(StatusCodes.BadSubscriptionIdInvalid, results[0].StatusCode.Code);
                ServerFixtureUtils.ValidateResponse(response);

                // Nothing to publish since previous ResendData call did not execute
                m_requestHeader.Timestamp = DateTime.UtcNow;
                response = serverTestServices.Publish(m_requestHeader, acknoledgements,
                                                      out publishedId, out availableSequenceNumbers,
                                                      out moreNotifications, out notificationMessage,
                                                      out StatusCodeCollection _, out diagnosticInfos);

                Assert.AreEqual(StatusCodes.Good, response.ServiceResult.Code);
                ServerFixtureUtils.ValidateResponse(response);
                ServerFixtureUtils.ValidateDiagnosticInfos(diagnosticInfos, acknoledgements);
                Assert.AreEqual(subscriptionIds[0], publishedId);
                Assert.AreEqual(0, notificationMessage.NotificationData.Count);

                resendDataRequestHeader.Timestamp = DateTime.UtcNow;
                SecureChannelContext.Current      = resendDataSecurityContext;
                m_server.CloseSession(resendDataRequestHeader);
            }
            finally
            {
                //restore security context, that close connection can work
                SecureChannelContext.Current = securityContext;
            }
        }
Example #31
0
        /// <summary>
        /// Reads an verifies all of the nodes.
        /// </summary>
        private bool DoCallTest(bool testErrors)
        {
            // follow tree from each starting node.
            bool success = true;

            // collection writeable variables that don't change during the test.
            List <TestMethod> methods = new List <TestMethod>();

            foreach (Node node in AvailableNodes.Values)
            {
                if (!CollectMethods(node, testErrors, methods))
                {
                    return(false);
                }
            }

            Log("Starting CallTest for {0} Methods", methods.Count);

            double increment = MaxProgress / (10 * methods.Count);
            double position  = 0;

            CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection();

            for (int ii = 0; success && ii < 10; ii++)
            {
                int nodes      = 0;
                int operations = 0;

                foreach (TestMethod method in methods)
                {
                    nodes++;

                    AddMethodCall(method, methodsToCall, testErrors);

                    // process batch.
                    if (methodsToCall.Count > 100)
                    {
                        operations += methodsToCall.Count;

                        if (!Call(methodsToCall))
                        {
                            success = false;
                            break;
                        }

                        if (nodes > (10 * methods.Count) / 5)
                        {
                            Log("Called {1} methods {0} times.", operations, nodes);
                            nodes      = 0;
                            operations = 0;
                        }

                        methodsToCall.Clear();
                    }

                    position += increment;
                    ReportProgress(position);
                }

                // process final batch.
                if (success)
                {
                    if (methodsToCall.Count > 0)
                    {
                        operations += methodsToCall.Count;

                        if (!Call(methodsToCall))
                        {
                            success = false;
                        }
                        else
                        {
                            Log("Called {1} methods {0} times.", operations, nodes);
                        }

                        methodsToCall.Clear();
                    }
                }

                if (testErrors)
                {
                    break;
                }
            }

            return(success);
        }
        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);
        }
Example #33
0
        /// <summary>
        /// Adds random parameters
        /// </summary>
        private void AddMethodCall(
            TestMethod method,
            CallMethodRequestCollection methodsToCall,
            bool testErrors)
        {
            VariantCollection inputArguments = new VariantCollection();

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

                object value = m_generator.GetRandom(
                    argument.DataType,
                    argument.ValueRank,
                    argument.ArrayDimensions,
                    Session.TypeTree);

                inputArguments.Add(new Variant(value));
            }

            CallMethodRequest request = null;

            // add valid method.
            if (!testErrors)
            {
                request = new CallMethodRequest();

                request.ObjectId       = method.Parent.NodeId;
                request.MethodId       = method.Method.NodeId;
                request.Handle         = method;
                request.InputArguments = new VariantCollection(inputArguments);

                methodsToCall.Add(request);

                return;
            }

            // add invalid object.
            request = new CallMethodRequest();

            request.ObjectId       = Objects.RootFolder;
            request.MethodId       = method.Method.NodeId;
            request.Handle         = method;
            request.InputArguments = new VariantCollection(inputArguments);

            methodsToCall.Add(request);

            if (inputArguments.Count > 0)
            {
                // add too few parameters.
                request = new CallMethodRequest();

                request.ObjectId       = method.Parent.NodeId;
                request.MethodId       = method.Method.NodeId;
                request.Handle         = method;
                request.InputArguments = new VariantCollection(inputArguments);
                request.InputArguments.RemoveAt(request.InputArguments.Count - 1);

                methodsToCall.Add(request);

                // add invalid parameter.
                request = new CallMethodRequest();

                request.ObjectId       = method.Parent.NodeId;
                request.MethodId       = method.Method.NodeId;
                request.Handle         = method;
                request.InputArguments = new VariantCollection(inputArguments);

                Argument argument = method.InputArguments[inputArguments.Count / 2];

                if (TypeInfo.GetBuiltInType(argument.DataType, Session.TypeTree) != BuiltInType.Variant)
                {
                    TypeInfo typeInfo = null;

                    do
                    {
                        Variant arg = (Variant)m_generator.GetRandom(BuiltInType.Variant);

                        typeInfo = TypeInfo.IsInstanceOfDataType(
                            arg.Value,
                            argument.DataType,
                            argument.ValueRank,
                            Session.NamespaceUris,
                            Session.TypeTree);

                        if (typeInfo == null)
                        {
                            request.InputArguments[inputArguments.Count / 2] = arg;
                            methodsToCall.Add(request);
                            break;
                        }
                    }while (typeInfo != null);
                }
            }

            // add extra parameters.
            request = new CallMethodRequest();

            request.ObjectId       = method.Parent.NodeId;
            request.MethodId       = method.Method.NodeId;
            request.Handle         = method;
            request.InputArguments = new VariantCollection(inputArguments);
            request.InputArguments.Add(new Variant(m_generator.GetRandom(BuiltInType.Variant)));

            methodsToCall.Add(request);
        }
Example #34
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);
                }
            }
        }
        /// <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);
                    }
                }
            }
        }
Example #36
0
        /// <summary>
        /// Begins an asynchronous invocation of the Call service.
        /// </summary>
        public IAsyncResult BeginCall(
            RequestHeader               requestHeader,
            CallMethodRequestCollection methodsToCall,
            AsyncCallback               callback,
            object                      asyncState)
        {
            CallRequest request = new CallRequest();

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

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

            if (UseTransportChannel)
            {
                return TransportChannel.BeginSendRequest(request, callback, asyncState);
            }

            return InnerChannel.BeginCall(new CallMessage(request), callback, asyncState);
        }
Example #37
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);
                }
            }
        }
        private async Task <Session> ConsoleSampleClient()
        {
            var application = new ApplicationInstance {
                ApplicationType = ApplicationType.Client
            };

            #region Create an Application Configuration
            Console.WriteLine(" 1 - Create an Application Configuration.");
            ExitCode = ExitCode.ErrorCreateApplication;

            // Load the Application Configuration and use the specified config section "Technosoftware.SimpleClient"
            var config = await application.LoadConfigurationAsync("Technosoftware.SimpleClient");

            // check the application certificate.
            var haveAppCertificate = await application.CheckApplicationInstanceCertificateAsync(false, CertificateFactory.DefaultKeySize, CertificateFactory.DefaultLifeTime);

            reverseConnectManager_ = null;
            if (ReverseConnectUri != null)
            {
                // start the reverse connection manager
                reverseConnectManager_ = new ReverseConnectManager();
                reverseConnectManager_.AddEndpoint(ReverseConnectUri);
                reverseConnectManager_.StartService(config);
            }

            if (haveAppCertificate)
            {
                config.ApplicationUri = X509Utils.GetApplicationUriFromCertificate(config.SecurityConfiguration.ApplicationCertificate.Certificate);
                if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
                {
                    autoAccept_ = true;
                }
                config.CertificateValidator.CertificateValidation += OnCertificateValidation;
            }
            else
            {
                Console.WriteLine("    WARN: missing application certificate, using unsecured connection.");
            }
            #endregion

            #region Discover endpoints
            Console.WriteLine(" 2 - Discover endpoints of {0}.", endpointUrl_);
            ExitCode = ExitCode.ErrorDiscoverEndpoints;
            EndpointDescription selectedEndpoint;
            if (reverseConnectManager_ == null)
            {
                selectedEndpoint = Discover.SelectEndpoint(endpointUrl_, haveAppCertificate && !SecurityNone, 15000);
            }
            else
            {
                Console.WriteLine("   Waiting for reverse connection.");
                var connection = await reverseConnectManager_.WaitForConnection(
                    new Uri(endpointUrl_), null, new CancellationTokenSource(60000).Token);

                if (connection == null)
                {
                    throw new ServiceResultException(StatusCodes.BadTimeout, "Waiting for a reverse connection timed out.");
                }
                selectedEndpoint = Discover.SelectEndpoint(config, connection, haveAppCertificate && !SecurityNone, 15000);
            }

            Console.WriteLine("    Selected endpoint uses: {0}",
                              selectedEndpoint.SecurityPolicyUri.Substring(selectedEndpoint.SecurityPolicyUri.LastIndexOf('#') + 1));
            #endregion

            #region Create a session with OPC UA server
            Console.WriteLine(" 3 - Create a session with OPC UA server.");
            ExitCode = ExitCode.ErrorCreateSession;

            // create the user identity
            UserIdentity userIdentity;
            if (String.IsNullOrEmpty(Username) && String.IsNullOrEmpty(Password))
            {
                userIdentity = new UserIdentity(new AnonymousIdentityToken());
            }
            else
            {
                userIdentity = new UserIdentity(Username, Password);
            }

            // create worker session
            if (reverseConnectManager_ == null)
            {
                session_ = await CreateSessionAsync(config, selectedEndpoint, userIdentity).ConfigureAwait(false);
            }
            else
            {
                Console.WriteLine("   Waiting for reverse connection.");
                // Define the cancellation token.
                var source = new CancellationTokenSource(60000);
                var token  = source.Token;
                try
                {
                    var connection = await reverseConnectManager_.WaitForConnection(
                        new Uri(endpointUrl_), null, token);

                    if (connection == null)
                    {
                        throw new ServiceResultException(StatusCodes.BadTimeout,
                                                         "Waiting for a reverse connection timed out.");
                    }

                    session_ = await CreateSessionAsync(config, connection, selectedEndpoint, userIdentity)
                               .ConfigureAwait(false);
                }
                finally
                {
                    source.Dispose();
                }
            }

            // register keep alive handler
            session_.SessionKeepAliveEvent += OnSessionKeepAliveEvent;
            #endregion

            #region Browse the OPC UA Server
            Console.WriteLine(" 4 - Browse address space.");
            // Create the browser
            var browser = new Browser(session_)
            {
                BrowseDirection   = BrowseDirection.Forward,
                ReferenceTypeId   = ReferenceTypeIds.HierarchicalReferences,
                IncludeSubtypes   = true,
                NodeClassMask     = 0,
                ContinueUntilDone = false
            };

            // Browse from the RootFolder
            var references = browser.Browse(Objects.ObjectsFolder);

            GetElements(session_, browser, 0, references, Verbose);

            #endregion

            #region Read a single value
            Console.WriteLine(" 5 - Read a single value.");
            var simulatedDataValue = session_.ReadValue(simulatedDataNodeId_);
            Console.WriteLine("Node Value:" + simulatedDataValue.Value);
            #endregion

            #region Read multiple values
            Console.WriteLine(" 6 - Read multiple values.");
            // The input parameters of the ReadValues() method
            var variableIds   = new List <NodeId>();
            var expectedTypes = new List <Type>();

            // Add a node to the list
            variableIds.Add(simulatedDataNodeId_);
            // Add an expected type to the list (null means we get the original type from the server)
            expectedTypes.Add(null);

            // Add another node to the list
            variableIds.Add(staticDataNodeId1_);
            // Add an expected type to the list (null means we get the original type from the server)
            expectedTypes.Add(null);

            // Add another node to the list
            variableIds.Add(staticDataNodeId2_);

            // Add an expected type to the list (null means we get the original type from the server)
            expectedTypes.Add(null);

            session_.ReadValues(variableIds, expectedTypes, out var values, out var errors);
            // write the result to the console.
            for (var i = 0; i < values.Count; i++)
            {
                Console.WriteLine("Status of Read of Node {0} is: {1}", variableIds[i].ToString(), errors[i]);
            }
            for (var i = 0; i < values.Count; i++)
            {
                Console.WriteLine("Value of Read of Node {0} is: Value: {1}", variableIds[i].ToString(), values[i]);
            }
            #endregion

            #region Read multiple values asynchronous
            Console.WriteLine(" 7 - Read multiple values asynchronous.");
            // start reading the value (setting a 10 second timeout).
            session_.BeginReadValues(
                variableIds,
                0,
                TimestampsToReturn.Both,
                OnReadComplete,
                new UserData {
                Session = session_, NodeIds = variableIds
            });
            #endregion

            #region Write a value
            Console.WriteLine(" 8 - Write a value.");
            short writeInt = 1234;

            Console.WriteLine("Write Value: " + writeInt);
            session_.WriteValue(staticDataNodeId1_, new DataValue(writeInt));

            // read it again to check the new value
            Console.WriteLine("Node Value (should be {0}): {1}", session_.ReadValue(staticDataNodeId1_).Value, writeInt);
            #endregion

            #region Write multiple values at once
            Console.WriteLine(" 9 - Write multiple values at once.");

            writeInt = 5678;
            var writeDouble = 1234.1234;

            var nodeIds    = new List <NodeId>();
            var dataValues = new List <DataValue>();

            nodeIds.Add(staticDataNodeId1_);
            nodeIds.Add(staticDataNodeId2_);

            dataValues.Add(new DataValue(writeInt));
            dataValues.Add(new DataValue(writeDouble));

            Console.WriteLine("Write Values: {0} and {1}", writeInt, writeDouble);
            var statusCodes = session_.WriteValues(nodeIds, dataValues);

            Console.WriteLine("Returned status codes:");
            foreach (var statusCode in statusCodes)
            {
                Console.WriteLine("Status: {0}", statusCode.ToString());
            }

            // read it again to check the new value
            Console.WriteLine("Node Value (should be {0}): {1}", session_.ReadValue(staticDataNodeId1_).Value, writeInt);
            Console.WriteLine("Node Value (should be {0}): {1}", session_.ReadValue(staticDataNodeId2_).Value, writeDouble);
            #endregion

            #region Write multiple values asynchronous
            Console.WriteLine("10 - Write multiple values asynchronous.");

            // start writing the values.
            session_.BeginWriteValues(
                nodeIds,
                dataValues,
                OnWriteComplete,
                new UserData {
                Session = session_, NodeIds = nodeIds
            });
            #endregion

            #region Call a Method
            Console.WriteLine("11 - Call a Method.");
            INode node = session_.ReadNode(callHelloMethodNodeId_);


            if (node is MethodNode)
            {
                var methodId = callHelloMethodNodeId_;

                var objectId = methodsNodeId_;

                var inputArguments = new VariantCollection {
                    new Variant("from Technosoftware")
                };

                var request = new CallMethodRequest {
                    ObjectId = objectId, MethodId = methodId, InputArguments = inputArguments
                };

                var requests = new CallMethodRequestCollection {
                    request
                };

                var responseHeader = session_.Call(
                    null,
                    requests,
                    out var results,
                    out var diagnosticInfos);

                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw new ServiceResultException(new ServiceResult(results[0].StatusCode, 0, diagnosticInfos,
                                                                       responseHeader.StringTable));
                }

                Console.WriteLine("{0}", results[0].OutputArguments[0]);
            }

            #endregion

            #region Create a subscription with publishing interval of 1 second
            Console.WriteLine("12 - Create a subscription with publishing interval of 1 second.");
            ExitCode      = ExitCode.ErrorCreateSubscription;
            subscription_ = new Subscription(session_.DefaultSubscription)
            {
                PublishingInterval = 1000
            };
            #endregion

            #region Add all dynamic values and the server time to the subscription
            Console.WriteLine("13 - Add all dynamic values and the server time to the subscription.");
            ExitCode = ExitCode.ErrorMonitoredItem;
            var list = new List <MonitoredItem> {
                new MonitoredItem(subscription_.DefaultItem)
                {
                    DisplayName = "ServerStatusCurrentTime", StartNodeId = "i=" + Variables.Server_ServerStatus_CurrentTime
                }
            };
            list.ForEach(i => i.MonitoredItemNotificationEvent += OnNotification);

            var newItem = new MonitoredItem(subscription_.DefaultItem)
            {
                DisplayName = "Simulated Data Value",
                StartNodeId = new NodeId(simulatedDataNodeId_)
            };
            newItem.MonitoredItemNotificationEvent += OnMonitoredItemNotificationEvent;
            list.Add(newItem);

            subscription_.AddItems(list);
            #endregion

            #region Add the subscription to the session
            Console.WriteLine("14 - Add the subscription to the session.");
            ExitCode = ExitCode.ErrorAddSubscription;
            session_.AddSubscription(subscription_);
            subscription_.Create();
            #endregion

            #region Running...Press Ctrl-C to exit...
            Console.WriteLine("15 - Running...Press Ctrl-C to exit...");
            ExitCode = ExitCode.ErrorRunning;
            #endregion

            return(session_);
        }
Example #39
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;
        }
Example #40
0
        private void OkBTN_Click(object sender, EventArgs e)
        {
            try
            {
                VariantCollection inputArguments = InputArgumentsCTRL.GetValues();
                                
                CallMethodRequest request = new CallMethodRequest();

                request.ObjectId       = m_objectId;
                request.MethodId       = m_methodId;
                request.InputArguments = inputArguments;

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

                CallMethodResultCollection results;
                DiagnosticInfoCollection diagnosticInfos;

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

                if (StatusCode.IsBad(results[0].StatusCode))
                {
                    throw new ServiceResultException(new ServiceResult(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable));
                }

                OutputArgumentsCTRL.SetValues(results[0].OutputArguments);

                if (results[0].OutputArguments.Count == 0)
                {
                    MessageBox.Show(this, "Method executed successfully.");
                }
            }
            catch (Exception exception)
            {
                GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
            }
        }
        /// <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);
        }
        /// <summary>
        /// Handles a cal operation.
        /// </summary>
        public override void Call(
            OperationContext context,
            IList<CallMethodRequest> methodsToCall,
            IList<CallMethodResult> results,
            IList<ServiceResult> errors)
        {
            ServerSystemContext systemContext = SystemContext.Copy(context);
            IDictionary<NodeId, NodeState> operationCache = new NodeIdDictionary<NodeState>();

            CallMethodRequestCollection requests = new CallMethodRequestCollection();
            List<int> indexes = new List<int>();

            // validates the nodes and constructs requests for external nodes.
            for (int ii = 0; ii < methodsToCall.Count; ii++)
            {
                CallMethodRequest methodToCall = methodsToCall[ii];

                // skip items that have already been processed.
                if (methodToCall.Processed)
                {
                    continue;
                }

                MethodState method = null;

                lock (Lock)
                {
                    // check for valid handle.
                    NodeHandle handle = GetManagerHandle(systemContext, methodToCall.ObjectId, operationCache);

                    if (handle == null)
                    {
                        continue;
                    }

                    // owned by this node manager.
                    methodToCall.Processed = true;

                    // validate the source node.
                    NodeState source = ValidateNode(systemContext, handle, operationCache);

                    if (source == null)
                    {
                        errors[ii] = StatusCodes.BadNodeIdUnknown;
                        continue;
                    }

                    // determine if a local node.
                    if (PredefinedNodes.ContainsKey(handle.NodeId))
                    {
                        // find the method.
                        method = source.FindMethod(systemContext, methodToCall.MethodId);

                        if (method == null)
                        {
                            // check for loose coupling.
                            if (source.ReferenceExists(ReferenceTypeIds.HasComponent, false, methodToCall.MethodId))
                            {
                                method = (MethodState)FindPredefinedNode(methodToCall.MethodId, typeof(MethodState));
                            }

                            if (method == null)
                            {
                                errors[ii] = StatusCodes.BadMethodInvalid;
                                continue;
                            }
                        }
                    }
                }

                if (method != null)
                {
                    // call the method.
                    CallMethodResult result = results[ii] = new CallMethodResult();

                    errors[ii] = Call(
                        systemContext,
                        methodToCall,
                        method,
                        result);
                        
                    continue;
                }

                CallMethodRequest request = (CallMethodRequest)methodToCall.Clone();
                request.ObjectId = m_mapper.ToRemoteId(methodToCall.ObjectId);
                request.MethodId = m_mapper.ToRemoteId(methodToCall.MethodId);

                for (int jj = 0; jj < request.InputArguments.Count; jj++)
                {
                    request.InputArguments[jj] = m_mapper.ToRemoteVariant(methodToCall.InputArguments[jj]);
                }

                requests.Add(request);
                indexes.Add(ii);
            }

            // send request to external system.
            try
            {
                Opc.Ua.Client.Session client = GetClientSession(systemContext);

                CallMethodResultCollection results2 = null;
                DiagnosticInfoCollection diagnosticInfos = null;

                ResponseHeader responseHeader = client.Call(
                    null,
                    requests,
                    out results2,
                    out diagnosticInfos);

                // these do sanity checks on the result - make sure response matched the request.
                ClientBase.ValidateResponse(results2, requests);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, requests);

                // set results.
                for (int ii = 0; ii < requests.Count; ii++)
                {
                    results[indexes[ii]] = results2[ii];
                    errors[indexes[ii]] = ServiceResult.Good;

                    if (results2[ii].StatusCode != StatusCodes.Good)
                    {
                        errors[indexes[ii]] = new ServiceResult(results[ii].StatusCode, ii, diagnosticInfos, responseHeader.StringTable);
                    }
                    else
                    {
                        for (int jj = 0; jj < results2[ii].OutputArguments.Count; jj++)
                        {
                            results2[ii].OutputArguments[jj] = m_mapper.ToLocalVariant(results2[ii].OutputArguments[jj]);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                // handle unexpected communication error.
                ServiceResult error = ServiceResult.Create(e, StatusCodes.BadUnexpectedError, "Could not access external system.");

                for (int ii = 0; ii < requests.Count; ii++)
                {
                    errors[indexes[ii]] = error;
                }
            }
        }
        /// <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);
                    }
                }
            }
        }
Example #44
0
        /// <summary>
        /// Calls the specified method and returns the output arguments.
        /// </summary>
        /// <param name="objectId">The NodeId of the object that provides the method.</param>
        /// <param name="methodId">The NodeId of the method to call.</param>
        /// <param name="args">The input arguments.</param>
        /// <returns>The list of output argument values.</returns>
        public IList<object> Call(NodeId objectId, NodeId methodId, params object[] args)
        {
            VariantCollection inputArguments = new VariantCollection();
            
            if (args != null)
            {
                for (int ii = 0; ii < args.Length; ii++)
                {
                    inputArguments.Add(new Variant(args[ii]));
                }
            }
                                            
            CallMethodRequest request = new CallMethodRequest();

            request.ObjectId       = objectId;
            request.MethodId       = methodId;
            request.InputArguments = inputArguments;

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

            CallMethodResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;

            ResponseHeader responseHeader = Call(
                null,
                requests,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, requests);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, requests);
            
            if (StatusCode.IsBad(results[0].StatusCode))
            {
                throw ServiceResultException.Create(results[0].StatusCode, 0, diagnosticInfos, responseHeader.StringTable);
            }

            List<object> outputArguments = new List<object>();

            foreach (Variant arg in results[0].OutputArguments)
            {
                outputArguments.Add(arg.Value);
            }

            return outputArguments;
        }