PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Synchrophasor/Current Version/Source/Libraries/TVA.PhasorProtocols/Anonymous/ConfigurationFrame.cs

#
C# | 302 lines | 229 code | 15 blank | 58 comment | 1 complexity | b8896df1805f1d42cee0d846de6657c6 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, EPL-1.0
  1. //******************************************************************************************************
  2. // ConfigurationFrame.cs - Gbtc
  3. //
  4. // Copyright Š 2011, Grid Protection Alliance. All Rights Reserved.
  5. //
  6. // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
  7. // the NOTICE file distributed with this work for additional information regarding copyright ownership.
  8. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
  9. // not use this file except in compliance with the License. You may obtain a copy of the License at:
  10. //
  11. // http://www.opensource.org/licenses/eclipse-1.0.php
  12. //
  13. // Unless agreed to in writing, the subject software distributed under the License is distributed on an
  14. // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
  15. // License for the specific language governing permissions and limitations.
  16. //
  17. // Code Modification History:
  18. // ----------------------------------------------------------------------------------------------------
  19. // 05/05/2009 - J. Ritchie Carroll
  20. // Generated original version of source code.
  21. // 09/15/2009 - Stephen C. Wills
  22. // Added new header and license agreement.
  23. // 12/20/2011 - J. Ritchie Carroll
  24. // Updated configuration caching algorithm to create multiple backup configurations.
  25. //
  26. //******************************************************************************************************
  27. using System;
  28. using System.IO;
  29. using System.Linq;
  30. using System.Runtime.Serialization;
  31. using System.Runtime.Serialization.Formatters;
  32. using System.Runtime.Serialization.Formatters.Soap;
  33. using System.Threading;
  34. using TVA.Configuration;
  35. using TVA.IO;
  36. using TVA.IO.Checksums;
  37. namespace TVA.PhasorProtocols.Anonymous
  38. {
  39. /// <summary>
  40. /// Represents a protocol independent implementation of a <see cref="IConfigurationFrame"/> that can be sent or received.
  41. /// </summary>
  42. [Serializable()]
  43. public class ConfigurationFrame : ConfigurationFrameBase
  44. {
  45. #region [ Constructors ]
  46. /// <summary>
  47. /// Creates a new <see cref="ConfigurationFrame"/> from specified parameters.
  48. /// </summary>
  49. /// <param name="idCode">The ID code of this <see cref="ConfigurationFrame"/>.</param>
  50. /// <param name="timestamp">The exact timestamp, in <see cref="Ticks"/>, of the data represented by this <see cref="ConfigurationFrame"/>.</param>
  51. /// <param name="frameRate">The defined frame rate of this <see cref="ConfigurationFrame"/>.</param>
  52. public ConfigurationFrame(ushort idCode, Ticks timestamp, ushort frameRate)
  53. : base(idCode, new ConfigurationCellCollection(), timestamp, frameRate)
  54. {
  55. }
  56. /// <summary>
  57. /// Creates a new <see cref="ConfigurationFrame"/> from serialization parameters.
  58. /// </summary>
  59. /// <param name="info">The <see cref="SerializationInfo"/> with populated with data.</param>
  60. /// <param name="context">The source <see cref="StreamingContext"/> for this deserialization.</param>
  61. protected ConfigurationFrame(SerializationInfo info, StreamingContext context)
  62. : base(info, context)
  63. {
  64. }
  65. #endregion
  66. #region [ Properties ]
  67. /// <summary>
  68. /// Gets reference to the <see cref="ConfigurationCellCollection"/> for this <see cref="ConfigurationFrame"/>.
  69. /// </summary>
  70. public new ConfigurationCellCollection Cells
  71. {
  72. get
  73. {
  74. return base.Cells as ConfigurationCellCollection;
  75. }
  76. }
  77. #endregion
  78. #region [ Methods ]
  79. /// <summary>
  80. /// Calculates checksum of given <paramref name="buffer"/>.
  81. /// </summary>
  82. /// <param name="buffer">Buffer image over which to calculate checksum.</param>
  83. /// <param name="offset">Start index into <paramref name="buffer"/> to calculate checksum.</param>
  84. /// <param name="length">Length of data within <paramref name="buffer"/> to calculate checksum.</param>
  85. /// <returns>Checksum over specified portion of <paramref name="buffer"/>.</returns>
  86. protected override ushort CalculateChecksum(byte[] buffer, int offset, int length)
  87. {
  88. // Just returning calculated CRC-CCITT over given buffer as a default CRC
  89. return buffer.CrcCCITTChecksum(offset, length);
  90. }
  91. #endregion
  92. #region [ Static ]
  93. // Static Fields
  94. private static string s_configurationCachePath;
  95. private static int s_configurationBackups = -1;
  96. // Static Properties
  97. /// <summary>
  98. /// Gets the path for storing serialized phasor protocol configurations.
  99. /// </summary>
  100. public static string ConfigurationCachePath
  101. {
  102. get
  103. {
  104. // This property will not change during system life-cycle so we cache if for future use
  105. if (string.IsNullOrEmpty(s_configurationCachePath))
  106. {
  107. // Define default configuration cache directory relative to path of host application
  108. s_configurationCachePath = string.Format("{0}\\ConfigurationCache\\", FilePath.GetAbsolutePath(""));
  109. // Make sure configuration cache path setting exists within system settings section of config file
  110. ConfigurationFile configFile = ConfigurationFile.Current;
  111. CategorizedSettingsElementCollection systemSettings = configFile.Settings["systemSettings"];
  112. systemSettings.Add("ConfigurationCachePath", s_configurationCachePath, "Defines the path used to cache serialized phasor protocol configurations");
  113. // Retrieve configuration cache directory as defined in the config file
  114. s_configurationCachePath = FilePath.AddPathSuffix(systemSettings["ConfigurationCachePath"].Value);
  115. // Make sure configuration cache directory exists
  116. if (!Directory.Exists(s_configurationCachePath))
  117. Directory.CreateDirectory(s_configurationCachePath);
  118. }
  119. return s_configurationCachePath;
  120. }
  121. }
  122. /// <summary>
  123. /// Gets total number of configuration backups to keep when storing serialized phasor protocol configurations.
  124. /// </summary>
  125. public static int ConfigurationBackups
  126. {
  127. get
  128. {
  129. if (s_configurationBackups == -1)
  130. {
  131. const int DefaultConfigurationBackups = 5;
  132. // Make sure configuration backups setting exists within system settings section of config file
  133. ConfigurationFile configFile = ConfigurationFile.Current;
  134. CategorizedSettingsElementCollection systemSettings = configFile.Settings["systemSettings"];
  135. systemSettings.Add("ConfigurationBackups", DefaultConfigurationBackups, "Defines the total number of older backup configurations to maintain.");
  136. // Retrieve configuration backups value as defined in the config file
  137. s_configurationBackups = systemSettings["ConfigurationBackups"].ValueAs<int>(DefaultConfigurationBackups);
  138. }
  139. return s_configurationBackups;
  140. }
  141. }
  142. // Static Methods
  143. /// <summary>
  144. /// Serializes configuration frame to cache folder on an independent thread for later use (if needed).
  145. /// </summary>
  146. /// <param name="configurationFrame">Reference to <see cref="IConfigurationFrame"/>.</param>
  147. /// <param name="exceptionHandler"><see cref="Action{T}"/> delegate to handle process exceptions.</param>
  148. /// <param name="configurationName"><see cref="string"/> representing the configuration name.</param>
  149. public static void Cache(IConfigurationFrame configurationFrame, Action<Exception> exceptionHandler, string configurationName)
  150. {
  151. Tuple<IConfigurationFrame, Action<Exception>, string> state = new Tuple<IConfigurationFrame, Action<Exception>, string>(configurationFrame, exceptionHandler, configurationName);
  152. ThreadPool.QueueUserWorkItem(Cache, (object)state);
  153. }
  154. // Cache configuration file
  155. private static void Cache(object state)
  156. {
  157. Tuple<IConfigurationFrame, Action<Exception>, string> args = state as Tuple<IConfigurationFrame, Action<Exception>, string>;
  158. if (args != null)
  159. {
  160. FileStream configFile = null;
  161. IConfigurationFrame configurationFrame = args.Item1;
  162. Action<Exception> exceptionHandler = args.Item2;
  163. string configurationName = args.Item3;
  164. string configurationCacheFileName = GetConfigurationCacheFileName(configurationName);
  165. try
  166. {
  167. // Create multiple backup configurations, if requested
  168. for (int i = ConfigurationBackups; i > 0; i--)
  169. {
  170. string origConfigFile = configurationCacheFileName + ".backup" + (i == 1 ? "" : (i - 1).ToString());
  171. if (File.Exists(origConfigFile))
  172. {
  173. string nextConfigFile = configurationCacheFileName + ".backup" + i;
  174. if (File.Exists(nextConfigFile))
  175. File.Delete(nextConfigFile);
  176. File.Move(origConfigFile, nextConfigFile);
  177. }
  178. }
  179. }
  180. catch (Exception ex)
  181. {
  182. exceptionHandler(new InvalidOperationException(string.Format("Failed to create extra backup serialized configuration frames due to exception: {0}", ex.Message)));
  183. }
  184. try
  185. {
  186. // Back up current configuration file, if any
  187. if (File.Exists(configurationCacheFileName))
  188. {
  189. string backupConfigFile = configurationCacheFileName + ".backup";
  190. if (File.Exists(backupConfigFile))
  191. File.Delete(backupConfigFile);
  192. File.Move(configurationCacheFileName, backupConfigFile);
  193. }
  194. }
  195. catch (Exception ex)
  196. {
  197. exceptionHandler(new InvalidOperationException(string.Format("Failed to backup last serialized configuration frame due to exception: {0}", ex.Message)));
  198. }
  199. try
  200. {
  201. // Serialize configuration frame to a file
  202. SoapFormatter xmlSerializer = new SoapFormatter();
  203. xmlSerializer.AssemblyFormat = FormatterAssemblyStyle.Simple;
  204. xmlSerializer.TypeFormat = FormatterTypeStyle.TypesWhenNeeded;
  205. configFile = File.Create(configurationCacheFileName);
  206. xmlSerializer.Serialize(configFile, configurationFrame);
  207. }
  208. catch (Exception ex)
  209. {
  210. exceptionHandler(new InvalidOperationException(string.Format("Failed to serialize configuration frame: {0}", ex.Message), ex));
  211. }
  212. finally
  213. {
  214. if (configFile != null)
  215. configFile.Close();
  216. }
  217. }
  218. }
  219. /// <summary>
  220. /// Gets the file name with path of the specified <paramref name="configurationName"/>.
  221. /// </summary>
  222. /// <param name="configurationName">Name of the configuration to get file name for.</param>
  223. /// <returns>File name with path of the specified <paramref name="configurationName"/>.</returns>
  224. public static string GetConfigurationCacheFileName(string configurationName)
  225. {
  226. return string.Format("{0}{1}.configuration.xml", ConfigurationCachePath, configurationName.ReplaceCharacters('_', c => Path.GetInvalidFileNameChars().Contains(c)));
  227. }
  228. /// <summary>
  229. /// Deletes the cached configuration, if defined.
  230. /// </summary>
  231. /// <param name="configurationName">Name of the configuration to delete.</param>
  232. public static void DeleteCachedConfiguration(string configurationName)
  233. {
  234. string configFileName = GetConfigurationCacheFileName(configurationName);
  235. if (File.Exists(configFileName))
  236. File.Delete(configFileName);
  237. }
  238. /// <summary>
  239. /// Deserializes cached configuration, if available.
  240. /// </summary>
  241. /// <param name="configurationName">Name of the configuration to get file name for.</param>
  242. /// <param name="fromCache">Set to True retrieve from cache, False to retrieve from specified file name in <paramref name="configurationName"/></param>
  243. /// <returns>Cached configuration frame, or null if not available.</returns>
  244. public static IConfigurationFrame GetCachedConfiguration(string configurationName, bool fromCache)
  245. {
  246. IConfigurationFrame configFrame = null;
  247. string configFileName;
  248. if (fromCache)
  249. configFileName = GetConfigurationCacheFileName(configurationName);
  250. else
  251. configFileName = configurationName;
  252. if (File.Exists(configFileName))
  253. configFrame = Common.DeserializeConfigurationFrame(configFileName);
  254. return configFrame;
  255. }
  256. #endregion
  257. }
  258. }