/// <summary> /// Updates the configuration file to persist all currently published nodes /// </summary> public static async Task UpdateNodeConfigurationFileAsync() { try { // itereate through all sessions, subscriptions and monitored items and create config file entries uint nodeConfigVersion = 0; List <PublisherConfigurationFileEntryModel> publisherNodeConfiguration = GetPublisherConfigurationFileEntries(null, true, out nodeConfigVersion); // update the config file try { await PublisherNodeConfigurationFileSemaphore.WaitAsync().ConfigureAwait(false); await File.WriteAllTextAsync(PublisherNodeConfigurationFilename, JsonConvert.SerializeObject(publisherNodeConfiguration, Formatting.Indented)).ConfigureAwait(false); } finally { PublisherNodeConfigurationFileSemaphore.Release(); } } catch (Exception e) { Logger.Error(e, "Update of node configuration file failed."); } }
/// <summary> /// Read and parse the publisher node configuration file. /// </summary> /// <returns></returns> public static async Task <bool> ReadConfigAsync() { // get information on the nodes to publish and validate the json by deserializing it. try { await PublisherNodeConfigurationSemaphore.WaitAsync().ConfigureAwait(false); if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GW_PNFP"))) { Logger.Information("Publishing node configuration file path read from environment."); PublisherNodeConfigurationFilename = Environment.GetEnvironmentVariable("_GW_PNFP"); } Logger.Information($"The name of the configuration file for published nodes is: {PublisherNodeConfigurationFilename}"); // if the file exists, read it, if not just continue if (File.Exists(PublisherNodeConfigurationFilename)) { Logger.Information($"Attemtping to load node configuration from: {PublisherNodeConfigurationFilename}"); try { await PublisherNodeConfigurationFileSemaphore.WaitAsync().ConfigureAwait(false); _configurationFileEntries = JsonConvert.DeserializeObject <List <PublisherConfigurationFileEntryLegacyModel> >(File.ReadAllText(PublisherNodeConfigurationFilename)); } finally { PublisherNodeConfigurationFileSemaphore.Release(); } if (_configurationFileEntries != null) { Logger.Information($"Loaded {_configurationFileEntries.Count} config file entry/entries."); foreach (var publisherConfigFileEntryLegacy in _configurationFileEntries) { if (publisherConfigFileEntryLegacy.NodeId == null) { // new node configuration syntax. foreach (var opcNode in publisherConfigFileEntryLegacy.OpcNodes) { if (opcNode.ExpandedNodeId != null) { ExpandedNodeId expandedNodeId = ExpandedNodeId.Parse(opcNode.ExpandedNodeId); _nodePublishingConfiguration.Add(new NodePublishingConfigurationModel(expandedNodeId, opcNode.ExpandedNodeId, publisherConfigFileEntryLegacy.EndpointUrl.OriginalString, publisherConfigFileEntryLegacy.UseSecurity, opcNode.OpcPublishingInterval, opcNode.OpcSamplingInterval, opcNode.DisplayName)); } else { // check Id string to check which format we have if (opcNode.Id.StartsWith("nsu=", StringComparison.InvariantCulture)) { // ExpandedNodeId format ExpandedNodeId expandedNodeId = ExpandedNodeId.Parse(opcNode.Id); _nodePublishingConfiguration.Add(new NodePublishingConfigurationModel(expandedNodeId, opcNode.Id, publisherConfigFileEntryLegacy.EndpointUrl.OriginalString, publisherConfigFileEntryLegacy.UseSecurity, opcNode.OpcPublishingInterval, opcNode.OpcSamplingInterval, opcNode.DisplayName)); } else { // NodeId format NodeId nodeId = NodeId.Parse(opcNode.Id); _nodePublishingConfiguration.Add(new NodePublishingConfigurationModel(nodeId, opcNode.Id, publisherConfigFileEntryLegacy.EndpointUrl.OriginalString, publisherConfigFileEntryLegacy.UseSecurity, opcNode.OpcPublishingInterval, opcNode.OpcSamplingInterval, opcNode.DisplayName)); } } } } else { // NodeId (ns=) format node configuration syntax using default sampling and publishing interval. _nodePublishingConfiguration.Add(new NodePublishingConfigurationModel(publisherConfigFileEntryLegacy.NodeId, publisherConfigFileEntryLegacy.NodeId.ToString(), publisherConfigFileEntryLegacy.EndpointUrl.OriginalString, publisherConfigFileEntryLegacy.UseSecurity, null, null, null)); } } } } else { Logger.Information($"The node configuration file '{PublisherNodeConfigurationFilename}' does not exist. Continue and wait for remote configuration requests."); } } catch (Exception e) { Logger.Fatal(e, "Loading of the node configuration file failed. Does the file exist and has correct syntax? Exiting..."); return(false); } finally { PublisherNodeConfigurationSemaphore.Release(); } Logger.Information($"There are {_nodePublishingConfiguration.Count.ToString(CultureInfo.InvariantCulture)} nodes to publish."); return(true); }