PageRenderTime 56ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/AppLib/CE.InsightsDW.ImportData.ConsoleApp/ProfileInputFile.cs

https://bitbucket.org/jeffmccommas/acex
C# | 291 lines | 269 code | 8 blank | 14 comment | 2 complexity | 349338083e36c640d2381b55ec48e653 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Xml;
  8. using System.Xml.Linq;
  9. using System.Xml.Schema;
  10. using Aclara.UFx.StatusManagement;
  11. using CE.InsightsDW.ImportData.Infastructure;
  12. using CE.InsightsDW.ImportData.Infastructure.DataAccess;
  13. using CE.InsightsDW.Model;
  14. // ReSharper disable once CheckNamespace
  15. namespace CE.InsightsDW.ImportData
  16. {
  17. public class ProfileInputFile : IProcessFile
  18. {
  19. private readonly int _clientId;
  20. private readonly IConfig _config;
  21. private const string PremiseNode_Customerid = "CustomerId";
  22. private const string PremiseNode_Accountid = "AccountId";
  23. private const string PremiseNode_PremiseId = "PremiseId";
  24. private const string AttributeNode_Source = "Source";
  25. private const string AttributeNode_ModifiedDate = "ModifiedDate";
  26. private const string AttributeNode_CreatedDate = "CreateDate";
  27. private const string AttributeNode_Key = "AttributeKey";
  28. private const string AttributeNode_Value = "AttributeValue";
  29. private Infastructure.InsightsDW _daInsightsDw;
  30. private InsightsMetadata _daMetadata;
  31. /// <summary>
  32. /// Constructor
  33. /// </summary>
  34. /// <param name="options"></param>
  35. /// <param name="config"></param>
  36. public ProfileInputFile(Options options, IConfig config)
  37. {
  38. _clientId = Convert.ToInt32(options.ClientId);
  39. _config = config;
  40. }
  41. /// <summary>
  42. /// Process the Profile file
  43. /// </summary>
  44. /// <param name="theFile">The file to be processed</param>
  45. /// <param name="emailMessageContents">Contents of error email message</param>
  46. /// <param name="logMessageContents">Messages for the log file</param>
  47. /// <param name="statusList">The Status</param>
  48. /// <returns>The tracking id</returns>
  49. public string ProcessFile(FileInfo theFile, ICollection<string> emailMessageContents, ICollection<LoggerMessageModel> logMessageContents,
  50. CountsForReportingModel captureCountsForReporting, out StatusList statusList)
  51. {
  52. var trackingid = string.Empty;
  53. statusList = new StatusList();
  54. var nodeCounter = 0;
  55. var totalNodeCounter = 0;
  56. var processedNodeCounter = 0;
  57. var attributeTable = new List<Holding_PremiseAttribute>();
  58. _daInsightsDw = new Infastructure.InsightsDW(_config.ShardName);
  59. _daMetadata = new InsightsMetadata();
  60. try
  61. {
  62. DateTime trackingIdDate;
  63. Helpers.SetTrackingData(theFile.Name, out trackingid, out trackingIdDate);
  64. var xsdFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" +
  65. _config.InputXSD;
  66. // This logic sets-up a custom iteration using linq and yield. Each element is traversed forward-only, greatly saving resources.
  67. var getCustomerElements = InputFileXMLStream.StreamData(theFile.FullName).Select(el => el);
  68. var schemas = new XmlSchemaSet();
  69. schemas.Add(Constants.FileNamespace, XmlReader.Create(new StreamReader(xsdFile)));
  70. foreach (var element in getCustomerElements)
  71. {
  72. //Validate the node
  73. var errors = false;
  74. var errStatusList = new StatusList();
  75. var doc = new XDocument(new XElement(Constants.RootNode));
  76. var xElement = doc.Element(Constants.RootNode);
  77. xElement?.Add(element);
  78. doc.Validate(schemas, (o, e) =>
  79. {
  80. errStatusList.Add(new Status(e.Message, StatusTypes.StatusSeverity.Error));
  81. var elementData = string.Concat(element.Elements());
  82. _daInsightsDw.LogErrorsByInputType(
  83. Helpers.ExtractElements(elementData, DWImportConstants.RunType.Profile, _clientId,
  84. trackingid), e.Message, theFile.Name, DWImportConstants.RunType.Profile,
  85. _config.ImportSpecificLoggingOn);
  86. logMessageContents.Add(new LoggerMessageModel
  87. {
  88. LogLevel = NLog.LogLevel.Error,
  89. Exception = new InsightsDWImportException(
  90. $"Validation Error for file {theFile.Name} data: {elementData}",
  91. e.Exception)
  92. });
  93. errors = true;
  94. }, true);
  95. if (nodeCounter == 0)
  96. {
  97. //Create the datatable for storage
  98. attributeTable = new List<Holding_PremiseAttribute>();
  99. }
  100. // Main Call
  101. if (!errors)
  102. {
  103. try
  104. {
  105. var xmlNode = InputFileXMLStream.GetXmlNode(element);
  106. ProcessNode(trackingid, trackingIdDate, xmlNode, attributeTable);
  107. nodeCounter++;
  108. }
  109. catch (Exception eX)
  110. {
  111. errStatusList.Add(new Status(eX.Message, StatusTypes.StatusSeverity.Error));
  112. var elementData = string.Concat(element.Elements());
  113. _daInsightsDw.LogErrorsByInputType(
  114. Helpers.ExtractElements(elementData, DWImportConstants.RunType.Profile, _clientId, trackingid),
  115. eX.Message, theFile.Name, DWImportConstants.RunType.Profile, _config.ImportSpecificLoggingOn);
  116. logMessageContents.Add(new LoggerMessageModel
  117. {
  118. LogLevel = NLog.LogLevel.Error,
  119. Exception =
  120. new InsightsDWImportException(
  121. $"Processing Error for file {theFile.Name} data: " + eX.Message)
  122. });
  123. errors = true;
  124. }
  125. }
  126. if (errors)
  127. {
  128. statusList.AddRange(errStatusList);
  129. errors = false;
  130. errStatusList.Clear();
  131. }
  132. totalNodeCounter++;
  133. // Write out data if reached max batch size
  134. if (attributeTable.Count >= _config.MaxBatchSize)
  135. {
  136. processedNodeCounter += nodeCounter;
  137. var results = _daInsightsDw.WritePremiseAttributeData(attributeTable);
  138. nodeCounter = 0;
  139. if (results != attributeTable.Count)
  140. {
  141. var logMessage1 = "Not all Profile data was inserted. Only " + results + " out of " + attributeTable.Count + " saved to database.";
  142. statusList.Add(new Status(DateTime.Now.ToString(CultureInfo.InvariantCulture) + logMessage1, StatusTypes.StatusSeverity.Error));
  143. logMessageContents.Add(new LoggerMessageModel { LogLevel = NLog.LogLevel.Info, MessageToLog = logMessage1 });
  144. emailMessageContents.Add(logMessage1);
  145. }
  146. attributeTable.Clear();
  147. }
  148. }
  149. // End of loop. Write what is left.
  150. if (attributeTable.Count > 0)
  151. {
  152. processedNodeCounter += nodeCounter;
  153. //Less than max rows, so write it out
  154. var results = _daInsightsDw.WritePremiseAttributeData(attributeTable);
  155. if (results != attributeTable.Count)
  156. {
  157. var logMessage1 = "Not all Profile data was inserted. Only " + results + " out of " + attributeTable.Count + " saved to database.";
  158. statusList.Add(new Status(DateTime.Now.ToString(CultureInfo.InvariantCulture) + logMessage1, StatusTypes.StatusSeverity.Error));
  159. logMessageContents.Add(new LoggerMessageModel { LogLevel = NLog.LogLevel.Info, MessageToLog = logMessage1 });
  160. emailMessageContents.Add(logMessage1);
  161. }
  162. }
  163. var logMessage = ">>>> Processed " + processedNodeCounter + " Profiles out of " + totalNodeCounter + " <<<<";
  164. statusList.Add(new Status(DateTime.Now.ToString(CultureInfo.InvariantCulture) + logMessage, StatusTypes.StatusSeverity.Informational));
  165. logMessageContents.Add(new LoggerMessageModel { LogLevel = NLog.LogLevel.Info, MessageToLog = logMessage });
  166. emailMessageContents.Add(logMessage);
  167. captureCountsForReporting.Count = processedNodeCounter;
  168. captureCountsForReporting.Comment = logMessage;
  169. }
  170. catch (Exception ex)
  171. {
  172. statusList.Add(new Status(ex, StatusTypes.StatusSeverity.Error));
  173. logMessageContents.Add(new LoggerMessageModel
  174. {
  175. LogLevel = NLog.LogLevel.Error,
  176. Exception = null,
  177. MessageToLog = ex.Message
  178. });
  179. }
  180. return trackingid;
  181. }
  182. /// <summary>
  183. /// Process the XML Node
  184. /// </summary>
  185. /// <param name="trackingid">The tracking Id</param>
  186. /// <param name="trackingdate">The tracking date</param>
  187. /// <param name="rootNode">The xml node</param>
  188. /// <param name="premiseAttributeTable">The data table</param>
  189. private void ProcessNode(string trackingid, DateTime trackingdate, XmlNode rootNode,
  190. ICollection<Holding_PremiseAttribute> premiseAttributeTable)
  191. {
  192. //For some reason, customer is coming in as a child node, so just get all children
  193. var cNode = rootNode.FirstChild;
  194. //Load the Premise Attribute Table
  195. if (!cNode.HasChildNodes)
  196. {
  197. return;
  198. }
  199. foreach (XmlElement accountNode in cNode.ChildNodes)
  200. {
  201. if (!accountNode.HasChildNodes)
  202. {
  203. continue;
  204. }
  205. foreach (XmlElement premiseNode in accountNode.ChildNodes)
  206. {
  207. foreach (XmlElement attributeNode in premiseNode.ChildNodes)
  208. {
  209. var premiseAttribute = new Holding_PremiseAttribute
  210. {
  211. ClientID = _clientId,
  212. CustomerID = Helpers.GetText(cNode, PremiseNode_Customerid),
  213. AccountID = Helpers.GetText(accountNode, PremiseNode_Accountid),
  214. PremiseID = Helpers.GetText(premiseNode, PremiseNode_PremiseId),
  215. TrackingID = trackingid,
  216. TrackingDate = trackingdate,
  217. OptionValue = Helpers.GetText(attributeNode, AttributeNode_Value),
  218. AttributeKey = Helpers.GetText(attributeNode, AttributeNode_Key),
  219. UpdateDate = Convert.ToDateTime(Helpers.GetText(attributeNode, AttributeNode_ModifiedDate)),
  220. SourceId = _daInsightsDw.ValidateAndGetSource(Helpers.GetText(attributeNode, AttributeNode_Source))
  221. };
  222. // Check if valid Profile Attribute
  223. if (!_daMetadata.IsValidClientProfileAttribute(premiseAttribute.AttributeKey))
  224. {
  225. throw new ApplicationException("Invalid Premise Attribute Key : " + premiseAttribute.AttributeKey);
  226. }
  227. var strDateTime = Helpers.GetText(attributeNode, AttributeNode_CreatedDate);
  228. if (strDateTime.Length == 0)
  229. {
  230. premiseAttribute.CreateDate = null;
  231. }
  232. else
  233. {
  234. premiseAttribute.CreateDate = Convert.ToDateTime(strDateTime);
  235. }
  236. premiseAttributeTable.Add(premiseAttribute);
  237. }
  238. }
  239. }
  240. }
  241. }
  242. }