//******************************************************************************************************// IaonSession.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:// ----------------------------------------------------------------------------------------------------// 08/23/2011 - J. Ritchie Carroll// Generated original version of source code.////****************************************************************************************************** using GSF.Collections;using GSF.Configuration;using System;using System.Collections.Concurrent;using System.Data;using System.Linq;using System.Text;using System.Threading; namespace GSF.TimeSeries.Adapters{ /// <summary> /// Represents a new Input, Action, Output interface session. /// </summary> public class IaonSession : IProvideStatus, IDisposable { #region [ Members ] // Constants /// <summary> /// Default value for <see cref="UseMeasurementRouting"/> property. /// </summary> public const bool DefaultUseMeasurementRouting = true; // Events /// <summary> /// Provides status messages to consumer. /// </summary> /// <remarks> /// <see cref="EventArgs{T1,T2}.Argument1"/> is the new status message.<br/> /// <see cref="EventArgs{T1,T2}.Argument2"/> is the message <see cref="UpdateType"/>. /// </remarks> public event EventHandler<EventArgs<string, UpdateType>> 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="IAdapter.InputMeasurementKeys"/> are updated. /// </summary> public event EventHandler InputMeasurementKeysUpdated; /// <summary> /// Event is raised when <see cref="IAdapter.OutputMeasurements"/> are updated. /// </summary> public event EventHandler OutputMeasurementsUpdated; /// <summary> /// Event is raised every five seconds allowing consumer to track current number of unpublished seconds of data in the queue. /// </summary> /// <remarks> /// <see cref="EventArgs{T}.Argument"/> is the total number of unpublished seconds of data. /// </remarks> public event EventHandler<EventArgs<int>> UnpublishedSamples; /// <summary> /// Event is raised every five seconds allowing host to track total number of unprocessed measurements. /// </summary> /// <remarks> /// <para> /// Each <see cref="IOutputAdapter"/> implementation reports its current queue size of unprocessed /// measurements so that if queue size reaches an unhealthy threshold, host can take evasive action. /// </para> /// <para> /// <see cref="EventArgs{T}.Argument"/> is total number of unprocessed measurements. /// </para> /// </remarks> public event EventHandler<EventArgs<int>> UnprocessedMeasurements; /// <summary> /// Indicates to the host that processing for one of the input adapters has completed. /// </summary> /// <remarks> /// This event is expected to only be raised when an input adapter has been designed to process /// a finite amount of data, e.g., reading a historical range of data during temporal procesing. /// </remarks> public event EventHandler ProcessingComplete; /// <summary> /// Event is raised when this <see cref="AdapterCollectionBase{T}"/> is disposed or an <see cref="IAdapter"/> in the collection is disposed. /// </summary> public event EventHandler Disposed; // Fields private Guid m_nodeID; private RoutingTables m_routingTables; private AllAdaptersCollection m_allAdapters; private InputAdapterCollection m_inputAdapters; private ActionAdapterCollection m_actionAdapters; private OutputAdapterCollection m_outputAdapters; private ConcurrentDictionary<string, AutoResetEvent> m_waitHandles; private ConcurrentDictionary<object, string> m_derivedNameCache; private MeasurementKey[] m_inputMeasurementKeysRestriction; private bool m_useMeasurementRouting; private int m_measurementWarningThreshold; private int m_measurementDumpingThreshold; private int m_defaultSampleSizeWarningThreshold; private string m_name; private bool m_disposed; #endregion #region [ Constructors ] /// <summary> /// Creates a new <see cref="IaonSession"/>. /// </summary> public IaonSession() { //ConfigurationFile configFile = ConfigurationFile.Current; // Initialize system settings //CategorizedSettingsElementCollection systemSettings = configFile.Settings["systemSettings"]; //systemSettings.Add("NodeID", Guid.NewGuid().ToString(), "Unique Node ID"); //systemSettings.Add("UseMeasurementRouting", DefaultUseMeasurementRouting, "Set to true to use optimized adapter measurement routing."); //m_nodeID = systemSettings["NodeID"].ValueAs<Guid>(); //m_useMeasurementRouting = systemSettings["UseMeasurementRouting"].ValueAsBoolean(IaonSession.DefaultUseMeasurementRouting); m_nodeID = Guid.NewGuid(); m_useMeasurementRouting = true; //// Initialize threshold settings //CategorizedSettingsElementCollection thresholdSettings = configFile.Settings["thresholdSettings"]; //thresholdSettings.Add("MeasurementWarningThreshold", "100000", "Number of unarchived measurements allowed in any output adapter queue before displaying a warning message"); //thresholdSettings.Add("MeasurementDumpingThreshold", "500000", "Number of unarchived measurements allowed in any output adapter queue before taking evasive action and dumping data"); //thresholdSettings.Add("DefaultSampleSizeWarningThreshold", "10", "Default number of unpublished samples (in seconds) allowed in any action adapter queue before displaying a warning message"); //m_measurementWarningThreshold = thresholdSettings["MeasurementWarningThreshold"].ValueAsInt32(); //m_measurementDumpingThreshold = thresholdSettings["MeasurementDumpingThreshold"].ValueAsInt32(); //m_defaultSampleSizeWarningThreshold = thresholdSettings["DefaultSampleSizeWarningThreshold"].ValueAsInt32(); m_measurementWarningThreshold = 100000; m_measurementDumpingThreshold = 500000; m_defaultSampleSizeWarningThreshold = 10; // Create a common wait handle dictionary for all adapters in this session m_waitHandles = new ConcurrentDictionary<string, AutoResetEvent>(StringComparer.InvariantCultureIgnoreCase); // Create a cache for derived adapter names m_derivedNameCache = new ConcurrentDictionary<object, string>(); // Create a new set of routing tables m_routingTables = new RoutingTables(); m_routingTables.ProcessException += m_routingTables_ProcessException; // Create a collection to manage all input, action and output adapter collections as a unit m_allAdapters = new AllAdaptersCollection(m_waitHandles); // Attach to common adapter events m_allAdapters.StatusMessage += StatusMessageHandler; m_allAdapters.ProcessException += ProcessExceptionHandler; m_allAdapters.InputMeasurementKeysUpdated += InputMeasurementKeysUpdatedHandler; m_allAdapters.OutputMeasurementsUpdated += OutputMeasurementsUpdatedHandler; m_allAdapters.Disposed += DisposedHandler; // Create input adapters collection m_inputAdapters = new InputAdapterCollection(m_waitHandles); if (m_useMeasurementRouting) m_inputAdapters.NewMeasurements += m_routingTables.RoutedMeasurementsHandler; else m_inputAdapters.NewMeasurements += m_routingTables.BroadcastMeasurementsHandler; m_inputAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_inputAdapters.ProcessingComplete += ProcessingCompleteHandler; // Create action adapters collection m_actionAdapters = new ActionAdapterCollection(m_waitHandles); if (m_useMeasurementRouting) m_actionAdapters.NewMeasurements += m_routingTables.RoutedMeasurementsHandler; else m_actionAdapters.NewMeasurements += m_routingTables.BroadcastMeasurementsHandler; m_actionAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_actionAdapters.UnpublishedSamples += UnpublishedSamplesHandler; // Create output adapters collection m_outputAdapters = new OutputAdapterCollection(m_waitHandles); m_outputAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_outputAdapters.UnprocessedMeasurements += UnprocessedMeasurementsHandler; // Associate adapter collections with routing tables m_routingTables.InputAdapters = m_inputAdapters; m_routingTables.ActionAdapters = m_actionAdapters; m_routingTables.OutputAdapters = m_outputAdapters; // We group these adapters such that they are initialized in the following order: output, input, action. This // is done so that the archival capabilities will be setup before we start receiving input and the input data // will be flowing before any actions get established for the input - at least generally. m_allAdapters.Add(m_outputAdapters); m_allAdapters.Add(m_inputAdapters); m_allAdapters.Add(m_actionAdapters); } /// <summary> /// Releases the unmanaged resources before the <see cref="IaonSession"/> object is reclaimed by <see cref="GC"/>. /// </summary> ~IaonSession() { Dispose(false); } #endregion #region [ Properties ] /// <summary> /// Gets the all adapters collection for this <see cref="IaonSession"/>. /// </summary> public virtual AllAdaptersCollection AllAdapters { get { return m_allAdapters; } } /// <summary> /// Gets the input adapter collection for this <see cref="IaonSession"/>. /// </summary> public virtual InputAdapterCollection InputAdapters { get { return m_inputAdapters; } } /// <summary> /// Gets the action adapter collection for this <see cref="IaonSession"/>. /// </summary> public virtual ActionAdapterCollection ActionAdapters { get { return m_actionAdapters; } } /// <summary> /// Gets the output adapter collection for this <see cref="IaonSession"/>. /// </summary> public virtual OutputAdapterCollection OutputAdapters { get { return m_outputAdapters; } } /// <summary> /// Gets or sets flag that determines if measurement routing should be used. /// </summary> public virtual bool UseMeasurementRouting { get { return m_useMeasurementRouting; } set { if (m_useMeasurementRouting != value) { if (m_useMeasurementRouting) m_inputAdapters.NewMeasurements -= m_routingTables.RoutedMeasurementsHandler; else m_inputAdapters.NewMeasurements -= m_routingTables.BroadcastMeasurementsHandler; if (m_useMeasurementRouting) m_actionAdapters.NewMeasurements -= m_routingTables.RoutedMeasurementsHandler; else m_actionAdapters.NewMeasurements -= m_routingTables.BroadcastMeasurementsHandler; m_useMeasurementRouting = value; if (m_useMeasurementRouting) m_inputAdapters.NewMeasurements += m_routingTables.RoutedMeasurementsHandler; else m_inputAdapters.NewMeasurements += m_routingTables.BroadcastMeasurementsHandler; if (m_useMeasurementRouting) m_actionAdapters.NewMeasurements += m_routingTables.RoutedMeasurementsHandler; else m_actionAdapters.NewMeasurements += m_routingTables.BroadcastMeasurementsHandler; m_inputAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_actionAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_outputAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; } } } /// <summary> /// Gets the routing tables for this <see cref="IaonSession"/>. /// </summary> public virtual RoutingTables RoutingTables { get { return m_routingTables; } } /// <summary> /// Gets or sets a routing table restriction for a collection of input measurement keys. /// </summary> public virtual MeasurementKey[] InputMeasurementKeysRestriction { get { return m_inputMeasurementKeysRestriction; } set { m_inputMeasurementKeysRestriction = value; } } /// <summary> /// Gets or sets the configuration <see cref="DataSet"/> for this <see cref="IaonSession"/>. /// </summary> public virtual DataSet DataSource { get { return m_allAdapters.DataSource; } set { m_allAdapters.DataSource = value; if (value != null) DetermineTemporalSupport(); } } /// <summary> /// Gets or sets the <see cref="Guid"/> node ID for this <see cref="IaonSession"/>. /// </summary> public virtual Guid NodeID { get { return m_nodeID; } set { m_nodeID = value; } } /// <summary> /// Gets name assigned to this <see cref="IaonSession"/>, if any. /// </summary> public virtual string Name { get { return m_name.ToNonNullString(); } set { m_name = value; } } /// <summary> /// Gets the combined status of the adapters in this <see cref="IaonSession"/>. /// </summary> public virtual string Status { get { StringBuilder status = new StringBuilder(); status.AppendLine(); status.AppendLine(">> Input Adapters:"); status.AppendLine(); if (m_inputAdapters != null) status.AppendLine(m_inputAdapters.Status); status.AppendLine(); status.AppendLine(">> Action Adapters:"); status.AppendLine(); if (m_actionAdapters != null) status.AppendLine(m_actionAdapters.Status); status.AppendLine(); status.AppendLine(">> Output Adapters:"); status.AppendLine(); if (m_outputAdapters != null) status.AppendLine(m_outputAdapters.Status); return status.ToString(); } } #endregion #region [ Methods ] /// <summary> /// Releases all the resources used by the <see cref="IaonSession"/> object. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Releases the unmanaged resources used by the <see cref="IaonSession"/> 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) { DataSet dataSource = this.DataSource; // Dispose input adapters collection if (m_inputAdapters != null) { m_inputAdapters.Stop(); if (m_useMeasurementRouting) m_inputAdapters.NewMeasurements -= m_routingTables.RoutedMeasurementsHandler; else m_inputAdapters.NewMeasurements -= m_routingTables.BroadcastMeasurementsHandler; m_inputAdapters.ProcessingComplete -= ProcessingCompleteHandler; m_inputAdapters.Dispose(); } m_inputAdapters = null; // Dispose action adapters collection if (m_actionAdapters != null) { m_actionAdapters.Stop(); if (m_useMeasurementRouting) m_actionAdapters.NewMeasurements -= m_routingTables.RoutedMeasurementsHandler; else m_actionAdapters.NewMeasurements -= m_routingTables.BroadcastMeasurementsHandler; m_actionAdapters.UnpublishedSamples -= UnpublishedSamplesHandler; m_actionAdapters.Dispose(); } m_actionAdapters = null; // Dispose output adapters collection if (m_outputAdapters != null) { m_outputAdapters.Stop(); m_outputAdapters.UnprocessedMeasurements -= UnprocessedMeasurementsHandler; m_outputAdapters.Dispose(); } m_outputAdapters = null; // Dispose all adapters collection if (m_allAdapters != null)Lines 1–500 of 1029. Load more
//****************************************************************************************************** // IaonSession.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: // ---------------------------------------------------------------------------------------------------- // 08/23/2011 - J. Ritchie Carroll // Generated original version of source code. // //****************************************************************************************************** using GSF.Collections; using GSF.Configuration; using System; using System.Collections.Concurrent; using System.Data; using System.Linq; using System.Text; using System.Threading; namespace GSF.TimeSeries.Adapters { /// <summary> /// Represents a new Input, Action, Output interface session. /// </summary> public class IaonSession : IProvideStatus, IDisposable { #region [ Members ] // Constants /// <summary> /// Default value for <see cref="UseMeasurementRouting"/> property. /// </summary> public const bool DefaultUseMeasurementRouting = true; // Events /// <summary> /// Provides status messages to consumer. /// </summary> /// <remarks> /// <see cref="EventArgs{T1,T2}.Argument1"/> is the new status message.<br/> /// <see cref="EventArgs{T1,T2}.Argument2"/> is the message <see cref="UpdateType"/>. /// </remarks> public event EventHandler<EventArgs<string, UpdateType>> 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="IAdapter.InputMeasurementKeys"/> are updated. /// </summary> public event EventHandler InputMeasurementKeysUpdated; /// <summary> /// Event is raised when <see cref="IAdapter.OutputMeasurements"/> are updated. /// </summary> public event EventHandler OutputMeasurementsUpdated; /// <summary> /// Event is raised every five seconds allowing consumer to track current number of unpublished seconds of data in the queue. /// </summary> /// <remarks> /// <see cref="EventArgs{T}.Argument"/> is the total number of unpublished seconds of data. /// </remarks> public event EventHandler<EventArgs<int>> UnpublishedSamples; /// <summary> /// Event is raised every five seconds allowing host to track total number of unprocessed measurements. /// </summary> /// <remarks> /// <para> /// Each <see cref="IOutputAdapter"/> implementation reports its current queue size of unprocessed /// measurements so that if queue size reaches an unhealthy threshold, host can take evasive action. /// </para> /// <para> /// <see cref="EventArgs{T}.Argument"/> is total number of unprocessed measurements. /// </para> /// </remarks> public event EventHandler<EventArgs<int>> UnprocessedMeasurements; /// <summary> /// Indicates to the host that processing for one of the input adapters has completed. /// </summary> /// <remarks> /// This event is expected to only be raised when an input adapter has been designed to process /// a finite amount of data, e.g., reading a historical range of data during temporal procesing. /// </remarks> public event EventHandler ProcessingComplete; /// <summary> /// Event is raised when this <see cref="AdapterCollectionBase{T}"/> is disposed or an <see cref="IAdapter"/> in the collection is disposed. /// </summary> public event EventHandler Disposed; // Fields private Guid m_nodeID; private RoutingTables m_routingTables; private AllAdaptersCollection m_allAdapters; private InputAdapterCollection m_inputAdapters; private ActionAdapterCollection m_actionAdapters; private OutputAdapterCollection m_outputAdapters; private ConcurrentDictionary<string, AutoResetEvent> m_waitHandles; private ConcurrentDictionary<object, string> m_derivedNameCache; private MeasurementKey[] m_inputMeasurementKeysRestriction; private bool m_useMeasurementRouting; private int m_measurementWarningThreshold; private int m_measurementDumpingThreshold; private int m_defaultSampleSizeWarningThreshold; private string m_name; private bool m_disposed; #endregion #region [ Constructors ] /// <summary> /// Creates a new <see cref="IaonSession"/>. /// </summary> public IaonSession() { //ConfigurationFile configFile = ConfigurationFile.Current; // Initialize system settings //CategorizedSettingsElementCollection systemSettings = configFile.Settings["systemSettings"]; //systemSettings.Add("NodeID", Guid.NewGuid().ToString(), "Unique Node ID"); //systemSettings.Add("UseMeasurementRouting", DefaultUseMeasurementRouting, "Set to true to use optimized adapter measurement routing."); //m_nodeID = systemSettings["NodeID"].ValueAs<Guid>(); //m_useMeasurementRouting = systemSettings["UseMeasurementRouting"].ValueAsBoolean(IaonSession.DefaultUseMeasurementRouting); m_nodeID = Guid.NewGuid(); m_useMeasurementRouting = true; //// Initialize threshold settings //CategorizedSettingsElementCollection thresholdSettings = configFile.Settings["thresholdSettings"]; //thresholdSettings.Add("MeasurementWarningThreshold", "100000", "Number of unarchived measurements allowed in any output adapter queue before displaying a warning message"); //thresholdSettings.Add("MeasurementDumpingThreshold", "500000", "Number of unarchived measurements allowed in any output adapter queue before taking evasive action and dumping data"); //thresholdSettings.Add("DefaultSampleSizeWarningThreshold", "10", "Default number of unpublished samples (in seconds) allowed in any action adapter queue before displaying a warning message"); //m_measurementWarningThreshold = thresholdSettings["MeasurementWarningThreshold"].ValueAsInt32(); //m_measurementDumpingThreshold = thresholdSettings["MeasurementDumpingThreshold"].ValueAsInt32(); //m_defaultSampleSizeWarningThreshold = thresholdSettings["DefaultSampleSizeWarningThreshold"].ValueAsInt32(); m_measurementWarningThreshold = 100000; m_measurementDumpingThreshold = 500000; m_defaultSampleSizeWarningThreshold = 10; // Create a common wait handle dictionary for all adapters in this session m_waitHandles = new ConcurrentDictionary<string, AutoResetEvent>(StringComparer.InvariantCultureIgnoreCase); // Create a cache for derived adapter names m_derivedNameCache = new ConcurrentDictionary<object, string>(); // Create a new set of routing tables m_routingTables = new RoutingTables(); m_routingTables.ProcessException += m_routingTables_ProcessException; // Create a collection to manage all input, action and output adapter collections as a unit m_allAdapters = new AllAdaptersCollection(m_waitHandles); // Attach to common adapter events m_allAdapters.StatusMessage += StatusMessageHandler; m_allAdapters.ProcessException += ProcessExceptionHandler; m_allAdapters.InputMeasurementKeysUpdated += InputMeasurementKeysUpdatedHandler; m_allAdapters.OutputMeasurementsUpdated += OutputMeasurementsUpdatedHandler; m_allAdapters.Disposed += DisposedHandler; // Create input adapters collection m_inputAdapters = new InputAdapterCollection(m_waitHandles); if (m_useMeasurementRouting) m_inputAdapters.NewMeasurements += m_routingTables.RoutedMeasurementsHandler; else m_inputAdapters.NewMeasurements += m_routingTables.BroadcastMeasurementsHandler; m_inputAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_inputAdapters.ProcessingComplete += ProcessingCompleteHandler; // Create action adapters collection m_actionAdapters = new ActionAdapterCollection(m_waitHandles); if (m_useMeasurementRouting) m_actionAdapters.NewMeasurements += m_routingTables.RoutedMeasurementsHandler; else m_actionAdapters.NewMeasurements += m_routingTables.BroadcastMeasurementsHandler; m_actionAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_actionAdapters.UnpublishedSamples += UnpublishedSamplesHandler; // Create output adapters collection m_outputAdapters = new OutputAdapterCollection(m_waitHandles); m_outputAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_outputAdapters.UnprocessedMeasurements += UnprocessedMeasurementsHandler; // Associate adapter collections with routing tables m_routingTables.InputAdapters = m_inputAdapters; m_routingTables.ActionAdapters = m_actionAdapters; m_routingTables.OutputAdapters = m_outputAdapters; // We group these adapters such that they are initialized in the following order: output, input, action. This // is done so that the archival capabilities will be setup before we start receiving input and the input data // will be flowing before any actions get established for the input - at least generally. m_allAdapters.Add(m_outputAdapters); m_allAdapters.Add(m_inputAdapters); m_allAdapters.Add(m_actionAdapters); } /// <summary> /// Releases the unmanaged resources before the <see cref="IaonSession"/> object is reclaimed by <see cref="GC"/>. /// </summary> ~IaonSession() { Dispose(false); } #endregion #region [ Properties ] /// <summary> /// Gets the all adapters collection for this <see cref="IaonSession"/>. /// </summary> public virtual AllAdaptersCollection AllAdapters { get { return m_allAdapters; } } /// <summary> /// Gets the input adapter collection for this <see cref="IaonSession"/>. /// </summary> public virtual InputAdapterCollection InputAdapters { get { return m_inputAdapters; } } /// <summary> /// Gets the action adapter collection for this <see cref="IaonSession"/>. /// </summary> public virtual ActionAdapterCollection ActionAdapters { get { return m_actionAdapters; } } /// <summary> /// Gets the output adapter collection for this <see cref="IaonSession"/>. /// </summary> public virtual OutputAdapterCollection OutputAdapters { get { return m_outputAdapters; } } /// <summary> /// Gets or sets flag that determines if measurement routing should be used. /// </summary> public virtual bool UseMeasurementRouting { get { return m_useMeasurementRouting; } set { if (m_useMeasurementRouting != value) { if (m_useMeasurementRouting) m_inputAdapters.NewMeasurements -= m_routingTables.RoutedMeasurementsHandler; else m_inputAdapters.NewMeasurements -= m_routingTables.BroadcastMeasurementsHandler; if (m_useMeasurementRouting) m_actionAdapters.NewMeasurements -= m_routingTables.RoutedMeasurementsHandler; else m_actionAdapters.NewMeasurements -= m_routingTables.BroadcastMeasurementsHandler; m_useMeasurementRouting = value; if (m_useMeasurementRouting) m_inputAdapters.NewMeasurements += m_routingTables.RoutedMeasurementsHandler; else m_inputAdapters.NewMeasurements += m_routingTables.BroadcastMeasurementsHandler; if (m_useMeasurementRouting) m_actionAdapters.NewMeasurements += m_routingTables.RoutedMeasurementsHandler; else m_actionAdapters.NewMeasurements += m_routingTables.BroadcastMeasurementsHandler; m_inputAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_actionAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; m_outputAdapters.ProcessMeasurementFilter = !m_useMeasurementRouting; } } } /// <summary> /// Gets the routing tables for this <see cref="IaonSession"/>. /// </summary> public virtual RoutingTables RoutingTables { get { return m_routingTables; } } /// <summary> /// Gets or sets a routing table restriction for a collection of input measurement keys. /// </summary> public virtual MeasurementKey[] InputMeasurementKeysRestriction { get { return m_inputMeasurementKeysRestriction; } set { m_inputMeasurementKeysRestriction = value; } } /// <summary> /// Gets or sets the configuration <see cref="DataSet"/> for this <see cref="IaonSession"/>. /// </summary> public virtual DataSet DataSource { get { return m_allAdapters.DataSource; } set { m_allAdapters.DataSource = value; if (value != null) DetermineTemporalSupport(); } } /// <summary> /// Gets or sets the <see cref="Guid"/> node ID for this <see cref="IaonSession"/>. /// </summary> public virtual Guid NodeID { get { return m_nodeID; } set { m_nodeID = value; } } /// <summary> /// Gets name assigned to this <see cref="IaonSession"/>, if any. /// </summary> public virtual string Name { get { return m_name.ToNonNullString(); } set { m_name = value; } } /// <summary> /// Gets the combined status of the adapters in this <see cref="IaonSession"/>. /// </summary> public virtual string Status { get { StringBuilder status = new StringBuilder(); status.AppendLine(); status.AppendLine(">> Input Adapters:"); status.AppendLine(); if (m_inputAdapters != null) status.AppendLine(m_inputAdapters.Status); status.AppendLine(); status.AppendLine(">> Action Adapters:"); status.AppendLine(); if (m_actionAdapters != null) status.AppendLine(m_actionAdapters.Status); status.AppendLine(); status.AppendLine(">> Output Adapters:"); status.AppendLine(); if (m_outputAdapters != null) status.AppendLine(m_outputAdapters.Status); return status.ToString(); } } #endregion #region [ Methods ] /// <summary> /// Releases all the resources used by the <see cref="IaonSession"/> object. /// </summary> public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// <summary> /// Releases the unmanaged resources used by the <see cref="IaonSession"/> 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) { DataSet dataSource = this.DataSource; // Dispose input adapters collection if (m_inputAdapters != null) { m_inputAdapters.Stop(); if (m_useMeasurementRouting) m_inputAdapters.NewMeasurements -= m_routingTables.RoutedMeasurementsHandler; else m_inputAdapters.NewMeasurements -= m_routingTables.BroadcastMeasurementsHandler; m_inputAdapters.ProcessingComplete -= ProcessingCompleteHandler; m_inputAdapters.Dispose(); } m_inputAdapters = null; // Dispose action adapters collection if (m_actionAdapters != null) { m_actionAdapters.Stop(); if (m_useMeasurementRouting) m_actionAdapters.NewMeasurements -= m_routingTables.RoutedMeasurementsHandler; else m_actionAdapters.NewMeasurements -= m_routingTables.BroadcastMeasurementsHandler; m_actionAdapters.UnpublishedSamples -= UnpublishedSamplesHandler; m_actionAdapters.Dispose(); } m_actionAdapters = null; // Dispose output adapters collection if (m_outputAdapters != null) { m_outputAdapters.Stop(); m_outputAdapters.UnprocessedMeasurements -= UnprocessedMeasurementsHandler; m_outputAdapters.Dispose(); } m_outputAdapters = null; // Dispose all adapters collection if (m_allAdapters != null)