//******************************************************************************************************// SubscriberRequestViewModel.cs - Gbtc//// Copyright © 2010, Grid Protection Alliance. All Rights Reserved.//// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See// the NOTICE file distributed with this work for additional information regarding copyright ownership.// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may// not use this file except in compliance with the License. You may obtain a copy of the License at://// http://www.opensource.org/licenses/MIT//// Unless agreed to in writing, the subject software distributed under the License is distributed on an// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the// License for the specific language governing permissions and limitations.//// Code Modification History:// ----------------------------------------------------------------------------------------------------// 11/29/2012 - Stephen C. Wills// Generated original version of source code.////****************************************************************************************************** using System;using System.Collections.Generic;using System.Data;using System.Diagnostics;using System.IO;using System.Linq;using System.Net;using System.Net.Security;using System.Security.Cryptography;using System.Security.Cryptography.X509Certificates;using System.Threading;using System.Windows;using System.Windows.Input;using System.Xml.Linq;using GSF.Collections;using GSF.Console;using GSF.Data;using GSF.IO;using GSF.PhasorProtocols.UI.DataModels;using GSF.PhasorProtocols.UI.UserControls;using GSF.Security.Cryptography;using GSF.ServiceProcess;using GSF.TimeSeries.UI;using GSF.TimeSeries.UI.Commands;using GSF.TimeSeries.UI.DataModels;using GSF.Units;using Microsoft.Win32;using Random = GSF.Security.Cryptography.Random; namespace GSF.TimeSeries.Transport.UI.ViewModels{ internal class SubscriberRequestViewModel : ViewModelBase, IDisposable { #region [ Members ] // Fields private string m_publisherAcronym; private string m_publisherName; private string m_hostname; private int m_publisherPort; private SecurityMode m_securityMode; private bool m_useSTTP; private bool m_useGEP; private bool m_useSourcePrefix; private bool m_receiveExternalMetadata; private bool m_receiveInternalMetadata; private bool m_useUdpDataChannel; private int m_udpDataChannelPort; private bool m_enableDataGapRecovery; private double m_recoveryStartDelay; private double m_dataMonitoringInterval; private double m_minimumRecoverySpan; private double m_maximumRecoverySpan; private int m_recoveryProcessingInterval; private string m_loggingPath; private bool m_disposed; private string m_subscriberAcronym; private string m_subscriberName; private int m_internalDataPublisherPort; private string m_sharedKey; private string m_identityCertificate; private string m_validIPAddresses; private string m_localCertificateFile; private string m_localCertificateServerPath; private string m_importCertificatePath; private byte[] m_localCertificateData; private string m_remoteCertificateFile; private byte[] m_remoteCertificateData; private bool m_isRemoteCertificateSelfSigned; private string m_validPolicyErrors; private string m_validChainFlags; private Visibility m_connectivityMessageVisibility; private bool m_advancedTlsSettingsPopupIsOpen; private AutoResetEvent m_responseComplete; private ICommand m_localBrowseCommand; private ICommand m_remoteBrowseCommand; private ICommand m_importCertificateCommand; private ICommand m_advancedTlsSettingsOpenCommand; private ICommand m_advancedTlsSettingsCloseCommand; private ICommand m_createCommand; private ICommand m_saveCommand; #endregion #region [ Constructors ] /// <summary> /// Creates a new instance of the <see cref="SubscriberRequestViewModel"/> class. /// </summary> public SubscriberRequestViewModel() { m_internalDataPublisherPort = 7165; m_securityMode = SecurityMode.TLS; m_useSTTP = true; m_useSourcePrefix = true; m_receiveInternalMetadata = true; m_udpDataChannelPort = 64170; m_publisherPort = DefaultPort; m_responseComplete = new AutoResetEvent(false); Load(); } /// <summary> /// Releases the unmanaged resources before the <see cref="SubscriberRequestViewModel"/> object is reclaimed by <see cref="GC"/>. /// </summary> ~SubscriberRequestViewModel() { Dispose(false); } #endregion #region [ Properties ] /// <summary> /// Gets or sets the string identifier used to identify the publisher. /// </summary> public string PublisherAcronym { get => m_publisherAcronym; set { bool updateRemoteCertificateFile = (string.IsNullOrEmpty(m_publisherAcronym) && string.IsNullOrEmpty(m_remoteCertificateFile)) || m_remoteCertificateFile.Equals($"{m_publisherAcronym}.cer", StringComparison.CurrentCultureIgnoreCase); m_publisherAcronym = value; OnPropertyChanged("PublisherAcronym"); if (updateRemoteCertificateFile) RemoteCertificateFile = string.IsNullOrEmpty(m_publisherAcronym) ? string.Empty : $"{m_publisherAcronym}.cer"; } } /// <summary> /// Gets or sets the name of the publisher. /// </summary> public string PublisherName { get => m_publisherName; set { m_publisherName = value; OnPropertyChanged("PublisherName"); } } /// <summary> /// Gets or sets the host name or IP address of the server hosting the data publisher. /// </summary> public string Hostname { get => m_hostname; set { m_hostname = value; OnPropertyChanged("Hostname"); } } /// <summary> /// Gets or sets the port that the data publisher is listening on. /// </summary> public int PublisherPort { get => m_publisherPort; set { m_publisherPort = value; OnPropertyChanged("PublisherPort"); } } /// <summary> /// Gets or sets the security mode used by the data publisher. /// </summary> public SecurityMode SecurityMode { get => m_securityMode; set { int oldDefaultPort = DefaultPort; m_securityMode = value; OnPropertyChanged("SecurityMode"); OnPropertyChanged("TransportLayerSecuritySelected"); OnPropertyChanged("GatewaySecuritySelected"); if (m_publisherPort == oldDefaultPort) PublisherPort = DefaultPort; } } /// <summary> /// Gets or sets flag that determines if STTP protocol should be used. /// </summary> public bool UseSTTP { get => m_useSTTP; set { m_useSTTP = value; OnPropertyChanged("UseSTTP"); } } /// <summary> /// Gets or sets flag that determines if GEP protocol should be used. /// </summary> public bool UseGEP { get => m_useGEP; set { m_useGEP = value; OnPropertyChanged("UseGEP"); } } /// <summary> /// Gets or sets flag that determines if source prefix should be used. /// </summary> public bool UseSourcePrefix { get => m_useSourcePrefix; set { m_useSourcePrefix = value; OnPropertyChanged("UseSourcePrefix"); } } /// <summary> /// Gets or sets the flag that determines whether the subscriber is /// requesting metadata for internal signals from the publisher. /// </summary> public bool ReceiveInternalMetadata { get => m_receiveInternalMetadata; set { m_receiveInternalMetadata = value; OnPropertyChanged("ReceiveInternalMetadata"); if (!m_receiveInternalMetadata && !m_receiveExternalMetadata) ReceiveExternalMetadata = true; } } /// <summary> /// Gets or sets the flag that determines whether the subscriber is /// requesting metadata for external signals from the publisher. /// </summary> public bool ReceiveExternalMetadata { get => m_receiveExternalMetadata; set { m_receiveExternalMetadata = value; OnPropertyChanged("ReceiveExternalMetadata"); if (!m_receiveInternalMetadata && !m_receiveExternalMetadata) ReceiveInternalMetadata = true; } } /// <summary> /// Gets or sets the flag that determines whether the subscriber /// should be configured with or without a UDP data channel. /// </summary> public bool UseUdpDataChannel { get => m_useUdpDataChannel; set { m_useUdpDataChannel = value; OnPropertyChanged("UseUdpDataChannel"); } } /// <summary> /// Gets or sets the port used for the UDP data channel. /// </summary> public int UdpDataChannelPort { get => m_udpDataChannelPort; set { m_udpDataChannelPort = value; OnPropertyChanged("UdpDataChannelPort"); } } /// <summary> /// Gets or sets flag that determines if data gap recovery will be enabled. /// </summary> public bool EnableDataGapRecovery { get => m_enableDataGapRecovery; set { m_enableDataGapRecovery = value; OnPropertyChanged("EnableDataGapRecovery"); } } /// <summary> /// Gets or sets the minimum time delay, in seconds, to wait before starting the data recovery for an <see cref="Outage"/>. /// </summary> /// <remarks> /// <para> /// For some archiving systems it may take a few seconds for data to make it to disk and therefore be readily /// available for a temporal subscription query. The <see cref="RecoveryStartDelay"/> should be adjusted based /// on the nature of the system used to archive data. If the archival system makes data immediately available /// because of internal caching or other means, this value can be zero. /// </para> /// <para> /// Use of this value depends on the local clock, as such the value should be increased by the uncertainty of /// accuracy of the local clock. For example, if it is know that the local clock floats +/-5 seconds from /// real-time, then increase the desired value of the <see cref="RecoveryStartDelay"/> by 5 seconds. /// </para> /// </remarks> public double RecoveryStartDelay { get => m_recoveryStartDelay; set { m_recoveryStartDelay = value; OnPropertyChanged("RecoveryStartDelay"); } } /// <summary> /// Gets or sets the interval, in seconds, over which the data monitor will check for new data. /// </summary> /// <remarks> /// Once a connection is established a timer is enabled to monitor for new incoming data. The data monitoring timer /// exists to make sure data is being received so that the process of recovery does not wait endlessly for data that /// may never come because of a possible error in the recovery process. The <see cref="DataMonitoringInterval"/> /// allows the consumer to adjust the interval over which the timer will check for new incoming data. /// <para> /// It will take some time, perhaps a couple of seconds, to start the temporal subscription and begin the process /// of recovering data for an <see cref="Outage"/>. Make sure the value for <see cref="DataMonitoringInterval"/> is /// sufficiently large enough to handle any initial delays in data transmission. /// </para> /// </remarks> public double DataMonitoringInterval { get => m_dataMonitoringInterval; set { m_dataMonitoringInterval = value; OnPropertyChanged("DataMonitoringInterval"); } } /// <summary> /// Gets to sets the minimum time span, in seconds, for which a data recovery will be attempted. /// Set to zero for no minimum. /// </summary> public double MinimumRecoverySpan { get => m_minimumRecoverySpan; set { m_minimumRecoverySpan = value; OnPropertyChanged("MinimumRecoverySpan"); } } /// <summary> /// Gets to sets the maximum time span, in days for UI - API is seconds, for which a data recovery will be attempted. /// Set to <see cref="Double.MaxValue"/> for no maximum. /// </summary> public double MaximumRecoverySpan { get => m_maximumRecoverySpan; set { m_maximumRecoverySpan = value; OnPropertyChanged("MaximumRecoverySpan"); } } /// <summary> /// Gets or sets the data recovery processing interval, in whole milliseconds, to use in the temporal data /// subscription when recovering data for an <see cref="Outage"/>.<br/> /// A value of <c>-1</c> indicates the default processing interval will be requested.<br/> /// A value of <c>0</c> indicates data will be processed as fast as possible. /// </summary> /// <remarks> /// With the exception of the values of -1 and 0, the <see cref="RecoveryProcessingInterval"/> value specifies /// the desired historical data playback processing interval in milliseconds. This is basically a delay, or timer /// interval, over which to process data. Setting this value to -1 means to use the default processing interval /// while setting the value to 0 means to process data as fast as possible, i.e., as fast as the historian can /// query the data. Depending on the available bandwidth, this parameter may need to be adjusted such that the /// data being recovered does not adversely interfere with the ongoing transmission of real-time data. /// </remarks> public int RecoveryProcessingInterval { get => m_recoveryProcessingInterval; set { m_recoveryProcessingInterval = value; OnPropertyChanged("RecoveryProcessingInterval"); } } /// <summary> /// Gets or sets logging path to be used to be runtime and outage logs of the subscriber which are required for /// automated data recovery. /// </summary> /// <remarks> /// Leave value blank for default path, i.e., installation folder. Can be a fully qualified path or a path that /// is relative to the installation folder, e.g., a value of "ConfigurationCache" might resolve to /// "C:\Program Files\MyTimeSeriespPp\ConfigurationCache\". /// </remarks> public string LoggingPath { get => m_loggingPath; set { m_loggingPath = value; OnPropertyChanged("LoggingPath"); } } /// <summary> /// Gets or sets the port used by the internal data publisher. /// </summary> public int InternalDataPublisherPort { get => m_internalDataPublisherPort; set { int oldDefaultPort = DefaultPort; m_internalDataPublisherPort = value; if (m_publisherPort == oldDefaultPort) PublisherPort = DefaultPort; } } /// <summary> /// Gets or sets the string identifier used to identify the subscriber. /// </summary> public string SubscriberAcronym { get => m_subscriberAcronym; set { m_subscriberAcronym = value; OnPropertyChanged("SubscriberAcronym"); } } /// <summary> /// Gets or sets the name of the subscriber. /// </summary> public string SubscriberName { get => m_subscriberName; set { m_subscriberName = value; OnPropertyChanged("SubscriberName"); } } /// <summary> /// Gets the flag that indicates whether the user has selected TLS as the security mode.Lines 1–500 of 1434. Load more
//****************************************************************************************************** // SubscriberRequestViewModel.cs - Gbtc // // Copyright © 2010, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 11/29/2012 - Stephen C. Wills // Generated original version of source code. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Windows; using System.Windows.Input; using System.Xml.Linq; using GSF.Collections; using GSF.Console; using GSF.Data; using GSF.IO; using GSF.PhasorProtocols.UI.DataModels; using GSF.PhasorProtocols.UI.UserControls; using GSF.Security.Cryptography; using GSF.ServiceProcess; using GSF.TimeSeries.UI; using GSF.TimeSeries.UI.Commands; using GSF.TimeSeries.UI.DataModels; using GSF.Units; using Microsoft.Win32; using Random = GSF.Security.Cryptography.Random; namespace GSF.TimeSeries.Transport.UI.ViewModels { internal class SubscriberRequestViewModel : ViewModelBase, IDisposable { #region [ Members ] // Fields private string m_publisherAcronym; private string m_publisherName; private string m_hostname; private int m_publisherPort; private SecurityMode m_securityMode; private bool m_useSTTP; private bool m_useGEP; private bool m_useSourcePrefix; private bool m_receiveExternalMetadata; private bool m_receiveInternalMetadata; private bool m_useUdpDataChannel; private int m_udpDataChannelPort; private bool m_enableDataGapRecovery; private double m_recoveryStartDelay; private double m_dataMonitoringInterval; private double m_minimumRecoverySpan; private double m_maximumRecoverySpan; private int m_recoveryProcessingInterval; private string m_loggingPath; private bool m_disposed; private string m_subscriberAcronym; private string m_subscriberName; private int m_internalDataPublisherPort; private string m_sharedKey; private string m_identityCertificate; private string m_validIPAddresses; private string m_localCertificateFile; private string m_localCertificateServerPath; private string m_importCertificatePath; private byte[] m_localCertificateData; private string m_remoteCertificateFile; private byte[] m_remoteCertificateData; private bool m_isRemoteCertificateSelfSigned; private string m_validPolicyErrors; private string m_validChainFlags; private Visibility m_connectivityMessageVisibility; private bool m_advancedTlsSettingsPopupIsOpen; private AutoResetEvent m_responseComplete; private ICommand m_localBrowseCommand; private ICommand m_remoteBrowseCommand; private ICommand m_importCertificateCommand; private ICommand m_advancedTlsSettingsOpenCommand; private ICommand m_advancedTlsSettingsCloseCommand; private ICommand m_createCommand; private ICommand m_saveCommand; #endregion #region [ Constructors ] /// <summary> /// Creates a new instance of the <see cref="SubscriberRequestViewModel"/> class. /// </summary> public SubscriberRequestViewModel() { m_internalDataPublisherPort = 7165; m_securityMode = SecurityMode.TLS; m_useSTTP = true; m_useSourcePrefix = true; m_receiveInternalMetadata = true; m_udpDataChannelPort = 64170; m_publisherPort = DefaultPort; m_responseComplete = new AutoResetEvent(false); Load(); } /// <summary> /// Releases the unmanaged resources before the <see cref="SubscriberRequestViewModel"/> object is reclaimed by <see cref="GC"/>. /// </summary> ~SubscriberRequestViewModel() { Dispose(false); } #endregion #region [ Properties ] /// <summary> /// Gets or sets the string identifier used to identify the publisher. /// </summary> public string PublisherAcronym { get => m_publisherAcronym; set { bool updateRemoteCertificateFile = (string.IsNullOrEmpty(m_publisherAcronym) && string.IsNullOrEmpty(m_remoteCertificateFile)) || m_remoteCertificateFile.Equals($"{m_publisherAcronym}.cer", StringComparison.CurrentCultureIgnoreCase); m_publisherAcronym = value; OnPropertyChanged("PublisherAcronym"); if (updateRemoteCertificateFile) RemoteCertificateFile = string.IsNullOrEmpty(m_publisherAcronym) ? string.Empty : $"{m_publisherAcronym}.cer"; } } /// <summary> /// Gets or sets the name of the publisher. /// </summary> public string PublisherName { get => m_publisherName; set { m_publisherName = value; OnPropertyChanged("PublisherName"); } } /// <summary> /// Gets or sets the host name or IP address of the server hosting the data publisher. /// </summary> public string Hostname { get => m_hostname; set { m_hostname = value; OnPropertyChanged("Hostname"); } } /// <summary> /// Gets or sets the port that the data publisher is listening on. /// </summary> public int PublisherPort { get => m_publisherPort; set { m_publisherPort = value; OnPropertyChanged("PublisherPort"); } } /// <summary> /// Gets or sets the security mode used by the data publisher. /// </summary> public SecurityMode SecurityMode { get => m_securityMode; set { int oldDefaultPort = DefaultPort; m_securityMode = value; OnPropertyChanged("SecurityMode"); OnPropertyChanged("TransportLayerSecuritySelected"); OnPropertyChanged("GatewaySecuritySelected"); if (m_publisherPort == oldDefaultPort) PublisherPort = DefaultPort; } } /// <summary> /// Gets or sets flag that determines if STTP protocol should be used. /// </summary> public bool UseSTTP { get => m_useSTTP; set { m_useSTTP = value; OnPropertyChanged("UseSTTP"); } } /// <summary> /// Gets or sets flag that determines if GEP protocol should be used. /// </summary> public bool UseGEP { get => m_useGEP; set { m_useGEP = value; OnPropertyChanged("UseGEP"); } } /// <summary> /// Gets or sets flag that determines if source prefix should be used. /// </summary> public bool UseSourcePrefix { get => m_useSourcePrefix; set { m_useSourcePrefix = value; OnPropertyChanged("UseSourcePrefix"); } } /// <summary> /// Gets or sets the flag that determines whether the subscriber is /// requesting metadata for internal signals from the publisher. /// </summary> public bool ReceiveInternalMetadata { get => m_receiveInternalMetadata; set { m_receiveInternalMetadata = value; OnPropertyChanged("ReceiveInternalMetadata"); if (!m_receiveInternalMetadata && !m_receiveExternalMetadata) ReceiveExternalMetadata = true; } } /// <summary> /// Gets or sets the flag that determines whether the subscriber is /// requesting metadata for external signals from the publisher. /// </summary> public bool ReceiveExternalMetadata { get => m_receiveExternalMetadata; set { m_receiveExternalMetadata = value; OnPropertyChanged("ReceiveExternalMetadata"); if (!m_receiveInternalMetadata && !m_receiveExternalMetadata) ReceiveInternalMetadata = true; } } /// <summary> /// Gets or sets the flag that determines whether the subscriber /// should be configured with or without a UDP data channel. /// </summary> public bool UseUdpDataChannel { get => m_useUdpDataChannel; set { m_useUdpDataChannel = value; OnPropertyChanged("UseUdpDataChannel"); } } /// <summary> /// Gets or sets the port used for the UDP data channel. /// </summary> public int UdpDataChannelPort { get => m_udpDataChannelPort; set { m_udpDataChannelPort = value; OnPropertyChanged("UdpDataChannelPort"); } } /// <summary> /// Gets or sets flag that determines if data gap recovery will be enabled. /// </summary> public bool EnableDataGapRecovery { get => m_enableDataGapRecovery; set { m_enableDataGapRecovery = value; OnPropertyChanged("EnableDataGapRecovery"); } } /// <summary> /// Gets or sets the minimum time delay, in seconds, to wait before starting the data recovery for an <see cref="Outage"/>. /// </summary> /// <remarks> /// <para> /// For some archiving systems it may take a few seconds for data to make it to disk and therefore be readily /// available for a temporal subscription query. The <see cref="RecoveryStartDelay"/> should be adjusted based /// on the nature of the system used to archive data. If the archival system makes data immediately available /// because of internal caching or other means, this value can be zero. /// </para> /// <para> /// Use of this value depends on the local clock, as such the value should be increased by the uncertainty of /// accuracy of the local clock. For example, if it is know that the local clock floats +/-5 seconds from /// real-time, then increase the desired value of the <see cref="RecoveryStartDelay"/> by 5 seconds. /// </para> /// </remarks> public double RecoveryStartDelay { get => m_recoveryStartDelay; set { m_recoveryStartDelay = value; OnPropertyChanged("RecoveryStartDelay"); } } /// <summary> /// Gets or sets the interval, in seconds, over which the data monitor will check for new data. /// </summary> /// <remarks> /// Once a connection is established a timer is enabled to monitor for new incoming data. The data monitoring timer /// exists to make sure data is being received so that the process of recovery does not wait endlessly for data that /// may never come because of a possible error in the recovery process. The <see cref="DataMonitoringInterval"/> /// allows the consumer to adjust the interval over which the timer will check for new incoming data. /// <para> /// It will take some time, perhaps a couple of seconds, to start the temporal subscription and begin the process /// of recovering data for an <see cref="Outage"/>. Make sure the value for <see cref="DataMonitoringInterval"/> is /// sufficiently large enough to handle any initial delays in data transmission. /// </para> /// </remarks> public double DataMonitoringInterval { get => m_dataMonitoringInterval; set { m_dataMonitoringInterval = value; OnPropertyChanged("DataMonitoringInterval"); } } /// <summary> /// Gets to sets the minimum time span, in seconds, for which a data recovery will be attempted. /// Set to zero for no minimum. /// </summary> public double MinimumRecoverySpan { get => m_minimumRecoverySpan; set { m_minimumRecoverySpan = value; OnPropertyChanged("MinimumRecoverySpan"); } } /// <summary> /// Gets to sets the maximum time span, in days for UI - API is seconds, for which a data recovery will be attempted. /// Set to <see cref="Double.MaxValue"/> for no maximum. /// </summary> public double MaximumRecoverySpan { get => m_maximumRecoverySpan; set { m_maximumRecoverySpan = value; OnPropertyChanged("MaximumRecoverySpan"); } } /// <summary> /// Gets or sets the data recovery processing interval, in whole milliseconds, to use in the temporal data /// subscription when recovering data for an <see cref="Outage"/>.<br/> /// A value of <c>-1</c> indicates the default processing interval will be requested.<br/> /// A value of <c>0</c> indicates data will be processed as fast as possible. /// </summary> /// <remarks> /// With the exception of the values of -1 and 0, the <see cref="RecoveryProcessingInterval"/> value specifies /// the desired historical data playback processing interval in milliseconds. This is basically a delay, or timer /// interval, over which to process data. Setting this value to -1 means to use the default processing interval /// while setting the value to 0 means to process data as fast as possible, i.e., as fast as the historian can /// query the data. Depending on the available bandwidth, this parameter may need to be adjusted such that the /// data being recovered does not adversely interfere with the ongoing transmission of real-time data. /// </remarks> public int RecoveryProcessingInterval { get => m_recoveryProcessingInterval; set { m_recoveryProcessingInterval = value; OnPropertyChanged("RecoveryProcessingInterval"); } } /// <summary> /// Gets or sets logging path to be used to be runtime and outage logs of the subscriber which are required for /// automated data recovery. /// </summary> /// <remarks> /// Leave value blank for default path, i.e., installation folder. Can be a fully qualified path or a path that /// is relative to the installation folder, e.g., a value of "ConfigurationCache" might resolve to /// "C:\Program Files\MyTimeSeriespPp\ConfigurationCache\". /// </remarks> public string LoggingPath { get => m_loggingPath; set { m_loggingPath = value; OnPropertyChanged("LoggingPath"); } } /// <summary> /// Gets or sets the port used by the internal data publisher. /// </summary> public int InternalDataPublisherPort { get => m_internalDataPublisherPort; set { int oldDefaultPort = DefaultPort; m_internalDataPublisherPort = value; if (m_publisherPort == oldDefaultPort) PublisherPort = DefaultPort; } } /// <summary> /// Gets or sets the string identifier used to identify the subscriber. /// </summary> public string SubscriberAcronym { get => m_subscriberAcronym; set { m_subscriberAcronym = value; OnPropertyChanged("SubscriberAcronym"); } } /// <summary> /// Gets or sets the name of the subscriber. /// </summary> public string SubscriberName { get => m_subscriberName; set { m_subscriberName = value; OnPropertyChanged("SubscriberName"); } } /// <summary> /// Gets the flag that indicates whether the user has selected TLS as the security mode.