/// <summary> /// Method to remove the node from the subscription and stop publishing telemetry to IoTHub. Executes synchronously. /// </summary> private ServiceResult OnUnpublishNodeCall(ISystemContext context, MethodState method, IList <object> inputArguments, IList <object> outputArguments) { string logPrefix = "OnUnpublishNodeCall:"; if (string.IsNullOrEmpty(inputArguments[0] as string) || string.IsNullOrEmpty(inputArguments[1] as string)) { Logger.Error($"{logPrefix} Invalid arguments!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments!")); } HttpStatusCode statusCode = HttpStatusCode.InternalServerError; NodeId nodeId = null; ExpandedNodeId expandedNodeId = null; Uri endpointUri = null; bool isNodeIdFormat = true; try { string id = inputArguments[0] as string; if (id.Contains("nsu=", StringComparison.InvariantCulture)) { expandedNodeId = ExpandedNodeId.Parse(id); isNodeIdFormat = false; } else { nodeId = NodeId.Parse(id); isNodeIdFormat = true; } endpointUri = new Uri(inputArguments[1] as string); } catch (UriFormatException) { Logger.Error($"{logPrefix} The endpointUrl is invalid '{inputArguments[1] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA endpoint URL as second argument!")); } catch (Exception e) { Logger.Error(e, $"{logPrefix} The NodeId has an invalid format '{inputArguments[0] as string}'!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide a valid OPC UA NodeId in NodeId or ExpandedNodeId format as first argument!")); } // find the session and stop monitoring the node. try { NodeConfiguration.OpcSessionsListSemaphore.Wait(); if (ShutdownTokenSource.IsCancellationRequested) { return(ServiceResult.Create(StatusCodes.BadUnexpectedError, $"Publisher shutdown in progress.")); } // find the session we need to monitor the node OpcUaSessionManager opcSession = null; try { opcSession = NodeConfiguration.OpcSessions.FirstOrDefault(s => s.EndpointUrl.Equals(endpointUri.OriginalString, StringComparison.OrdinalIgnoreCase)); } catch { opcSession = null; } if (opcSession == null) { // do nothing if there is no session for this endpoint. Logger.Error($"{logPrefix} Session for endpoint '{endpointUri.OriginalString}' not found."); return(ServiceResult.Create(StatusCodes.BadSessionIdInvalid, "Session for endpoint of node to unpublished not found!")); } else { if (isNodeIdFormat) { // stop monitoring the node, execute syncronously Logger.Information($"{logPrefix} Request to stop monitoring item with NodeId '{nodeId.ToString()}')"); statusCode = opcSession.RequestMonitorItemRemovalAsync(nodeId, null, ShutdownTokenSource.Token).Result; } else { // stop monitoring the node, execute syncronously Logger.Information($"{logPrefix} Request to stop monitoring item with ExpandedNodeId '{expandedNodeId.ToString()}')"); statusCode = opcSession.RequestMonitorItemRemovalAsync(null, expandedNodeId, ShutdownTokenSource.Token).Result; } } } catch (Exception e) { Logger.Error(e, $"{logPrefix} Exception while trying to configure publishing node '{nodeId.ToString()}'"); return(ServiceResult.Create(e, StatusCodes.BadUnexpectedError, $"Unexpected error unpublishing node: {e.Message}")); } finally { NodeConfiguration.OpcSessionsListSemaphore.Release(); } return(statusCode == HttpStatusCode.OK || statusCode == HttpStatusCode.Accepted ? ServiceResult.Good : ServiceResult.Create(StatusCodes.Bad, "Can not stop monitoring node!")); }