/// <summary> /// Creates a new <see cref="MetadataRetriever"/> instance with the specified <paramref name="connectionString"/>. /// </summary> /// <param name="connectionString">GEP connection string for openHistorian.</param> private MetadataRetriever(string connectionString) { m_subscriber = new DataSubscriber { ConnectionString = connectionString, ReceiveInternalMetadata = true, ReceiveExternalMetadata = true }; m_subscriber.OperationalModes |= OperationalModes.UseCommonSerializationFormat | OperationalModes.CompressMetadata | OperationalModes.CompressSignalIndexCache; // Attach to needed subscriber events m_subscriber.ProcessException += m_subscriber_ProcessException; m_subscriber.ConnectionEstablished += m_subscriber_ConnectionEstablished; m_subscriber.MetaDataReceived += m_subscriber_MetaDataReceived; // Initialize the subscriber m_subscriber.Initialize(); // Create a wait handle to allow time to receive meta-data m_waitHandle = new ManualResetEventSlim(); // Start subscriber connection cycle m_subscriber.Start(); }
/// <summary> /// Initializes the <see cref="DataGapRecoverer"/>. /// </summary> public void Initialize() { if (m_disposed) throw new InvalidOperationException("Data gap recoverer has been disposed. Cannot initialize."); Dictionary<string, string> settings = m_connectionString.ToNonNullString().ParseKeyValuePairs(); string setting; double timeInterval; int processingInterval; if (settings.TryGetValue("sourceConnectionName", out setting) && !string.IsNullOrWhiteSpace(setting)) m_sourceConnectionName = setting; if (settings.TryGetValue("recoveryStartDelay", out setting) && double.TryParse(setting, out timeInterval)) RecoveryStartDelay = timeInterval; if (settings.TryGetValue("dataMonitoringInterval", out setting) && double.TryParse(setting, out timeInterval)) DataMonitoringInterval = timeInterval; if (settings.TryGetValue("minimumRecoverySpan", out setting) && double.TryParse(setting, out timeInterval)) MinimumRecoverySpan = timeInterval; if (settings.TryGetValue("maximumRecoverySpan", out setting) && double.TryParse(setting, out timeInterval)) MaximumRecoverySpan = timeInterval; if (settings.TryGetValue("filterExpression", out setting) && !string.IsNullOrWhiteSpace(setting)) FilterExpression = setting; if (settings.TryGetValue("recoveryProcessingInterval", out setting) && int.TryParse(setting, out processingInterval)) RecoveryProcessingInterval = processingInterval; if (settings.TryGetValue("useMillisecondResolution", out setting)) UseMillisecondResolution = setting.ParseBoolean(); // Get logging path, if any has been defined if (settings.TryGetValue("loggingPath", out setting)) { setting = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(setting)); if (Directory.Exists(setting)) m_loggingPath = setting; else OnStatusMessage("WARNING: Logging path \"{0}\" not found, defaulting to \"{1}\"...", setting, FilePath.GetAbsolutePath("")); } if (string.IsNullOrEmpty(m_sourceConnectionName)) throw new NullReferenceException("Source connection name must defined - it is used to create outage log file name."); // Setup a new temporal data subscriber that will be used to query historical data m_temporalSubscription = new DataSubscriber(); m_temporalSubscription.Name = m_sourceConnectionName + "!" + GetType().Name; m_temporalSubscription.DataSource = m_dataSource; m_temporalSubscription.ConnectionString = m_connectionString; m_temporalSubscription.StatusMessage += Common_StatusMessage; m_temporalSubscription.ProcessException += Common_ProcessException; m_temporalSubscription.ConnectionEstablished += TemporalSubscription_ConnectionEstablished; m_temporalSubscription.ConnectionTerminated += TemporalSubscription_ConnectionTerminated; m_temporalSubscription.ProcessingComplete += TemporalSubscription_ProcessingComplete; m_temporalSubscription.NewMeasurements += TemporalSubscription_NewMeasurements; m_temporalSubscription.Initialize(); // Setup data gap outage log to persist unprocessed outages between class life-cycles m_dataGapLog = new OutageLog(); m_dataGapLog.FileName = GetLoggingPath(m_sourceConnectionName + "_OutageLog.txt"); m_dataGapLog.ProcessException += Common_ProcessException; m_dataGapLog.Initialize(); // Setup data gap processor to process items one at a time, a 5-second minimum period is established between each gap processing m_dataGapLogProcessor = new OutageLogProcessor(m_dataGapLog, ProcessDataGap, CanProcessDataGap, OnProcessException, GSF.Common.Max(5000, (int)(m_recoveryStartDelay * SI.Milli))); }
/// <summary> /// Releases the unmanaged resources used by the <see cref="DataGapRecoverer"/> object and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (!m_disposed) { try { if (disposing) { if ((object)m_dataGapRecoveryCompleted != null) { // Signal any waiting threads m_abnormalTermination = true; m_dataGapRecoveryCompleted.Set(); m_dataGapRecoveryCompleted.Dispose(); m_dataGapRecoveryCompleted = null; } if ((object)m_dataStreamMonitor != null) { m_dataStreamMonitor.Elapsed -= DataStreamMonitor_Elapsed; m_dataStreamMonitor.Dispose(); m_dataStreamMonitor = null; } if ((object)m_dataGapLogProcessor != null) { m_dataGapLogProcessor.Dispose(); m_dataGapLogProcessor = null; } if ((object)m_dataGapLog != null) { m_dataGapLog.ProcessException -= Common_ProcessException; m_dataGapLog.Dispose(); m_dataGapLog = null; } if ((object)m_temporalSubscription != null) { m_temporalSubscription.StatusMessage -= Common_StatusMessage; m_temporalSubscription.ProcessException -= Common_ProcessException; m_temporalSubscription.ConnectionEstablished -= TemporalSubscription_ConnectionEstablished; m_temporalSubscription.ConnectionTerminated -= TemporalSubscription_ConnectionTerminated; m_temporalSubscription.NewMeasurements -= TemporalSubscription_NewMeasurements; m_temporalSubscription.ProcessingComplete -= TemporalSubscription_ProcessingComplete; m_temporalSubscription.Dispose(); m_temporalSubscription = null; } } } finally { m_disposed = true; // Prevent duplicate dispose. if ((object)Disposed != null) Disposed(this, EventArgs.Empty); } } }
/// <summary> /// Creates a new local concentrator. /// </summary> public LocalConcentrator(DataSubscriber parent) { m_parent = parent; }
/// <summary> /// Releases the unmanaged resources used by the <see cref="LocalConcentrator"/> object and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (!m_disposed) { try { if (disposing) m_parent = null; } finally { m_disposed = true; // Prevent duplicate dispose. base.Dispose(disposing); // Call base class Dispose(). } } }
/// <summary> /// Creates a new instance of the <see cref="AlarmMonitor"/> class. /// </summary> /// <param name="singleton">Indicates whether this instance should update the global reference to become the singleton.</param> public AlarmMonitor(bool singleton = false) { object refreshInterval = IsolatedStorageManager.ReadFromIsolatedStorage("AlarmStatusRefreshInterval") ?? DefaultRefreshInterval; if (!int.TryParse(refreshInterval.ToString(), out m_refreshInterval)) m_refreshInterval = DefaultRefreshInterval; m_currentAlarmsLock = new object(); m_currentAlarms = new HashSet<Alarm>(); m_refreshTimer = new Timer(m_refreshInterval * 1000); m_refreshTimer.Elapsed += RefreshTimer_Elapsed; m_alarmStatusQuery = new AlarmStatusQuery(); m_alarmStatusQuery.RaisedAlarmStates += m_alarmStatusQuery_RaisedAlarmStates; m_alarmStatusQuery.ProcessException += m_alarmStatusQuery_ProcessException; // Load all alarms defined in the database UpdateDefinedAlarms(); // Setup subscription to subscribe to all alarm measurements m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false) { FilterExpression = "FILTER ActiveMeasurements WHERE SignalType='ALRM'" }; m_dataSubscriber = new DataSubscriber(); m_dataSubscriber.ConnectionEstablished += m_dataSubscriber_ConnectionEstablished; m_dataSubscriber.ReceivedServerResponse += m_dataSubscriber_ReceivedServerResponse; m_dataSubscriber.NewMeasurements += m_dataSubscriber_NewMeasurements; m_dataSubscriber.ProcessException += m_dataSubscriber_ProcessException; m_dataSubscriber.ConnectionString = GetDataPublisherConnectionString(); m_dataSubscriber.OperationalModes |= OperationalModes.UseCommonSerializationFormat | OperationalModes.CompressSignalIndexCache | OperationalModes.CompressPayloadData; m_dataSubscriber.DataLossInterval = -1; m_dataSubscriber.Initialize(); if (singleton) Default = this; }
// ------ Data Subscriber Methods ------ // Creates and starts a data subscriber using the connection information supplied by the user in ConnectionUri. // Subscribers created through this method should also be released by the ReleaseDataSubscriber method. private DataSubscriber CreateDataSubscriber() { DataSubscriber subscriber = new DataSubscriber(); int index = ConnectionUri.IndexOf(URI_SEPARATOR); string server = (index >= 0) ? ConnectionUri.Substring(0, index) : ConnectionUri; subscriber.StatusMessage += DataSubscriber_StatusMessage; subscriber.ProcessException += DataSubscriber_ProcessException; subscriber.ConnectionEstablished += DataSubscriber_ConnectionEstablished; subscriber.ConnectionTerminated += DataSubscriber_ConnectionTerminated; subscriber.MetaDataReceived += DataSubscriber_MetaDataReceived; subscriber.DataStartTime += DataSubscriber_DataStartTime; subscriber.NewMeasurements += DataSubscriber_NewMeasurements; subscriber.ConnectionString = string.Format("server={0}; interface={1};{2} localCertificate={3}; remoteCertificate={4}; validPolicyErrors={5}; validChainFlags={6}", server, IPv6Enabled ? "::0" : "0.0.0.0", UseZeroMQChannel ? " useZeroMQChannel=true;" : "", FilePath.GetAbsolutePath("Local.cer"), FilePath.GetAbsolutePath("Remote.cer"), ~SslPolicyErrors.None, ~X509ChainStatusFlags.NoError); subscriber.SecurityMode = EnableEncryption ? SecurityMode.TLS : SecurityMode.None; if (!EnableCompression) subscriber.OperationalModes = DataSubscriber.DefaultOperationalModes & ~OperationalModes.CompressPayloadData; subscriber.ReceiveInternalMetadata = true; subscriber.ReceiveExternalMetadata = true; subscriber.Initialize(); subscriber.Start(); return subscriber; }
// Terminates an existing connection to a data publisher private void TerminateConnection() { ClearSubscription(); if ((object)m_subscriber != null) { UpdateStatus("Terminating current connection..."); // Stop the subscription if connected m_subscriber.Stop(); // Detach from subscriber events m_subscriber.MetaDataReceived -= subscriber_MetaDataReceived; m_subscriber.StatusMessage -= subscriber_StatusMessage; m_subscriber.ProcessException -= subscriber_ProcessException; m_subscriber.ConnectionEstablished -= subscriber_ConnectionEstablished; m_subscriber.ConnectionTerminated -= subscriber_ConnectionTerminated; m_subscriber.NewMeasurements -= subscriber_NewMeasurements; m_subscriber.ProcessingComplete -= subscriber_ProcessingComplete; // Dispose of the subscription m_subscriber.Dispose(); } m_subscriber = null; }
private void InitializeSubscription() { try { using (AdoDataConnection database = new AdoDataConnection(CommonFunctions.DefaultSettingsCategory)) { m_subscriber = new DataSubscriber(); m_subscriber.StatusMessage += m_subscriber_StatusMessage; m_subscriber.ProcessException += m_subscriber_ProcessException; m_subscriber.ConnectionEstablished += m_subscriber_ConnectionEstablished; m_subscriber.NewMeasurements += m_subscriber_NewMeasurements; m_subscriber.ConnectionTerminated += m_subscriber_ConnectionTerminated; m_subscriber.ProcessingComplete += m_subscriber_ProcessingComplete; m_subscriber.ConnectionString = database.DataPublisherConnectionString(); m_subscriber.Initialize(); m_subscriber.Start(); } } catch { // TODO: show error in popup window //Popup("Failed to initialize subscription." + Environment.NewLine + ex.Message, "Failed to Subscribe", MessageBoxImage.Error); } }
/// <summary> /// Unsubscribes data from the service. /// </summary> public void UnsubscribeUnsynchronizedData() { try { if (m_unsynchronizedSubscriber != null) { m_unsynchronizedSubscriber.Unsubscribe(); StopUnsynchronizedSubscription(); } } catch { m_unsynchronizedSubscriber = null; } }
// Connects or reconnects to a data publisher private void InitiateConnection() { // Shutdown any existing connection TerminateConnection(); // Attempt to extract server name from connection string string server = "unknown"; if (!string.IsNullOrEmpty(m_connectionString)) { Dictionary<string, string> settings = m_connectionString.ParseKeyValuePairs(); if (!settings.TryGetValue("server", out server)) server = "unknown"; } UpdateStatus("Attempting connection to \"{0}\"...", server); // Create a new data subscriber m_subscriber = new DataSubscriber(); // Attach to subscriber events m_subscriber.MetaDataReceived += subscriber_MetaDataReceived; m_subscriber.StatusMessage += subscriber_StatusMessage; m_subscriber.ProcessException += subscriber_ProcessException; m_subscriber.ConnectionEstablished += subscriber_ConnectionEstablished; m_subscriber.ConnectionTerminated += subscriber_ConnectionTerminated; m_subscriber.NewMeasurements += subscriber_NewMeasurements; m_subscriber.ProcessingComplete += subscriber_ProcessingComplete; // Initialize subscriber m_subscriber.ConnectionString = m_connectionString; m_subscriber.OperationalModes |= OperationalModes.UseCommonSerializationFormat | OperationalModes.CompressSignalIndexCache | OperationalModes.CompressMetadata; m_subscriber.Initialize(); // Start subscriber connection cycle m_subscriber.Start(); }
private void StopUnsynchronizedSubscription() { if (m_unsynchronizedSubscriber != null) { m_unsynchronizedSubscriber.StatusMessage -= m_unsynchronizedSubscriber_StatusMessage; m_unsynchronizedSubscriber.ProcessException -= m_unsynchronizedSubscriber_ProcessException; m_unsynchronizedSubscriber.ConnectionEstablished -= m_unsynchronizedSubscriber_ConnectionEstablished; m_unsynchronizedSubscriber.NewMeasurements -= m_unsynchronizedSubscriber_NewMeasurements; m_unsynchronizedSubscriber.ConnectionTerminated -= m_unsynchronizedSubscriber_ConnectionTerminated; m_unsynchronizedSubscriber.Stop(); m_unsynchronizedSubscriber.Dispose(); m_unsynchronizedSubscriber = null; } }
private void InitializeUnsynchronizedSubscription() { try { using (AdoDataConnection database = new AdoDataConnection(CommonFunctions.DefaultSettingsCategory)) { m_unsynchronizedSubscriber = new DataSubscriber(); m_unsynchronizedSubscriber.StatusMessage += m_unsynchronizedSubscriber_StatusMessage; m_unsynchronizedSubscriber.ProcessException += m_unsynchronizedSubscriber_ProcessException; m_unsynchronizedSubscriber.ConnectionEstablished += m_unsynchronizedSubscriber_ConnectionEstablished; m_unsynchronizedSubscriber.NewMeasurements += m_unsynchronizedSubscriber_NewMeasurements; m_unsynchronizedSubscriber.ConnectionTerminated += m_unsynchronizedSubscriber_ConnectionTerminated; m_unsynchronizedSubscriber.ConnectionString = database.DataPublisherConnectionString(); m_unsynchronizedSubscriber.Initialize(); m_unsynchronizedSubscriber.Start(); } } catch (Exception ex) { MessageBox.Show("Failed to initialize subscription." + Environment.NewLine + ex.Message, "Failed to Subscribe", MessageBoxButton.OK); } }
private void HomeUserControl_Unloaded(object sender, RoutedEventArgs e) { try { if (m_windowsServiceClient != null && m_windowsServiceClient.Helper != null) { m_windowsServiceClient.Helper.ReceivedServiceResponse -= Helper_ReceivedServiceResponse; } if (m_refreshTimer != null) m_refreshTimer.Stop(); UnsubscribeUnsynchronizedData(); } finally { m_refreshTimer = null; m_unsynchronizedSubscriber = null; } }
/// <summary> /// Connects to the stream server defined by the <see cref="ConnectionUri"/>. /// </summary> public void ConnectToStreamSource() { OnStateChanged(PlaybackState.Connecting); try { m_dataSubscriber = CreateDataSubscriber(); m_timeoutTimer = CreateTimeoutTimer(); m_timeoutTimer.Start(); } catch (Exception ex) { DisconnectFromStreamSource(); OnStateChanged(PlaybackState.Exception, "Connection attempt failed: " + ex.Message); } }
private void DisposeSubscription() { if (m_subscriber != null) { m_subscriber.StatusMessage -= m_subscriber_StatusMessage; m_subscriber.ProcessException -= m_subscriber_ProcessException; m_subscriber.ConnectionEstablished -= m_subscriber_ConnectionEstablished; m_subscriber.NewMeasurements -= m_subscriber_NewMeasurements; m_subscriber.ConnectionTerminated -= m_subscriber_ConnectionTerminated; m_subscriber.ProcessingComplete -= m_subscriber_ProcessingComplete; m_subscriber.Stop(); m_subscriber.Dispose(); m_subscriber = null; } }
/// <summary> /// Disconnects from the stream server and releases resources. /// </summary> public void DisconnectFromStreamSource() { DataSubscriber subscriber; Timer timeoutTimer; DataSet metadata; Stop(); subscriber = m_dataSubscriber; timeoutTimer = m_timeoutTimer; metadata = m_metadata; m_dataSubscriber = null; m_timeoutTimer = null; m_metadata = null; ReleaseDataSubscriber(subscriber); ReleaseTimeoutTimer(timeoutTimer); ReleaseMetadata(metadata); OnStateChanged(PlaybackState.Disconnected); OnGotSongList(null); }
private void Unsubscribe() { try { if (m_subscriber != null) { m_subscriber.Unsubscribe(); DisposeSubscription(); } } catch { m_subscriber = null; } StopRefreshTimer(); }
// Unsubscribes, detaches from events, and disposes of the subscriber. // Subscribers created through the CreateDataSubscriber should be released by this method. private void ReleaseDataSubscriber(DataSubscriber subscriber) { if (subscriber != null) { subscriber.Unsubscribe(); subscriber.StatusMessage -= DataSubscriber_StatusMessage; subscriber.ProcessException -= DataSubscriber_ProcessException; subscriber.ConnectionEstablished -= DataSubscriber_ConnectionEstablished; subscriber.ConnectionTerminated -= DataSubscriber_ConnectionTerminated; subscriber.MetaDataReceived -= DataSubscriber_MetaDataReceived; subscriber.DataStartTime -= DataSubscriber_DataStartTime; subscriber.NewMeasurements -= DataSubscriber_NewMeasurements; subscriber.Dispose(); } }
// ------ Data Subscriber Methods ------ // Creates and starts a data subscriber using the connection information supplied by the user in ConnectionUri. // Subscribers created through this method should also be released by the ReleaseDataSubscriber method. private DataSubscriber CreateDataSubscriber() { DataSubscriber subscriber = new DataSubscriber(); int index = ConnectionUri.IndexOf(URI_SEPARATOR, StringComparison.Ordinal); string server = (index >= 0) ? ConnectionUri.Substring(0, index) : ConnectionUri; subscriber.StatusMessage += DataSubscriber_StatusMessage; subscriber.ProcessException += DataSubscriber_ProcessException; subscriber.ConnectionEstablished += DataSubscriber_ConnectionEstablished; subscriber.ConnectionTerminated += DataSubscriber_ConnectionTerminated; subscriber.MetaDataReceived += DataSubscriber_MetaDataReceived; subscriber.DataStartTime += DataSubscriber_DataStartTime; subscriber.NewMeasurements += DataSubscriber_NewMeasurements; subscriber.ConnectionString = $"server={server}; interface={(IPv6Enabled ? "::0" : "0.0.0.0")};{(UseZeroMQChannel ? " useZeroMQChannel=true;" : "")} localCertificate={FilePath.GetAbsolutePath("Local.cer")}; remoteCertificate={FilePath.GetAbsolutePath("Remote.cer")}; validPolicyErrors={~SslPolicyErrors.None}; validChainFlags={~X509ChainStatusFlags.NoError}"; subscriber.SecurityMode = EnableEncryption ? SecurityMode.TLS : SecurityMode.None; subscriber.OperationalModes = DataSubscriber.DefaultOperationalModes; subscriber.CompressionModes = CompressionModes.GZip; if (EnableCompression) { subscriber.OperationalModes |= OperationalModes.CompressPayloadData; bool usingUDP = false; if (index >= 0) usingUDP = ConnectionUri.Substring(index + URI_SEPARATOR.Length).ParseKeyValuePairs('&').ContainsKey("udp"); if (!usingUDP) subscriber.CompressionModes |= CompressionModes.TSSC; // TSSC mode requires TCP connection } subscriber.ReceiveInternalMetadata = true; subscriber.ReceiveExternalMetadata = true; subscriber.Initialize(); subscriber.Start(); return subscriber; }
/// <summary> /// Releases the unmanaged resources used by the <see cref="MetadataRetriever"/> object and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> private void Dispose(bool disposing) { if (!m_disposed) { try { // This will be done regardless of whether the object is finalized or disposed. if (disposing) { if ((object)m_subscriber != null) { // Detach from subscriber events m_subscriber.ProcessException -= m_subscriber_ProcessException; m_subscriber.ConnectionEstablished -= m_subscriber_ConnectionEstablished; m_subscriber.MetaDataReceived -= m_subscriber_MetaDataReceived; m_subscriber.Dispose(); m_subscriber = null; } if ((object)m_waitHandle != null) { m_waitHandle.Set(); // Release any waiting threads m_waitHandle.Dispose(); m_waitHandle = null; } } } finally { m_disposed = true; // Prevent duplicate dispose. } } }
/// <summary> /// Releases the unmanaged resources used by the <see cref="AlarmMonitor"/> object and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (!m_disposed) { try { if (disposing) { if ((object)m_refreshTimer != null) { m_refreshTimer.Dispose(); m_refreshTimer = null; } if ((object)m_alarmStatusQuery != null) { m_alarmStatusQuery.RaisedAlarmStates -= m_alarmStatusQuery_RaisedAlarmStates; m_alarmStatusQuery.ProcessException -= m_alarmStatusQuery_ProcessException; m_alarmStatusQuery.Dispose(); m_alarmStatusQuery = null; } if ((object)m_dataSubscriber != null) { m_dataSubscriber.ConnectionEstablished -= m_dataSubscriber_ConnectionEstablished; m_dataSubscriber.ReceivedServerResponse -= m_dataSubscriber_ReceivedServerResponse; m_dataSubscriber.NewMeasurements -= m_dataSubscriber_NewMeasurements; m_dataSubscriber.ProcessException -= m_dataSubscriber_ProcessException; m_dataSubscriber.Dispose(); m_dataSubscriber = null; } } } finally { m_disposed = true; // Prevent duplicate dispose. } } }