From de14a8c4ac49cfc836e9f47f1fce36982e164435 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 24 Mar 2021 11:01:43 -0700 Subject: [PATCH] IO-797 Add fault tolerance for scanning. --- .../Utils/Decoder/EstimateDecoder.cs | 143 ++++++++++-------- BodyshopUploader/Utils/DiskScan.cs | 26 ++-- BodyshopUploader/Utils/HTTPServer.cs | 4 +- BodyshopUploader/Utils/JobProcessingQueue.cs | 9 ++ 4 files changed, 104 insertions(+), 78 deletions(-) diff --git a/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs b/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs index 9c4049c..783c098 100644 --- a/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs +++ b/BodyshopUploader/Utils/Decoder/EstimateDecoder.cs @@ -15,7 +15,8 @@ namespace BodyshopPartner.Utils.Decoder public static class CIECAEstimateImport { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); - + private static int numRetries = 6; + private static int retrySleep = 100; /// /// Decode the set of estimate files based on the creation of an envelope file. /// @@ -31,16 +32,18 @@ namespace BodyshopPartner.Utils.Decoder string system = ParseEnvFile(ref ret, _dir); - ParseAd1File(ref ret, _dir); - ParseAd2File(ref ret, _dir); - ParseVehFile(ref ret, _dir); - ParsePfhFile(ref ret, _dir); - ParsePflFile(ref ret, _dir, _source); - ParsePfmFile(ref ret, _dir); - ParseStlFile(ref ret, _dir); - ParseTtlFile(ref ret, _dir); - ParseLinFile(ref ret, _dir, system); - ParsePfpFile(ref ret, _dir); + bool ad1Success = ParseAd1File(ref ret, _dir); + bool ad2Success = ParseAd2File(ref ret, _dir); + bool vehSuccess = ParseVehFile(ref ret, _dir); + bool pfhSuccess = ParsePfhFile(ref ret, _dir); + bool pflSuccess = ParsePflFile(ref ret, _dir, _source); + bool pfmSuccess = ParsePfmFile(ref ret, _dir); + bool stlSuccess = ParseStlFile(ref ret, _dir); + bool ttlSuccess = ParseTtlFile(ref ret, _dir); + bool linSuccess = ParseLinFile(ref ret, _dir, system); + bool pfpSuccess = ParsePfpFile(ref ret, _dir); + + if (!ad1Success || !ad2Success || !vehSuccess || !pfhSuccess || !pflSuccess || !pfmSuccess || !stlSuccess || !ttlSuccess || !linSuccess || !pfpSuccess) return false; return ret; } @@ -54,7 +57,7 @@ namespace BodyshopPartner.Utils.Decoder logger.Trace(@"Parsing Env at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -74,9 +77,9 @@ namespace BodyshopPartner.Utils.Decoder } catch (IOException ex) { - logger.Trace(ex, "Unable to open AD1 file. Retrying. "); + logger.Trace(ex, "Unable to open ENV file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } @@ -84,16 +87,16 @@ namespace BodyshopPartner.Utils.Decoder return "M"; } - public static void ParseAd1File(ref dynamic j, string RootFilePath) + public static bool ParseAd1File(ref dynamic j, string RootFilePath) { if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { - return; + return false; } logger.Trace(@"Parsing AD1 at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -257,30 +260,31 @@ namespace BodyshopPartner.Utils.Decoder j.owner.data = ownerRoot; reader.Dispose(); - return; + return true; } } catch (IOException ex) { logger.Trace(ex, "Unable to open AD1 file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParseAd2File(ref dynamic j, string RootFilePath) + public static bool ParseAd2File(ref dynamic j, string RootFilePath) { if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { - return; + return false; } logger.Trace(@"Parsing AD2 at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -409,30 +413,31 @@ namespace BodyshopPartner.Utils.Decoder reader.Dispose(); - return; + return true; } } catch (IOException ex) { logger.Trace(ex, "Unable to open AD2 file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParsePfhFile(ref dynamic j, string RootFilePath) + public static bool ParsePfhFile(ref dynamic j, string RootFilePath) { if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { - return; + return false; } logger.Trace(@"Parsing PFH at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -470,28 +475,29 @@ namespace BodyshopPartner.Utils.Decoder //j.adj_btr_in = readValues[17];//ADJ_BTR_IN j.tax_predis = readValues[18];//TAX_PREDIS reader.Dispose(); - return; + return true; } } catch (IOException ex) { logger.Trace(ex, "Unable to open PFH file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParsePflFile(ref dynamic j, string RootFilePath, SourceSystem _source = SourceSystem.Mitchell) + public static bool ParsePflFile(ref dynamic j, string RootFilePath, SourceSystem _source = SourceSystem.Mitchell) { if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { - return; + return false; } logger.Trace(@"Parsing PFl at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -590,28 +596,29 @@ namespace BodyshopPartner.Utils.Decoder //j.lbr_tx_in5 = readValues[15];//LBR_TX_IN5 reader.Dispose(); - return; + return true; } } catch (IOException ex) { logger.Trace(ex, "Unable to open PFl file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParsePfmFile(ref dynamic j, string RootFilePath) + public static bool ParsePfmFile(ref dynamic j, string RootFilePath) { if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { - return; + return false; } logger.Trace(@"Parsing PFM at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -722,26 +729,27 @@ namespace BodyshopPartner.Utils.Decoder reader.Dispose(); - return; + return true; } } catch (IOException ex) { logger.Trace(ex, "Unable to open PFM file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParseVehFile(ref dynamic j, string RootFilePath) + public static bool ParseVehFile(ref dynamic j, string RootFilePath) { - if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return false; } logger.Trace(@"Parsing Veh at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -825,27 +833,28 @@ namespace BodyshopPartner.Utils.Decoder j.kmin = readValues[18]; v.shopid = AppMetaData.ActiveShopId; } - return; + return true; } catch (IOException ex) { logger.Trace(ex, "Unable to open VEH file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParseLinFile(ref dynamic j, string RootFilePath, string system) + public static bool ParseLinFile(ref dynamic j, string RootFilePath, string system) { if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { - return; + return false; } logger.Trace(@"Parsing LIN at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -1044,26 +1053,27 @@ namespace BodyshopPartner.Utils.Decoder reader.Dispose(); - return; + return true; } } catch (IOException ex) { logger.Trace(ex, "Unable to open LIN file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParseTtlFile(ref dynamic j, string RootFilePath) + public static bool ParseTtlFile(ref dynamic j, string RootFilePath) { - if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return false; } logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -1097,25 +1107,26 @@ namespace BodyshopPartner.Utils.Decoder } - return; + return true; } catch (IOException ex) { logger.Trace(ex, "Unable to open TTL file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParseStlFile(ref dynamic j, string RootFilePath) + public static bool ParseStlFile(ref dynamic j, string RootFilePath) { - if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; } + if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return false; } logger.Trace(@"Parsing STL at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -1158,27 +1169,28 @@ namespace BodyshopPartner.Utils.Decoder j.cieca_stl = new JObject(); j.cieca_stl.data = totals; } - return; + return true; } catch (IOException ex) { logger.Trace(ex, "Unable to open STL file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } - public static void ParsePfpFile(ref dynamic j, string RootFilePath) + public static bool ParsePfpFile(ref dynamic j, string RootFilePath) { if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { - return; + return false; } logger.Trace(@"Parsing PFP at: {0}{1}", RootFilePath, j.ciecaid.Value); int retryNumber = 0; - while (retryNumber < 11) + while (retryNumber < numRetries) { try { @@ -1233,16 +1245,17 @@ namespace BodyshopPartner.Utils.Decoder j.parts_tax_rates = taxRates; reader.Dispose(); - return; + return true; } } catch (IOException ex) { - logger.Trace(ex, "Unable to open LIN file. Retrying. "); + logger.Trace(ex, "Unable to open PFP file. Retrying. "); retryNumber++; - Thread.Sleep(3000); + Thread.Sleep(retrySleep); } } + return false; } diff --git a/BodyshopUploader/Utils/DiskScan.cs b/BodyshopUploader/Utils/DiskScan.cs index 5db4fa7..e7761f4 100644 --- a/BodyshopUploader/Utils/DiskScan.cs +++ b/BodyshopUploader/Utils/DiskScan.cs @@ -5,7 +5,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; - +using Newtonsoft.Json.Linq; namespace BodyshopPartner.Utils { public static class DiskScan @@ -32,18 +32,22 @@ namespace BodyshopPartner.Utils }; dynamic job = Utils.Decoder.EstimateDecoder.CIECAEstimateImport.DecodeEstimate(envfp); - - EstimatesOnDisk.Add(new ScanResponseItem() + + if (!(job is Boolean)) { - Id = job.ciecaid, - Filepath = envfp, - Cieca_Id = job.ciecaid, - Clm_No = job.clm_no, - Owner = job.ownr_fn?.Value + " " + job.ownr_ln?.Value, - Ins_Co_Nm = job.ins_co_nm?.Value, - Vehicle = job.vehicle.data.v_model_yr.Value + " " + job.vehicle.data.v_make_desc.Value + " " + job.vehicle.data.v_model_desc.Value, - }); + EstimatesOnDisk.Add(new ScanResponseItem() + { + Id = job.ciecaid, + Filepath = envfp, + Cieca_Id = job.ciecaid, + Clm_No = job.clm_no, + Owner = job.ownr_fn?.Value + " " + job.ownr_ln?.Value, + Ins_Co_Nm = job.ins_co_nm?.Value, + Vehicle = job.vehicle.data.v_model_yr.Value + " " + job.vehicle.data.v_make_desc.Value + " " + job.vehicle.data.v_model_desc.Value, + + }); + } }); logger.Info("Estimates found: " + ad1FilePaths.Count); return EstimatesOnDisk; diff --git a/BodyshopUploader/Utils/HTTPServer.cs b/BodyshopUploader/Utils/HTTPServer.cs index f20c35a..81d3084 100644 --- a/BodyshopUploader/Utils/HTTPServer.cs +++ b/BodyshopUploader/Utils/HTTPServer.cs @@ -171,8 +171,8 @@ namespace BodyshopPartner.Utils } catch (Exception Ex) { - logger.Error(Ex, "Error encountered while processing QuickBooks requests."); - hlog("Error encountered while processing QuickBooks requests."); + logger.Error(Ex, "Error encountered while scanning for estimates on disk.", Ex.ToString()); + hlog("Error encountered while processing QuickBooks requests. " + Ex.Message); HttpResponse.Add(new ScanResponseItem() { Id = "-1", Success = false, ErrorMessage = Ex.Message }); } res.WithCORS().AsText(JsonConvert.SerializeObject(HttpResponse)); diff --git a/BodyshopUploader/Utils/JobProcessingQueue.cs b/BodyshopUploader/Utils/JobProcessingQueue.cs index 15dba30..62e885a 100644 --- a/BodyshopUploader/Utils/JobProcessingQueue.cs +++ b/BodyshopUploader/Utils/JobProcessingQueue.cs @@ -117,6 +117,15 @@ namespace BodyshopPartner.Utils private static async Task UpsertQueueItem(DTO_QueueItem item) { + if (item.Job is Boolean) + { + //throw an error + logger.Error("The currently process job is missing part of the EMS set and could not be processed."); + string msg = Properties.Resources.Msg_NewJobUploadError; + Notifications.notifier.ShowError(msg); + return; + + } //TODO: This should perform some sort of upsert to update the vehicle with more up to date information. //Strip out what isn't needed by replacing it with nulls to save DB space.