1684 lines · 75.1 KB · C#
RawDownload
//******************************************************************************************************//  AdapterBase.cs - Gbtc////  Copyright © 2012, 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://  ----------------------------------------------------------------------------------------------------//  09/02/2010 - J. Ritchie Carroll//       Generated original version of source code.//  12/20/2012 - Starlynn Danyelle Gilliam//       Modified Header.////****************************************************************************************************** using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Diagnostics.CodeAnalysis;using System.Globalization;using System.Linq;using System.Runtime.CompilerServices;using System.Text;using System.Text.RegularExpressions;using System.Threading;using GSF.Annotations;using GSF.Configuration;using GSF.Data;using GSF.Diagnostics;using GSF.Units; // ReSharper disable TryCastAlwaysSucceedsnamespace GSF.TimeSeries.Adapters{    /// <summary>    /// Represents the base class for any adapter.    /// </summary>    [SuppressMessage("SonarQube.Methods", "S1206", Justification = "Class life-cycle is controlled through library.")]    public abstract class AdapterBase : IAdapter    {        #region [ Members ]         // Constants         /// <summary>        /// Default measurement reporting interval.        /// </summary>        public 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 adapter is aware of a configuration change.        /// </summary>        public event EventHandler ConfigurationChanged;         /// <summary>        /// Event is raised when <see cref="AdapterBase"/> is disposed.        /// </summary>        public event EventHandler Disposed;         // Fields        private string m_name;        private uint m_id;        private string m_connectionString;        private Dictionary<string, string> m_settings;        private DataSet m_dataSource;        private int m_initializationTimeout;        private bool m_autoStart;        private MeasurementKey[] m_inputMeasurementKeys;        private IMeasurement[] m_outputMeasurements;        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()        {            Log = Logger.CreatePublisher(GetType(), MessageClass.Framework);            m_name = this.GetType().Name;            Log.InitialStackMessages = Log.InitialStackMessages.Union("AdapterName", m_name);            m_settings = new Dictionary<string, string>();            m_startTimeConstraint = DateTime.MinValue;            m_stopTimeConstraint = DateTime.MaxValue;            m_processingInterval = -1;            GenHashCode();             // Set incoming measurements to none by default            m_inputMeasurementKeys = new MeasurementKey[0];             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>        /// Log messages generated by an adapter.        /// </summary>        protected LogPublisher Log { get; }         /// <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;                Log.InitialStackMessages = Log.InitialStackMessages.Union("AdapterName", m_name);                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 &lt;TableName&gt; WHERE &lt;Expression&gt; [ORDER BY &lt;SortField&gt;]}<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>Multiplier 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;                 // Pre-parse settings upon connection string assignment                if (string.IsNullOrWhiteSpace(m_connectionString))                    m_settings = new Dictionary<string, string>();                else                    m_settings = m_connectionString.ParseKeyValuePairs();            }        }         /// <summary>        /// Gets connection info for adapter, if any.        /// </summary>        /// <remarks>        /// For example, this could return IP or host name of source connection.        /// </remarks>        public virtual string ConnectionInfo => null;         /// <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 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."),        CustomConfigurationEditor("GSF.TimeSeries.UI.WPF.dll", "GSF.TimeSeries.UI.Editors.MeasurementEditor")]        public virtual MeasurementKey[] InputMeasurementKeys        {            get            {                return m_inputMeasurementKeys;            }            set            {                if (m_inputMeasurementKeys == value)                    return;                 if ((object)m_inputMeasurementKeys != null && (object)value != null)                {                    if (new HashSet<MeasurementKey>(m_inputMeasurementKeys).SetEquals(value))                        return;                }                 m_inputMeasurementKeys = value;                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."),        CustomConfigurationEditor("GSF.TimeSeries.UI.WPF.dll", "GSF.TimeSeries.UI.Editors.MeasurementEditor")]        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 => 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;            }        }         /// <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 => m_startTime;         /// <summary>        /// Gets the UTC time this <see cref="AdapterBase"/> was stopped.        /// </summary>        public Ticks StopTime => 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 processing 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 => m_startTimeConstraint;         /// <summary>        /// Gets the stop time temporal processing constraint defined by call to <see cref="SetTemporalConstraint"/>.        /// </summary>        /// <remarks>        /// This value will be <see cref="DateTime.MaxValue"/> when stop time constraint is not set - meaning the adapter        /// is processing data in real-time.        /// </remarks>        public virtual DateTime StopTimeConstraint => m_stopTimeConstraint;         /// <summary>        /// Gets or sets the desired processing interval, in milliseconds, for the adapter.        /// </summary>        /// <remarks>        /// With the exception of the values of -1 and 0, this value specifies the desired processing interval for data, i.e.,        /// basically a delay, or timer interval, over which to process data. A value of -1 means to use the default processing        /// interval while a value of 0 means to process data as fast as possible.        /// </remarks>        public virtual int ProcessingInterval        {            get            {                return m_processingInterval;            }            set            {                m_processingInterval = value;                 if (m_processingInterval < -1)                    m_processingInterval = -1;            }        } 

Lines 1–500 of 1684.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t