diff --git a/Adaptation/FileHandlers/OpenInsight/FileRead.cs b/Adaptation/FileHandlers/OpenInsight/FileRead.cs index e4d8739..c7e7abf 100644 --- a/Adaptation/FileHandlers/OpenInsight/FileRead.cs +++ b/Adaptation/FileHandlers/OpenInsight/FileRead.cs @@ -6,6 +6,7 @@ using Adaptation.Shared.Methods; using Adaptation.Shared.Metrology; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Linq; @@ -17,25 +18,29 @@ namespace Adaptation.FileHandlers.OpenInsight; public class FileRead : Shared.FileRead, IFileRead { + private int _LastIndex; private readonly string _IqsConnectionString; private readonly string _OpenInsightFilePattern; private readonly string _OpenInsightApiECDirectory; + private readonly ReadOnlyCollection _IQSCopyCollection; public FileRead(ISMTP smtp, Dictionary fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList modelObjectParameters, string equipmentDictionaryName, Dictionary> dummyRuns, Dictionary> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) { + _LastIndex = -1; _MinFileLength = 10; - _NullData = string.Empty; _Logistics = new(this); + _NullData = string.Empty; if (_FileParameter is null) throw new Exception(cellInstanceConnectionName); if (_ModelObjectParameterDefinitions is null) throw new Exception(cellInstanceConnectionName); if (!_IsDuplicator) throw new Exception(cellInstanceConnectionName); - _OpenInsightApiECDirectory = @"\\mesfs.infineon.com\EC_Metrology_Si\Archive\API"; + _IQSCopyCollection = new(GetProperties(cellInstanceConnectionName, modelObjectParameters, "IQS.Copy.")); _IqsConnectionString = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "IQS.ConnectionString"); _OpenInsightFilePattern = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "OpenInsight.FilePattern"); + _OpenInsightApiECDirectory = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "OpenInsight.Api.EC.Directory"); } void IFileRead.Move(Tuple> extractResults, Exception exception) @@ -160,8 +165,11 @@ public class FileRead : Shared.FileRead, IFileRead if (!string.IsNullOrEmpty(lines)) { long? subGroupId; - string openInsightApiIFXDirectory = string.Empty; + _LastIndex += 1; + if (_LastIndex >= _IQSCopyCollection.Count) + _LastIndex = 0; long breakAfter = dateTime.AddSeconds(_BreakAfterSeconds).Ticks; + ModelObjectParameterDefinition modelObjectParameterDefinition = _IQSCopyCollection[_LastIndex]; long preWait = _FileConnectorConfiguration?.FileHandleWaitTime is null ? dateTime.AddMilliseconds(1234).Ticks : dateTime.AddMilliseconds(_FileConnectorConfiguration.FileHandleWaitTime.Value).Ticks; if (string.IsNullOrEmpty(descriptions[0].Reactor) || string.IsNullOrEmpty(descriptions[0].PSN)) subGroupId = null; @@ -172,7 +180,17 @@ public class FileRead : Shared.FileRead, IFileRead else collection.Add(new(new ScopeInfo(tests[0], $"{subGroupId.Value} {_OpenInsightFilePattern}"), lines)); string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); - FromIQS.Save(_OpenInsightApiECDirectory, openInsightApiIFXDirectory, _Logistics, reportFullPath, logistics, descriptions.First(), lines, subGroupId, weekOfYear); + FromIQS.Save(_OpenInsightApiECDirectory, _Logistics, reportFullPath, logistics, descriptions.First(), lines, subGroupId, weekOfYear); + try + { FromIQS.SaveCopy(_FileConnectorConfiguration.SourceFileLocation, _IqsConnectionString, modelObjectParameterDefinition.Name, modelObjectParameterDefinition.Value.Split('|')); } + catch (Exception exception) + { + string subject = string.Concat("Exception:", _CellInstanceConnectionName); + string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); + try + { _SMTP.SendHighPriorityEmailMessage(subject, body); } + catch (Exception) { } + } } } if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) diff --git a/Adaptation/FileHandlers/OpenInsight/FromIQS.cs b/Adaptation/FileHandlers/OpenInsight/FromIQS.cs index 2d5e211..1b8eecf 100644 --- a/Adaptation/FileHandlers/OpenInsight/FromIQS.cs +++ b/Adaptation/FileHandlers/OpenInsight/FromIQS.cs @@ -1,5 +1,6 @@ using Adaptation.Shared; using System; +using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Globalization; @@ -17,7 +18,7 @@ public class FromIQS #nullable enable private static string GetCommandText(Logistics logistics, QS408M.Description description, string dateTime, long? subGroupId) - { + { // cSpell:disable StringBuilder result = new(); _ = result .AppendLine(" select iq.ev_count, iq.cl_count, iq.sl_count, iq.se_sgrp, iq.se_sgtm, iq.se_tsno, iq.td_test, iq.pr_name, iq.jd_name, iq.pl_name, iq.pd_name, iq.td_name, iq.se_val ") @@ -75,7 +76,7 @@ public class FromIQS .AppendLine(" order by iq.ev_count desc, iq.cl_count desc, iq.sl_count desc, iq.se_sgrp, iq.se_tsno, iq.td_test ") .AppendLine(" for json path "); return result.ToString(); - } + } // cSpell:restore private static StringBuilder GetForJsonPath(string connectionString, string commandText) { @@ -204,40 +205,135 @@ public class FromIQS return result; } - internal static void Save(string openInsightApiECDirectory, string openInsightApiIFXDirectory, Logistics logistics, string reportFullPath, string logisticLines, QS408M.Description description, string lines, long? subGroupId, string weekOfYear) + internal static void Save(string openInsightApiECDirectory, Logistics logistics, string reportFullPath, string logisticLines, QS408M.Description description, string lines, long? subGroupId, string weekOfYear) { string checkFile; string fileName = Path.GetFileName(reportFullPath); string json = GetJson(logistics, logisticLines, description); string? ecPathRoot = Path.GetPathRoot(openInsightApiECDirectory); - string? ifxPathRoot = Path.GetPathRoot(openInsightApiIFXDirectory); bool ecExists = ecPathRoot is not null && Directory.Exists(ecPathRoot); - bool ifxExists = ifxPathRoot is not null && Directory.Exists(ifxPathRoot); string weekYear = $"{logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}"; string ecDirectory = Path.Combine(openInsightApiECDirectory, weekYear, $"-{description.PSN}", $"-{description.Reactor}", $"-{description.RDS}", $"-{subGroupId}"); - string ifxDirectory = Path.Combine(openInsightApiIFXDirectory, weekYear, $"-{description.PSN}", $"-{description.Reactor}", $"-{description.RDS}", $"-{subGroupId}"); if (ecExists && !Directory.Exists(ecDirectory)) _ = Directory.CreateDirectory(ecDirectory); - if (ifxExists && !Directory.Exists(ifxDirectory)) - _ = Directory.CreateDirectory(ifxDirectory); checkFile = Path.Combine(ecDirectory, fileName); if (ecExists && !File.Exists(checkFile)) File.Copy(reportFullPath, checkFile); - checkFile = Path.Combine(ifxDirectory, fileName); - if (ifxExists && !File.Exists(checkFile)) - File.Copy(reportFullPath, checkFile); checkFile = Path.Combine(ecDirectory, $"{logistics.DateTimeFromSequence.Ticks}.txt"); if (ecExists && !File.Exists(checkFile)) File.WriteAllText(checkFile, lines); - checkFile = Path.Combine(ifxDirectory, $"{logistics.DateTimeFromSequence.Ticks}.txt"); - if (ifxExists && !File.Exists(checkFile)) - File.WriteAllText(checkFile, lines); checkFile = Path.Combine(ecDirectory, $"{logistics.DateTimeFromSequence.Ticks}.json"); if (ecExists && !File.Exists(checkFile)) File.WriteAllText(checkFile, json); - checkFile = Path.Combine(ifxDirectory, $"{logistics.DateTimeFromSequence.Ticks}.json"); - if (ifxExists && !File.Exists(checkFile)) - File.WriteAllText(checkFile, json); + } + + private static string GetCommandText(string[] iqsCopyValues) + { // cSpell:disable + StringBuilder result = new(); + if (iqsCopyValues.Length != 4) + throw new NotSupportedException(); + string find = iqsCopyValues[1]; + string replace = iqsCopyValues[3]; + _ = result + .AppendLine(" select pd.f_name [Part Name], ") + .AppendLine(" null [Part Revision], ") + .Append(" '").Append(replace).AppendLine("' [Test Name], ") + .AppendLine(" null [Description], ") + .AppendLine(" null [Lot Number], ") + .AppendLine(" null [Job Name], ") + .AppendLine(" null [Process Name], ") + .AppendLine(" case when sl.f_url = 0 then null else sl.f_url end [Reasonable Limit (Upper)], ") + .AppendLine(" case when sl.f_url = 0 then 0 else 1 end [Alarm Reasonable Limit (Upper)], ") + .AppendLine(" case when sl.f_usl = 0 then null else sl.f_usl end [Specification Limit (Upper)], ") + .AppendLine(" case when sl.f_usl = 0 then 0 else 1 end [Alarm Specification Limit (Upper)], ") + .AppendLine(" case when sl.f_ugb = 0 then null else sl.f_ugb end [Warning Limit (Upper)], ") + .AppendLine(" case when sl.f_ugb = 0 then 0 else 1 end [Alarm Warning Limit (Upper)], ") + .AppendLine(" case when sl.f_tar = 0 then null else sl.f_tar end [Specification Limit (Target)], ") + .AppendLine(" case when sl.f_lgb = 0 then null else sl.f_lgb end [Warning Limit (Lower)], ") + .AppendLine(" case when sl.f_lgb = 0 then 0 else 1 end [Alarm Warning Limit (Lower)], ") + .AppendLine(" case when sl.f_lsl = 0 then null else sl.f_lsl end [Specification Limit (Lower)], ") + .AppendLine(" case when sl.f_lsl = 0 then 0 else 1 end [Alarm Specification Limit (Lower)], ") + .AppendLine(" case when sl.f_lrl = 0 then null else sl.f_lrl end [Reasonable Limit (Lower)], ") + .AppendLine(" case when sl.f_lrl = 0 then 0 else 1 end [Alarm Reasonable Limit (Lower)], ") + .AppendLine(" td.f_name [Original Test Name], ") + .AppendLine(" td.f_test [Test Id], ") + .AppendLine(" ( ") + .AppendLine(" select count(sl_b.f_spec) ") + .AppendLine(" from [spcepiworld].[dbo].[spec_lim] sl_b ") + .AppendLine(" join [spcepiworld].[dbo].[part_dat] pd_b ") + .AppendLine(" on sl_b.f_part = pd_b.f_part ") + .AppendLine(" join [spcepiworld].[dbo].[test_dat] td_b ") + .AppendLine(" on sl_b.f_test = td_b.f_test ") + .AppendLine(" where sl_b.f_prcs = 0 ") + .Append(" and td_b.f_name = '").Append(replace).AppendLine("' ") + .AppendLine(" and pd_b.f_name = pd.f_name ") + .AppendLine(" and sl_b.f_url = sl.f_url ") + .AppendLine(" and sl_b.f_usl = sl.f_usl ") + .AppendLine(" and sl_b.f_ugb = sl.f_ugb ") + .AppendLine(" and sl_b.f_tar = sl.f_tar ") + .AppendLine(" and sl_b.f_lgb = sl.f_lgb ") + .AppendLine(" and sl_b.f_lsl = sl.f_lsl ") + .AppendLine(" and sl_b.f_lrl = sl.f_lrl ") + .AppendLine(" group by sl_b.f_spec ") + .AppendLine(" ) count ") + .AppendLine(" from [spcepiworld].[dbo].[spec_lim] sl ") + .AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ") + .AppendLine(" on sl.f_part = pd.f_part ") + .AppendLine(" join [spcepiworld].[dbo].[test_dat] td ") + .AppendLine(" on sl.f_test = td.f_test ") + .AppendLine(" where sl.f_prcs = 0 ") + .AppendLine(" and td.f_name = '").Append(find).AppendLine("' ") + .AppendLine(" and isnull(( ") + .AppendLine(" select count(sl_b.f_spec) ") + .AppendLine(" from [spcepiworld].[dbo].[spec_lim] sl_b ") + .AppendLine(" join [spcepiworld].[dbo].[part_dat] pd_b ") + .AppendLine(" on sl_b.f_part = pd_b.f_part ") + .AppendLine(" join [spcepiworld].[dbo].[test_dat] td_b ") + .AppendLine(" on sl_b.f_test = td_b.f_test ") + .AppendLine(" where sl_b.f_prcs = 0 ") + .Append(" and td_b.f_name = '").Append(replace).AppendLine("' ") + .AppendLine(" and pd_b.f_name = pd.f_name ") + .AppendLine(" and sl_b.f_url = sl.f_url ") + .AppendLine(" and sl_b.f_usl = sl.f_usl ") + .AppendLine(" and sl_b.f_ugb = sl.f_ugb ") + .AppendLine(" and sl_b.f_tar = sl.f_tar ") + .AppendLine(" and sl_b.f_lgb = sl.f_lgb ") + .AppendLine(" and sl_b.f_lsl = sl.f_lsl ") + .AppendLine(" and sl_b.f_lrl = sl.f_lrl ") + .AppendLine(" group by sl_b.f_spec ") + .AppendLine(" ), 0) = 0 ") + .AppendLine(" for json path "); + return result.ToString(); + } // cSpell:restore + + internal static void SaveCopy(string fileConnectorConfigurationSourceFileLocation, string connectionString, string name, string[] iqsCopyValues) + { + string checkFile = Path.Combine(fileConnectorConfigurationSourceFileLocation, $"{name}.tsv"); + if (!File.Exists(checkFile)) + { + string commandText = GetCommandText(iqsCopyValues); + StringBuilder stringBuilder = GetForJsonPath(connectionString, commandText); + if (stringBuilder.Length > 0) + { + JsonElement[]? jsonElements = JsonSerializer.Deserialize(stringBuilder.ToString()); + if (jsonElements is not null && jsonElements.Length != 0 && jsonElements[0].ValueKind == JsonValueKind.Object) + { + _ = stringBuilder.Clear(); + List lines = new(); + JsonProperty[] jsonProperties = jsonElements[0].EnumerateObject().ToArray(); + foreach (JsonProperty jsonProperty in jsonProperties) + _ = stringBuilder.Append(jsonProperty.Name).Append('\t'); + lines.Add(stringBuilder.ToString()); + for (int i = 0; i < jsonElements.Length; i++) + { + foreach (JsonProperty jsonProperty in jsonProperties) + _ = stringBuilder.Append(jsonProperty.Value).Append('\t'); + lines.Add(stringBuilder.ToString()); + } + File.WriteAllLines(checkFile, lines); + } + } + } } #nullable disable diff --git a/Adaptation/_Tests/CreateSelfDescription/Staging/v2.52.0/MET08THFTIRQS408M.cs b/Adaptation/_Tests/CreateSelfDescription/Staging/v2.52.0/MET08THFTIRQS408M.cs index 4f85eef..8d03a7c 100644 --- a/Adaptation/_Tests/CreateSelfDescription/Staging/v2.52.0/MET08THFTIRQS408M.cs +++ b/Adaptation/_Tests/CreateSelfDescription/Staging/v2.52.0/MET08THFTIRQS408M.cs @@ -110,6 +110,20 @@ public class MET08THFTIRQS408M : EAFLoggingUnitTesting NonThrowTryCatch(); } +#if DEBUG + [Ignore] +#endif + [TestMethod] + public void Staging__v2_52_1__MET08THFTIRQS408M__OpenInsight() + { + string check = "*.pdsf"; + MethodBase methodBase = new StackFrame().GetMethod(); + EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); + _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); + EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); + NonThrowTryCatch(); + } + #if DEBUG [Ignore] #endif diff --git a/Adaptation/_Tests/Extract/Staging/v2.52.0/MET08THFTIRQS408M.cs b/Adaptation/_Tests/Extract/Staging/v2.52.0/MET08THFTIRQS408M.cs index 95fb80f..15c036d 100644 --- a/Adaptation/_Tests/Extract/Staging/v2.52.0/MET08THFTIRQS408M.cs +++ b/Adaptation/_Tests/Extract/Staging/v2.52.0/MET08THFTIRQS408M.cs @@ -23,6 +23,13 @@ public class MET08THFTIRQS408M _MET08THFTIRQS408M = CreateSelfDescription.Staging.v2_52_0.MET08THFTIRQS408M.EAFLoggingUnitTesting; } + private static void NonThrowTryCatch() + { + try + { throw new Exception(); } + catch (Exception) { } + } + #if DEBUG [Ignore] #endif @@ -59,6 +66,7 @@ public class MET08THFTIRQS408M dateTime = FileHandlers.QS408M.ProcessData.GetDateTime(logistics, tickOffset: 0, dateTimeText: "Tue Nov 10 12:03:56 1970"); Assert.IsTrue(dateTime == logistics.DateTimeFromSequence); _ = Shared.AdaptationTesting.ReExtractCompareUpdatePassDirectory(variables, fileRead, logistics); + NonThrowTryCatch(); } #if DEBUG @@ -85,6 +93,23 @@ public class MET08THFTIRQS408M dateTime = FileHandlers.QS408M.ProcessData.GetDateTime(logistics, tickOffset: 0, dateTimeText: "Tue Nov 10 12:03:56 1970"); Assert.IsTrue(dateTime == logistics.DateTimeFromSequence); _ = Shared.AdaptationTesting.ReExtractCompareUpdatePassDirectory(variables, fileRead, logistics); + NonThrowTryCatch(); + } + +#if DEBUG + [Ignore] +#endif + [TestMethod] + public void Staging__v2_52_1__MET08THFTIRQS408M__OpenInsight638042558563679143__IqsCopy() + { + string check = "*.pdsf"; + MethodBase methodBase = new StackFrame().GetMethod(); + _MET08THFTIRQS408M.Staging__v2_52_1__MET08THFTIRQS408M__OpenInsight(); + string[] variables = _MET08THFTIRQS408M.AdaptationTesting.GetVariables(methodBase, check, validatePDSF: false); + IFileRead fileRead = _MET08THFTIRQS408M.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); + Logistics logistics = new(fileRead); + _ = Shared.AdaptationTesting.ReExtractCompareUpdatePassDirectory(variables, fileRead, logistics); + NonThrowTryCatch(); } #if DEBUG