/// <summary> /// Handles the Click event of the Conditions_RefreshMI control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void Conditions_RefreshMI_Click(object sender, EventArgs e) { try { CallMethodRequest request = new CallMethodRequest(); request.ObjectId = ObjectTypeIds.ConditionType; request.MethodId = MethodIds.ConditionType_ConditionRefresh; request.InputArguments.Add(new Variant(m_subscription.Id)); CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection(); methodsToCall.Add(request); CallMethodResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Call( null, methodsToCall, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, methodsToCall); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall); if (StatusCode.IsBad(results[0].StatusCode)) { throw ServiceResultException.Create((uint)results[0].StatusCode, "Unexpected error calling RefreshConditions."); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
private 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); }
/// <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); } } }
/// <summary> /// Responds to the dialog. /// </summary> private void Respond(int selectedResponse) { // build list of dialogs to respond to (caller should always make sure that only one is selected). CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection(); for (int ii = 0; ii < ConditionsLV.SelectedItems.Count; ii++) { DialogConditionState dialog = ConditionsLV.SelectedItems[ii].Tag as DialogConditionState; if (dialog == null) { continue; } CallMethodRequest request = new CallMethodRequest(); request.ObjectId = dialog.NodeId; request.MethodId = MethodIds.DialogConditionType_Respond; request.InputArguments.Add(new Variant(selectedResponse)); request.Handle = ConditionsLV.SelectedItems[ii]; methodsToCall.Add(request); } if (methodsToCall.Count == 0) { return; } // call the methods. CallMethodResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; m_session.Call( null, methodsToCall, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, methodsToCall); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall); for (int ii = 0; ii < results.Count; ii++) { if (StatusCode.IsBad(results[ii].StatusCode)) { ListViewItem item = (ListViewItem)methodsToCall[ii].Handle; item.SubItems[8].Text = Utils.Format("{0}", results[ii].StatusCode); } } }
protected override PublishedNodesCollection GetPublishedNodesLegacy(string endpointUrl, CancellationToken ct) { string logPrefix = $"{_logClassPrefix}:GetPublishedNodesLegacy:"; PublishedNodesCollection nodeList = null; VariantCollection inputArgumentsTestserver = new VariantCollection() { "" }; try { CallMethodRequestCollection requests = new CallMethodRequestCollection(); CallMethodResultCollection results = new CallMethodResultCollection(); DiagnosticInfoCollection diagnosticInfos = null; CallMethodRequest request = new CallMethodRequest { ObjectId = new NodeId("Methods", 2), MethodId = new NodeId("GetPublishedNodes", 2), }; request.InputArguments = inputArgumentsTestserver; requests.Add(request); try { ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos); } catch (Exception e) { Logger.Fatal(e, $"{logPrefix} Exception"); } if (StatusCode.IsBad(results[0].StatusCode)) { Logger.Warning($"{logPrefix} call was not successfull (status: '{results[0].StatusCode}'"); } else { if (results?[0]?.OutputArguments.Count == 1) { string stringResult = results[0].OutputArguments[0].ToString(); int jsonStartIndex = stringResult.IndexOf("[", StringComparison.InvariantCulture); int jsonEndIndex = stringResult.LastIndexOf("]", StringComparison.InvariantCulture); nodeList = JsonConvert.DeserializeObject <PublishedNodesCollection>(stringResult.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1)); } } } catch (Exception e) { Logger.Fatal(e, $"{logPrefix} Exception"); } return(nodeList); }
/// <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."); }
/// <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); }
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); } }
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); }
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; } }
/// <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); }
/// <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); }
/// <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); } } } }
protected override bool UnpublishAllConfiguredNodes(CancellationToken ct) { string logPrefix = $"{_logClassPrefix}:UnpublishAllConfiguredNodes:"; List <PublisherConfigurationFileEntryLegacyModel> configFileEntries = null; bool result = true; VariantCollection inputArgumentsTestserver = new VariantCollection() { TestserverUrl }; try { CallMethodRequestCollection requests = new CallMethodRequestCollection(); CallMethodResultCollection results = new CallMethodResultCollection(); DiagnosticInfoCollection diagnosticInfos = null; CallMethodRequest request = new CallMethodRequest { ObjectId = new NodeId("Methods", 2), MethodId = new NodeId("GetPublishedNodes", 2), }; request.InputArguments = inputArgumentsTestserver; requests.Add(request); try { ResponseHeader responseHeader = _session.Call(null, requests, out results, out diagnosticInfos); } catch (Exception e) { Logger.Fatal(e, $"{logPrefix} Exception"); } if (StatusCode.IsBad(results[0].StatusCode)) { Logger.Warning($"{logPrefix} call was not successfull (status: '{results[0].StatusCode}'"); } else { if (results?[0]?.OutputArguments.Count == 1) { string stringResult = results[0].OutputArguments[0].ToString(); int jsonStartIndex = stringResult.IndexOf("[", StringComparison.InvariantCulture); int jsonEndIndex = stringResult.IndexOf("]", StringComparison.InvariantCulture); configFileEntries = JsonConvert.DeserializeObject <List <PublisherConfigurationFileEntryLegacyModel> >(stringResult.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1)); foreach (var configFileEntry in configFileEntries) { if (configFileEntry.OpcNodes == null) { result &= UnpublishOneNode(new NodeIdInfo(configFileEntry.NodeId.ToString())); } else { foreach (var node in configFileEntry.OpcNodes) { result &= UnpublishOneNode(new NodeIdInfo(node.Id), configFileEntry.EndpointUrl.AbsoluteUri); } } } } } } catch (Exception e) { Logger.Fatal(e, $"{logPrefix} Exception"); } return(result); }
/// <summary> /// 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); }
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; } } }
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); } } }
/// <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); } } }
/// <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; }
/// <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; }
/// <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; } } }