//******************************************************************************************************// AdapterBase.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 Eclipse Public License -v 1.0 (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/eclipse-1.0.php//// 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:// ----------------------------------------------------------------------------------------------------// 09/02/2010 - J. Ritchie Carroll// Generated original version of source code.////****************************************************************************************************** using GSF.Units;using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.ComponentModel;using System.Data;using System.Globalization;using System.Linq;using System.Runtime.CompilerServices;using System.Text;using System.Text.RegularExpressions;using System.Threading; namespace GSF.TimeSeries.Adapters{ /// <summary> /// Represents the base class for any adapter. /// </summary> public abstract class AdapterBase : IAdapter { #region [ Members ] // Constants private const int DefaultMeasurementReportingInterval = 100000; /// <summary> /// Default initialization timeout. /// </summary> public const int DefaultInitializationTimeout = 15000; // Events /// <summary> /// Provides status messages to consumer. /// </summary> /// <remarks> /// <see cref="EventArgs{T}.Argument"/> is new status message. /// </remarks> public event EventHandler<EventArgs<string>> StatusMessage; /// <summary> /// Event is raised when there is an exception encountered while processing. /// </summary> /// <remarks> /// <see cref="EventArgs{T}.Argument"/> is the exception that was thrown. /// </remarks> public event EventHandler<EventArgs<Exception>> ProcessException; /// <summary> /// Event is raised when <see cref="InputMeasurementKeys"/> are updated. /// </summary> public event EventHandler InputMeasurementKeysUpdated; /// <summary> /// Event is raised when <see cref="OutputMeasurements"/> are updated. /// </summary> public event EventHandler OutputMeasurementsUpdated; /// <summary> /// Event is raised when <see cref="AdapterBase"/> is disposed. /// </summary> /// <remarks> /// If an adapter references another adapter by enumerating the <see cref="Parent"/> collection, this /// event should be monitored to release the reference. /// </remarks> public event EventHandler Disposed; // Fields private string m_name; private uint m_id; private string m_connectionString; private IAdapterCollection m_parent; private Dictionary<string, string> m_settings; private DataSet m_dataSource; private int m_initializationTimeout; private bool m_autoStart; private bool m_processMeasurementFilter; private ManualResetEvent m_initializeWaitHandle; private AutoResetEvent[] m_externalEventHandles; private int m_externalEventTimeout; private MeasurementKey[] m_inputMeasurementKeys; private IMeasurement[] m_outputMeasurements; private List<MeasurementKey> m_inputMeasurementKeysHash; private long m_processedMeasurements; private int m_measurementReportingInterval; private bool m_enabled; private long m_startTime; private long m_stopTime; private DateTime m_startTimeConstraint; private DateTime m_stopTimeConstraint; private int m_processingInterval; private int m_hashCode; private bool m_initialized; private bool m_disposed; #endregion #region [ Constructors ] /// <summary> /// Constructs a new instance of the <see cref="AdapterBase"/>. /// </summary> protected AdapterBase() { m_name = this.GetType().Name; m_settings = new Dictionary<string, string>(); m_startTimeConstraint = DateTime.MinValue; m_stopTimeConstraint = DateTime.MaxValue; m_processingInterval = -1; GenHashCode(); // Create wait handle to use for adapter initialization m_initializeWaitHandle = new ManualResetEvent(false); m_initializationTimeout = DefaultInitializationTimeout; } /// <summary> /// Releases the unmanaged resources before the <see cref="AdapterBase"/> object is reclaimed by <see cref="GC"/>. /// </summary> ~AdapterBase() { Dispose(false); } #endregion #region [ Properties ] /// <summary> /// Gets or sets the name of this <see cref="AdapterBase"/>. /// </summary> /// <remarks> /// Derived classes should provide a name for the adapter. /// </remarks> public virtual string Name { get { return m_name; } set { m_name = value; GenHashCode(); } } /// <summary> /// Gets or sets numeric ID associated with this <see cref="AdapterBase"/>. /// </summary> public virtual uint ID { get { return m_id; } set { m_id = value; GenHashCode(); } } /// <summary> /// Gets or sets key/value pair connection information specific to this <see cref="AdapterBase"/>. /// </summary> /// <remarks> /// <para> /// Example connection string using manually defined measurements:<br/> /// <c>inputMeasurementKeys={P1:1245;P1:1247;P2:1335};</c><br/> /// <c>outputMeasurements={P3:1345,60.0,1.0;P3:1346;P3:1347}</c><br/> /// When defined manually, elements in key:<br/> /// * inputMeasurementKeys are defined as "ArchiveSource:PointID"<br/> /// * outputMeasurements are defined as "ArchiveSource:PointID,Adder,Multiplier", the adder and multiplier are optional /// defaulting to 0.0 and 1.0 respectively. /// <br/> /// </para> /// <para> /// Example connection string using measurements defined in a <see cref="DataSource"/> table:<br/> /// <c>inputMeasurementKeys={FILTER ActiveMeasurements WHERE Company='GSF' AND SignalType='FREQ' ORDER BY ID};</c><br/> /// <c>outputMeasurements={FILTER ActiveMeasurements WHERE SignalType IN ('IPHA','VPHA') AND Phase='+'}</c><br/> /// <br/> /// Basic filtering syntax is as follows:<br/> /// <br/> /// {FILTER <TableName> WHERE <Expression> [ORDER BY <SortField>]}<br/> /// <br/> /// Source tables are expected to have at least the following fields:<br/> /// <list type="table"> /// <listheader> /// <term>Name</term> /// <term>Type</term> /// <description>Description.</description> /// </listheader> /// <item> /// <term>ID</term> /// <term>NVARCHAR</term> /// <description>Measurement key formatted as: ArchiveSource:PointID.</description> /// </item> /// <item> /// <term>PointTag</term> /// <term>NVARCHAR</term> /// <description>Point tag of measurement.</description> /// </item> /// <item> /// <term>Adder</term> /// <term>FLOAT</term> /// <description>Adder to apply to value, if any (default to 0.0).</description> /// </item> /// <item> /// <term>Multiplier</term> /// <term>FLOAT</term> /// <description>Multipler to apply to value, if any (default to 1.0).</description> /// </item> /// </list> /// </para> /// </remarks> public virtual string ConnectionString { get { return m_connectionString; } set { m_connectionString = value; // Preparse settings upon connection string assignment if (m_connectionString.IsNullOrWhiteSpace()) m_settings = new Dictionary<string, string>(); else m_settings = m_connectionString.ParseKeyValuePairs(); } } /// <summary> /// Gets a read-only reference to the collection that contains this <see cref="AdapterBase"/>. /// </summary> public ReadOnlyCollection<IAdapter> Parent { get { return new ReadOnlyCollection<IAdapter>(m_parent); } } /// <summary> /// Gets or sets <see cref="DataSet"/> based data source available to this <see cref="AdapterBase"/>. /// </summary> public virtual DataSet DataSource { get { return m_dataSource; } set { m_dataSource = value; } } /// <summary> /// Gets or sets maximum time system will wait during <see cref="Start"/> for initialization. /// </summary> /// <remarks> /// Set to <see cref="Timeout.Infinite"/> to wait indefinitely. /// </remarks> public virtual int InitializationTimeout { get { return m_initializationTimeout; } set { m_initializationTimeout = value; } } /// <summary> /// Gets or sets flag indicating if adapter should automatically start or otherwise connect on demand. /// </summary> public virtual bool AutoStart { get { return m_autoStart; } set { m_autoStart = value; } } /// <summary> /// Gets or sets flag that determines if measurements being queued for processing should be tested to see if they are in the <see cref="InputMeasurementKeys"/>. /// </summary> public virtual bool ProcessMeasurementFilter { get { return m_processMeasurementFilter; } set { m_processMeasurementFilter = value; } } /// <summary> /// Gets or sets primary keys of input measurements the <see cref="AdapterBase"/> expects, if any. /// </summary> /// <remarks> /// If your adapter needs to receive all measurements, you must explicitly set InputMeasurementKeys to null. /// </remarks> [ConnectionStringParameter, DefaultValue(null), Description("Defines primary keys of input measurements the adapter expects; can be one of a filter expression, measurement key, point tag or Guid.")] public virtual MeasurementKey[] InputMeasurementKeys { get { return m_inputMeasurementKeys; } set { m_inputMeasurementKeys = value; // Update input key lookup hash table if (value != null && value.Length > 0) { m_inputMeasurementKeysHash = new List<MeasurementKey>(value); m_inputMeasurementKeysHash.Sort(); } else m_inputMeasurementKeysHash = null; OnInputMeasurementKeysUpdated(); } } /// <summary> /// Gets or sets output measurements that the <see cref="AdapterBase"/> will produce, if any. /// </summary> [ConnectionStringParameter, DefaultValue(null), Description("Defines primary keys of output measurements the adapter expects; can be one of a filter expression, measurement key, point tag or Guid.")] public virtual IMeasurement[] OutputMeasurements { get { return m_outputMeasurements; } set { m_outputMeasurements = value; OnOutputMeasurementsUpdated(); } } /// <summary> /// Gets the total number of measurements handled thus far by the <see cref="AdapterBase"/>. /// </summary> public virtual long ProcessedMeasurements { get { return m_processedMeasurements; } } /// <summary> /// Gets or sets the measurement reporting interval. /// </summary> /// <remarks> /// This is used to determined how many measurements should be processed before reporting status. /// </remarks> public virtual int MeasurementReportingInterval { get { return m_measurementReportingInterval; } set { m_measurementReportingInterval = value; } } /// <summary> /// Gets or sets flag indicating if the adapter has been initialized successfully. /// </summary> public virtual bool Initialized { get { return m_initialized; } set { m_initialized = value; // When initialization is complete we send notification if ((object)m_initializeWaitHandle != null) { if (value) m_initializeWaitHandle.Set(); else m_initializeWaitHandle.Reset(); } } } /// <summary> /// Gets or sets enabled state of this <see cref="AdapterBase"/>. /// </summary> /// <remarks> /// Base class simply starts or stops <see cref="AdapterBase"/> based on flag value. Derived classes should /// extend this if needed to enable or disable operational state of the adapter based on flag value. /// </remarks> public bool Enabled { get { return m_enabled; } set { if (m_enabled && !value) Stop(); else if (!m_enabled && value) Start(); } } /// <summary> /// Gets the UTC time this <see cref="AdapterBase"/> was started. /// </summary> public Ticks StartTime { get { return m_startTime; } } /// <summary> /// Gets the UTC time this <see cref="AdapterBase"/> was stopped. /// </summary> public Ticks StopTime { get { return m_stopTime; } } /// <summary> /// Gets the flag indicating if this adapter supports temporal processing. /// </summary> public abstract bool SupportsTemporalProcessing { get; } /// <summary> /// Gets the start time temporal procesing constraint defined by call to <see cref="SetTemporalConstraint"/>. /// </summary> /// <remarks> /// This value will be <see cref="DateTime.MinValue"/> when start time constraint is not set - meaning the adapter /// is processing data in real-time. /// </remarks> public virtual DateTime StartTimeConstraint { get { return m_startTimeConstraint; }Lines 1–500 of 1766. Load more
//****************************************************************************************************** // AdapterBase.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 Eclipse Public License -v 1.0 (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/eclipse-1.0.php // // 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: // ---------------------------------------------------------------------------------------------------- // 09/02/2010 - J. Ritchie Carroll // Generated original version of source code. // //****************************************************************************************************** using GSF.Units; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Data; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; namespace GSF.TimeSeries.Adapters { /// <summary> /// Represents the base class for any adapter. /// </summary> public abstract class AdapterBase : IAdapter { #region [ Members ] // Constants private const int DefaultMeasurementReportingInterval = 100000; /// <summary> /// Default initialization timeout. /// </summary> public const int DefaultInitializationTimeout = 15000; // Events /// <summary> /// Provides status messages to consumer. /// </summary> /// <remarks> /// <see cref="EventArgs{T}.Argument"/> is new status message. /// </remarks> public event EventHandler<EventArgs<string>> StatusMessage; /// <summary> /// Event is raised when there is an exception encountered while processing. /// </summary> /// <remarks> /// <see cref="EventArgs{T}.Argument"/> is the exception that was thrown. /// </remarks> public event EventHandler<EventArgs<Exception>> ProcessException; /// <summary> /// Event is raised when <see cref="InputMeasurementKeys"/> are updated. /// </summary> public event EventHandler InputMeasurementKeysUpdated; /// <summary> /// Event is raised when <see cref="OutputMeasurements"/> are updated. /// </summary> public event EventHandler OutputMeasurementsUpdated; /// <summary> /// Event is raised when <see cref="AdapterBase"/> is disposed. /// </summary> /// <remarks> /// If an adapter references another adapter by enumerating the <see cref="Parent"/> collection, this /// event should be monitored to release the reference. /// </remarks> public event EventHandler Disposed; // Fields private string m_name; private uint m_id; private string m_connectionString; private IAdapterCollection m_parent; private Dictionary<string, string> m_settings; private DataSet m_dataSource; private int m_initializationTimeout; private bool m_autoStart; private bool m_processMeasurementFilter; private ManualResetEvent m_initializeWaitHandle; private AutoResetEvent[] m_externalEventHandles; private int m_externalEventTimeout; private MeasurementKey[] m_inputMeasurementKeys; private IMeasurement[] m_outputMeasurements; private List<MeasurementKey> m_inputMeasurementKeysHash; private long m_processedMeasurements; private int m_measurementReportingInterval; private bool m_enabled; private long m_startTime; private long m_stopTime; private DateTime m_startTimeConstraint; private DateTime m_stopTimeConstraint; private int m_processingInterval; private int m_hashCode; private bool m_initialized; private bool m_disposed; #endregion #region [ Constructors ] /// <summary> /// Constructs a new instance of the <see cref="AdapterBase"/>. /// </summary> protected AdapterBase() { m_name = this.GetType().Name; m_settings = new Dictionary<string, string>(); m_startTimeConstraint = DateTime.MinValue; m_stopTimeConstraint = DateTime.MaxValue; m_processingInterval = -1; GenHashCode(); // Create wait handle to use for adapter initialization m_initializeWaitHandle = new ManualResetEvent(false); m_initializationTimeout = DefaultInitializationTimeout; } /// <summary> /// Releases the unmanaged resources before the <see cref="AdapterBase"/> object is reclaimed by <see cref="GC"/>. /// </summary> ~AdapterBase() { Dispose(false); } #endregion #region [ Properties ] /// <summary> /// Gets or sets the name of this <see cref="AdapterBase"/>. /// </summary> /// <remarks> /// Derived classes should provide a name for the adapter. /// </remarks> public virtual string Name { get { return m_name; } set { m_name = value; GenHashCode(); } } /// <summary> /// Gets or sets numeric ID associated with this <see cref="AdapterBase"/>. /// </summary> public virtual uint ID { get { return m_id; } set { m_id = value; GenHashCode(); } } /// <summary> /// Gets or sets key/value pair connection information specific to this <see cref="AdapterBase"/>. /// </summary> /// <remarks> /// <para> /// Example connection string using manually defined measurements:<br/> /// <c>inputMeasurementKeys={P1:1245;P1:1247;P2:1335};</c><br/> /// <c>outputMeasurements={P3:1345,60.0,1.0;P3:1346;P3:1347}</c><br/> /// When defined manually, elements in key:<br/> /// * inputMeasurementKeys are defined as "ArchiveSource:PointID"<br/> /// * outputMeasurements are defined as "ArchiveSource:PointID,Adder,Multiplier", the adder and multiplier are optional /// defaulting to 0.0 and 1.0 respectively. /// <br/> /// </para> /// <para> /// Example connection string using measurements defined in a <see cref="DataSource"/> table:<br/> /// <c>inputMeasurementKeys={FILTER ActiveMeasurements WHERE Company='GSF' AND SignalType='FREQ' ORDER BY ID};</c><br/> /// <c>outputMeasurements={FILTER ActiveMeasurements WHERE SignalType IN ('IPHA','VPHA') AND Phase='+'}</c><br/> /// <br/> /// Basic filtering syntax is as follows:<br/> /// <br/> /// {FILTER <TableName> WHERE <Expression> [ORDER BY <SortField>]}<br/> /// <br/> /// Source tables are expected to have at least the following fields:<br/> /// <list type="table"> /// <listheader> /// <term>Name</term> /// <term>Type</term> /// <description>Description.</description> /// </listheader> /// <item> /// <term>ID</term> /// <term>NVARCHAR</term> /// <description>Measurement key formatted as: ArchiveSource:PointID.</description> /// </item> /// <item> /// <term>PointTag</term> /// <term>NVARCHAR</term> /// <description>Point tag of measurement.</description> /// </item> /// <item> /// <term>Adder</term> /// <term>FLOAT</term> /// <description>Adder to apply to value, if any (default to 0.0).</description> /// </item> /// <item> /// <term>Multiplier</term> /// <term>FLOAT</term> /// <description>Multipler to apply to value, if any (default to 1.0).</description> /// </item> /// </list> /// </para> /// </remarks> public virtual string ConnectionString { get { return m_connectionString; } set { m_connectionString = value; // Preparse settings upon connection string assignment if (m_connectionString.IsNullOrWhiteSpace()) m_settings = new Dictionary<string, string>(); else m_settings = m_connectionString.ParseKeyValuePairs(); } } /// <summary> /// Gets a read-only reference to the collection that contains this <see cref="AdapterBase"/>. /// </summary> public ReadOnlyCollection<IAdapter> Parent { get { return new ReadOnlyCollection<IAdapter>(m_parent); } } /// <summary> /// Gets or sets <see cref="DataSet"/> based data source available to this <see cref="AdapterBase"/>. /// </summary> public virtual DataSet DataSource { get { return m_dataSource; } set { m_dataSource = value; } } /// <summary> /// Gets or sets maximum time system will wait during <see cref="Start"/> for initialization. /// </summary> /// <remarks> /// Set to <see cref="Timeout.Infinite"/> to wait indefinitely. /// </remarks> public virtual int InitializationTimeout { get { return m_initializationTimeout; } set { m_initializationTimeout = value; } } /// <summary> /// Gets or sets flag indicating if adapter should automatically start or otherwise connect on demand. /// </summary> public virtual bool AutoStart { get { return m_autoStart; } set { m_autoStart = value; } } /// <summary> /// Gets or sets flag that determines if measurements being queued for processing should be tested to see if they are in the <see cref="InputMeasurementKeys"/>. /// </summary> public virtual bool ProcessMeasurementFilter { get { return m_processMeasurementFilter; } set { m_processMeasurementFilter = value; } } /// <summary> /// Gets or sets primary keys of input measurements the <see cref="AdapterBase"/> expects, if any. /// </summary> /// <remarks> /// If your adapter needs to receive all measurements, you must explicitly set InputMeasurementKeys to null. /// </remarks> [ConnectionStringParameter, DefaultValue(null), Description("Defines primary keys of input measurements the adapter expects; can be one of a filter expression, measurement key, point tag or Guid.")] public virtual MeasurementKey[] InputMeasurementKeys { get { return m_inputMeasurementKeys; } set { m_inputMeasurementKeys = value; // Update input key lookup hash table if (value != null && value.Length > 0) { m_inputMeasurementKeysHash = new List<MeasurementKey>(value); m_inputMeasurementKeysHash.Sort(); } else m_inputMeasurementKeysHash = null; OnInputMeasurementKeysUpdated(); } } /// <summary> /// Gets or sets output measurements that the <see cref="AdapterBase"/> will produce, if any. /// </summary> [ConnectionStringParameter, DefaultValue(null), Description("Defines primary keys of output measurements the adapter expects; can be one of a filter expression, measurement key, point tag or Guid.")] public virtual IMeasurement[] OutputMeasurements { get { return m_outputMeasurements; } set { m_outputMeasurements = value; OnOutputMeasurementsUpdated(); } } /// <summary> /// Gets the total number of measurements handled thus far by the <see cref="AdapterBase"/>. /// </summary> public virtual long ProcessedMeasurements { get { return m_processedMeasurements; } } /// <summary> /// Gets or sets the measurement reporting interval. /// </summary> /// <remarks> /// This is used to determined how many measurements should be processed before reporting status. /// </remarks> public virtual int MeasurementReportingInterval { get { return m_measurementReportingInterval; } set { m_measurementReportingInterval = value; } } /// <summary> /// Gets or sets flag indicating if the adapter has been initialized successfully. /// </summary> public virtual bool Initialized { get { return m_initialized; } set { m_initialized = value; // When initialization is complete we send notification if ((object)m_initializeWaitHandle != null) { if (value) m_initializeWaitHandle.Set(); else m_initializeWaitHandle.Reset(); } } } /// <summary> /// Gets or sets enabled state of this <see cref="AdapterBase"/>. /// </summary> /// <remarks> /// Base class simply starts or stops <see cref="AdapterBase"/> based on flag value. Derived classes should /// extend this if needed to enable or disable operational state of the adapter based on flag value. /// </remarks> public bool Enabled { get { return m_enabled; } set { if (m_enabled && !value) Stop(); else if (!m_enabled && value) Start(); } } /// <summary> /// Gets the UTC time this <see cref="AdapterBase"/> was started. /// </summary> public Ticks StartTime { get { return m_startTime; } } /// <summary> /// Gets the UTC time this <see cref="AdapterBase"/> was stopped. /// </summary> public Ticks StopTime { get { return m_stopTime; } } /// <summary> /// Gets the flag indicating if this adapter supports temporal processing. /// </summary> public abstract bool SupportsTemporalProcessing { get; } /// <summary> /// Gets the start time temporal procesing constraint defined by call to <see cref="SetTemporalConstraint"/>. /// </summary> /// <remarks> /// This value will be <see cref="DateTime.MinValue"/> when start time constraint is not set - meaning the adapter /// is processing data in real-time. /// </remarks> public virtual DateTime StartTimeConstraint { get { return m_startTimeConstraint; }