Esempio n. 1
0
        /// <summary>
        /// Creates a <see cref="OutageLogProcessor"/> using a pre-initialized <see cref="OutageLog"/>.
        /// </summary>
        /// <param name="outageLog">Pre-initialized <see cref="OutageLog"/> to process.</param>
        /// <param name="processOutageFunction">A delegate that defines a processing function for an <see cref="Outage"/>.</param>
        /// <param name="canProcessOutageFunction">A delegate that determines if an <see cref="Outage"/> can currently be processed.</param>
        /// <param name="processExceptionHandler">Delegate to handle any exceptions encountered while processing as <see cref="Outage"/>.</param>
        /// <param name="processingInterval">Processing interval, in milliseconds.</param>
        public OutageLogProcessor(OutageLog outageLog, Action<Outage> processOutageFunction, Func<Outage, bool> canProcessOutageFunction, Action<Exception> processExceptionHandler, int processingInterval)
        {
            if ((object)outageLog == null)
                throw new ArgumentNullException("outageLog");

            if ((object)processOutageFunction == null)
                throw new ArgumentNullException("processOutageFunction");

            if ((object)canProcessOutageFunction == null)
                throw new ArgumentNullException("canProcessOutageFunction");

            if ((object)processExceptionHandler == null)
                throw new ArgumentNullException("processExceptionHandler");

            m_outageLog = outageLog;
            m_outageLog.CollectionChanged += outageLog_CollectionChanged;

            m_processOutageFunction = processOutageFunction;
            m_canProcessOutageFunction = canProcessOutageFunction;
            m_processInterval = processingInterval;
            m_enabled = true;

            m_operation = new LongSynchronizedOperation(ProcessNextItem, processExceptionHandler);
            m_operation.IsBackground = true;
            m_operation.RunOnceAsync();
        }
Esempio n. 2
0
        //private Dictionary<MeasurementKey, double> m_baseVoltages;

        #endregion

        /// <summary>
        /// Creates a new instance of the EPRI <see cref="FileExporter"/>.
        /// </summary>
        public FileExporter()
        {
            m_fileExport = new LongSynchronizedOperation(WriteFileData, OnProcessException)
            {
                IsBackground = true
            };
            m_fileDataLock = new object();
        }
        /// <summary>
        /// Constructs a new instance of the <see cref="InputAdapterBase"/>.
        /// </summary>
        protected InputAdapterBase()
        {
            m_connectionOperation = new LongSynchronizedOperation(AttemptConnectionOperation)
            {
                IsBackground = true
            };

            m_connectionTimer = Common.TimerScheduler.CreateTimer(2000);
            m_connectionTimer.Elapsed += m_connectionTimer_Elapsed;

            m_connectionTimer.AutoReset = false;
            m_connectionTimer.Enabled = false;
        }
Esempio n. 4
0
        /// <summary>
        /// Creates a new instance of the <see cref="ReportingProcessBase"/> class.
        /// </summary>
        /// <param name="reportType">Report type - passed into StatHistorianReportGenerator.</param>
        protected ReportingProcessBase(string reportType)
        {
            m_reportType = reportType;
            m_reportGenerationQueue = new ConcurrentQueue<Tuple<DateTime, bool>>();
            m_executeOperation = new LongSynchronizedOperation(Execute)
            {
                IsBackground = true
            };

            m_persistSettings = true;
            m_settingsCategory = string.Format("{0}Reporting", m_reportType);
            m_archiveFilePath = "Eval(statArchiveFile.FileName)";
            m_reportLocation = "Reports";
            m_title = string.Format("Eval(securityProvider.ApplicationName) {0} Report", m_reportType);
            m_company = "Eval(systemSettings.CompanyName)";
            m_idleReportLifetime = 14.0D;
            m_enableReportEmail = false;
            m_smtpServer = "localhost";
            m_fromAddress = "*****@*****.**";
            m_toAddresses = "*****@*****.**";
        }
        /// <summary>
        /// Event handler for service starting operations.
        /// </summary>
        /// <param name="sender">Event source.</param>
        /// <param name="e">Event arguments containing command line arguments passed into service at startup.</param>
        /// <remarks>
        /// Time-series framework uses this handler to load settings from configuration file as service is starting.
        /// </remarks>
        protected virtual void ServiceStartingHandler(object sender, EventArgs<string[]> e)
        {
            ShutdownHandler.Initialize();

            // Define a run-time log
            m_runTimeLog = new RunTimeLog();
            m_runTimeLog.FileName = "RunTimeLog.txt";
            m_runTimeLog.ProcessException += ProcessExceptionHandler;
            m_runTimeLog.Initialize();

            // Initialize Iaon session
            m_iaonSession = new IaonSession();
            m_iaonSession.StatusMessage += StatusMessageHandler;
            m_iaonSession.ProcessException += ProcessExceptionHandler;
            m_iaonSession.ConfigurationChanged += ConfigurationChangedHandler;

            // Create a handler for unobserved task exceptions
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

            // Make sure default service settings exist
            ConfigurationFile configFile = ConfigurationFile.Current;

            string servicePath = FilePath.GetAbsolutePath("");
            string cachePath = string.Format("{0}{1}ConfigurationCache{1}", servicePath, Path.DirectorySeparatorChar);
            string defaultLogPath = string.Format("{0}{1}Logs{1}", servicePath, Path.DirectorySeparatorChar);

            // System settings
            CategorizedSettingsElementCollection systemSettings = configFile.Settings["systemSettings"];
            systemSettings.Add("ConfigurationType", "Database", "Specifies type of configuration: Database, WebService, BinaryFile or XmlFile");
            systemSettings.Add("ConnectionString", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=IaonHost.mdb", "Configuration database connection string");
            systemSettings.Add("DataProviderString", "AssemblyName={System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089};ConnectionType=System.Data.OleDb.OleDbConnection;AdapterType=System.Data.OleDb.OleDbDataAdapter", "Configuration database ADO.NET data provider assembly type creation string");
            systemSettings.Add("ConfigurationCachePath", cachePath, "Defines the path used to cache serialized configurations");
            systemSettings.Add("LogPath", defaultLogPath, "Defines the path used to archive log files");
            systemSettings.Add("MaxLogFiles", DefaultMaxLogFiles, "Defines the maximum number of log files to keep");
            systemSettings.Add("CachedConfigurationFile", "SystemConfiguration.xml", "File name for last known good system configuration (only cached for a Database or WebService connection)");
            systemSettings.Add("UniqueAdaptersIDs", "True", "Set to true if all runtime adapter ID's will be unique to allow for easier adapter specification");
            systemSettings.Add("ProcessPriority", "High", "Sets desired process priority: Normal, AboveNormal, High, RealTime");
            systemSettings.Add("AllowRemoteRestart", "True", "Controls ability to remotely restart the host service.");
            systemSettings.Add("MinThreadPoolWorkerThreads", DefaultMinThreadPoolSize, "Defines the minimum number of allowed thread pool worker threads.");
            systemSettings.Add("MaxThreadPoolWorkerThreads", DefaultMaxThreadPoolSize, "Defines the maximum number of allowed thread pool worker threads.");
            systemSettings.Add("MinThreadPoolIOPortThreads", DefaultMinThreadPoolSize, "Defines the minimum number of allowed thread pool I/O completion port threads (used by socket layer).");
            systemSettings.Add("MaxThreadPoolIOPortThreads", DefaultMaxThreadPoolSize, "Defines the maximum number of allowed thread pool I/O completion port threads (used by socket layer).");
            systemSettings.Add("ConfigurationBackups", DefaultConfigurationBackups, "Defines the total number of older backup configurations to maintain.");
            systemSettings.Add("PreferCachedConfiguration", "False", "Set to true to try the cached configuration first, before loading database configuration - typically used when cache is updated by external process.");
            systemSettings.Add("LocalCertificate", $"{ServiceName}.cer", "Path to the local certificate used by this server for authentication.");
            systemSettings.Add("RemoteCertificatesPath", @"Certs\Remotes", "Path to the directory where remote certificates are stored.");
            systemSettings.Add("DefaultCulture", "en-US", "Default culture to use for language, country/region and calendar formats.");

            // Example connection settings
            CategorizedSettingsElementCollection exampleSettings = configFile.Settings["exampleConnectionSettings"];
            exampleSettings.Add("SqlServer.ConnectionString", "Data Source=serverName; Initial Catalog=databaseName; User ID=userName; Password=password", "Example SQL Server database connection string");
            exampleSettings.Add("SqlServer.DataProviderString", "AssemblyName={System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}; ConnectionType=System.Data.SqlClient.SqlConnection; AdapterType=System.Data.SqlClient.SqlDataAdapter", "Example SQL Server database .NET provider string");
            exampleSettings.Add("MySQL.ConnectionString", "Server=serverName;Database=databaseName; Uid=root; Pwd=password; allow user variables = true;", "Example MySQL database connection string");
            exampleSettings.Add("MySQL.DataProviderString", "AssemblyName={MySql.Data, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d}; ConnectionType=MySql.Data.MySqlClient.MySqlConnection; AdapterType=MySql.Data.MySqlClient.MySqlDataAdapter", "Example MySQL database .NET provider string");
            exampleSettings.Add("Oracle.ConnectionString", "Data Source=tnsName; User ID=schemaUserName; Password=schemaPassword", "Example Oracle database connection string");
            exampleSettings.Add("Oracle.DataProviderString", "AssemblyName={Oracle.DataAccess, Version=2.112.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342}; ConnectionType=Oracle.DataAccess.Client.OracleConnection; AdapterType=Oracle.DataAccess.Client.OracleDataAdapter", "Example Oracle database .NET provider string");
            exampleSettings.Add("SQLite.ConnectionString", "Data Source=databaseName.db; Version=3; Foreign Keys=True; FailIfMissing=True", "Example SQLite database connection string");
            exampleSettings.Add("SQLite.DataProviderString", "AssemblyName={System.Data.SQLite, Version=1.0.99.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139}; ConnectionType=System.Data.SQLite.SQLiteConnection; AdapterType=System.Data.SQLite.SQLiteDataAdapter", "Example SQLite database .NET provider string");
            exampleSettings.Add("OleDB.ConnectionString", "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=databaseName.mdb", "Example Microsoft Access (via OleDb) database connection string");
            exampleSettings.Add("OleDB.DataProviderString", "AssemblyName={System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}; ConnectionType=System.Data.OleDb.OleDbConnection; AdapterType=System.Data.OleDb.OleDbDataAdapter", "Example OleDb database .NET provider string");
            exampleSettings.Add("Odbc.ConnectionString", "Driver={SQL Server Native Client 10.0}; Server=serverName; Database=databaseName; Uid=userName; Pwd=password;", "Example ODBC database connection string");
            exampleSettings.Add("Odbc.DataProviderString", "AssemblyName={System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089}; ConnectionType=System.Data.Odbc.OdbcConnection; AdapterType=System.Data.Odbc.OdbcDataAdapter", "Example ODBC database .NET provider string");
            exampleSettings.Add("WebService.ConnectionString", "http://localhost/ConfigSource/SystemConfiguration.xml", "Example web service connection string");
            exampleSettings.Add("XmlFile.ConnectionString", "SystemConfiguration.xml", "Example XML configuration file connection string");

            // Attempt to set default culture
            try
            {
                string defaultCulture = systemSettings["DefaultCulture"].ValueAs("en-US");
                CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture(defaultCulture);     // Defaults for date formatting, etc.
                CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture(defaultCulture);   // Culture for resource strings, etc.
            }
            catch (Exception ex)
            {
                DisplayStatusMessage("Failed to set default culture due to exception, defaulting to \"{1}\": {0}", UpdateType.Alarm, ex.Message, CultureInfo.CurrentCulture.Name.ToNonNullNorEmptyString("Undetermined"));
                LogException(ex);
            }

            // Retrieve application log path as defined in the config file
            string logPath = FilePath.GetAbsolutePath(systemSettings["LogPath"].Value);

            // Make sure log directory exists
            try
            {
                if (!Directory.Exists(logPath))
                    Directory.CreateDirectory(logPath);
            }
            catch (Exception ex)
            {
                // Attempt to default back to common log file path
                if (!Directory.Exists(defaultLogPath))
                {
                    try
                    {
                        Directory.CreateDirectory(defaultLogPath);
                    }
                    catch
                    {
                        defaultLogPath = servicePath;
                    }
                }

                DisplayStatusMessage("Failed to create logging directory \"{0}\" due to exception, defaulting to \"{1}\": {2}", UpdateType.Alarm, logPath, defaultLogPath, ex.Message);
                LogException(ex);
                logPath = defaultLogPath;
            }

            int maxLogFiles = systemSettings["MaxLogFiles"].ValueAs(DefaultMaxLogFiles);

            try
            {
                Logger.FileWriter.SetPath(logPath);
                Logger.FileWriter.SetLoggingFileCount(maxLogFiles);
            }
            catch (Exception ex)
            {
                DisplayStatusMessage("Failed to set logging path \"{0}\" or max file count \"{1}\" due to exception: {2}", UpdateType.Alarm, logPath, maxLogFiles, ex.Message);
                LogException(ex);
            }

            // Retrieve configuration cache directory as defined in the config file
            cachePath = FilePath.GetAbsolutePath(systemSettings["ConfigurationCachePath"].Value);

            // Make sure configuration cache directory exists
            try
            {
                if (!Directory.Exists(cachePath))
                    Directory.CreateDirectory(cachePath);
            }
            catch (Exception ex)
            {
                DisplayStatusMessage("Failed to create configuration cache directory \"{0}\" due to exception: {1}", UpdateType.Alarm, cachePath, ex.Message);
                LogException(ex);
            }

            try
            {
                Directory.SetCurrentDirectory(servicePath);
            }
            catch (Exception ex)
            {
                DisplayStatusMessage("Failed to set current directory to execution path \"{0}\" due to exception: {1}", UpdateType.Alarm, servicePath, ex.Message);
                LogException(ex);
            }

            // Initialize system settings
            m_configurationType = systemSettings["ConfigurationType"].ValueAs<ConfigurationType>();
            m_cachedXmlConfigurationFile = FilePath.AddPathSuffix(cachePath) + systemSettings["CachedConfigurationFile"].Value;
            m_cachedBinaryConfigurationFile = FilePath.AddPathSuffix(cachePath) + FilePath.GetFileNameWithoutExtension(m_cachedXmlConfigurationFile) + ".bin";
            m_configurationBackups = systemSettings["ConfigurationBackups"].ValueAs(DefaultConfigurationBackups);
            m_uniqueAdapterIDs = systemSettings["UniqueAdaptersIDs"].ValueAsBoolean(true);
            m_allowRemoteRestart = systemSettings["AllowRemoteRestart"].ValueAsBoolean(true);
            m_preferCachedConfiguration = systemSettings["PreferCachedConfiguration"].ValueAsBoolean(false);

            m_reloadConfigQueue = ProcessQueue<Tuple<string, Action<bool>>>.CreateSynchronousQueue(ExecuteReloadConfig, 500.0D, Timeout.Infinite, false, false);
            m_reloadConfigQueue.ProcessException += m_iaonSession.ProcessExceptionHandler;

            m_configurationCacheOperation = new LongSynchronizedOperation(ExecuteConfigurationCache)
            {
                IsBackground = true
            };

            // Setup default thread pool size
            try
            {
                ThreadPool.SetMinThreads(systemSettings["MinThreadPoolWorkerThreads"].ValueAs(DefaultMinThreadPoolSize), systemSettings["MinThreadPoolIOPortThreads"].ValueAs(DefaultMinThreadPoolSize));
                ThreadPool.SetMaxThreads(systemSettings["MaxThreadPoolWorkerThreads"].ValueAs(DefaultMaxThreadPoolSize), systemSettings["MaxThreadPoolIOPortThreads"].ValueAs(DefaultMaxThreadPoolSize));
            }
            catch (Exception ex)
            {
                DisplayStatusMessage("Failed to set desired thread pool size due to exception: {0}", UpdateType.Alarm, ex.Message);
                LogException(ex);
            }

            // Define guid with query string delimiters according to database needs
            if (string.IsNullOrWhiteSpace(m_nodeIDQueryString))
                m_nodeIDQueryString = "'" + m_iaonSession.NodeID + "'";

            // Set up the configuration loader
            switch (m_configurationType)
            {
                case ConfigurationType.Database:
                    m_configurationLoader = new DatabaseConfigurationLoader
                    {
                        ConnectionString = systemSettings["ConnectionString"].Value,
                        DataProviderString = systemSettings["DataProviderString"].Value,
                        NodeIDQueryString = m_nodeIDQueryString
                    };

                    break;

                case ConfigurationType.WebService:
                    m_configurationLoader = new WebServiceConfigurationLoader
                    {
                        URI = systemSettings["ConnectionString"].Value
                    };

                    break;

                case ConfigurationType.BinaryFile:
                    m_configurationLoader = new BinaryFileConfigurationLoader
                    {
                        FilePath = systemSettings["ConnectionString"].Value
                    };

                    break;

                case ConfigurationType.XmlFile:
                    m_configurationLoader = new XMLConfigurationLoader
                    {
                        FilePath = systemSettings["ConnectionString"].Value
                    };

                    break;
            }

            m_binaryCacheConfigurationLoader = new BinaryFileConfigurationLoader
            {
                FilePath = m_cachedBinaryConfigurationFile
            };

            m_xmlCacheConfigurationLoader = new XMLConfigurationLoader
            {
                FilePath = m_cachedXmlConfigurationFile
            };

            m_configurationLoader.StatusMessage += (o, args) => DisplayStatusMessage(args.Argument, UpdateType.Information);
            m_binaryCacheConfigurationLoader.StatusMessage += (o, args) => DisplayStatusMessage(args.Argument, UpdateType.Information);
            m_xmlCacheConfigurationLoader.StatusMessage += (o, args) => DisplayStatusMessage(args.Argument, UpdateType.Information);

            m_configurationLoader.ProcessException += ConfigurationLoader_ProcessException;
            m_binaryCacheConfigurationLoader.ProcessException += ConfigurationLoader_ProcessException;
            m_xmlCacheConfigurationLoader.ProcessException += ConfigurationLoader_ProcessException;

            m_reloadConfigQueue.Start();

#if !MONO
            try
            {
                // Attempt to assign desired process priority. Note that process will require SeIncreaseBasePriorityPrivilege or 
                // Administrative privileges to make this change
                Process.GetCurrentProcess().PriorityClass = systemSettings["ProcessPriority"].ValueAs<ProcessPriorityClass>();
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
#endif
        }
Esempio n. 6
0
        /// <summary>
        /// Creates a new instance of the <see cref="AlarmAdapter"/> class.
        /// </summary>
        public AlarmAdapter()
        {
            m_alarmLock = new object();
            m_alarmLookup = new Dictionary<Guid, SignalAlarms>();

            m_measurementQueue = new DoubleBufferedQueue<IMeasurement>();
            m_processMeasurementsOperation = new MixedSynchronizedOperation(ProcessMeasurements, OnProcessException);

            m_alarmLogOperation = new LongSynchronizedOperation(LogStateChanges, OnProcessException);
            m_stateChanges = new DoubleBufferedQueue<StateChange>();
            m_alarmLogOperation.IsBackground = true;
        }
        /// <summary>
        /// Constructs a new instance of the <see cref="OutputAdapterBase"/>.
        /// </summary>
        protected OutputAdapterBase()
        {
            m_metadataRefreshOperation = new LongSynchronizedOperation(ExecuteMetadataRefresh)
            {
                IsBackground = true
            };

            m_measurementQueue = ProcessQueue<IMeasurement>.CreateRealTimeQueue(ProcessMeasurements);
            m_measurementQueue.ProcessException += m_measurementQueue_ProcessException;

            m_connectionOperation = new LongSynchronizedOperation(AttemptConnectionOperation)
            {
                IsBackground = true
            };

            m_connectionTimer = Common.TimerScheduler.CreateTimer(2000);
            m_connectionTimer.Elapsed += m_connectionTimer_Elapsed;

            m_connectionTimer.AutoReset = false;
            m_connectionTimer.Enabled = false;

            // We monitor total number of unarchived measurements every 5 seconds - this is a useful statistic to monitor, if
            // total number of unarchived measurements gets very large, measurement archival could be falling behind
            m_monitorTimer = Common.TimerScheduler.CreateTimer(5000);
            m_monitorTimer.Elapsed += m_monitorTimer_Elapsed;

            m_monitorTimer.AutoReset = true;
            m_monitorTimer.Enabled = false;
        }
 /// <summary>
 /// Creates a new instance of the <see cref="SandBoxEngine"/> class.
 /// </summary>
 public SandBoxEngine()
 {
     m_processLatestDataOperation = new LongSynchronizedOperation(ProcessLatestDataOperation, ex => Log.Error(ex.Message, ex));
 }
Esempio n. 9
0
        /// <summary>
        /// Creates a new <see cref="DataSubscriber"/>.
        /// </summary>
        public DataSubscriber()
        {
            m_registerStatisticsOperation = new LongSynchronizedOperation(HandleDeviceStatisticsRegistration)
            {
                IsBackground = true
            };

            m_requests = new List<ServerCommand>();

            m_synchronizeMetadataOperation = new LongSynchronizedOperation(SynchronizeMetadata)
            {
                IsBackground = true
            };

            m_encoding = Encoding.Unicode;
            m_operationalModes = DefaultOperationalModes;
            m_metadataSynchronizationTimeout = DefaultMetadataSynchronizationTimeout;
            m_allowedParsingExceptions = DefaultAllowedParsingExceptions;
            m_parsingExceptionWindow = DefaultParsingExceptionWindow;

            string loggingPath = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(DefaultLoggingPath));

            if (Directory.Exists(loggingPath))
                m_loggingPath = loggingPath;

            // Default to not using transactions for meta-data on SQL server (helps avoid deadlocks)
            try
            {
                using (AdoDataConnection database = new AdoDataConnection("systemSettings"))
                {
                    m_useTransactionForMetadata = database.DatabaseType != DatabaseType.SQLServer;
                }
            }
            catch
            {
                m_useTransactionForMetadata = DefaultUseTransactionForMetadata;
            }

            DataLossInterval = 10.0D;

            m_bufferBlockCache = new List<BufferBlockMeasurement>();
            m_useLocalClockAsRealTime = true;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ConfigurationFile"/> class.
        /// </summary>        
        internal ConfigurationFile(string configFilePath)
        {
            m_culture = CultureInfo.InvariantCulture;

            // Do not run the save operation on a background thread since the application may be
            // performing the save as a final step during shutdown and the save operation must
            // complete, incomplete saves can cause a zero length config file to be created.
            m_saveOperation = new LongSynchronizedOperation(ExecuteConfigurationSave)
            {
                IsBackground = false
            };

            m_configuration = GetConfiguration(configFilePath);

            if (m_configuration.HasFile && File.Exists(m_configuration.FilePath))
                ValidateConfigurationFile(m_configuration.FilePath);
            else
                CreateConfigurationFile(m_configuration.FilePath);

            m_configuration = GetConfiguration(configFilePath);
            m_userConfiguration = new UserConfigurationFile();
        }
Esempio n. 11
0
        /// <summary>
        /// Creates a new <see cref="SubscriberStatusQuery"/>.
        /// </summary>
        public SubscriberStatusQuery()
        {
            m_serviceClient = CommonFunctions.GetWindowsServiceClient();
            m_serviceClient.Helper.ReceivedServiceResponse += Helper_ReceivedServiceResponse;

            m_subscriberStatuses = new List<Tuple<Guid, bool, string>>();
            m_responseComplete = new AutoResetEvent(false);
            m_statusQueryOperation = new LongSynchronizedOperation(ExecuteStatusQuery) { IsBackground = true };
            m_statusQueryIDs = new HashSet<Guid>();
            m_statusQueryLock = new object();
            m_responseTimeout = DefaultResponseTimeout;

            m_statusQueryOperation.IsBackground = true;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="MultipleDestinationExporter"/> class.
 /// </summary>
 /// <param name="settingsCategory">The config file settings category under which the export destinations are defined.</param>
 /// <param name="exportTimeout">The total allowed time in milliseconds for each export to execute.</param>
 public MultipleDestinationExporter(string settingsCategory, int exportTimeout)
 {
     m_exportTimeout = exportTimeout;
     m_settingsCategory = settingsCategory;
     m_persistSettings = DefaultPersistSettings;
     m_maximumRetryAttempts = DefaultMaximumRetryAttempts;
     m_retryDelayInterval = DefaultRetryDelayInterval;
     m_textEncoding = Encoding.Default; // We use default ANSI page encoding for text based exports...
     m_exportDestinationsLock = new object();
     m_exportOperation = new LongSynchronizedOperation(ExecuteExports, OnProcessException)
     {
         IsBackground = true
     };            
 }
Esempio n. 13
0
        /// <summary>
        /// Creates a new instance of the <see cref="RoutingTables"/> class.
        /// </summary>
        public RoutingTables(IRouteMappingTables mappingTable = null)
        {
            m_prevCalculatedConsumers = new HashSet<IAdapter>();
            m_prevCalculatedProducers = new HashSet<IAdapter>();
            m_routeMappingTables = mappingTable ?? new RouteMappingDoubleBufferQueue();
            m_routeMappingTables.Initialize(OnStatusMessage, OnProcessException);

            m_calculateRoutingTablesOperation = new LongSynchronizedOperation(CalculateRoutingTables)
            {
                IsBackground = true
            };
        }
Esempio n. 14
0
        /// <summary>
        /// Creates a new instance of the <see cref="InterprocessCache"/> with the specified number of <paramref name="maximumConcurrentLocks"/>.
        /// </summary>
        /// <param name="maximumConcurrentLocks">Maximum concurrent reader locks to allow.</param>
        public InterprocessCache(int maximumConcurrentLocks)
        {
            // Initialize field values
            m_loadOperation = new LongSynchronizedOperation(SynchronizedRead)
            {
                IsBackground = true
            };
            m_saveOperation = new LongSynchronizedOperation(SynchronizedWrite);
            m_loadIsReady = new ManualResetEventSlim(false);
            m_saveIsReady = new ManualResetEventSlim(true);
            m_maximumConcurrentLocks = maximumConcurrentLocks;
            m_maximumRetryAttempts = DefaultMaximumRetryAttempts;
            m_retryQueue = new BitArray(2);
            m_fileData = new byte[0];

            // Setup retry timer
            m_retryTimer = new Timer();
            m_retryTimer.Elapsed += m_retryTimer_Elapsed;
            m_retryTimer.AutoReset = false;
            m_retryTimer.Interval = DefaultRetryDelayInterval;
        }
        /// <summary>
        /// Initializes <see cref="TimeSeriesProducer"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary<string, string> settings = Settings;
            string setting;
            int value;

            // Parse required settings
            if (!settings.TryGetValue(nameof(Servers), out setting) || string.IsNullOrWhiteSpace(setting))
                throw new ArgumentException($"Required \"{nameof(Servers)}\" setting is missing.");

            Servers = setting.Trim();
            m_servers = Servers.Split(',').Select(uri => new Uri(uri)).ToArray();

            // Parse optional settings
            if (settings.TryGetValue(nameof(Topic), out setting) && !string.IsNullOrWhiteSpace(setting))
                Topic = setting.Trim();
            else
                Topic = DefaultTopic;

            if (settings.TryGetValue(nameof(Partitions), out setting) && int.TryParse(setting, out value))
                Partitions = value;
            else
                Partitions = DefaultPartitions;

            if (settings.TryGetValue(nameof(Encoding), out setting))
                Encoding = setting;
            else
                Encoding = null;

            if (settings.TryGetValue(nameof(TimestampFormat), out setting))
                TimestampFormat = setting;
            else
                TimestampFormat = DefaultTimestampFormat;

            if (settings.TryGetValue(nameof(ValueFormat), out setting))
                ValueFormat = setting;
            else
                ValueFormat = DefaultValueFormat;

            if (settings.TryGetValue(nameof(SerializeMetadata), out setting))
                SerializeMetadata = setting.ParseBoolean();
            else
                SerializeMetadata = DefaultSerializeMetadata;

            if (settings.TryGetValue(nameof(CacheMetadataLocally), out setting))
                CacheMetadataLocally = setting.ParseBoolean();
            else
                CacheMetadataLocally = DefaultCacheMetadataLocally;

            if (CacheMetadataLocally)
                m_cacheMetadataLocally = new LongSynchronizedOperation(() => TimeSeriesMetadata.CacheLocally(m_metadata, MetadataTopic, status => OnStatusMessage(MessageLevel.Info, status))) { IsBackground = true };
        }
        /// <summary>
        /// Initializes <see cref="TimeSeriesProducer"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary<string, string> settings = Settings;
            string setting;
            int intValue;
            double doubleValue;

            // Parse required settings
            if (!settings.TryGetValue(nameof(Servers), out setting) || string.IsNullOrWhiteSpace(setting))
                throw new ArgumentException($"Required \"{nameof(Servers)}\" setting is missing.");

            Servers = setting.Trim();
            m_servers = Servers.Split(',').Select(uri => new Uri(uri)).ToArray();

            // Parse optional settings
            if (settings.TryGetValue(nameof(Topic), out setting) && !string.IsNullOrWhiteSpace(setting))
                Topic = setting.Trim();
            else
                Topic = TimeSeriesProducer.DefaultTopic;

            if (settings.TryGetValue(nameof(Partitions), out setting) && int.TryParse(setting, out intValue))
                Partitions = intValue;
            else
                Partitions = TimeSeriesProducer.DefaultPartitions;

            if (settings.TryGetValue(nameof(TrackConsumerOffset), out setting))
                TrackConsumerOffset = setting.ParseBoolean();
            else
                TrackConsumerOffset = DefaultTrackConsumerIndex;

            if (!settings.TryGetValue(nameof(ConsumerOffsetFileName), out setting) || string.IsNullOrWhiteSpace(setting))
                setting = Name + ".offset";

            ConsumerOffsetFileName = FilePath.GetAbsolutePath(setting);

            if (settings.TryGetValue(nameof(ConsumerOffsetCacheInterval), out setting) && double.TryParse(setting, out doubleValue))
                ConsumerOffsetCacheInterval = doubleValue;
            else
                ConsumerOffsetCacheInterval = DefaultConsumerOffsetCacheInterval;

            if (settings.TryGetValue(nameof(ReadDelay), out setting) && int.TryParse(setting, out intValue))
                ReadDelay = intValue;
            else
                ReadDelay = DefaultReadDelay;

            if (settings.TryGetValue(nameof(CacheMetadataLocally), out setting))
                CacheMetadataLocally = setting.ParseBoolean();
            else
                CacheMetadataLocally = TimeSeriesProducer.DefaultCacheMetadataLocally;

            if (CacheMetadataLocally)
                m_cacheMetadataLocally = new LongSynchronizedOperation(() => TimeSeriesMetadata.CacheLocally(m_metadata, MetadataTopic, status => OnStatusMessage(MessageLevel.Info, status)))
                {
                    IsBackground = true
                };

            if ((object)OutputMeasurements != null && OutputMeasurements.Length > 0)
                m_outputMeasurementKeys = new HashSet<MeasurementKey>(OutputMeasurements.Select(m => m.Key));
        }
Esempio n. 17
0
        /// <summary>
        /// Creates a new <see cref="AuthorizedMeasurementsQuery"/>.
        /// </summary>
        public AuthorizedMeasurementsQuery()
        {
            m_serviceClient = CommonFunctions.GetWindowsServiceClient();
            m_serviceClient.Helper.ReceivedServiceResponse += Helper_ReceivedServiceResponse;

            m_authorizedSignalIDs = new List<Guid>();
            m_responseComplete = new AutoResetEvent(false);
            m_authorizationQueryOperation = new LongSynchronizedOperation(ExecuteAuthorizationQuery) { IsBackground = true };
            m_authorizationQueryIDs = new HashSet<Guid>();
            m_authorizationQueryLock = new object();
            m_responseTimeout = DefaultResponseTimeout;
        }
        // Per partition consumer read handler
        private void ProcessPartitionMessages(object state)
        {
            int partition = (int)state;

            try
            {
                Dictionary<uint, MeasurementKey> idTable = new Dictionary<uint, MeasurementKey>();
                ConsumerOptions options = new ConsumerOptions(Topic, m_router);
                LongSynchronizedOperation cacheLastConsumerOffset = null;
                OffsetPosition consumerCursor = new OffsetPosition { PartitionId = partition, Offset = 0 };
                long lastUpdateTime = 0;
                long lastMetadataUpdateCount = 0;
                long lastMeasurementTime = 0;

                options.PartitionWhitelist.Add(partition);
                options.Log = new TimeSeriesLogger((message, parameters) => OnStatusMessage(MessageLevel.Info, string.Format($"P[{partition}]: " + message, parameters)), ex => OnProcessException(MessageLevel.Warning, ex));

                // Handle consumer offset tracking, i.e., adapter will start reading messages where it left off from last run
                if (TrackConsumerOffset)
                {
                    // Parse path/filename.ext into constituent parts
                    string[] fileParts = new string[3];

                    fileParts[0] = FilePath.GetDirectoryName(ConsumerOffsetFileName);               // 0: path/
                    fileParts[1] = FilePath.GetFileNameWithoutExtension(ConsumerOffsetFileName);    // 1: filename
                    fileParts[2] = FilePath.GetExtension(ConsumerOffsetFileName);                   // 2: .ext

                    // Include partition index as part of consumer offset cache file name
                    string fileName = $"{fileParts[0]}{fileParts[1]}-P{partition}{fileParts[2]}";

                    if (File.Exists(fileName))
                    {
                        try
                        {
                            // Read last consumer offset
                            consumerCursor.Offset = long.Parse(File.ReadAllText(fileName));
                        }
                        catch (Exception ex)
                        {
                            OnProcessException(MessageLevel.Warning, new InvalidOperationException($"Failed to read last consumer offset from \"{fileName}\": {ex.Message}", ex));
                        }
                    }

                    cacheLastConsumerOffset = new LongSynchronizedOperation(() =>
                    {
                        // Do not write file any more often than defined consumer offset cache interval
                        int restTime = (int)(Ticks.FromSeconds(ConsumerOffsetCacheInterval) - (DateTime.UtcNow.Ticks - lastUpdateTime)).ToMilliseconds();

                        if (restTime > 0)
                            Thread.Sleep(restTime);

                        lastUpdateTime = DateTime.UtcNow.Ticks;

                        // Write current consumer offset
                        File.WriteAllText(fileName, consumerCursor.Offset.ToString());
                    }, 
                    ex => OnProcessException(MessageLevel.Warning, new InvalidOperationException($"Failed to cache current consumer offset to \"{fileName}\": {ex.Message}", ex)))
                    {
                        IsBackground = true
                    };
                }

                using (Consumer consumer = new Consumer(options, new OffsetPosition(partition, consumerCursor.Offset)))
                {
                    lock (m_consumers)
                        m_consumers.Add(new WeakReference<Consumer>(consumer));

                    foreach (Message message in consumer.Consume())
                    {
                        if ((object)m_metadata == null)
                            continue;

                        uint id;
                        byte metadataVersion;
                        IMeasurement measurement = message.KafkaDeserialize(out id, out metadataVersion);

                        // Kick-off a refresh for new metadata if message version numbers change
                        if (m_lastMetadataVersion != metadataVersion)
                        {
                            m_lastMetadataVersion = metadataVersion;
                            m_updateMetadata.RunOnceAsync();
                        }

                        // Clear all undefined items in dictionary when metadata gets updated
                        if (lastMetadataUpdateCount < m_metadataUpdateCount)
                        {
                            lastMetadataUpdateCount = m_metadataUpdateCount;
                            foreach (uint undefinedID in idTable.Where(item => item.Value.SignalID == Guid.Empty).Select(item => item.Key).ToArray())
                                idTable.Remove(undefinedID);
                        }

                        // Get associated measurement key, or look it up in metadata table
                        measurement.Metadata = idTable.GetOrAdd(id, lookupID => MeasurementKey.LookUpBySignalID(m_metadata?.Records?.FirstOrDefault(record => record.ID == lookupID)?.ParseSignalID() ?? Guid.Empty)).Metadata;

                        // Only publish measurements with associated metadata and are assigned to this adapter
                        if (measurement.Key != MeasurementKey.Undefined && ((object)m_outputMeasurementKeys == null || m_outputMeasurementKeys.Contains(measurement.Key)))
                            OnNewMeasurements(new[] { measurement });

                        // Cache last consumer offset
                        consumerCursor.Offset = message.Offset;

                        if ((object)cacheLastConsumerOffset != null)
                            cacheLastConsumerOffset.RunOnceAsync();

                        if (ReadDelay > -1)
                        {
                            // As a group of measurements transition from timestamp to another, inject configured read delay
                            if (lastMeasurementTime != measurement.Timestamp)
                                Thread.Sleep(ReadDelay);

                            lastMeasurementTime = measurement.Timestamp;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OnProcessException(MessageLevel.Warning, new InvalidOperationException($"Exception while reading Kafka messages for topic \"{Topic}\" P[{partition}]: {ex.Message}", ex));
            }
        }
Esempio n. 19
0
        //private Dictionary<MeasurementKey, double> m_baseVoltages;

        #endregion

        /// <summary>
        /// Creates a new instance of the EPRI <see cref="FileExporter"/>.
        /// </summary>
        public FileExporter()
        {
            m_fileExport = new LongSynchronizedOperation(WriteFileData, ex => OnProcessException(MessageLevel.Error, ex))
            {
                IsBackground = true
            };
            m_fileDataLock = new object();
        }
 /// <summary>
 /// Creates a new <see cref="TimeSeriesConsumer"/> instance.
 /// </summary>
 public TimeSeriesConsumer()
 {
     m_consumers = new List<WeakReference<Consumer>>();
     m_updateMetadata = new LongSynchronizedOperation(UpdateMetadata, ex => OnProcessException(MessageLevel.Warning, ex))
     {
         IsBackground = true
     };
 }
Esempio n. 21
0
        /// <summary>
        /// Creates a new <see cref="AlarmStatusQuery"/>.
        /// </summary>
        public AlarmStatusQuery()
        {
            // Attach to service connected events
            CommonFunctions.ServiceConnectionRefreshed += CommonFunctions_ServiceConnectionRefreshed;

            // Determine initial state of connectivity
            UpdateServiceConnectivity();

            m_alarmStateQueryOperation = new LongSynchronizedOperation(ExecuteAlarmStateQuery)
            {
                IsBackground = true
            };
            m_responseComplete = new AutoResetEvent(false);
            m_responseTimeout = DefaultResponseTimeout;
        }
Esempio n. 22
0
 /// <summary>
 /// Creates a new instance of the <see cref="RoutingTables"/> class.
 /// </summary>
 public RoutingTables()
 {
     m_calculateRoutingTablesOperation = new LongSynchronizedOperation(CalculateRoutingTables)
     {
         IsBackground = true
     };
 }