diff --git a/Adaptation/.editorconfig b/Adaptation/.editorconfig index 69ecc38..d117dc5 100644 --- a/Adaptation/.editorconfig +++ b/Adaptation/.editorconfig @@ -121,6 +121,7 @@ dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]cs dotnet_diagnostic.IDE0300.severity = none # IDE0300: Collection initialization can be simplified dotnet_diagnostic.IDE0301.severity = none #IDE0301: Collection initialization can be simplified dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified +dotnet_diagnostic.MSTEST0037.severity = error # MSTEST0037: Use proper 'Assert' methods dotnet_diagnostic.SYSLIB1045.severity = none # SYSLIB1045: diagnostics for regex source generation dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case diff --git a/Adaptation/.vscode/tasks.json b/Adaptation/.vscode/tasks.json index 68cdbae..74fac0e 100644 --- a/Adaptation/.vscode/tasks.json +++ b/Adaptation/.vscode/tasks.json @@ -82,6 +82,26 @@ "command": "code ../MET08AWCT.csproj", "problemMatcher": [] }, + { + "label": "Readme", + "type": "shell", + "command": "code ../README.md", + "problemMatcher": [] + }, + { + "label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20", + "type": "shell", + "command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe", + "args": [ + "s", + "X", + "L:/DevOps/EAF-Mesa-Integration/MET08AWCT", + "Day-Helper-2025-03-20", + "false", + "4" + ], + "problemMatcher": [] + }, { "label": "Git Config", "type": "shell", diff --git a/Adaptation/FileHandlers/Archive/FileRead.cs b/Adaptation/FileHandlers/Archive/FileRead.cs index 392e3af..118ef8e 100644 --- a/Adaptation/FileHandlers/Archive/FileRead.cs +++ b/Adaptation/FileHandlers/Archive/FileRead.cs @@ -26,7 +26,7 @@ public class FileRead : Shared.FileRead, IFileRead private static PropertyInfo? _PropertyInfo; private static NetworkStream? _NetworkStream; - 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) : + 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) { if (_FileConnectorConfiguration.FileScanningIntervalInSeconds is null) diff --git a/Adaptation/FileHandlers/CellInstanceConnectionName.cs b/Adaptation/FileHandlers/CellInstanceConnectionName.cs index 3255a8f..0efff95 100644 --- a/Adaptation/FileHandlers/CellInstanceConnectionName.cs +++ b/Adaptation/FileHandlers/CellInstanceConnectionName.cs @@ -9,7 +9,7 @@ namespace Adaptation.FileHandlers; public class CellInstanceConnectionName { - internal static IFileRead Get(ISMTP smtp, Dictionary fileParameter, string cellInstanceName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList modelObjectParameters, string equipmentDictionaryName, Dictionary> dummyRuns, Dictionary> staticRuns, bool useCyclicalForDescription, int? connectionCount) + internal static IFileRead Get(ISMTP smtp, Dictionary fileParameter, string cellInstanceName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList modelObjectParameters, string equipmentDictionaryName, Dictionary> dummyRuns, Dictionary> staticRuns, bool useCyclicalForDescription, int? connectionCount) { IFileRead result = cellInstanceConnectionName switch { diff --git a/Adaptation/FileHandlers/Dummy/FileRead.cs b/Adaptation/FileHandlers/Dummy/FileRead.cs index 916f5d7..3b777eb 100644 --- a/Adaptation/FileHandlers/Dummy/FileRead.cs +++ b/Adaptation/FileHandlers/Dummy/FileRead.cs @@ -23,7 +23,7 @@ public class FileRead : Shared.FileRead, IFileRead private int _LastDummyRunIndex; private readonly string[] _CellNames; - 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) : + 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) { _MinFileLength = 10; diff --git a/Adaptation/FileHandlers/wc/FileRead.cs b/Adaptation/FileHandlers/wc/FileRead.cs index cfc5fe0..fd0b474 100644 --- a/Adaptation/FileHandlers/wc/FileRead.cs +++ b/Adaptation/FileHandlers/wc/FileRead.cs @@ -27,7 +27,7 @@ public class FileRead : Shared.FileRead, IFileRead private static PropertyInfo? _PropertyInfo; private static NetworkStream? _NetworkStream; - 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) : + 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) { if (_FileConnectorConfiguration.FileScanningIntervalInSeconds is null) diff --git a/Adaptation/MET08AWCT.Tests.csproj b/Adaptation/MET08AWCT.Tests.csproj index d273faf..bdde428 100644 --- a/Adaptation/MET08AWCT.Tests.csproj +++ b/Adaptation/MET08AWCT.Tests.csproj @@ -69,7 +69,7 @@ - NU1701 + NU1701 diff --git a/Adaptation/Shared/Duplicator/Description.cs b/Adaptation/Shared/Duplicator/Description.cs index f725b29..964612e 100644 --- a/Adaptation/Shared/Duplicator/Description.cs +++ b/Adaptation/Shared/Duplicator/Description.cs @@ -12,7 +12,7 @@ public class Description : IDescription, Properties.IDescription public int Test { get; set; } public int Count { get; set; } public int Index { get; set; } - public string Lot { get; set; } + public string RDS { get; set; } // public string EventName { get; set; } public string NullData { get; set; } @@ -141,7 +141,7 @@ public class Description : IDescription, Properties.IDescription MID = logistics.MID, // Date = DateTime.Now.ToString(GetDateFormat()), - Lot = string.Empty, + RDS = string.Empty, }; results.Add(description); } diff --git a/Adaptation/Shared/FileRead.cs b/Adaptation/Shared/FileRead.cs index 4b6f3fc..49a4526 100644 --- a/Adaptation/Shared/FileRead.cs +++ b/Adaptation/Shared/FileRead.cs @@ -44,9 +44,9 @@ public class FileRead : Properties.IFileRead protected readonly string _CellInstanceConnectionNameBase; protected readonly Dictionary> _DummyRuns; protected readonly Dictionary _FileParameter; - protected readonly Dictionary> _StaticRuns; protected readonly string _ParameterizedModelObjectDefinitionType; protected readonly FileConnectorConfiguration _FileConnectorConfiguration; + protected readonly Dictionary> _StaticRuns; protected readonly IList _ModelObjectParameterDefinitions; bool Properties.IFileRead.IsEvent => _IsEvent; @@ -63,203 +63,6 @@ public class FileRead : Properties.IFileRead string Properties.IFileRead.CellInstanceConnectionName => _CellInstanceConnectionName; string Properties.IFileRead.ParameterizedModelObjectDefinitionType => _ParameterizedModelObjectDefinitionType; - public FileRead(IDescription description, bool isEvent, 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) - { - _SMTP = smtp; - _IsEvent = isEvent; - _DummyRuns = dummyRuns; - _LastTicksDuration = 0; - _StaticRuns = staticRuns; - _IsEAFHosted = isEAFHosted; - _Description = description; - _FileParameter = fileParameter; - _ReportFullPath = string.Empty; - _CellInstanceName = cellInstanceName; - _Calendar = new CultureInfo("en-US").Calendar; - _Log = LogManager.GetLogger(typeof(FileRead)); - _UseCyclicalForDescription = useCyclicalForDescription; - _CellInstanceConnectionName = cellInstanceConnectionName; - _ModelObjectParameterDefinitions = modelObjectParameters; - _FileConnectorConfiguration = fileConnectorConfiguration; - _ParameterizedModelObjectDefinitionType = parameterizedModelObjectDefinitionType; - _IsSourceTimer = fileConnectorConfiguration.SourceFileFilter.StartsWith("*Timer.txt"); - string cellInstanceConnectionNameBase = cellInstanceConnectionName.Replace("-", string.Empty); - _Hyphens = cellInstanceConnectionName.Length - cellInstanceConnectionNameBase.Length; - _TracePath = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "Path.Trace"); - _ExceptionSubject = string.Concat("Exception:", _CellInstanceConnectionName, _FileConnectorConfiguration?.SourceDirectoryCloaking); - string suffix; - string[] segments = _ParameterizedModelObjectDefinitionType.Split('.'); - string @namespace = segments[0]; - string eventNameFileRead = "FileRead"; - string eventName = segments[segments.Length - 1]; - bool isDuplicator = segments[0] == cellInstanceName; - _IsDuplicator = isDuplicator; - _CellInstanceConnectionNameBase = cellInstanceConnectionNameBase; - if (eventName == eventNameFileRead) - suffix = string.Empty; - else - suffix = string.Concat('_', eventName.Split(new string[] { eventNameFileRead }, StringSplitOptions.RemoveEmptyEntries)[1]); - string parameterizedModelObjectDefinitionTypeAppended = string.Concat(@namespace, suffix); - if (!isEAFHosted) - { - if (string.IsNullOrEmpty(equipmentTypeName) || equipmentTypeName != parameterizedModelObjectDefinitionTypeAppended) - throw new Exception(cellInstanceConnectionName); - if (string.IsNullOrEmpty(equipmentDictionaryName) && isEvent) - throw new Exception(cellInstanceConnectionName); - if (!string.IsNullOrEmpty(equipmentDictionaryName) && !isEvent && connectionCount > 1) - throw new Exception(cellInstanceConnectionName); - // if (string.IsNullOrEmpty(equipmentDictionaryName) && !isEvent) - // throw new Exception(cellInstanceConnectionName); - // if (!string.IsNullOrEmpty(equipmentDictionaryName) && isEvent) - // throw new Exception(cellInstanceConnectionName); - } - if (isDuplicator) - _MesEntity = string.Empty; - else - _MesEntity = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, string.Concat("CellInstance.", cellInstanceName, ".Alias")); - _EventName = eventName; - _EventNameFileRead = eventNameFileRead; - _EquipmentType = parameterizedModelObjectDefinitionTypeAppended; - long breakAfterSeconds; - if (_FileConnectorConfiguration is null) - breakAfterSeconds = 360; - else - { - if (_FileConnectorConfiguration.FileScanningOption == FileConnectorConfiguration.FileScanningOptionEnum.TimeBased) - breakAfterSeconds = Math.Abs(_FileConnectorConfiguration.FileHandleTimeout.Value); - else if (_FileConnectorConfiguration.FileScanningOption == FileConnectorConfiguration.FileScanningOptionEnum.FileWatcher) - breakAfterSeconds = Math.Abs(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value); - else - throw new Exception(); - } - _BreakAfterSeconds = breakAfterSeconds; - UpdateLastTicksDuration(breakAfterSeconds * 10000000); - if (_IsDuplicator) - { - if (string.IsNullOrEmpty(_FileConnectorConfiguration.TargetFileLocation) || string.IsNullOrEmpty(_FileConnectorConfiguration.ErrorTargetFileLocation)) - throw new Exception("_Configuration is empty?"); - if (_FileConnectorConfiguration.TargetFileLocation.Contains('%') || _FileConnectorConfiguration.ErrorTargetFileLocation.Contains('%')) - throw new Exception("_Configuration is incorrect for a duplicator!"); - // if (_FileConnectorConfiguration is not null) - // { - // if (string.IsNullOrEmpty(_FileConnectorConfiguration.SourceDirectoryCloaking)) - // throw new Exception("SourceDirectoryCloaking is empty?"); - // if (!_FileConnectorConfiguration.SourceDirectoryCloaking.StartsWith("~")) - // throw new Exception("SourceDirectoryCloaking is incorrect for a duplicator!"); - // } - } - } - - protected static string GetPropertyValue(string cellInstanceConnectionName, IList modelObjectParameters, string propertyName) - { - string result; - List results = (from l in modelObjectParameters where l.Name == propertyName select l.Value).ToList(); - if (results.Count != 1) - throw new Exception(cellInstanceConnectionName); - result = results[0]; - return result; - } - - protected static ModelObjectParameterDefinition[] GetProperties(string cellInstanceConnectionName, IList modelObjectParameters, string propertyNamePrefix) - { - ModelObjectParameterDefinition[] results = (from l in modelObjectParameters where l.Name.StartsWith(propertyNamePrefix) select l).ToArray(); - if (results.Length == 0) - throw new Exception(cellInstanceConnectionName); - return results; - } - - protected static ModelObjectParameterDefinition[] GetProperties(string cellInstanceConnectionName, IList modelObjectParameters, string propertyNamePrefix, string propertyNameSuffix) - { - ModelObjectParameterDefinition[] results = (from l in modelObjectParameters where l.Name.StartsWith(propertyNamePrefix) && l.Name.EndsWith(propertyNameSuffix) select l).ToArray(); - if (results.Length == 0) - throw new Exception(cellInstanceConnectionName); - return results; - } - - protected void UpdateLastTicksDuration(long ticksDuration) - { - if (ticksDuration < 50000000) - ticksDuration = 50000000; - _LastTicksDuration = (long)Math.Ceiling(ticksDuration * .667); - _Log.Info($"{new TimeSpan(ticksDuration).TotalMilliseconds} TotalMillisecond(s) to process{Environment.NewLine}{_CellInstanceConnectionName}{Environment.NewLine}<{_ReportFullPath}>"); - } - - protected void WaitForThread(Thread thread, List threadExceptions) - { - if (thread is not null) - { - ThreadState threadState; - for (short i = 0; i < short.MaxValue; i++) - { - if (thread is null) - break; - else - { - threadState = thread.ThreadState; - if (threadState is not ThreadState.Running and not ThreadState.WaitSleepJoin) - break; - } - Thread.Sleep(500); - } - lock (threadExceptions) - { - if (threadExceptions.Count != 0) - { - foreach (Exception item in threadExceptions) - _Log.Error(string.Concat(item.Message, Environment.NewLine, Environment.NewLine, item.StackTrace)); - Exception exception = threadExceptions[0]; - threadExceptions.Clear(); - throw exception; - } - } - } - } - - private void WriteAllLines(string to, string[] exceptionLines) - { - string fileName = string.Concat(to, @"\readme.txt"); - try - { - if (!Directory.Exists(to)) - _ = Directory.CreateDirectory(to); - File.WriteAllLines(fileName, exceptionLines); - } - catch (Exception ex) { _Log.Error(ex.Message); } - } - - protected string[] Move(Tuple> extractResults, string to, string from, string resolvedFileLocation, Exception exception) - { - string[] results; - bool isErrorFile = exception is not null; - if (!to.EndsWith(@"\")) - _ = string.Concat(to, @"\"); - if (!isErrorFile) - results = Array.Empty(); - else - { - results = new string[] { _Logistics.Sequence.ToString(), _Logistics.ReportFullPath, from, resolvedFileLocation, to, string.Empty, string.Empty, exception.Message, string.Empty, string.Empty, exception.StackTrace }; - if (!_IsDuplicator) - WriteAllLines(to, results); - } - if (extractResults is not null && extractResults.Item4 is not null && extractResults.Item4.Count != 0) - { - string itemFile; - List directories = new(); - foreach (FileInfo sourceFile in extractResults.Item4) - { - if (sourceFile.FullName != _Logistics.ReportFullPath) - { - itemFile = sourceFile.FullName.Replace(from, to); - Shared1880(itemFile, directories, sourceFile, isErrorFile); - } - else if (!isErrorFile && _Logistics is not null) - Shared1811(to, sourceFile); - } - Shared0231(directories); - } - return results; - } - protected static string GetTupleFile(Logistics logistics, List descriptions, Properties.IScopeInfo scopeInfo, string duplicateDirectory, string duplicateFile) where T : Properties.IDescription { string result; @@ -268,10 +71,10 @@ public class FileRead : Properties.IFileRead string dateValue; string rdsPlaceholder = "%RDS%"; string mesEntityPlaceholder = "%MesEntity%"; - if (descriptions.Count == 0 || string.IsNullOrEmpty(descriptions[0].Lot)) + if (descriptions.Count == 0 || string.IsNullOrEmpty(descriptions[0].RDS)) rds = logistics.MID; else - rds = descriptions[0].Lot; + rds = descriptions[0].RDS; string[] segments = scopeInfo.FileName.Split(new string[] { "DateTime:" }, StringSplitOptions.RemoveEmptyEntries); if (segments.Length == 0) result = string.Concat(duplicateDirectory, @"\", scopeInfo.FileNameWithoutExtension.Replace(rdsPlaceholder, rds).Replace(mesEntityPlaceholder, logistics.MesEntity)); @@ -384,217 +187,131 @@ public class FileRead : Properties.IFileRead } } - protected void SetFileParameter(string key, string value) + protected void WaitForFileConsumption(DateTime dateTime, List descriptions, bool isDummyRun, string successDirectory, string duplicateDirectory, List<(Properties.IScopeInfo, string)> collection, string duplicateFile) where T : Properties.IDescription { - if (_FileConnectorConfiguration is null || _FileConnectorConfiguration.TargetFileLocation.Contains(string.Concat("%", key, "%")) || _FileConnectorConfiguration.ErrorTargetFileLocation.Contains(string.Concat("%", key, "%")) || _FileConnectorConfiguration.TargetFileName.Contains(string.Concat("%", key, "%")) || _FileConnectorConfiguration.ErrorTargetFileName.Contains(string.Concat("%", key, "%"))) - { - if (_FileParameter.ContainsKey(key)) - _FileParameter[key] = value; - else - _FileParameter.Add(key, value); - } - } - - protected void SetFileParameterLotIDToLogisticsMID(bool includeLogisticsSequence = true) - { - string key; - if (!includeLogisticsSequence) - key = "LotID"; - else - key = "LotIDWithLogisticsSequence"; - string value = string.Concat(_Logistics.MID, "_", _Logistics.Sequence, "_", DateTime.Now.Ticks - _Logistics.Sequence); - SetFileParameter(key, value); - } - - protected void SetFileParameterLotID(string value, bool includeLogisticsSequence = true) - { - string key; - if (!includeLogisticsSequence) - key = "LotID"; + if (!isDummyRun && _IsEAFHosted) + WaitForFileConsumption(_FileConnectorConfiguration.SourceDirectoryCloaking, _Logistics, dateTime, descriptions, successDirectory, duplicateDirectory, duplicateFile, collection); else { - key = "LotIDWithLogisticsSequence"; - value = string.Concat(value, "_", _Logistics.Sequence, "_", DateTime.Now.Ticks - _Logistics.Sequence); - } - SetFileParameter(key, value); - } - - protected void WritePDSF(IFileRead fileRead, JsonElement[] jsonElements) - { - string directory; - string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); - string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}{@"\"}{_Logistics.DateTimeFromSequence:yyyy-MM-dd}"; - if (!_CellInstanceConnectionName.StartsWith(_CellInstanceName) && _CellInstanceConnectionNameBase == _EquipmentType) - directory = Path.Combine(_TracePath, _EquipmentType, "Target", weekDirectory, _CellInstanceName, _CellInstanceConnectionName); - else - directory = Path.Combine(_TracePath, _EquipmentType, "Source", weekDirectory, _CellInstanceName, _CellInstanceConnectionName); - if (!Directory.Exists(directory)) - _ = Directory.CreateDirectory(directory); - string file = Path.Combine(directory, string.Concat(_Logistics.MesEntity, "_", _Logistics.Sequence, ".ipdsf")); - string lines = ProcessDataStandardFormat.GetPDSFText(fileRead, _Logistics, jsonElements, logisticsText: string.Empty); - File.WriteAllText(file, lines); - if (_Logistics.TotalSecondsSinceLastWriteTimeFromSequence > 600) - { - try - { File.SetLastWriteTime(file, _Logistics.DateTimeFromSequence); } - catch (Exception) { } - } - } - - protected void Move(Tuple> extractResults) - { - if (!_IsEAFHosted) - { - string to; - if (!_FileConnectorConfiguration.TargetFileLocation.EndsWith(Path.DirectorySeparatorChar.ToString())) - to = _FileConnectorConfiguration.TargetFileLocation; - else - to = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation); - foreach (KeyValuePair keyValuePair in _FileParameter) - to = to.Replace(string.Concat('%', keyValuePair.Key, '%'), keyValuePair.Value); - if (to.Contains('%')) - _Log.Debug("Can't debug without EAF Hosting"); - else - _ = Move(extractResults, to, _FileConnectorConfiguration.SourceFileLocation, resolvedFileLocation: string.Empty, exception: null); - } - } - - protected void TriggerEvents(Tuple> extractResults, List headerNames, Dictionary keyValuePairs) - { - object value; - string segments; - string description; - List list; - for (int i = 0; i < extractResults.Item3.Length; i++) - { - _Log.Debug(string.Concat("TriggerEvent - {", _Logistics.ReportFullPath, "} ", i, " of ", extractResults.Item3.Length)); - foreach (JsonProperty jsonProperty in extractResults.Item3[i].EnumerateObject()) + long breakAfter = DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileHandleWaitTime.Value).Ticks; + for (short i = 0; i < short.MaxValue; i++) { - if (jsonProperty.Value.ValueKind != JsonValueKind.String || !keyValuePairs.TryGetValue(jsonProperty.Name, out segments)) - description = string.Empty; - else - description = segments.Split('|')[0]; - if (!_UseCyclicalForDescription || headerNames.Contains(jsonProperty.Name)) - value = jsonProperty.Value.ToString(); - else - { - list = new List(); - for (int z = 0; z < extractResults.Item3.Length; z++) - list.Add(new object[] { z, extractResults.Item3[z].GetProperty(jsonProperty.Name).ToString() }); - value = list; - } - } - if (_UseCyclicalForDescription) - break; - } - } - - protected static void NestExistingFiles(FileConnectorConfiguration fileConnectorConfiguration) - { - if (!fileConnectorConfiguration.IncludeSubDirectories.Value) - { - string[] matches = GetMatches(fileConnectorConfiguration); - if (matches is not null && matches.Length > 0) - { - string fileName; - string nestedDirectory = Path.Combine(fileConnectorConfiguration.SourceFileLocation, DateTime.Now.Ticks.ToString()); - if (!Directory.Exists(nestedDirectory)) - _ = Directory.CreateDirectory(nestedDirectory); - foreach (string match in matches) - { - fileName = Path.GetFileName(match); - File.Move(match, Path.Combine(nestedDirectory, fileName)); - } + if (!_IsEAFHosted || DateTime.Now.Ticks > breakAfter) + break; + Thread.Sleep(500); } } } - protected static string[] GetMatches(FileConnectorConfiguration fileConnectorConfiguration) + public FileRead(IDescription description, bool isEvent, 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) { - string[] segments; - string[] results = null; - foreach (string subSourceFileFilter in fileConnectorConfiguration.SourceFileFilters) + _SMTP = smtp; + _IsEvent = isEvent; + _DummyRuns = dummyRuns; + _LastTicksDuration = 0; + _StaticRuns = staticRuns; + _IsEAFHosted = isEAFHosted; + _Description = description; + _FileParameter = fileParameter; + _ReportFullPath = string.Empty; + _CellInstanceName = cellInstanceName; + _Calendar = new CultureInfo("en-US").Calendar; + _Log = LogManager.GetLogger(typeof(FileRead)); + _UseCyclicalForDescription = useCyclicalForDescription; + _CellInstanceConnectionName = cellInstanceConnectionName; + _ModelObjectParameterDefinitions = modelObjectParameters; + _FileConnectorConfiguration = fileConnectorConfiguration; + _ParameterizedModelObjectDefinitionType = parameterizedModelObjectDefinitionType; + _IsSourceTimer = fileConnectorConfiguration.SourceFileFilter.StartsWith("*Timer.txt"); + string cellInstanceConnectionNameBase = cellInstanceConnectionName.Replace("-", string.Empty); + _Hyphens = cellInstanceConnectionName.Length - cellInstanceConnectionNameBase.Length; + _TracePath = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "Path.Trace"); + _ExceptionSubject = string.Concat("Exception:", _CellInstanceConnectionName, _FileConnectorConfiguration?.SourceDirectoryCloaking); + string suffix; + string[] segments = _ParameterizedModelObjectDefinitionType.Split('.'); + string @namespace = segments[0]; + string eventNameFileRead = "FileRead"; + string eventName = segments[segments.Length - 1]; + bool isDuplicator = segments[0] == cellInstanceName; + _IsDuplicator = isDuplicator; + _CellInstanceConnectionNameBase = cellInstanceConnectionNameBase; + if (eventName == eventNameFileRead) + suffix = string.Empty; + else + suffix = string.Concat('_', eventName.Split(new string[] { eventNameFileRead }, StringSplitOptions.RemoveEmptyEntries)[1]); + string parameterizedModelObjectDefinitionTypeAppended = string.Concat(@namespace, suffix); + if (!isEAFHosted) { - segments = subSourceFileFilter.Split('\\'); - if (fileConnectorConfiguration.IncludeSubDirectories.Value) - results = Directory.GetFiles(fileConnectorConfiguration.SourceFileLocation, segments.Last(), SearchOption.AllDirectories); - else - results = Directory.GetFiles(fileConnectorConfiguration.SourceFileLocation, segments.Last(), SearchOption.TopDirectoryOnly); - if (results.Length != 0) - break; + if (string.IsNullOrEmpty(equipmentTypeName) || equipmentTypeName != parameterizedModelObjectDefinitionTypeAppended) + throw new Exception(cellInstanceConnectionName); + if (string.IsNullOrEmpty(equipmentDictionaryName) && isEvent) + throw new Exception(cellInstanceConnectionName); + if (!string.IsNullOrEmpty(equipmentDictionaryName) && !isEvent && connectionCount > 1) + throw new Exception(cellInstanceConnectionName); + // if (string.IsNullOrEmpty(equipmentDictionaryName) && !isEvent) + // throw new Exception(cellInstanceConnectionName); + // if (!string.IsNullOrEmpty(equipmentDictionaryName) && isEvent) + // throw new Exception(cellInstanceConnectionName); } - return results; - } - - protected Tuple> ReExtract(IFileRead fileRead, List headerNames, Dictionary keyValuePairs) - { - Tuple> results; - if (!Directory.Exists(_FileConnectorConfiguration.SourceFileLocation)) - results = null; + if (isDuplicator) + _MesEntity = string.Empty; + else + _MesEntity = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, string.Concat("CellInstance.", cellInstanceName, ".Alias")); + _EventName = eventName; + _EventNameFileRead = eventNameFileRead; + _EquipmentType = parameterizedModelObjectDefinitionTypeAppended; + long breakAfterSeconds; + if (_FileConnectorConfiguration is null) + breakAfterSeconds = 360; else { - string[] matches = GetMatches(_FileConnectorConfiguration); - if (matches is null || matches.Length == 0) - results = null; + if (_FileConnectorConfiguration.FileScanningOption == FileConnectorConfiguration.FileScanningOptionEnum.TimeBased) + breakAfterSeconds = Math.Abs(_FileConnectorConfiguration.FileHandleTimeout.Value); + else if (_FileConnectorConfiguration.FileScanningOption == FileConnectorConfiguration.FileScanningOptionEnum.FileWatcher) + breakAfterSeconds = Math.Abs(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value); else - { - _ReportFullPath = matches[0]; - results = fileRead.GetExtractResult(_ReportFullPath, _EventName); - if (!_IsEAFHosted) - TriggerEvents(results, headerNames, keyValuePairs); - } - } - return results; - } - - protected static List GetDuplicatorDescriptions(JsonElement[] jsonElements) - { - List results = new(); - Duplicator.Description description; - JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString }; - foreach (JsonElement jsonElement in jsonElements) - { - if (jsonElement.ValueKind != JsonValueKind.Object) throw new Exception(); - description = JsonSerializer.Deserialize(jsonElement.ToString(), jsonSerializerOptions); - results.Add(description); } - return results; + _BreakAfterSeconds = breakAfterSeconds; + UpdateLastTicksDuration(breakAfterSeconds * 10000000); + if (_IsDuplicator) + { + if (string.IsNullOrEmpty(_FileConnectorConfiguration.TargetFileLocation) || string.IsNullOrEmpty(_FileConnectorConfiguration.ErrorTargetFileLocation)) + throw new Exception("_Configuration is empty?"); + if (_FileConnectorConfiguration.TargetFileLocation.Contains('%') || _FileConnectorConfiguration.ErrorTargetFileLocation.Contains('%')) + throw new Exception("_Configuration is incorrect for a duplicator!"); + // if (_FileConnectorConfiguration is not null) + // { + // if (string.IsNullOrEmpty(_FileConnectorConfiguration.SourceDirectoryCloaking)) + // throw new Exception("SourceDirectoryCloaking is empty?"); + // if (!_FileConnectorConfiguration.SourceDirectoryCloaking.StartsWith("~")) + // throw new Exception("SourceDirectoryCloaking is incorrect for a duplicator!"); + // } + } } - private void Shared1880(string itemFile, List directories, FileInfo sourceFile, bool isErrorFile) + protected static string GetPropertyValue(string cellInstanceConnectionName, IList modelObjectParameters, string propertyName) { - string itemDirectory; - directories.Add(Path.GetDirectoryName(sourceFile.FullName)); - itemDirectory = Path.GetDirectoryName(itemFile); - FileConnectorConfiguration.PostProcessingModeEnum processingModeEnum; - if (!isErrorFile) - processingModeEnum = _FileConnectorConfiguration.PostProcessingMode.Value; - else - processingModeEnum = _FileConnectorConfiguration.ErrorPostProcessingMode.Value; - if (processingModeEnum != FileConnectorConfiguration.PostProcessingModeEnum.Delete && !Directory.Exists(itemDirectory)) - { - _ = Directory.CreateDirectory(itemDirectory); - FileInfo fileInfo = new(_Logistics.ReportFullPath); - Directory.SetCreationTime(itemDirectory, fileInfo.LastWriteTime); - } - if (_IsEAFHosted) - { - switch (processingModeEnum) - { - case FileConnectorConfiguration.PostProcessingModeEnum.Move: - File.Move(sourceFile.FullName, itemFile); - break; - case FileConnectorConfiguration.PostProcessingModeEnum.Copy: - File.Copy(sourceFile.FullName, itemFile); - break; - case FileConnectorConfiguration.PostProcessingModeEnum.Delete: - File.Delete(sourceFile.FullName); - break; - default: - throw new Exception(); - } - } + string result; + List results = (from l in modelObjectParameters where l.Name == propertyName select l.Value).ToList(); + if (results.Count != 1) + throw new Exception(cellInstanceConnectionName); + result = results[0]; + return result; + } + + protected void UpdateLastTicksDuration(long ticksDuration) + { + if (ticksDuration < 50000000) + ticksDuration = 50000000; + _LastTicksDuration = (long)Math.Ceiling(ticksDuration * .667); + _Log.Info($"{new TimeSpan(ticksDuration).TotalMilliseconds} TotalMillisecond(s) to process{Environment.NewLine}{_CellInstanceConnectionName}{Environment.NewLine}<{_ReportFullPath}>"); + } + + internal static string GetParentParent(string value) + { + string result = Path.GetDirectoryName(Path.GetDirectoryName(value)); + return result; } internal static List GetDirectoryNames(string directory) @@ -635,6 +352,326 @@ public class FileRead : Properties.IFileRead #nullable disable } + internal static string GetJobIdParentDirectory(string directory) + { + string result; + if (!string.IsNullOrEmpty(Path.GetFileName(directory))) + result = Path.GetFullPath(GetParentParent(directory)); + else + result = Path.GetFullPath(GetParentParent(Path.GetDirectoryName(directory))); + if (!Directory.Exists(result)) + _ = Directory.CreateDirectory(result); + return result; + } + + internal static string GetFileNameAfterUnderscoreSplit(string reportFullPath) + { + string result; + string[] segments = Path.GetFileNameWithoutExtension(reportFullPath).Split('_'); + if (segments.Length <= 2) + result = segments[0]; + else + result = string.Concat(segments[0], segments[2]); + return result; + } + + internal string[] GetInProcessDirectory(string jobIdDirectory) + { + List results = new(); + if (!_IsEAFHosted) + results = new string[] { jobIdDirectory }.ToList(); + else + { + string[] files; + string logisticsSequence = _Logistics.Sequence.ToString(); + string[] directories = Directory.GetDirectories(jobIdDirectory, $"*{logisticsSequence}*", SearchOption.TopDirectoryOnly); + foreach (string directory in directories) + { + files = Directory.GetFiles(directory, "*", SearchOption.TopDirectoryOnly); + if (files.Length == 0) + continue; + results.Add(directory); + } + } + if ((results is null) || results.Count != 1) + throw new Exception("Didn't find directory by logistics sequence"); + return results.ToArray(); + } + + protected static string[] GetMatches(FileConnectorConfiguration fileConnectorConfiguration) + { + string[] segments; + string[] results = null; + foreach (string subSourceFileFilter in fileConnectorConfiguration.SourceFileFilters) + { + segments = subSourceFileFilter.Split('\\'); + if (fileConnectorConfiguration.IncludeSubDirectories.Value) + results = Directory.GetFiles(fileConnectorConfiguration.SourceFileLocation, segments.Last(), SearchOption.AllDirectories); + else + results = Directory.GetFiles(fileConnectorConfiguration.SourceFileLocation, segments.Last(), SearchOption.TopDirectoryOnly); + if (results.Length != 0) + break; + } + return results; + } + + protected static void NestExistingFiles(FileConnectorConfiguration fileConnectorConfiguration) + { + // if (!fileConnectorConfiguration.IncludeSubDirectories.Value && fileConnectorConfiguration.TriggerOnCreated is not null && fileConnectorConfiguration.TriggerOnCreated.Value) + if (!fileConnectorConfiguration.IncludeSubDirectories.Value) + { + string[] matches = GetMatches(fileConnectorConfiguration); + if (matches is not null && matches.Length > 0) + { + string fileName; + string nestedDirectory = Path.Combine(fileConnectorConfiguration.SourceFileLocation, DateTime.Now.Ticks.ToString()); + if (!Directory.Exists(nestedDirectory)) + _ = Directory.CreateDirectory(nestedDirectory); + foreach (string match in matches) + { + fileName = Path.GetFileName(match); + File.Move(match, Path.Combine(nestedDirectory, fileName)); + } + } + } + } + + protected static List GetDuplicatorDescriptions(JsonElement[] jsonElements) + { + List results = new(); + Duplicator.Description description; + JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString }; + foreach (JsonElement jsonElement in jsonElements) + { + if (jsonElement.ValueKind != JsonValueKind.Object) + throw new Exception(); + description = JsonSerializer.Deserialize(jsonElement.ToString(), jsonSerializerOptions); + results.Add(description); + } + return results; + } + + protected static ModelObjectParameterDefinition[] GetProperties(string cellInstanceConnectionName, IList modelObjectParameters, string propertyNamePrefix) + { + ModelObjectParameterDefinition[] results = (from l in modelObjectParameters where l.Name.StartsWith(propertyNamePrefix) select l).ToArray(); + if (results.Length == 0) + throw new Exception(cellInstanceConnectionName); + return results; + } + + protected static ModelObjectParameterDefinition[] GetProperties(string cellInstanceConnectionName, IList modelObjectParameters, string propertyNamePrefix, string propertyNameSuffix) + { + ModelObjectParameterDefinition[] results = (from l in modelObjectParameters where l.Name.StartsWith(propertyNamePrefix) && l.Name.EndsWith(propertyNameSuffix) select l).ToArray(); + if (results.Length == 0) + throw new Exception(cellInstanceConnectionName); + return results; + } + + protected void SetFileParameter(string key, string value) + { + if (_FileConnectorConfiguration is null || _FileConnectorConfiguration.TargetFileLocation.Contains(string.Concat("%", key, "%")) || _FileConnectorConfiguration.ErrorTargetFileLocation.Contains(string.Concat("%", key, "%")) || _FileConnectorConfiguration.TargetFileName.Contains(string.Concat("%", key, "%")) || _FileConnectorConfiguration.ErrorTargetFileName.Contains(string.Concat("%", key, "%"))) + { + if (_FileParameter.ContainsKey(key)) + _FileParameter[key] = value; + else + _FileParameter.Add(key, value); + } + } + + protected void WritePDSF(IFileRead fileRead, JsonElement[] jsonElements) + { + string directory; + string day = $"{_Logistics.DateTimeFromSequence:yyyy-MM-dd}"; + string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); + string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}"; + if (!_CellInstanceConnectionName.StartsWith(_CellInstanceName) && _CellInstanceConnectionNameBase == _EquipmentType) + directory = Path.Combine(_TracePath, _EquipmentType, "Target", weekDirectory, day, _CellInstanceName, _CellInstanceConnectionName); + else + directory = Path.Combine(_TracePath, _EquipmentType, "Source", weekDirectory, day, _CellInstanceName, _CellInstanceConnectionName); + if (!Directory.Exists(directory)) + _ = Directory.CreateDirectory(directory); + string file = Path.Combine(directory, string.Concat(_Logistics.MesEntity, "_", _Logistics.Sequence, ".ipdsf")); + string lines = ProcessDataStandardFormat.GetPDSFText(fileRead, _Logistics, jsonElements, logisticsText: string.Empty); + File.WriteAllText(file, lines); + if (_Logistics.TotalSecondsSinceLastWriteTimeFromSequence > 600) + { + try + { File.SetLastWriteTime(file, _Logistics.DateTimeFromSequence); } + catch (Exception) { } + } + } + + protected void WaitForThread(Thread thread, List threadExceptions) + { + if (thread is not null) + { + ThreadState threadState; + for (short i = 0; i < short.MaxValue; i++) + { + if (thread is null) + break; + else + { + threadState = thread.ThreadState; + if (threadState is not ThreadState.Running and not ThreadState.WaitSleepJoin) + break; + } + Thread.Sleep(500); + } + lock (threadExceptions) + { + if (threadExceptions.Count != 0) + { + foreach (Exception item in threadExceptions) + _Log.Error(string.Concat(item.Message, Environment.NewLine, Environment.NewLine, item.StackTrace)); + Exception exception = threadExceptions[0]; + threadExceptions.Clear(); + throw exception; + } + } + } + } + + protected void Move(Tuple> extractResults) + { + if (!_IsEAFHosted) + { + string to; + if (!_FileConnectorConfiguration.TargetFileLocation.EndsWith(Path.DirectorySeparatorChar.ToString())) + to = _FileConnectorConfiguration.TargetFileLocation; + else + to = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation); + foreach (KeyValuePair keyValuePair in _FileParameter) + to = to.Replace(string.Concat('%', keyValuePair.Key, '%'), keyValuePair.Value); + if (to.Contains('%')) + _Log.Debug("Can't debug without EAF Hosting"); + else + _ = Move(extractResults, to, _FileConnectorConfiguration.SourceFileLocation, resolvedFileLocation: string.Empty, exception: null); + } + } + + protected string[] Move(Tuple> extractResults, string to, string from, string resolvedFileLocation, Exception exception) + { + string[] results; + bool isErrorFile = exception is not null; + if (!to.EndsWith(@"\")) + _ = string.Concat(to, @"\"); + if (!isErrorFile) + results = Array.Empty(); + else + { + results = new string[] { _Logistics.Sequence.ToString(), _Logistics.ReportFullPath, from, resolvedFileLocation, to, string.Empty, string.Empty, exception.Message, string.Empty, string.Empty, exception.StackTrace }; + if (!_IsDuplicator) + WriteAllLines(to, results); + } + if (extractResults is not null && extractResults.Item4 is not null && extractResults.Item4.Count != 0) + { + string itemFile; + List directories = new(); + foreach (FileInfo sourceFile in extractResults.Item4) + { + if (sourceFile.FullName != _Logistics.ReportFullPath) + { + itemFile = sourceFile.FullName.Replace(from, to); + Shared1880(itemFile, directories, sourceFile, isErrorFile); + } + else if (!isErrorFile && _Logistics is not null) + Shared1811(to, sourceFile); + } + Shared0231(directories); + } + return results; + } + + private void WriteAllLines(string to, string[] exceptionLines) + { + string fileName = string.Concat(to, @"\readme.txt"); + try + { + if (!Directory.Exists(to)) + _ = Directory.CreateDirectory(to); + File.WriteAllLines(fileName, exceptionLines); + } + catch (Exception ex) { _Log.Error(ex.Message); } + } + + private void Shared1880(string itemFile, List directories, FileInfo sourceFile, bool isErrorFile) + { + string itemDirectory; + directories.Add(Path.GetDirectoryName(sourceFile.FullName)); + itemDirectory = Path.GetDirectoryName(itemFile); + FileConnectorConfiguration.PostProcessingModeEnum processingModeEnum; + if (!isErrorFile) + processingModeEnum = _FileConnectorConfiguration.PostProcessingMode.Value; + else + processingModeEnum = _FileConnectorConfiguration.ErrorPostProcessingMode.Value; + if (processingModeEnum != FileConnectorConfiguration.PostProcessingModeEnum.Delete && !Directory.Exists(itemDirectory)) + { + _ = Directory.CreateDirectory(itemDirectory); + FileInfo fileInfo = new(_Logistics.ReportFullPath); + Directory.SetCreationTime(itemDirectory, fileInfo.LastWriteTime); + } + if (_IsEAFHosted) + { + switch (processingModeEnum) + { + case FileConnectorConfiguration.PostProcessingModeEnum.Move: + File.Move(sourceFile.FullName, itemFile); + break; + case FileConnectorConfiguration.PostProcessingModeEnum.Copy: + File.Copy(sourceFile.FullName, itemFile); + break; + case FileConnectorConfiguration.PostProcessingModeEnum.Delete: + File.Delete(sourceFile.FullName); + break; + case FileConnectorConfiguration.PostProcessingModeEnum.None: + File.Move(sourceFile.FullName, itemFile); + break; + default: + throw new Exception(); + } + } + } + + private void Shared1811(string to, FileInfo sourceFile) + { + if (!_IsDuplicator && _FileConnectorConfiguration.SourceFileFilter != "*" && sourceFile.Exists && sourceFile.Length < _MinFileLength) + { + string directoryName = Path.GetFileName(to); + string jobIdDirectory = GetJobIdDirectory(to); + DateTime dateTime = DateTime.Now.AddMinutes(-15); + string day = $"{_Logistics.DateTimeFromSequence:yyyy-MM-dd}"; + string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); + string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}"; + string destinationDirectory = Path.Combine(jobIdDirectory, "_ Ignore 100 bytes", weekDirectory, day, directoryName); + if (!Directory.Exists(destinationDirectory)) + _ = Directory.CreateDirectory(destinationDirectory); + File.Move(sourceFile.FullName, string.Concat(destinationDirectory, @"\", sourceFile.Name)); + try + { + string[] checkDirectories = Directory.GetDirectories(jobIdDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string checkDirectory in checkDirectories) + { + if (!checkDirectory.Contains('_')) + continue; + if (Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly).Length != 0) + continue; + if (Directory.GetFiles(checkDirectory, "*", SearchOption.TopDirectoryOnly).Length != 0) + continue; + if (Directory.GetDirectories(checkDirectory, "*", SearchOption.AllDirectories).Length != 0) + continue; + if (Directory.GetFiles(checkDirectory, "*", SearchOption.AllDirectories).Length != 0) + continue; + if (new DirectoryInfo(checkDirectory).CreationTime > dateTime) + continue; + Directory.Delete(checkDirectory, recursive: false); + } + } + catch (Exception) { throw; } + DeleteEmptyTopDirectories(jobIdDirectory); + } + } + private string GetJobIdDirectory(string path) { string result; @@ -680,44 +717,6 @@ public class FileRead : Properties.IFileRead } } - private void Shared1811(string to, FileInfo sourceFile) - { - if (!_IsDuplicator && _FileConnectorConfiguration.SourceFileFilter != "*" && sourceFile.Exists && sourceFile.Length < _MinFileLength) - { - string directoryName = Path.GetFileName(to); - string jobIdDirectory = GetJobIdDirectory(to); - DateTime dateTime = DateTime.Now.AddMinutes(-15); - string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); - string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}{@"\"}{_Logistics.DateTimeFromSequence:yyyy-MM-dd}"; - string destinationDirectory = Path.Combine(jobIdDirectory, "_ Ignore 100 bytes", weekDirectory, directoryName); - if (!Directory.Exists(destinationDirectory)) - _ = Directory.CreateDirectory(destinationDirectory); - File.Move(sourceFile.FullName, string.Concat(destinationDirectory, @"\", sourceFile.Name)); - try - { - string[] checkDirectories = Directory.GetDirectories(jobIdDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string checkDirectory in checkDirectories) - { - if (!checkDirectory.Contains('_')) - continue; - if (Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly).Length != 0) - continue; - if (Directory.GetFiles(checkDirectory, "*", SearchOption.TopDirectoryOnly).Length != 0) - continue; - if (Directory.GetDirectories(checkDirectory, "*", SearchOption.AllDirectories).Length != 0) - continue; - if (Directory.GetFiles(checkDirectory, "*", SearchOption.AllDirectories).Length != 0) - continue; - if (new DirectoryInfo(checkDirectory).CreationTime > dateTime) - continue; - Directory.Delete(checkDirectory, recursive: false); - } - } - catch (Exception) { throw; } - DeleteEmptyTopDirectories(jobIdDirectory); - } - } - private void Shared0231(List directories) { if (_FileConnectorConfiguration.PostProcessingMode != FileConnectorConfiguration.PostProcessingModeEnum.Copy) @@ -730,66 +729,81 @@ public class FileRead : Properties.IFileRead } } - protected void WaitForFileConsumption(DateTime dateTime, List descriptions, bool isDummyRun, string successDirectory, string duplicateDirectory, List<(Properties.IScopeInfo, string)> collection, string duplicateFile) where T : Properties.IDescription + protected void SetFileParameterLotID(string value, bool includeLogisticsSequence = true) { - if (!isDummyRun && _IsEAFHosted) - WaitForFileConsumption(_FileConnectorConfiguration.SourceDirectoryCloaking, _Logistics, dateTime, descriptions, successDirectory, duplicateDirectory, duplicateFile, collection); + string key; + if (!includeLogisticsSequence) + key = "LotID"; else { - long breakAfter = DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileHandleWaitTime.Value).Ticks; - for (short i = 0; i < short.MaxValue; i++) + key = "LotIDWithLogisticsSequence"; + value = string.Concat(value, "_", _Logistics.Sequence, "_", DateTime.Now.Ticks - _Logistics.Sequence); + } + SetFileParameter(key, value); + } + + protected void SetFileParameterLotIDToLogisticsMID(bool includeLogisticsSequence = true) + { + string key; + if (!includeLogisticsSequence) + key = "LotID"; + else + key = "LotIDWithLogisticsSequence"; + string value = string.Concat(_Logistics.MID, "_", _Logistics.Sequence, "_", DateTime.Now.Ticks - _Logistics.Sequence); + SetFileParameter(key, value); + } + + protected Tuple> ReExtract(IFileRead fileRead, List headerNames, Dictionary keyValuePairs) + { + Tuple> results; + if (!Directory.Exists(_FileConnectorConfiguration.SourceFileLocation)) + results = null; + else + { + string[] matches = GetMatches(_FileConnectorConfiguration); + if (matches is null || matches.Length == 0) + results = null; + else { - if (!_IsEAFHosted || DateTime.Now.Ticks > breakAfter) - break; - Thread.Sleep(500); + _ReportFullPath = matches[0]; + results = fileRead.GetExtractResult(_ReportFullPath, _EventName); + if (!_IsEAFHosted) + TriggerEvents(results, headerNames, keyValuePairs); } } - } - - internal static string GetJobIdParentDirectory(string directory) - { - string result; - if (!string.IsNullOrEmpty(Path.GetFileName(directory))) - result = Path.GetFullPath(GetParentParent(directory)); - else - result = Path.GetFullPath(GetParentParent(Path.GetDirectoryName(directory))); - if (!Directory.Exists(result)) - _ = Directory.CreateDirectory(result); - return result; - } - - internal string[] GetInProcessDirectory(string jobIdDirectory) - { - string[] results; - if (!_IsEAFHosted) - results = new string[] { jobIdDirectory }; - else - { - string logisticsSequence = _Logistics.Sequence.ToString(); - results = Directory.GetDirectories(jobIdDirectory, string.Concat(_Logistics.MID, '*', logisticsSequence, '*'), SearchOption.TopDirectoryOnly); - } - if ((results is null) || results.Length != 1) - throw new Exception("Didn't find directory by logistics sequence"); return results; } - internal static string GetFileNameAfterUnderscoreSplit(string reportFullPath) + protected void TriggerEvents(Tuple> extractResults, List headerNames, Dictionary keyValuePairs) { - string result; - string[] segments = Path.GetFileNameWithoutExtension(reportFullPath).Split('_'); - if (segments.Length <= 2) - result = segments[0]; - else - result = string.Concat(segments[0], segments[2]); - return result; - } - - internal static string GetParentParent(string value) - { - string result = Path.GetDirectoryName(Path.GetDirectoryName(value)); - return result; + object value; + string segments; + string description; + List list; + for (int i = 0; i < extractResults.Item3.Length; i++) + { + _Log.Debug(string.Concat("TriggerEvent - {", _Logistics.ReportFullPath, "} ", i, " of ", extractResults.Item3.Length)); + foreach (JsonProperty jsonProperty in extractResults.Item3[i].EnumerateObject()) + { + if (jsonProperty.Value.ValueKind != JsonValueKind.String || !keyValuePairs.TryGetValue(jsonProperty.Name, out segments)) + description = string.Empty; + else + description = segments.Split('|')[0]; + if (!_UseCyclicalForDescription || headerNames.Contains(jsonProperty.Name)) + value = jsonProperty.Value.ToString(); + else + { + list = new List(); + for (int z = 0; z < extractResults.Item3.Length; z++) + list.Add(new object[] { z, extractResults.Item3[z].GetProperty(jsonProperty.Name).ToString() }); + value = list; + } + } + if (_UseCyclicalForDescription) + break; + } } } -// 2022-06-08 -> Shared - FileRead \ No newline at end of file +// 2025-03-25 -> Shared - FileRead \ No newline at end of file diff --git a/Adaptation/Shared/Logistics.cs b/Adaptation/Shared/Logistics.cs index cb1f805..4f187f8 100644 --- a/Adaptation/Shared/Logistics.cs +++ b/Adaptation/Shared/Logistics.cs @@ -35,6 +35,9 @@ public class Logistics : ILogistics public long Sequence => _Sequence; public double TotalSecondsSinceLastWriteTimeFromSequence => _TotalSecondsSinceLastWriteTimeFromSequence; + private static string DefaultMesEntity(DateTime dateTime) => + string.Concat(dateTime.Ticks, "_MES_ENTITY"); + public Logistics(IFileRead fileRead) { DateTime dateTime = DateTime.Now; @@ -84,13 +87,13 @@ public class Logistics : ILogistics _Logistics2 = new List(); } - public Logistics(string reportFullPath, string logistics) + internal Logistics(string reportFullPath, ProcessDataStandardFormat processDataStandardFormat) { string key; DateTime dateTime; string[] segments; _FileInfo = new(reportFullPath); - _Logistics1 = logistics.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList(); + _Logistics1 = processDataStandardFormat.Logistics.ToList(); if (Logistics1.Count == 0 || !Logistics1[0].StartsWith("LOGISTICS_1")) { _NullData = null; @@ -190,8 +193,6 @@ public class Logistics : ILogistics } } - private static string DefaultMesEntity(DateTime dateTime) => string.Concat(dateTime.Ticks, "_MES_ENTITY"); - internal void Update(string mid, string processJobID) { _MID = mid; diff --git a/Adaptation/Shared/Metrology/WS.Attachment.cs b/Adaptation/Shared/Metrology/WS.Attachment.cs index 8edb116..0a7950e 100644 --- a/Adaptation/Shared/Metrology/WS.Attachment.cs +++ b/Adaptation/Shared/Metrology/WS.Attachment.cs @@ -6,23 +6,25 @@ public partial class WS public class Attachment { - public string SubGroupId { get; set; } - public long HeaderId { get; set; } - public string HeaderIdDirectory { get; set; } - public string UniqueId { get; set; } - public string DestinationFileName { get; set; } - public string SourceFileName { get; set; } - public string AttachmentId { get; set; } +#nullable enable - public Attachment(string subGroupId, long headerId, string headerIdDirectory, string uniqueId, string destinationFileName, string sourceFileName) + public long HeaderId { get; set; } + public string UniqueId { get; set; } + public string SubGroupId { get; set; } + public string AttachmentId { get; set; } + public string SourceFileName { get; set; } + public string HeaderIdDirectory { get; set; } + public string DestinationFileName { get; set; } + + public Attachment(Results? results, string headerIdDirectory, string uniqueId, string destinationFileName, string sourceFileName) { - SubGroupId = subGroupId; - HeaderId = headerId; - HeaderIdDirectory = headerIdDirectory; UniqueId = uniqueId; - DestinationFileName = destinationFileName; SourceFileName = sourceFileName; + HeaderIdDirectory = headerIdDirectory; + DestinationFileName = destinationFileName; AttachmentId = System.Guid.NewGuid().ToString(); + HeaderId = results?.HeaderId is null ? -1 : results.HeaderId.Value; + SubGroupId = results?.SubgroupId is null ? string.Empty : results.SubgroupId.Value.ToString(); } } diff --git a/Adaptation/Shared/Metrology/WS.Results.cs b/Adaptation/Shared/Metrology/WS.Results.cs index 2d1c603..07685a3 100644 --- a/Adaptation/Shared/Metrology/WS.Results.cs +++ b/Adaptation/Shared/Metrology/WS.Results.cs @@ -1,27 +1,75 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; namespace Adaptation.Shared.Metrology; public partial class WS { - // this class represents the response from the Inbound API endpoint + public class Results { - // true or false if data was written to the database - public bool Success { get; set; } - // if true, contains ID of the Header record in the database - public long HeaderID { get; set; } +#nullable enable - // if false, this collection will contain a list of errors - public List Errors { get; set; } + [JsonConstructor] + public Results(List? errors, + long? headerId, + long? subgroupId, + bool? success, + List? warnings) + { + Errors = errors; + Success = success; + HeaderId = headerId; + Warnings = warnings; + SubgroupId = subgroupId; + } - // this collection will contain a list of warnings, they will not prevent data from being saved - public List Warnings { get; set; } + [JsonPropertyName("errors")] public List? Errors { get; set; } + [JsonPropertyName("headerID")] public long? HeaderId { get; set; } + [JsonPropertyName("subgroupId")] public long? SubgroupId { get; set; } + [JsonPropertyName("success")] public bool? Success { get; set; } + [JsonPropertyName("warnings")] public List? Warnings { get; set; } + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, ResultsSourceGenerationContext.Default.Results); + return result; + } + + internal static Results Get(Results results, long? subgroupId) => + new(results.Errors, results.HeaderId, subgroupId, results.Success, results.Warnings); + + internal static Results Get(string resultsJson, Exception e) + { + Results results; + Exception? exception = e; + List errors = new(); + StringBuilder stringBuilder = new(); + while (exception is not null) + { + _ = stringBuilder.AppendLine(exception.Message); + exception = exception.InnerException; + } + errors.Add(resultsJson); + errors.Add(stringBuilder.ToString()); + results = new(errors: errors, + headerId: null, + subgroupId: null, + success: false, + warnings: new()); + return results; + } - // this is just a helper function to make displaying the results easier - public override string ToString() => JsonSerializer.Serialize(this, GetType()); } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(WS.Results))] +internal partial class ResultsSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Adaptation/Shared/Metrology/WS.cs b/Adaptation/Shared/Metrology/WS.cs index c49e61d..b7666db 100644 --- a/Adaptation/Shared/Metrology/WS.cs +++ b/Adaptation/Shared/Metrology/WS.cs @@ -10,9 +10,11 @@ namespace Adaptation.Shared.Metrology; public partial class WS { +#nullable enable + public static (string, Results) SendData(string url, long sequence, string directory, object payload, int timeoutSeconds = 120) { - Results results = new(); + Results? wsResults = null; string resultsJson = string.Empty; try { @@ -30,29 +32,20 @@ public partial class WS }; HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).Result; resultsJson = httpResponseMessage.Content.ReadAsStringAsync().Result; - results = JsonSerializer.Deserialize(resultsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - string checkDirectory = Path.Combine(directory, $"-{results.HeaderID}"); + wsResults = JsonSerializer.Deserialize(resultsJson, ResultsSourceGenerationContext.Default.Results); + if (wsResults is null) + throw new NullReferenceException(nameof(wsResults)); + string checkDirectory = Path.Combine(directory, $"-{wsResults.HeaderId}"); if (!Directory.Exists(checkDirectory)) _ = Directory.CreateDirectory(checkDirectory); File.WriteAllText(Path.Combine(checkDirectory, $"{sequence}.json"), json); } - if (!results.Success) - results.Errors.Add(results.ToString()); + if (wsResults.Success is null || !wsResults.Success.Value) + wsResults.Errors?.Add(wsResults.ToString()); } catch (Exception e) - { - Exception exception = e; - StringBuilder stringBuilder = new(); - while (exception is not null) - { - _ = stringBuilder.AppendLine(exception.Message); - exception = exception.InnerException; - } - results.Errors ??= new List(); - results.Errors.Add(resultsJson); - results.Errors.Add(stringBuilder.ToString()); - } - return new(resultsJson, results); + { wsResults ??= Results.Get(resultsJson, e); } + return new(resultsJson, wsResults); } public static void AttachFile(string url, Attachment attachment, int timeoutSeconds = 60) @@ -69,16 +62,20 @@ public partial class WS } } - public static void AttachFiles(string url, List headerAttachments = null, List dataAttachments = null) + public static void AttachFiles(string url, List? headerAttachments = null, List? dataAttachments = null) { string directory; try { + string? directoryName; if (headerAttachments is not null) { foreach (Attachment attachment in headerAttachments) { - directory = Path.Combine(Path.GetDirectoryName(attachment.HeaderIdDirectory), attachment.AttachmentId) ?? throw new Exception(); + directoryName = Path.GetDirectoryName(attachment.HeaderIdDirectory); + if (string.IsNullOrEmpty(directoryName)) + continue; + directory = Path.Combine(directoryName, attachment.AttachmentId) ?? throw new Exception(); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); @@ -88,7 +85,10 @@ public partial class WS { foreach (Attachment attachment in dataAttachments) { - directory = Path.Combine(Path.GetDirectoryName(attachment.HeaderIdDirectory.Replace("Header", "Data")), attachment.AttachmentId) ?? throw new Exception(); + directoryName = Path.GetDirectoryName(attachment.HeaderIdDirectory.Replace("Header", "Data")); + if (string.IsNullOrEmpty(directoryName)) + continue; + directory = Path.Combine(directoryName, attachment.AttachmentId) ?? throw new Exception(); if (!Directory.Exists(directory)) _ = Directory.CreateDirectory(directory); File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); @@ -108,7 +108,7 @@ public partial class WS } catch (Exception e) { - Exception exception = e; + Exception? exception = e; StringBuilder stringBuilder = new(); while (exception is not null) { diff --git a/Adaptation/Shared/ProcessDataStandardFormat.cs b/Adaptation/Shared/ProcessDataStandardFormat.cs index b2ca7b6..a86241d 100644 --- a/Adaptation/Shared/ProcessDataStandardFormat.cs +++ b/Adaptation/Shared/ProcessDataStandardFormat.cs @@ -1,18 +1,22 @@ using Adaptation.Shared.Methods; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; namespace Adaptation.Shared; -public class ProcessDataStandardFormat +#nullable enable + +internal class ProcessDataStandardFormat { - public enum SearchFor + internal enum SearchFor { EquipmentIntegration = 1, BusinessIntegration = 2, @@ -20,325 +24,47 @@ public class ProcessDataStandardFormat Archive = 4 } - public static string GetPDSFText(IFileRead fileRead, Logistics logistics, JsonElement[] jsonElements, string logisticsText) + internal long? Sequence { get; private set; } + internal ReadOnlyCollection Body { get; private set; } + internal ReadOnlyCollection Footer { get; private set; } + internal ReadOnlyCollection Header { get; private set; } + internal ReadOnlyCollection Columns { get; private set; } + internal ProcessDataStandardFormat? InputPDSF { get; private set; } + internal ReadOnlyCollection Logistics { get; private set; } + + internal ProcessDataStandardFormat(ReadOnlyCollection body, + ReadOnlyCollection columns, + ReadOnlyCollection footer, + ReadOnlyCollection header, + ProcessDataStandardFormat? inputPDSF, + ReadOnlyCollection logistics, + long? sequence) { - string result; - if (jsonElements.Length == 0) - result = string.Empty; - else - { - int columns = 0; - List lines; - string endOffset = "E#######T"; - string dataOffset = "D#######T"; - string headerOffset = "H#######T"; - string format = "MM/dd/yyyy HH:mm:ss"; - StringBuilder stringBuilder = new(); - lines = new string[] { "HEADER_TAG\tHEADER_VALUE", "FORMAT\t2.00", "NUMBER_PASSES\t0001", string.Concat("HEADER_OFFSET\t", headerOffset), string.Concat("DATA_OFFSET\t", dataOffset), string.Concat("END_OFFSET\t", endOffset) }.ToList(); - _ = stringBuilder.Append("\"Time\"").Append('\t'); - _ = stringBuilder.Append("\"A_LOGISTICS\"").Append('\t'); - _ = stringBuilder.Append("\"B_LOGISTICS\"").Append('\t'); - for (int i = 0; i < jsonElements.Length;) - { - foreach (JsonProperty jsonProperty in jsonElements[0].EnumerateObject()) - { - columns += 1; - _ = stringBuilder.Append('"').Append(jsonProperty.Name).Append('"').Append('\t'); - } - break; - } - _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); - lines.Add(stringBuilder.ToString()); - for (int i = 0; i < jsonElements.Length; i++) - { - _ = stringBuilder.Clear(); - _ = stringBuilder.Append("0.1").Append('\t'); - _ = stringBuilder.Append('1').Append('\t'); - _ = stringBuilder.Append('2').Append('\t'); - foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject()) - _ = stringBuilder.Append(jsonProperty.Value).Append('\t'); - _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); - lines.Add(stringBuilder.ToString()); - } - lines.Add(string.Concat("NUM_DATA_ROWS ", jsonElements.Length.ToString().PadLeft(9, '0'))); - lines.Add(string.Concat("NUM_DATA_COLUMNS ", (columns + 3).ToString().PadLeft(9, '0'))); - lines.Add("DELIMITER ;"); - lines.Add(string.Concat("START_TIME_FORMAT ", format)); - lines.Add(string.Concat("START_TIME ", logistics.DateTimeFromSequence.ToString(format))); //12/26/2019 15:22:44 - lines.Add(string.Concat("LOGISTICS_COLUMN", '\t', "A_LOGISTICS")); - lines.Add(string.Concat("LOGISTICS_COLUMN", '\t', "B_LOGISTICS")); - if (!string.IsNullOrEmpty(logisticsText)) - lines.Add(logisticsText); - else - { - lines.Add(string.Concat("LOGISTICS_1", '\t', "A_CHAMBER=;A_INFO=", fileRead.EventName, ";A_INFO2=", fileRead.EquipmentType, ";A_JOBID=", fileRead.CellInstanceName, ";A_MES_ENTITY=", fileRead.MesEntity, ";A_MID=", logistics.MID, ";A_NULL_DATA=", fileRead.NullData, ";A_PPID=NO_PPID;A_PROCESS_JOBID=", logistics.ProcessJobID, ";A_PRODUCT=;A_SEQUENCE=", logistics.Sequence, ";A_WAFER_ID=;")); - lines.Add(string.Concat("LOGISTICS_2", '\t', "B_CHAMBER=;B_INFO=", fileRead.EventName, ";B_INFO2=", fileRead.EquipmentType, ";B_JOBID=", fileRead.CellInstanceName, ";B_MES_ENTITY=", fileRead.MesEntity, ";B_MID=", logistics.MID, ";B_NULL_DATA=", fileRead.NullData, ";B_PPID=NO_PPID;B_PROCESS_JOBID=", logistics.ProcessJobID, ";B_PRODUCT=;B_SEQUENCE=", logistics.Sequence, ";B_WAFER_ID=;")); - lines.Add("END_HEADER"); - } - _ = stringBuilder.Clear(); - foreach (string line in lines) - _ = stringBuilder.AppendLine(line); - result = stringBuilder.ToString(); - result = result.Replace(headerOffset, result.IndexOf("NUM_DATA_ROWS").ToString().PadLeft(9, '0')). - Replace(dataOffset, result.IndexOf('"').ToString().PadLeft(9, '0')). - Replace(endOffset, result.Length.ToString().PadLeft(9, '0')); - } - return result; + Body = body; + Columns = columns; + Footer = footer; + Header = header; + InputPDSF = inputPDSF; + Logistics = logistics; + Sequence = sequence; } - public static Tuple GetLogisticsColumnsAndBody(string reportFullPath, string[] lines = null) - { - string segment; - List body = new(); - StringBuilder logistics = new(); - lines ??= File.ReadAllLines(reportFullPath); - string[] segments; - if (lines.Length < 7) - segments = Array.Empty(); - else - segments = lines[6].Trim().Split('\t'); - List columns = new(); - for (int c = 0; c < segments.Length; c++) - { - segment = segments[c].Substring(1, segments[c].Length - 2); - if (!columns.Contains(segment)) - columns.Add(segment); - else - { - for (short i = 1; i < short.MaxValue; i++) - { - segment = string.Concat(segment, "_", i); - if (!columns.Contains(segment)) - { - columns.Add(segment); - break; - } - } - } - } - bool lookForLogistics = false; - for (int r = 7; r < lines.Length; r++) - { - if (lines[r].StartsWith("NUM_DATA_ROWS")) - lookForLogistics = true; - if (!lookForLogistics) - { - body.Add(lines[r]); - continue; - } - if (lines[r].StartsWith("LOGISTICS_1")) - { - for (int i = r; i < lines.Length; i++) - { - if (lines[r].StartsWith("END_HEADER")) - break; - _ = logistics.AppendLine(lines[i]); - } - break; - } - } - return new Tuple(logistics.ToString(), columns.ToArray(), body.ToArray()); - } + internal static string EquipmentIntegration(bool addSpaces = true, char separator = ' ') => + GetString(SearchFor.EquipmentIntegration, addSpaces, separator); - public static JsonElement[] GetArray(Tuple pdsf, bool lookForNumbers = false) - { - JsonElement[] results; - string logistics = pdsf.Item1; - string[] columns = pdsf.Item2; - string[] bodyLines = pdsf.Item3; - if (bodyLines.Length == 0 || !bodyLines[0].Contains('\t')) - results = JsonSerializer.Deserialize("[]"); - else - { - string value; - string[] segments; - List lines = new(); - StringBuilder stringBuilder = new(); - foreach (string bodyLine in bodyLines) - { - _ = stringBuilder.Clear(); - _ = stringBuilder.Append('{'); - segments = bodyLine.Trim().Split('\t'); - if (!lookForNumbers) - { - for (int c = 1; c < segments.Length; c++) - { - value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); - _ = stringBuilder.Append('"').Append(columns[c]).Append("\":\"").Append(value).Append("\","); - } - } - else - { - for (int c = 1; c < segments.Length; c++) - { - value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); - if (string.IsNullOrEmpty(value)) - _ = stringBuilder.Append('"').Append(columns[c]).Append("\":").Append(value).Append("null,"); - else if (value.All(char.IsDigit)) - _ = stringBuilder.Append('"').Append(columns[c]).Append("\":").Append(value).Append(','); - else - _ = stringBuilder.Append('"').Append(columns[c]).Append("\":\"").Append(value).Append("\","); - } - } - _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); - _ = stringBuilder.AppendLine("}"); - lines.Add(stringBuilder.ToString()); - } - string json = $"[{string.Join(",", lines)}]"; - results = JsonSerializer.Deserialize(json); - } - return results; - } + internal static string BusinessIntegration(bool addSpaces = true, char separator = ' ') => + GetString(SearchFor.BusinessIntegration, addSpaces, separator); - public static Dictionary> GetDictionary(Tuple pdsf) - { - Dictionary> results = new(); - string[] segments; - string[] columns = pdsf.Item2; - string[] bodyLines = pdsf.Item3; - foreach (string column in columns) - results.Add(column, new List()); - foreach (string bodyLine in bodyLines) - { - segments = bodyLine.Split('\t'); - for (int c = 1; c < segments.Length; c++) - { - if (c >= columns.Length) - continue; - results[columns[c]].Add(segments[c]); - } - } - return results; - } + internal static string SystemExport(bool addSpaces = true, char separator = ' ') => + GetString(SearchFor.SystemExport, addSpaces, separator); - public static Tuple>>> GetTestDictionary(Tuple pdsf) - { - Dictionary>> results = new(); - List collection; - string testColumn = nameof(Test); - Dictionary> keyValuePairs = GetDictionary(pdsf); - if (!keyValuePairs.TryGetValue(testColumn, out collection)) - throw new Exception(); - int min; - int max; - Test testKey; - List vs; - string columnKey; - Dictionary> tests = new(); - for (int i = 0; i < collection.Count; i++) - { - if (Enum.TryParse(collection[i], out Test test)) - { - if (!results.ContainsKey(test)) - { - tests.Add(test, new List()); - results.Add(test, new Dictionary>()); - } - tests[test].Add(i); - } - } - foreach (KeyValuePair> testKeyValuePair in tests) - { - testKey = testKeyValuePair.Key; - min = testKeyValuePair.Value.Min(); - max = testKeyValuePair.Value.Max() + 1; - foreach (KeyValuePair> keyValuePair in keyValuePairs) - results[testKey].Add(keyValuePair.Key, new List()); - foreach (KeyValuePair> keyValuePair in keyValuePairs) - { - vs = keyValuePair.Value; - columnKey = keyValuePair.Key; - for (int i = min; i < max; i++) - { - if (vs.Count > i) - results[testKey][columnKey].Add(vs[i]); - else - results[testKey][columnKey].Add(string.Empty); - } - } - } - return new Tuple>>>(pdsf.Item1, results); - } + internal static string Archive(bool addSpaces = true, char separator = ' ') => + GetString(SearchFor.Archive, addSpaces, separator); - private static string GetString(SearchFor searchFor, bool addSpaces, char separator = ' ') - { - if (!addSpaces) - return string.Concat(((int)searchFor).ToString().PadLeft(2, '0'), searchFor); - else - return string.Concat(((int)searchFor).ToString().PadLeft(2, '0'), separator, searchFor.ToString().Replace("In", string.Concat(separator, "In")).Replace("Ex", string.Concat(separator, "Ex"))); - } + internal static ProcessDataStandardFormat GetEmpty(Logistics logistics) => + new(new(Array.Empty()), new(Array.Empty()), new(Array.Empty()), new(Array.Empty()), null, new(logistics.Logistics1), null); - public static string EquipmentIntegration(bool addSpaces = true, char separator = ' ') => GetString(SearchFor.EquipmentIntegration, addSpaces, separator); - - public static string BusinessIntegration(bool addSpaces = true, char separator = ' ') => GetString(SearchFor.BusinessIntegration, addSpaces, separator); - - public static string SystemExport(bool addSpaces = true, char separator = ' ') => GetString(SearchFor.SystemExport, addSpaces, separator); - - public static string Archive(bool addSpaces = true, char separator = ' ') => GetString(SearchFor.Archive, addSpaces, separator); - - public static string GetLines(Logistics logistics, Properties.IScopeInfo scopeInfo, List names, Dictionary> keyValuePairs, string dateFormat, string timeFormat, List pairedParameterNames, bool useDateTimeFromSequence = true, string format = "", List ignoreParameterNames = null) - { - StringBuilder result = new(); - ignoreParameterNames ??= new List(); - if (useDateTimeFromSequence && !string.IsNullOrEmpty(format)) - throw new Exception(); - else if (!useDateTimeFromSequence && string.IsNullOrEmpty(format)) - throw new Exception(); - string nullData; - const string columnDate = "Date"; - const string columnTime = "Time"; - const string firstDuplicate = "_1"; - _ = result.AppendLine(scopeInfo.Header); - StringBuilder line = new(); - if (logistics.NullData is null) - nullData = string.Empty; - else - nullData = logistics.NullData.ToString(); - int count = (from l in keyValuePairs select l.Value.Count).Min(); - for (int r = 0; r < count; r++) - { - _ = line.Clear(); - _ = line.Append('!'); - foreach (KeyValuePair> keyValuePair in keyValuePairs) - { - if (!names.Contains(keyValuePair.Key)) - continue; - if (ignoreParameterNames.Contains(keyValuePair.Key)) - continue; - if (pairedParameterNames.Contains(keyValuePair.Key)) - { - if (string.IsNullOrEmpty(keyValuePair.Value[r]) || keyValuePair.Value[r] == nullData) - continue; - else - _ = result.Append(line).Append(keyValuePair.Key).Append(';').AppendLine(keyValuePair.Value[r]); - } - else - { - if (useDateTimeFromSequence && keyValuePair.Key == columnDate) - _ = line.Append(logistics.DateTimeFromSequence.ToString(dateFormat)); - else if (useDateTimeFromSequence && keyValuePair.Key == columnTime) - _ = line.Append(logistics.DateTimeFromSequence.ToString(timeFormat)); - else if (!useDateTimeFromSequence && keyValuePair.Key == columnDate && keyValuePair.Value[r].Length == format.Length) - _ = line.Append(DateTime.ParseExact(keyValuePair.Value[r], format, CultureInfo.InvariantCulture).ToString(dateFormat)); - else if (!useDateTimeFromSequence && keyValuePair.Key == columnTime && keyValuePairs.ContainsKey(string.Concat(keyValuePair.Key, firstDuplicate)) && keyValuePairs[string.Concat(keyValuePair.Key, firstDuplicate)][r].Length == format.Length) - _ = line.Append(DateTime.ParseExact(keyValuePairs[string.Concat(keyValuePair.Key, firstDuplicate)][r], format, CultureInfo.InvariantCulture).ToString(timeFormat)); - else if (string.IsNullOrEmpty(keyValuePair.Value[r]) || keyValuePair.Value[r] == nullData) - _ = line.Append(nullData); - else - _ = line.Append(keyValuePair.Value[r]); - _ = line.Append(';'); - } - } - if (pairedParameterNames.Count == 0) - { - _ = line.Remove(line.Length - 1, 1); - _ = result.AppendLine(line.ToString()); - } - } - return result.ToString(); - } - - public static List PDSFToFixedWidth(string reportFullPath) + internal static List PDSFToFixedWidth(string reportFullPath) { List results = new(); if (!File.Exists(reportFullPath)) @@ -407,4 +133,634 @@ public class ProcessDataStandardFormat return results; } + internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string reportFullPath, string[]? lines = null, int columnsLine = 6) + { + ProcessDataStandardFormat result; + string segment; + string[] segments; + bool addToFooter = false; + List body = new(); + List header = new(); + List footer = new(); + List columns = new(); + ReadOnlyCollection logistics; + lines ??= File.ReadAllLines(reportFullPath); + if (lines.Length < columnsLine + 1) + segments = Array.Empty(); + else + { + segments = lines[columnsLine].Trim().Split('\t'); + for (int i = 0; i < columnsLine; i++) + header.Add(lines[i]); + } + for (int c = 0; c < segments.Length; c++) + { + segment = segments[c].Substring(1, segments[c].Length - 2); + if (!columns.Contains(segment)) + columns.Add(segment); + else + { + for (short i = 1; i < short.MaxValue; i++) + { + segment = string.Concat(segment, "_", i); + if (!columns.Contains(segment)) + { + columns.Add(segment); + break; + } + } + } + } + for (int r = columnsLine + 1; r < lines.Length; r++) + { + if (lines[r].StartsWith("NUM_DATA_ROWS")) + addToFooter = true; + if (!addToFooter) + body.Add(lines[r]); + else + { + footer.Add(lines[r]); + if (lines[r].StartsWith("END_HEADER")) + break; + } + } + string? linesOne = lines.Length > 0 && body.Count == 0 && columns.Count == 0 ? lines[1] : null; + logistics = GetLogistics(footer, linesOne: linesOne); + result = new(body: body.AsReadOnly(), + columns: columns.AsReadOnly(), + footer: footer.AsReadOnly(), + header: header.AsReadOnly(), + inputPDSF: null, + logistics: logistics, + sequence: null); + return result; + } + + private static ReadOnlyCollection GetLogistics(List footer, string? linesOne) + { + List results = new(); + bool foundLogistics1 = false; + foreach (string line in footer) + { + if (line.StartsWith("END_HEADER")) + break; + if (line.StartsWith("LOGISTICS_1")) + foundLogistics1 = true; + if (foundLogistics1 && line.StartsWith("LOGISTICS_")) + results.Add(line); + } + if (!string.IsNullOrEmpty(linesOne) && results.Count == 0) + results.Add(linesOne); + return results.AsReadOnly(); + } + + internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string reportFullPath, ProcessDataStandardFormatMapping pdsfMapping) + { + ProcessDataStandardFormat result; + const int columnsLine = 6; + FileInfo fileInfo = new(reportFullPath); + ProcessDataStandardFormat processDataStandardFormat = GetProcessDataStandardFormat(fileInfo.LastWriteTime, columnsLine, fileInfo.FullName, lines: null); + JsonElement[]? jsonElements = pdsfMapping.OldColumnNames.Count != pdsfMapping.ColumnIndices.Count ? null : GetFullArray(processDataStandardFormat); + JsonProperty[]? jsonProperties = jsonElements is null || jsonElements.Length == 0 ? null : jsonElements[0].EnumerateObject().ToArray(); + if (jsonElements is null || jsonProperties is null || jsonProperties.Length != pdsfMapping.NewColumnNames.Count) + result = processDataStandardFormat; + else + { + result = GetProcessDataStandardFormat(pdsfMapping, jsonElements, processDataStandardFormat); + if (result.Sequence is null || result.Columns.Count == 0 || result.Body.Count == 0 || result.Logistics.Count == 0) + result = processDataStandardFormat; + } + return result; + } + + private static ProcessDataStandardFormat GetProcessDataStandardFormat(DateTime lastWriteTime, int columnsLine, string path, string[]? lines) + { + ProcessDataStandardFormat result; + long sequence; + string[] segments; + bool addToFooter = false; + List body = new(); + List header = new(); + List footer = new(); + ReadOnlyCollection logistics; + lines ??= File.ReadAllLines(path); + if (lines.Length <= columnsLine) + segments = Array.Empty(); + else + { + segments = lines[columnsLine].Split('\t'); + for (int i = 0; i < columnsLine; i++) + header.Add(lines[i]); + } + string[] columns = segments.Select(l => l.Trim('"')).ToArray(); + for (int r = columnsLine + 1; r < lines.Length; r++) + { + if (lines[r].StartsWith("NUM_DATA_ROWS")) + addToFooter = true; + if (!addToFooter) + body.Add(lines[r]); + else + { + footer.Add(lines[r]); + if (lines[r].StartsWith("END_HEADER")) + break; + } + } + logistics = GetLogistics(footer, linesOne: null); + if (logistics.Count == 0) + sequence = lastWriteTime.Ticks; + else + { + segments = logistics[0].Split(new string[] { "SEQUENCE=" }, StringSplitOptions.None); + sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? lastWriteTime.Ticks : s; + } + result = new(body: body.AsReadOnly(), + columns: new(columns), + footer: footer.AsReadOnly(), + header: header.AsReadOnly(), + inputPDSF: null, + logistics: logistics, + sequence: sequence); + return result; + } + + private static JsonElement[]? GetFullArray(ProcessDataStandardFormat processDataStandardFormat) + { + JsonElement[]? results; + if (processDataStandardFormat.Body.Count == 0 || !processDataStandardFormat.Body[0].Contains('\t')) + results = JsonSerializer.Deserialize("[]", JsonElementCollectionSourceGenerationContext.Default.JsonElementArray) ?? throw new Exception(); + else + { + string value; + List segments; + List lines = new(); + StringBuilder stringBuilder = new(); + foreach (string bodyLine in processDataStandardFormat.Body) + { + _ = stringBuilder.Clear(); + _ = stringBuilder.Append('{'); + segments = bodyLine.Split('\t').ToList(); + for (int c = 0; c < segments.Count; c++) + { + value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); + _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); + } + _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); + _ = stringBuilder.AppendLine("}"); + lines.Add(stringBuilder.ToString()); + } + string json = $"[{string.Join(",", lines)}]"; + results = JsonSerializer.Deserialize(json, JsonElementCollectionSourceGenerationContext.Default.JsonElementArray); + } + return results; + } + + private static ProcessDataStandardFormat GetProcessDataStandardFormat(ProcessDataStandardFormatMapping processDataStandardFormatMapping, JsonElement[] jsonElements, ProcessDataStandardFormat processDataStandardFormat) + { + ProcessDataStandardFormat result; + int column; + string value; + JsonProperty jsonProperty; + List values = new(); + List results = new(); + JsonProperty[] jsonProperties; + List unknownColumns = new(); + for (int i = 0; i < jsonElements.Length; i++) + { + values.Clear(); + if (jsonElements[i].ValueKind != JsonValueKind.Object) + { + unknownColumns.Add(string.Empty); + break; + } + jsonProperties = jsonElements[i].EnumerateObject().ToArray(); + if (jsonProperties.Length != processDataStandardFormatMapping.NewColumnNames.Count) + continue; + for (int c = 0; c < processDataStandardFormatMapping.ColumnIndices.Count; c++) + { + column = processDataStandardFormatMapping.ColumnIndices[c]; + if (column == -1) + value = processDataStandardFormatMapping.OldColumnNames[c]; + else + { + jsonProperty = jsonProperties[column]; + value = jsonProperty.Value.ToString(); + } + values.Add(value); + } + results.Add(string.Join("\t", values)); + } + result = new(body: new(results), + columns: processDataStandardFormatMapping.OldColumnNames, + footer: processDataStandardFormat.Footer, + header: processDataStandardFormat.Header, + inputPDSF: processDataStandardFormat, + logistics: processDataStandardFormat.Logistics, + sequence: processDataStandardFormat.Sequence); + return result; + } + + private static string GetJson(ProcessDataStandardFormat processDataStandardFormat) + { + if (processDataStandardFormat.InputPDSF is null) + throw new NullReferenceException(nameof(processDataStandardFormat.InputPDSF)); +#pragma warning disable CA1845, IDE0057 + string result; + string line; + string value; + string[] segments; + List lines = new(); + for (int i = 0; i < processDataStandardFormat.InputPDSF.Body.Count; i++) + { + line = "{"; + segments = processDataStandardFormat.InputPDSF.Body[i].Trim().Split('\t'); + if (segments.Length != processDataStandardFormat.InputPDSF.Columns.Count) + break; + for (int c = 0; c < segments.Length; c++) + { + value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); + line += string.Concat('"', processDataStandardFormat.InputPDSF.Columns[c].Trim('"'), '"', ':', '"', value, '"', ','); + } + line = string.Concat(line.Substring(0, line.Length - 1), '}'); + lines.Add(line); + } + result = string.Concat( + '{', + Environment.NewLine, + '"', + "Count", + '"', + ": ", + processDataStandardFormat.Body.Count, + ',', + Environment.NewLine, + '"', + "Records", + '"', + ": ", + Environment.NewLine, + '[', + Environment.NewLine, + string.Join($",{Environment.NewLine}", lines), + Environment.NewLine, + ']', + ',', + Environment.NewLine, + '"', + "Sequence", + '"', + ": ", + processDataStandardFormat.Sequence, + Environment.NewLine, + '}'); + return result; +#pragma warning restore CA1845, IDE0057 + } + + internal static void Write(string path, ProcessDataStandardFormat processDataStandardFormat, List? wsResults) + { + List results = new(); + if (processDataStandardFormat.Sequence is null) + throw new NullReferenceException(nameof(processDataStandardFormat.Sequence)); + string endOffset = "E#######T"; + string dataOffset = "D#######T"; + string headerOffset = "H#######T"; + string format = "MM/dd/yyyy HH:mm:ss"; + string startTime = new DateTime(processDataStandardFormat.Sequence.Value).ToString(format); + results.Add("HEADER_TAG\tHEADER_VALUE"); + results.Add("FORMAT\t2.00"); + results.Add("NUMBER_PASSES\t0001"); + results.Add($"HEADER_OFFSET\t{headerOffset}"); + results.Add($"DATA_OFFSET\t{dataOffset}"); + results.Add($"END_OFFSET\t{endOffset}"); + results.Add($"\"{string.Join("\"\t\"", processDataStandardFormat.Columns)}\""); + results.AddRange(processDataStandardFormat.Body); + results.Add($"NUM_DATA_ROWS\t{processDataStandardFormat.Body.Count.ToString().PadLeft(9, '0')}"); + results.Add($"NUM_DATA_COLUMNS\t{processDataStandardFormat.Columns.Count.ToString().PadLeft(9, '0')}"); + results.Add("DELIMITER\t;"); + results.Add($"START_TIME_FORMAT\t{format}"); + results.Add($"START_TIME\t{startTime}"); + results.Add("LOGISTICS_COLUMN\tA_LOGISTICS"); + results.Add("LOGISTICS_COLUMN\tB_LOGISTICS"); + if (wsResults is null || wsResults.Count != 1) + results.AddRange(processDataStandardFormat.Logistics); + else + { + string[] segments; + foreach (string logistics in processDataStandardFormat.Logistics) + { + segments = logistics.Split(new string[] { "\t" }, StringSplitOptions.None); + if (segments.Length != 2 || string.IsNullOrEmpty(segments[1])) + results.Add(logistics); + else + results.Add($"{segments[0]}\t{segments[1][0]}_HeaderId={wsResults[0].HeaderId};{segments[1][0]}_SubgroupId={wsResults[0].SubgroupId};{segments[1]}"); + } + } + results.Add("END_HEADER"); + if (processDataStandardFormat.InputPDSF is not null) + { + results.Add(string.Empty); + List hyphens = new(); + results.AddRange(processDataStandardFormat.InputPDSF.Header.Select(l => l.Replace('\t', '|'))); + results.Add(string.Empty); + results.Add($"|{string.Join("|", processDataStandardFormat.InputPDSF.Columns)}|"); + for (int i = 0; i < processDataStandardFormat.InputPDSF.Columns.Count; i++) + hyphens.Add('-'); + results.Add($"|{string.Join("|", hyphens)}|"); + results.AddRange(processDataStandardFormat.InputPDSF.Body.Select(l => l.Replace('\t', '|'))); + results.Add(string.Empty); + results.AddRange(processDataStandardFormat.InputPDSF.Footer.Select(l => l.Replace('\t', '|'))); + results.Add(string.Empty); + results.Add("EOF"); + results.Add(string.Empty); + string json = GetJson(processDataStandardFormat); + results.Add(json); + } + File.WriteAllText(path, string.Join(Environment.NewLine, results)); + } + + internal static Dictionary> GetDictionary(ProcessDataStandardFormat processDataStandardFormat) + { + Dictionary> results = new(); + string[] segments; + foreach (string column in processDataStandardFormat.Columns) + results.Add(column, new List()); + foreach (string bodyLine in processDataStandardFormat.Body) + { + segments = bodyLine.Split('\t'); + for (int c = 1; c < segments.Length; c++) + { + if (c >= processDataStandardFormat.Columns.Count) + continue; + results[processDataStandardFormat.Columns[c]].Add(segments[c]); + } + } + return results; + } + + internal static JsonElement[] GetArray(ProcessDataStandardFormat processDataStandardFormat, bool lookForNumbers = false) + { + JsonElement[] results; + if (processDataStandardFormat.Body.Count == 0 || !processDataStandardFormat.Body[0].Contains('\t')) + results = JsonSerializer.Deserialize("[]", JsonElementCollectionSourceGenerationContext.Default.JsonElementArray) ?? throw new Exception(); + else + { + string value; + string[] segments; + List lines = new(); + StringBuilder stringBuilder = new(); + foreach (string bodyLine in processDataStandardFormat.Body) + { + _ = stringBuilder.Clear(); + _ = stringBuilder.Append('{'); + segments = bodyLine.Trim().Split('\t'); + if (!lookForNumbers) + { + for (int c = 1; c < segments.Length; c++) + { + value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); + _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); + } + } + else + { + for (int c = 1; c < segments.Length; c++) + { + value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); + if (string.IsNullOrEmpty(value)) + _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,"); + else if (value.All(char.IsDigit)) + _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append(','); + else + _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); + } + } + _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); + _ = stringBuilder.AppendLine("}"); + lines.Add(stringBuilder.ToString()); + } + string json = $"[{string.Join(",", lines)}]"; + results = JsonSerializer.Deserialize(json) ?? throw new Exception(); + } + return results; + } + + internal static string GetPDSFText(IFileRead fileRead, Logistics logistics, JsonElement[] jsonElements, string logisticsText) + { + string result; + if (jsonElements.Length == 0) + result = string.Empty; + else + { + int columns = 0; + List lines; + string endOffset = "E#######T"; + string dataOffset = "D#######T"; + string headerOffset = "H#######T"; + string format = "MM/dd/yyyy HH:mm:ss"; + StringBuilder stringBuilder = new(); + lines = new string[] { "HEADER_TAG\tHEADER_VALUE", "FORMAT\t2.00", "NUMBER_PASSES\t0001", string.Concat("HEADER_OFFSET\t", headerOffset), string.Concat("DATA_OFFSET\t", dataOffset), string.Concat("END_OFFSET\t", endOffset) }.ToList(); + _ = stringBuilder.Append("\"Time\"").Append('\t'); + _ = stringBuilder.Append("\"A_LOGISTICS\"").Append('\t'); + _ = stringBuilder.Append("\"B_LOGISTICS\"").Append('\t'); + for (int i = 0; i < jsonElements.Length;) + { + foreach (JsonProperty jsonProperty in jsonElements[0].EnumerateObject()) + { + columns += 1; + _ = stringBuilder.Append('"').Append(jsonProperty.Name).Append('"').Append('\t'); + } + break; + } + _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); + lines.Add(stringBuilder.ToString()); + for (int i = 0; i < jsonElements.Length; i++) + { + _ = stringBuilder.Clear(); + _ = stringBuilder.Append("0.1").Append('\t'); + _ = stringBuilder.Append('1').Append('\t'); + _ = stringBuilder.Append('2').Append('\t'); + foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject()) + _ = stringBuilder.Append(jsonProperty.Value).Append('\t'); + _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); + lines.Add(stringBuilder.ToString()); + } + lines.Add(string.Concat("NUM_DATA_ROWS ", jsonElements.Length.ToString().PadLeft(9, '0'))); + lines.Add(string.Concat("NUM_DATA_COLUMNS ", (columns + 3).ToString().PadLeft(9, '0'))); + lines.Add("DELIMITER ;"); + lines.Add(string.Concat("START_TIME_FORMAT ", format)); + lines.Add(string.Concat("START_TIME ", logistics.DateTimeFromSequence.ToString(format))); //12/26/2019 15:22:44 + lines.Add(string.Concat("LOGISTICS_COLUMN", '\t', "A_LOGISTICS")); + lines.Add(string.Concat("LOGISTICS_COLUMN", '\t', "B_LOGISTICS")); + if (!string.IsNullOrEmpty(logisticsText)) + lines.Add(logisticsText); + else + { + lines.Add(string.Concat("LOGISTICS_1", '\t', "A_CHAMBER=;A_INFO=", fileRead.EventName, ";A_INFO2=", fileRead.EquipmentType, ";A_JOBID=", fileRead.CellInstanceName, ";A_MES_ENTITY=", fileRead.MesEntity, ";A_MID=", logistics.MID, ";A_NULL_DATA=", fileRead.NullData, ";A_PPID=NO_PPID;A_PROCESS_JOBID=", logistics.ProcessJobID, ";A_PRODUCT=;A_SEQUENCE=", logistics.Sequence, ";A_WAFER_ID=;")); + lines.Add(string.Concat("LOGISTICS_2", '\t', "B_CHAMBER=;B_INFO=", fileRead.EventName, ";B_INFO2=", fileRead.EquipmentType, ";B_JOBID=", fileRead.CellInstanceName, ";B_MES_ENTITY=", fileRead.MesEntity, ";B_MID=", logistics.MID, ";B_NULL_DATA=", fileRead.NullData, ";B_PPID=NO_PPID;B_PROCESS_JOBID=", logistics.ProcessJobID, ";B_PRODUCT=;B_SEQUENCE=", logistics.Sequence, ";B_WAFER_ID=;")); + lines.Add("END_HEADER"); + } + _ = stringBuilder.Clear(); + foreach (string line in lines) + _ = stringBuilder.AppendLine(line); + result = stringBuilder.ToString(); + result = result.Replace(headerOffset, result.IndexOf("NUM_DATA_ROWS").ToString().PadLeft(9, '0')). + Replace(dataOffset, result.IndexOf('"').ToString().PadLeft(9, '0')). + Replace(endOffset, result.Length.ToString().PadLeft(9, '0')); + } + return result; + } + + internal static Tuple>>> GetTestDictionary(ProcessDataStandardFormat processDataStandardFormat) + { + Dictionary>> results = new(); + List? collection; + string testColumn = nameof(Test); + Dictionary> keyValuePairs = GetDictionary(processDataStandardFormat); + if (!keyValuePairs.TryGetValue(testColumn, out collection)) + throw new Exception(); + int min; + int max; + Test testKey; + List vs; + string columnKey; + Dictionary> tests = new(); + for (int i = 0; i < collection.Count; i++) + { + if (Enum.TryParse(collection[i], out Test test)) + { + if (!results.ContainsKey(test)) + { + tests.Add(test, new List()); + results.Add(test, new Dictionary>()); + } + tests[test].Add(i); + } + } + foreach (KeyValuePair> testKeyValuePair in tests) + { + testKey = testKeyValuePair.Key; + min = testKeyValuePair.Value.Min(); + max = testKeyValuePair.Value.Max() + 1; + foreach (KeyValuePair> keyValuePair in keyValuePairs) + results[testKey].Add(keyValuePair.Key, new List()); + foreach (KeyValuePair> keyValuePair in keyValuePairs) + { + vs = keyValuePair.Value; + columnKey = keyValuePair.Key; + for (int i = min; i < max; i++) + { + if (vs.Count > i) + results[testKey][columnKey].Add(vs[i]); + else + results[testKey][columnKey].Add(string.Empty); + } + } + } + return new Tuple>>>(processDataStandardFormat.Logistics[0], results); + } + + internal static string GetLines(Logistics logistics, Properties.IScopeInfo scopeInfo, List names, Dictionary> keyValuePairs, string dateFormat, string timeFormat, List pairedParameterNames, bool useDateTimeFromSequence = true, string format = "", List? ignoreParameterNames = null) + { + StringBuilder result = new(); + ignoreParameterNames ??= new List(); + if (useDateTimeFromSequence && !string.IsNullOrEmpty(format)) + throw new Exception(); + else if (!useDateTimeFromSequence && string.IsNullOrEmpty(format)) + throw new Exception(); + string? nullData; + const string columnDate = "Date"; + const string columnTime = "Time"; + const string firstDuplicate = "_1"; + _ = result.AppendLine(scopeInfo.Header); + StringBuilder line = new(); + if (logistics.NullData is null) + nullData = string.Empty; + else + nullData = logistics.NullData.ToString(); + int count = (from l in keyValuePairs select l.Value.Count).Min(); + for (int r = 0; r < count; r++) + { + _ = line.Clear(); + _ = line.Append('!'); + foreach (KeyValuePair> keyValuePair in keyValuePairs) + { + if (!names.Contains(keyValuePair.Key)) + continue; + if (ignoreParameterNames.Contains(keyValuePair.Key)) + continue; + if (pairedParameterNames.Contains(keyValuePair.Key)) + { + if (string.IsNullOrEmpty(keyValuePair.Value[r]) || keyValuePair.Value[r] == nullData) + continue; + else + _ = result.Append(line).Append(keyValuePair.Key).Append(';').AppendLine(keyValuePair.Value[r]); + } + else + { + if (useDateTimeFromSequence && keyValuePair.Key == columnDate) + _ = line.Append(logistics.DateTimeFromSequence.ToString(dateFormat)); + else if (useDateTimeFromSequence && keyValuePair.Key == columnTime) + _ = line.Append(logistics.DateTimeFromSequence.ToString(timeFormat)); + else if (!useDateTimeFromSequence && keyValuePair.Key == columnDate && keyValuePair.Value[r].Length == format.Length) + _ = line.Append(DateTime.ParseExact(keyValuePair.Value[r], format, CultureInfo.InvariantCulture).ToString(dateFormat)); + else if (!useDateTimeFromSequence && keyValuePair.Key == columnTime && keyValuePairs.ContainsKey(string.Concat(keyValuePair.Key, firstDuplicate)) && keyValuePairs[string.Concat(keyValuePair.Key, firstDuplicate)][r].Length == format.Length) + _ = line.Append(DateTime.ParseExact(keyValuePairs[string.Concat(keyValuePair.Key, firstDuplicate)][r], format, CultureInfo.InvariantCulture).ToString(timeFormat)); + else if (string.IsNullOrEmpty(keyValuePair.Value[r]) || keyValuePair.Value[r] == nullData) + _ = line.Append(nullData); + else + _ = line.Append(keyValuePair.Value[r]); + _ = line.Append(';'); + } + } + if (pairedParameterNames.Count == 0) + { + _ = line.Remove(line.Length - 1, 1); + _ = result.AppendLine(line.ToString()); + } + } + return result.ToString(); + } + + private static string GetString(SearchFor searchFor, bool addSpaces, char separator = ' ') + { + if (!addSpaces) + return string.Concat(((int)searchFor).ToString().PadLeft(2, '0'), searchFor); + else + return string.Concat(((int)searchFor).ToString().PadLeft(2, '0'), separator, searchFor.ToString().Replace("In", string.Concat(separator, "In")).Replace("Ex", string.Concat(separator, "Ex"))); + } + + private static int? TryGetPropertyIndex(JsonProperty[] jsonProperties, string propertyName) + { + int? result = null; + for (int i = 0; i < jsonProperties.Length; i++) + { + if (jsonProperties[i].Name != propertyName) + continue; + result = i; + break; + } + if (result is null) + { + for (int i = 0; i < jsonProperties.Length; i++) + { + if (jsonProperties[i].Name[0] != propertyName[0]) + continue; + if (jsonProperties[i].Name.Length != propertyName.Length) + continue; + if (jsonProperties[i].Name != propertyName) + continue; + result = i; + break; + } + } + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(JsonElement[]))] +internal partial class JsonElementCollectionSourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Adaptation/Shared/ProcessDataStandardFormatMapping.cs b/Adaptation/Shared/ProcessDataStandardFormatMapping.cs new file mode 100644 index 0000000..c5a75ec --- /dev/null +++ b/Adaptation/Shared/ProcessDataStandardFormatMapping.cs @@ -0,0 +1,33 @@ +using System.Collections.ObjectModel; + +namespace Adaptation.Shared; + +public class ProcessDataStandardFormatMapping +{ + + public ReadOnlyCollection BackfillColumns { get; private set; } + public ReadOnlyCollection ColumnIndices { get; private set; } + public ReadOnlyCollection IgnoreColumns { get; private set; } + public ReadOnlyCollection IndexOnlyColumns { get; private set; } + public ReadOnlyDictionary KeyValuePairs { get; private set; } + public ReadOnlyCollection NewColumnNames { get; private set; } + public ReadOnlyCollection OldColumnNames { get; private set; } + + public ProcessDataStandardFormatMapping(ReadOnlyCollection backfillColumns, + ReadOnlyCollection columnIndices, + ReadOnlyCollection ignoreColumns, + ReadOnlyCollection indexOnlyColumns, + ReadOnlyDictionary keyValuePairs, + ReadOnlyCollection newColumnNames, + ReadOnlyCollection oldColumnNames) + { + BackfillColumns = backfillColumns; + ColumnIndices = columnIndices; + IgnoreColumns = ignoreColumns; + IndexOnlyColumns = indexOnlyColumns; + KeyValuePairs = keyValuePairs; + NewColumnNames = newColumnNames; + OldColumnNames = oldColumnNames; + } + +} \ No newline at end of file diff --git a/Adaptation/Shared/Properties/IDescription.cs b/Adaptation/Shared/Properties/IDescription.cs index 34b92af..1166e17 100644 --- a/Adaptation/Shared/Properties/IDescription.cs +++ b/Adaptation/Shared/Properties/IDescription.cs @@ -6,6 +6,6 @@ public interface IDescription int Test { get; } int Count { get; } int Index { get; } - string Lot { get; } + string RDS { get; } } \ No newline at end of file diff --git a/Adaptation/_Tests/Shared/AdaptationTesting.cs b/Adaptation/_Tests/Shared/AdaptationTesting.cs index 8a341d4..8c0bc93 100644 --- a/Adaptation/_Tests/Shared/AdaptationTesting.cs +++ b/Adaptation/_Tests/Shared/AdaptationTesting.cs @@ -56,11 +56,33 @@ public class AdaptationTesting : ISMTP public Dictionary ParameterizedModelObjectDefinitionTypes => _ParameterizedModelObjectDefinitionTypes; public Dictionary>> EquipmentDictionaryEventDescriptions => _EquipmentDictionaryEventDescriptions; - void ISMTP.SendLowPriorityEmailMessage(string subject, string body) => throw new NotImplementedException(); + void ISMTP.SendLowPriorityEmailMessage(string subject, string body) => + throw new NotImplementedException(); - void ISMTP.SendHighPriorityEmailMessage(string subject, string body) => throw new NotImplementedException(); + void ISMTP.SendHighPriorityEmailMessage(string subject, string body) => + throw new NotImplementedException(); - void ISMTP.SendNormalPriorityEmailMessage(string subject, string body) => throw new NotImplementedException(); + void ISMTP.SendNormalPriorityEmailMessage(string subject, string body) => + throw new NotImplementedException(); + + internal static T ParseXML(string @this, bool throwExceptions) where T : class + { + object result = null; + try + { + Stream stream = ToStream(@this.Trim()); + XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document }); + XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes()); + result = xmlSerializer.Deserialize(xmlReader); + stream.Dispose(); + } + catch (Exception) + { + if (throwExceptions) + throw; + } + return result as T; + } public AdaptationTesting(string dummyRoot, TestContext testContext, bool skipEquipmentDictionary, string testContextPropertiesAsJson, bool hasWaitForProperty) { @@ -105,93 +127,6 @@ public class AdaptationTesting : ISMTP return result; } - public static string GetTestResultsDirectory(string testContextTestResultsDirectory, bool hasWaitForProperty) - { - string result = string.Empty; - string testResults = "05_TestResults"; - string checkDirectory = testContextTestResultsDirectory; - if (hasWaitForProperty && (string.IsNullOrEmpty(checkDirectory) || !checkDirectory.Contains(testResults))) - throw new Exception($"A:{checkDirectory}; B:{testResults};"); - else if (!hasWaitForProperty && (string.IsNullOrEmpty(checkDirectory) || !checkDirectory.Contains(testResults))) - result = testContextTestResultsDirectory; - else - { - string rootDirectory = Path.GetPathRoot(checkDirectory); - for (int i = 0; i < int.MaxValue; i++) - { - checkDirectory = Path.GetDirectoryName(checkDirectory); - if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == rootDirectory) - break; - if (checkDirectory.EndsWith(testResults) && Directory.Exists(checkDirectory)) - { - result = checkDirectory; - break; - } - } - } - if (string.IsNullOrEmpty(result)) - throw new Exception(); - return result; - } - - private string GetTestResultsDirectory(bool hasWaitForProperty) - { - string result = GetTestResultsDirectory(_TestContext.TestResultsDirectory, hasWaitForProperty); - return result; - } - - protected static string GetCellInstanceConnectionName(string cellInstanceConnectionName) - { - string result; - if (string.IsNullOrEmpty(cellInstanceConnectionName) || cellInstanceConnectionName[cellInstanceConnectionName.Length - 1] != '_') - result = cellInstanceConnectionName; - else - { - bool check = false; - List chars = new(); - StringBuilder stringBuilder = new(); - for (int i = cellInstanceConnectionName.Length - 1; i > -1; i--) - { - if (!check && cellInstanceConnectionName[i] != '_') - check = true; - else if (!check && cellInstanceConnectionName[i] == '_') - chars.Add('-'); - if (check) - chars.Add(cellInstanceConnectionName[i]); - } - for (int i = chars.Count - 1; i > -1; i--) - _ = stringBuilder.Append(chars[i]); - result = stringBuilder.ToString(); - } - return result; - } - - private static string GetMethodBaseNameWithActualCICN(string methodBaseName, string cellInstanceName, string cellInstanceConnectionNameFromMethodBaseName, string cellInstanceConnectionName, string ticks) - { - string results; - if (string.IsNullOrEmpty(cellInstanceConnectionNameFromMethodBaseName) || string.IsNullOrEmpty(cellInstanceConnectionName)) - results = methodBaseName; - else if (cellInstanceConnectionNameFromMethodBaseName.Length != cellInstanceConnectionName.Length) - throw new Exception(); - else - { - string[] segments = methodBaseName.Split(new string[] { cellInstanceName }, StringSplitOptions.None); - if (segments.Length == 2) - results = methodBaseName.Replace(cellInstanceConnectionNameFromMethodBaseName, cellInstanceConnectionName); - else if (segments.Length != 3) - throw new Exception(); - else if (string.IsNullOrEmpty(ticks)) - results = string.Concat(segments[0], cellInstanceName, segments[1], cellInstanceConnectionName); - else if (!segments[2].Contains(ticks)) - throw new Exception(); - else - results = string.Concat(segments[0], cellInstanceName, segments[1], cellInstanceConnectionName, ticks, segments[2].Split(new string[] { ticks }, StringSplitOptions.None)[1]); - } - if (methodBaseName.Length != results.Length) - throw new Exception(); - return results; - } - public static MethodBaseName GetMethodBaseName(string dummyRoot, string environment, bool hasWaitForProperty, string methodBaseName, string testResultsDirectory) { MethodBaseName result; @@ -275,74 +210,58 @@ public class AdaptationTesting : ISMTP return result; } - private MethodBaseName GetMethodBaseName(MethodBase methodBase) + protected static string GetCellInstanceConnectionName(string cellInstanceConnectionName) { - MethodBaseName result; - string testResultsDirectory = GetTestResultsDirectory(_HasWaitForProperty); - result = GetMethodBaseName(_DummyRoot, _Environment, _HasWaitForProperty, methodBase.Name, testResultsDirectory); + string result; + if (string.IsNullOrEmpty(cellInstanceConnectionName) || cellInstanceConnectionName[cellInstanceConnectionName.Length - 1] != '_') + result = cellInstanceConnectionName; + else + { + bool check = false; + List chars = new(); + StringBuilder stringBuilder = new(); + for (int i = cellInstanceConnectionName.Length - 1; i > -1; i--) + { + if (!check && cellInstanceConnectionName[i] != '_') + check = true; + else if (!check && cellInstanceConnectionName[i] == '_') + chars.Add('-'); + if (check) + chars.Add(cellInstanceConnectionName[i]); + } + for (int i = chars.Count - 1; i > -1; i--) + _ = stringBuilder.Append(chars[i]); + result = stringBuilder.ToString(); + } return result; } - private string[] GetTextFiles(MethodBaseName mbn) + private static string GetMethodBaseNameWithActualCICN(string methodBaseName, string cellInstanceName, string cellInstanceConnectionNameFromMethodBaseName, string cellInstanceConnectionName, string ticks) { - string[] results; - if (string.IsNullOrEmpty(mbn.TextFileDirectory)) - results = Array.Empty(); - else if (!Directory.Exists(mbn.TextFileDirectory)) - { - results = Array.Empty(); - if (!_HasWaitForProperty) - _ = Directory.CreateDirectory(mbn.TextFileDirectory); - else - { - string renameDirectory = Path.Combine(Path.GetDirectoryName(mbn.TextFileDirectory), $"_Rename - {Path.GetFileName(mbn.TextFileDirectory)}"); - _ = Directory.CreateDirectory(renameDirectory); - _ = Process.Start("explorer.exe", renameDirectory); - File.WriteAllText(Path.Combine(renameDirectory, $"{nameof(FileConnectorConfiguration.SourceFileFilter)}.txt"), string.Empty); - File.WriteAllText(Path.Combine(renameDirectory, $"{nameof(FileConnectorConfiguration.SourceFileLocation)}.txt"), string.Empty); - } - } + string results; + if (string.IsNullOrEmpty(cellInstanceConnectionNameFromMethodBaseName) || string.IsNullOrEmpty(cellInstanceConnectionName)) + results = methodBaseName; + else if (cellInstanceConnectionNameFromMethodBaseName.Length != cellInstanceConnectionName.Length) + throw new Exception(); else { - results = Directory.GetFiles(mbn.TextFileDirectory, "*.txt", SearchOption.TopDirectoryOnly); - if (!string.IsNullOrEmpty(mbn.Ticks) && _HasWaitForProperty && results.Length == 0) - { - _ = Process.Start("explorer.exe", mbn.TextFileDirectory); - File.WriteAllText(Path.Combine(mbn.TextFileDirectory, "_ Why.why"), string.Empty); - } + string[] segments = methodBaseName.Split(new string[] { cellInstanceName }, StringSplitOptions.None); + if (segments.Length == 2) + results = methodBaseName.Replace(cellInstanceConnectionNameFromMethodBaseName, cellInstanceConnectionName); + else if (segments.Length != 3) + throw new Exception(); + else if (string.IsNullOrEmpty(ticks)) + results = string.Concat(segments[0], cellInstanceName, segments[1], cellInstanceConnectionName); + else if (!segments[2].Contains(ticks)) + throw new Exception(); + else + results = string.Concat(segments[0], cellInstanceName, segments[1], cellInstanceConnectionName, ticks, segments[2].Split(new string[] { ticks }, StringSplitOptions.None)[1]); } + if (methodBaseName.Length != results.Length) + throw new Exception(); return results; } - protected static Stream ToStream(string @this) - { - MemoryStream memoryStream = new(); - StreamWriter streamWriter = new(memoryStream); - streamWriter.Write(@this); - streamWriter.Flush(); - memoryStream.Position = 0; - return memoryStream; - } - - internal static T ParseXML(string @this, bool throwExceptions) where T : class - { - object result = null; - try - { - Stream stream = ToStream(@this.Trim()); - XmlReader xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document }); - XmlSerializer xmlSerializer = new(typeof(T), typeof(T).GetNestedTypes()); - result = xmlSerializer.Deserialize(xmlReader); - stream.Dispose(); - } - catch (Exception) - { - if (throwExceptions) - throw; - } - return result as T; - } - public static CellInstanceVersion GetCellInstanceVersion(string url) { CellInstanceVersion result; @@ -368,6 +287,54 @@ public class AdaptationTesting : ISMTP return result; } + public static string GetTestResultsDirectory(string testContextTestResultsDirectory, bool hasWaitForProperty) + { + string result = string.Empty; + string testResults = "05_TestResults"; + string checkDirectory = testContextTestResultsDirectory; + if (hasWaitForProperty && (string.IsNullOrEmpty(checkDirectory) || !checkDirectory.Contains(testResults))) + throw new Exception($"A:{checkDirectory}; B:{testResults};"); + else if (!hasWaitForProperty && (string.IsNullOrEmpty(checkDirectory) || !checkDirectory.Contains(testResults))) + result = testContextTestResultsDirectory; + else + { + string rootDirectory = Path.GetPathRoot(checkDirectory); + for (int i = 0; i < int.MaxValue; i++) + { + checkDirectory = Path.GetDirectoryName(checkDirectory); + if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == rootDirectory) + break; + if (checkDirectory.EndsWith(testResults) && Directory.Exists(checkDirectory)) + { + result = checkDirectory; + break; + } + } + } + if (string.IsNullOrEmpty(result)) + throw new Exception(); + return result; + } + + public string[] GetCSharpText(string testName) + { + string[] results; + string testResultsDirectory = GetTestResultsDirectory(_HasWaitForProperty); + MethodBaseName mbn = GetMethodBaseName(_DummyRoot, _Environment, _HasWaitForProperty, testName, testResultsDirectory); + FileInfo fileInfo = new(mbn.FileFullName); + if (!string.IsNullOrEmpty(mbn.CellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName)) + _ = Directory.CreateDirectory(fileInfo.Directory.FullName); + Tuple cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); + results = GetCSharpTextB(fileInfo, mbn.CellInstanceName, mbn.CellInstanceVersionName, cellInstanceVersionTuple.Item2); + return results; + } + + private string GetTestResultsDirectory(bool hasWaitForProperty) + { + string result = GetTestResultsDirectory(_TestContext.TestResultsDirectory, hasWaitForProperty); + return result; + } + protected Tuple GetCellInstanceVersionTuple(string cellInstanceName, string cellInstanceVersionName) { Tuple result; @@ -382,41 +349,6 @@ public class AdaptationTesting : ISMTP return result; } - protected static Dictionary GetComponentModelComponentsIndexes(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName) - { - Dictionary results = new(); - ComponentsCellComponent componentsCellComponent; - if (cellInstanceVersion.ComponentModel.Components is not null) - { - for (int i = 0; i < cellInstanceVersion.ComponentModel.Components.Length; i++) - { - componentsCellComponent = cellInstanceVersion.ComponentModel.Components[i]; - for (int j = 0; j < componentsCellComponent.Children.Length; j++) - { - if (string.IsNullOrEmpty(componentsCellComponent.Children[j].Equipment.Name)) - continue; - results.Add(componentsCellComponent.Children[j].Name, new int[] { i, j }); - } - } - } - if (results.Count == 0 || (!string.IsNullOrEmpty(cellInstanceConnectionName) && !results.ContainsKey(cellInstanceConnectionName))) - throw new Exception("Match not found (check test method name matches Mango)!"); - return results; - } - - protected static int[] GetCellInstanceConnectionNameIndexes(string cellInstanceConnectionName, Dictionary componentModelComponentsIndexes) - { - int[] result; - if (string.IsNullOrEmpty(cellInstanceConnectionName)) - result = componentModelComponentsIndexes.ElementAt(0).Value; - else - { - if (componentModelComponentsIndexes is null || !componentModelComponentsIndexes.TryGetValue(cellInstanceConnectionName, out result)) - throw new Exception(); - } - return result; - } - protected string[] GetCSharpTextB(FileInfo fileInfo, string cellInstanceName, string cellInstanceVersionName, CellInstanceVersion cellInstanceVersion) { List results = new(); @@ -608,6 +540,62 @@ public class AdaptationTesting : ISMTP return results.ToArray(); } + public string[] GetConfiguration(MethodBase methodBase) + { + string[] results; + MethodBaseName mbn = GetMethodBaseName(methodBase); + FileInfo fileInfo = new(mbn.FileFullName); + if (!string.IsNullOrEmpty(mbn.CellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName)) + _ = Directory.CreateDirectory(fileInfo.Directory.FullName); + Tuple cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); + Tuple fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, mbn.CellInstanceConnectionName); + if (string.IsNullOrEmpty(mbn.Ticks) && fileConnectorConfigurationTuple.Item2?.FileScanningIntervalInSeconds is not null) + { + string fileScanningIntervalInSecondsLine; + string versionDirectory = Path.GetDirectoryName(fileInfo.DirectoryName); + if (fileConnectorConfigurationTuple.Item2.FileScanningIntervalInSeconds.Value < 0) + fileScanningIntervalInSecondsLine = $"-\t{fileConnectorConfigurationTuple.Item2.FileScanningIntervalInSeconds.Value:0000}\t{Path.GetFileName(fileInfo.DirectoryName)}"; + else + fileScanningIntervalInSecondsLine = $"+\t{fileConnectorConfigurationTuple.Item2.FileScanningIntervalInSeconds.Value:+0000}\t{Path.GetFileName(fileInfo.DirectoryName)}"; + File.AppendAllLines(Path.Combine(versionDirectory, "FileScanningIntervalInSeconds.txt"), new string[] { fileScanningIntervalInSecondsLine }); + } + Tuple equipmentTypeVersionTuple = GetEquipmentTypeVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName); + Tuple parameterizedModelObjectDefinitionTypeTuple = GetParameterizedModelObjectDefinitionTypeTuple(equipmentTypeVersionTuple); + Tuple> modelObjectParametersTuple = GetModelObjectParameters(equipmentTypeVersionTuple); + Tuple equipmentDictionaryVersionTuple = GetEquipmentDictionaryVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName, equipmentTypeVersionTuple.Item4); + Tuple>> equipmentDictionaryIsAlwaysEnabledEventsTuple = GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(equipmentDictionaryVersionTuple); + Dictionary objects = GetKeyValuePairs(mbn.CellInstanceName, mbn.CellInstanceVersionName, mbn.CellInstanceConnectionName, fileConnectorConfigurationTuple.Item2, equipmentTypeVersionTuple.Item2, parameterizedModelObjectDefinitionTypeTuple.Item2, modelObjectParametersTuple.Item2, equipmentDictionaryVersionTuple.Item2, equipmentDictionaryIsAlwaysEnabledEventsTuple.Item2, cellInstanceVersionTuple.Item2.EdaConnection.PortNumber); + string json = JsonSerializer.Serialize(objects, new JsonSerializerOptions { WriteIndented = true }); + results = new string[] { fileInfo.FullName, json }; + return results; + } + + private MethodBaseName GetMethodBaseName(MethodBase methodBase) + { + MethodBaseName result; + string testResultsDirectory = GetTestResultsDirectory(_HasWaitForProperty); + result = GetMethodBaseName(_DummyRoot, _Environment, _HasWaitForProperty, methodBase.Name, testResultsDirectory); + return result; + } + + protected Tuple GetFileConnectorConfigurationTuple(Tuple cellInstanceVersionTuple, string cellInstanceConnectionName) + { + Tuple result; + FileConnectorConfiguration fileConnectorConfiguration; + string cellInstanceServiceV2With = string.Concat(cellInstanceVersionTuple.Item1, '/', cellInstanceConnectionName); + if (!_FileConnectorConfigurations.TryGetValue(cellInstanceServiceV2With, out fileConnectorConfiguration)) + { + Dictionary componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersionTuple.Item2, cellInstanceConnectionName); + int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes); + ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersionTuple.Item2.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]]; + string json = JsonSerializer.Serialize(componentsCellComponentCellComponent.Equipment, new JsonSerializerOptions { WriteIndented = true }); + fileConnectorConfiguration = GetFileConnectorConfiguration(json, componentsCellComponentCellComponent); + _FileConnectorConfigurations.Add(cellInstanceServiceV2With, fileConnectorConfiguration); + } + result = new Tuple(cellInstanceServiceV2With, fileConnectorConfiguration); + return result; + } + protected static FileConnectorConfiguration GetFileConnectorConfiguration(string json, ComponentsCellComponentCellComponent componentsCellComponentCellComponent) { FileConnectorConfiguration result; @@ -640,21 +628,55 @@ public class AdaptationTesting : ISMTP return result; } - protected Tuple GetFileConnectorConfigurationTuple(Tuple cellInstanceVersionTuple, string cellInstanceConnectionName) + protected Tuple GetEquipmentTypeVersionTuple(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName) { - Tuple result; - FileConnectorConfiguration fileConnectorConfiguration; - string cellInstanceServiceV2With = string.Concat(cellInstanceVersionTuple.Item1, '/', cellInstanceConnectionName); - if (!_FileConnectorConfigurations.TryGetValue(cellInstanceServiceV2With, out fileConnectorConfiguration)) + Tuple result; + EquipmentTypeVersion equipmentTypeVersion; + Dictionary componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersion, cellInstanceConnectionName); + int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes); + ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersion.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]]; + string equipmentTypeServiceV2 = string.Concat("http://", _HostNameAndPort, "/EquipmentTypeServiceV2/", componentsCellComponentCellComponent.Equipment.EquipmentType.Name, "/", componentsCellComponentCellComponent.Equipment.EquipmentType.Version, "/configuration"); + if (!_EquipmentTypeVersions.TryGetValue(equipmentTypeServiceV2, out equipmentTypeVersion)) { - Dictionary componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersionTuple.Item2, cellInstanceConnectionName); - int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes); - ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersionTuple.Item2.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]]; - string json = JsonSerializer.Serialize(componentsCellComponentCellComponent.Equipment, new JsonSerializerOptions { WriteIndented = true }); - fileConnectorConfiguration = GetFileConnectorConfiguration(json, componentsCellComponentCellComponent); - _FileConnectorConfigurations.Add(cellInstanceServiceV2With, fileConnectorConfiguration); + equipmentTypeVersion = GetEquipmentTypeVersion(equipmentTypeServiceV2); + _EquipmentTypeVersions.Add(equipmentTypeServiceV2, equipmentTypeVersion); + } + result = new Tuple(equipmentTypeServiceV2, componentsCellComponentCellComponent.Equipment.EquipmentType.Name, componentsCellComponentCellComponent.Equipment.EquipmentType.Version, equipmentTypeVersion); + return result; + } + + protected static Dictionary GetComponentModelComponentsIndexes(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName) + { + Dictionary results = new(); + ComponentsCellComponent componentsCellComponent; + if (cellInstanceVersion.ComponentModel.Components is not null) + { + for (int i = 0; i < cellInstanceVersion.ComponentModel.Components.Length; i++) + { + componentsCellComponent = cellInstanceVersion.ComponentModel.Components[i]; + for (int j = 0; j < componentsCellComponent.Children.Length; j++) + { + if (string.IsNullOrEmpty(componentsCellComponent.Children[j].Equipment.Name)) + continue; + results.Add(componentsCellComponent.Children[j].Name, new int[] { i, j }); + } + } + } + if (results.Count == 0 || (!string.IsNullOrEmpty(cellInstanceConnectionName) && !results.ContainsKey(cellInstanceConnectionName))) + throw new Exception("Match not found (check test method name matches Mango)!"); + return results; + } + + protected static int[] GetCellInstanceConnectionNameIndexes(string cellInstanceConnectionName, Dictionary componentModelComponentsIndexes) + { + int[] result; + if (string.IsNullOrEmpty(cellInstanceConnectionName)) + result = componentModelComponentsIndexes.ElementAt(0).Value; + else + { + if (componentModelComponentsIndexes is null || !componentModelComponentsIndexes.TryGetValue(cellInstanceConnectionName, out result)) + throw new Exception(); } - result = new Tuple(cellInstanceServiceV2With, fileConnectorConfiguration); return result; } @@ -683,35 +705,6 @@ public class AdaptationTesting : ISMTP return result; } - protected Tuple GetEquipmentTypeVersionTuple(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName) - { - Tuple result; - EquipmentTypeVersion equipmentTypeVersion; - Dictionary componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersion, cellInstanceConnectionName); - int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes); - ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersion.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]]; - string equipmentTypeServiceV2 = string.Concat("http://", _HostNameAndPort, "/EquipmentTypeServiceV2/", componentsCellComponentCellComponent.Equipment.EquipmentType.Name, "/", componentsCellComponentCellComponent.Equipment.EquipmentType.Version, "/configuration"); - if (!_EquipmentTypeVersions.TryGetValue(equipmentTypeServiceV2, out equipmentTypeVersion)) - { - equipmentTypeVersion = GetEquipmentTypeVersion(equipmentTypeServiceV2); - _EquipmentTypeVersions.Add(equipmentTypeServiceV2, equipmentTypeVersion); - } - result = new Tuple(equipmentTypeServiceV2, componentsCellComponentCellComponent.Equipment.EquipmentType.Name, componentsCellComponentCellComponent.Equipment.EquipmentType.Version, equipmentTypeVersion); - return result; - } - - protected Tuple GetParameterizedModelObjectDefinitionTypeTuple(Tuple equipmentTypeVersionTuple) - { - Tuple result; - string parameterizedModelObjectDefinitionType; - if (_FileConnectorConfigurations.ContainsKey(equipmentTypeVersionTuple.Item1)) - parameterizedModelObjectDefinitionType = _ParameterizedModelObjectDefinitionTypes[equipmentTypeVersionTuple.Item1]; - else - parameterizedModelObjectDefinitionType = equipmentTypeVersionTuple.Item4.FileHandlerObjectTypes.ParameterizedModelObjectDefinition.Type; - result = new Tuple(equipmentTypeVersionTuple.Item1, parameterizedModelObjectDefinitionType); - return result; - } - protected IList GetModelObjectParameters(string json) { IList results; @@ -736,18 +729,38 @@ public class AdaptationTesting : ISMTP return results; } - protected Tuple> GetModelObjectParameters(Tuple equipmentTypeVersionTuple) + protected Tuple GetEquipmentDictionaryVersionTuple(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName, EquipmentTypeVersion equipmentTypeVersion) { - Tuple> result; - IList modelObjectParameters; - if (_FileConnectorConfigurations.ContainsKey(equipmentTypeVersionTuple.Item1)) - modelObjectParameters = _ModelObjectParameters[equipmentTypeVersionTuple.Item1]; + Tuple result; + string equipmentDictionaryName; + string equipmentDictionaryVersionName; + EquipmentDictionaryVersion equipmentDictionaryVersion; + Dictionary componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersion, cellInstanceConnectionName); + int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes); + ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersion.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]]; + string[] segments = GetEquipmentDictionaryStrings(componentsCellComponentCellComponent.Equipment, equipmentTypeVersion); + if (_SkipEquipmentDictionary || segments is null || segments.Length != 2 || string.IsNullOrEmpty(segments[0]) || string.IsNullOrEmpty(segments[1])) + { + equipmentDictionaryName = string.Empty; + equipmentDictionaryVersionName = string.Empty; + } else { - string json = JsonSerializer.Serialize(equipmentTypeVersionTuple.Item4, new JsonSerializerOptions { WriteIndented = true }); - modelObjectParameters = GetModelObjectParameters(json); + equipmentDictionaryName = segments[0]; + equipmentDictionaryVersionName = segments[1]; } - result = new Tuple>(equipmentTypeVersionTuple.Item1, modelObjectParameters); + string equipmentDictionaryServiceV2 = string.Concat("http://", _HostNameAndPort, "/EquipmentDictionaryServiceV2/", equipmentDictionaryName, "/", equipmentDictionaryVersionName, "/configuration"); + if (string.IsNullOrEmpty(equipmentDictionaryName) || string.IsNullOrEmpty(equipmentDictionaryVersionName)) + equipmentDictionaryVersion = null; + else + { + if (!_EquipmentDictionaryVersions.TryGetValue(equipmentDictionaryServiceV2, out equipmentDictionaryVersion)) + { + equipmentDictionaryVersion = GetEquipmentDictionaryVersion(equipmentDictionaryServiceV2); + _EquipmentDictionaryVersions.Add(equipmentDictionaryServiceV2, equipmentDictionaryVersion); + } + } + result = new Tuple(equipmentDictionaryServiceV2, equipmentDictionaryName, equipmentDictionaryVersionName, equipmentDictionaryVersion); return result; } @@ -802,70 +815,6 @@ public class AdaptationTesting : ISMTP return result; } - protected Tuple GetEquipmentDictionaryVersionTuple(CellInstanceVersion cellInstanceVersion, string cellInstanceConnectionName, EquipmentTypeVersion equipmentTypeVersion) - { - Tuple result; - string equipmentDictionaryName; - string equipmentDictionaryVersionName; - EquipmentDictionaryVersion equipmentDictionaryVersion; - Dictionary componentModelComponentsIndexes = GetComponentModelComponentsIndexes(cellInstanceVersion, cellInstanceConnectionName); - int[] cellInstanceConnectionNameIndexes = GetCellInstanceConnectionNameIndexes(cellInstanceConnectionName, componentModelComponentsIndexes); - ComponentsCellComponentCellComponent componentsCellComponentCellComponent = cellInstanceVersion.ComponentModel.Components[cellInstanceConnectionNameIndexes[0]].Children[cellInstanceConnectionNameIndexes[1]]; - string[] segments = GetEquipmentDictionaryStrings(componentsCellComponentCellComponent.Equipment, equipmentTypeVersion); - if (_SkipEquipmentDictionary || segments is null || segments.Length != 2 || string.IsNullOrEmpty(segments[0]) || string.IsNullOrEmpty(segments[1])) - { - equipmentDictionaryName = string.Empty; - equipmentDictionaryVersionName = string.Empty; - } - else - { - equipmentDictionaryName = segments[0]; - equipmentDictionaryVersionName = segments[1]; - } - string equipmentDictionaryServiceV2 = string.Concat("http://", _HostNameAndPort, "/EquipmentDictionaryServiceV2/", equipmentDictionaryName, "/", equipmentDictionaryVersionName, "/configuration"); - if (string.IsNullOrEmpty(equipmentDictionaryName) || string.IsNullOrEmpty(equipmentDictionaryVersionName)) - equipmentDictionaryVersion = null; - else - { - if (!_EquipmentDictionaryVersions.TryGetValue(equipmentDictionaryServiceV2, out equipmentDictionaryVersion)) - { - equipmentDictionaryVersion = GetEquipmentDictionaryVersion(equipmentDictionaryServiceV2); - _EquipmentDictionaryVersions.Add(equipmentDictionaryServiceV2, equipmentDictionaryVersion); - } - } - result = new Tuple(equipmentDictionaryServiceV2, equipmentDictionaryName, equipmentDictionaryVersionName, equipmentDictionaryVersion); - return result; - } - - protected Tuple>> GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(Tuple equipmentDictionaryVersionTuple) - { - Tuple>> result; - List> results; - List> collection; - if (_SkipEquipmentDictionary) - results = new List>(); - else if (string.IsNullOrEmpty(equipmentDictionaryVersionTuple.Item1)) - throw new Exception(); - else if (equipmentDictionaryVersionTuple?.Item4?.Events?.Event is null) - results = new List>(); - else if (_EquipmentDictionaryEventDescriptions.TryGetValue(equipmentDictionaryVersionTuple.Item1, out collection)) - results = collection; - else - { - results = new List>(); - foreach (EquipmentDictionaryVersionEventsEvent equipmentDictionaryVersionEventsEvent in equipmentDictionaryVersionTuple.Item4.Events.Event) - { - if (string.IsNullOrEmpty(equipmentDictionaryVersionEventsEvent.Description)) - continue; - if (!equipmentDictionaryVersionEventsEvent.IsAlwaysEnabled) - continue; - results.Add(new Tuple(equipmentDictionaryVersionEventsEvent.Name, equipmentDictionaryVersionEventsEvent.Description)); - } - } - result = new Tuple>>(equipmentDictionaryVersionTuple.Item1, results); - return result; - } - protected Dictionary GetKeyValuePairs(string cellInstanceName, string cellInstanceVersionName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList modelObjectParameters, string equipmentDictionaryName, List> equipmentDictionaryIsAlwaysEnabledEvents, int edaConnectionPortNumber) { Dictionary results = new() @@ -886,108 +835,6 @@ public class AdaptationTesting : ISMTP return results; } - public string[] GetCSharpText(string testName) - { - string[] results; - string testResultsDirectory = GetTestResultsDirectory(_HasWaitForProperty); - MethodBaseName mbn = GetMethodBaseName(_DummyRoot, _Environment, _HasWaitForProperty, testName, testResultsDirectory); - FileInfo fileInfo = new(mbn.FileFullName); - if (!string.IsNullOrEmpty(mbn.CellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName)) - _ = Directory.CreateDirectory(fileInfo.Directory.FullName); - Tuple cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); - results = GetCSharpTextB(fileInfo, mbn.CellInstanceName, mbn.CellInstanceVersionName, cellInstanceVersionTuple.Item2); - return results; - } - - public string[] GetConfiguration(MethodBase methodBase) - { - string[] results; - MethodBaseName mbn = GetMethodBaseName(methodBase); - FileInfo fileInfo = new(mbn.FileFullName); - if (!string.IsNullOrEmpty(mbn.CellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName)) - _ = Directory.CreateDirectory(fileInfo.Directory.FullName); - Tuple cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); - Tuple fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, mbn.CellInstanceConnectionName); - if (string.IsNullOrEmpty(mbn.Ticks) && fileConnectorConfigurationTuple.Item2?.FileScanningIntervalInSeconds is not null) - { - string fileScanningIntervalInSecondsLine; - string versionDirectory = Path.GetDirectoryName(fileInfo.DirectoryName); - if (fileConnectorConfigurationTuple.Item2.FileScanningIntervalInSeconds.Value < 0) - fileScanningIntervalInSecondsLine = $"-\t{fileConnectorConfigurationTuple.Item2.FileScanningIntervalInSeconds.Value:0000}\t{Path.GetFileName(fileInfo.DirectoryName)}"; - else - fileScanningIntervalInSecondsLine = $"+\t{fileConnectorConfigurationTuple.Item2.FileScanningIntervalInSeconds.Value:+0000}\t{Path.GetFileName(fileInfo.DirectoryName)}"; - File.AppendAllLines(Path.Combine(versionDirectory, "FileScanningIntervalInSeconds.txt"), new string[] { fileScanningIntervalInSecondsLine }); - } - Tuple equipmentTypeVersionTuple = GetEquipmentTypeVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName); - Tuple parameterizedModelObjectDefinitionTypeTuple = GetParameterizedModelObjectDefinitionTypeTuple(equipmentTypeVersionTuple); - Tuple> modelObjectParametersTuple = GetModelObjectParameters(equipmentTypeVersionTuple); - Tuple equipmentDictionaryVersionTuple = GetEquipmentDictionaryVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName, equipmentTypeVersionTuple.Item4); - Tuple>> equipmentDictionaryIsAlwaysEnabledEventsTuple = GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(equipmentDictionaryVersionTuple); - Dictionary objects = GetKeyValuePairs(mbn.CellInstanceName, mbn.CellInstanceVersionName, mbn.CellInstanceConnectionName, fileConnectorConfigurationTuple.Item2, equipmentTypeVersionTuple.Item2, parameterizedModelObjectDefinitionTypeTuple.Item2, modelObjectParametersTuple.Item2, equipmentDictionaryVersionTuple.Item2, equipmentDictionaryIsAlwaysEnabledEventsTuple.Item2, cellInstanceVersionTuple.Item2.EdaConnection.PortNumber); - string json = JsonSerializer.Serialize(objects, new JsonSerializerOptions { WriteIndented = true }); - results = new string[] { fileInfo.FullName, json }; - return results; - } - - public IFileRead Get(MethodBase methodBase, string sourceFileLocation, string sourceFileFilter, bool useCyclicalForDescription) - { - IFileRead result; - MethodBaseName mbn = GetMethodBaseName(methodBase); - FileInfo fileInfo = new(mbn.FileFullName); - Dictionary fileParameter = new(); - if (!string.IsNullOrEmpty(mbn.CellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName)) - _ = Directory.CreateDirectory(fileInfo.Directory.FullName); - Dictionary> dummyRuns = new(); - Dictionary> staticRuns = new(); - Tuple cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); - Tuple fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, mbn.CellInstanceConnectionName); - Tuple equipmentTypeVersionTuple = GetEquipmentTypeVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName); - Tuple parameterizedModelObjectDefinitionTypeTuple = GetParameterizedModelObjectDefinitionTypeTuple(equipmentTypeVersionTuple); - Tuple> modelObjectParametersTuple = GetModelObjectParameters(equipmentTypeVersionTuple); - Tuple equipmentDictionaryVersionTuple = GetEquipmentDictionaryVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName, equipmentTypeVersionTuple.Item4); - _ = GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(equipmentDictionaryVersionTuple); - if (!string.IsNullOrEmpty(sourceFileLocation) && sourceFileLocation != fileConnectorConfigurationTuple.Item2.SourceFileLocation) - fileConnectorConfigurationTuple.Item2.SourceFileLocation = sourceFileLocation; - if (!string.IsNullOrEmpty(sourceFileFilter) && sourceFileFilter != fileConnectorConfigurationTuple.Item2.SourceFileFilter) - { - fileConnectorConfigurationTuple.Item2.SourceFileFilter = sourceFileFilter; - fileConnectorConfigurationTuple.Item2.SourceFileFilters = sourceFileFilter.Split('|').ToList(); - } - if (_TestContext.FullyQualifiedTestClassName.Contains(nameof(Extract))) - { - try - { - if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.ErrorTargetFileLocation)) - { - if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.ErrorTargetFileLocation)) - _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.ErrorTargetFileLocation); - } - if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.SourceFileLocation)) - { - if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.SourceFileLocation)) - _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.SourceFileLocation); - } - if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.TargetFileLocation)) - { - if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.TargetFileLocation)) - _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.TargetFileLocation); - } - if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder)) - { - if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder.Split('|')[0])) - _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder.Split('|')[0]); - } - } - catch (IOException ex) - { - if (!ex.Message.Contains("SMB1")) - throw; - } - } - result = FileHandlers.CellInstanceConnectionName.Get(this, fileParameter, mbn.CellInstanceName, mbn.CellInstanceConnectionName, fileConnectorConfigurationTuple.Item2, equipmentTypeVersionTuple.Item2, parameterizedModelObjectDefinitionTypeTuple.Item2, modelObjectParametersTuple.Item2, equipmentDictionaryVersionTuple.Item2, dummyRuns, staticRuns, useCyclicalForDescription, connectionCount: cellInstanceVersionTuple.Item2.EquipmentConnections.Length); - return result; - } - public string[] GetVariables(MethodBase methodBase, string check, bool validatePDSF = true) { string[] results; @@ -1090,80 +937,118 @@ public class AdaptationTesting : ISMTP return results; } - internal static Tuple GetLogisticsColumnsAndBody(string fileFullName) + private string[] GetTextFiles(MethodBaseName mbn) { - Tuple results; - results = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(fileFullName); - Assert.IsFalse(string.IsNullOrEmpty(results.Item1)); - Assert.IsTrue(results.Item2.Length > 0, "Column check"); - Assert.IsTrue(results.Item3.Length > 0, "Body check"); - return results; - } - - internal static Tuple GetLogisticsColumnsAndBody(string searchDirectory, string searchPattern) - { - Tuple results; - if (searchPattern.Length > 3 && !searchPattern.Contains('*') && File.Exists(searchPattern)) - results = GetLogisticsColumnsAndBody(searchPattern); + string[] results; + if (string.IsNullOrEmpty(mbn.TextFileDirectory)) + results = Array.Empty(); + else if (!Directory.Exists(mbn.TextFileDirectory)) + { + results = Array.Empty(); + if (!_HasWaitForProperty) + _ = Directory.CreateDirectory(mbn.TextFileDirectory); + else + { + string renameDirectory = Path.Combine(Path.GetDirectoryName(mbn.TextFileDirectory), $"_Rename - {Path.GetFileName(mbn.TextFileDirectory)}"); + _ = Directory.CreateDirectory(renameDirectory); + _ = Process.Start("explorer.exe", renameDirectory); + File.WriteAllText(Path.Combine(renameDirectory, $"{nameof(FileConnectorConfiguration.SourceFileFilter)}.txt"), string.Empty); + File.WriteAllText(Path.Combine(renameDirectory, $"{nameof(FileConnectorConfiguration.SourceFileLocation)}.txt"), string.Empty); + } + } else { - string[] pdsfFiles; - pdsfFiles = Directory.GetFiles(searchDirectory, searchPattern, SearchOption.TopDirectoryOnly); - if (pdsfFiles.Length == 0) - _ = Process.Start("explorer.exe", searchDirectory); - Assert.IsTrue(pdsfFiles.Length != 0, "GetFiles check"); - results = GetLogisticsColumnsAndBody(pdsfFiles[0]); + results = Directory.GetFiles(mbn.TextFileDirectory, "*.txt", SearchOption.TopDirectoryOnly); + if (!string.IsNullOrEmpty(mbn.Ticks) && _HasWaitForProperty && results.Length == 0) + { + _ = Process.Start("explorer.exe", mbn.TextFileDirectory); + File.WriteAllText(Path.Combine(mbn.TextFileDirectory, "_ Why.why"), string.Empty); + } } - Assert.IsFalse(string.IsNullOrEmpty(results.Item1)); - Assert.IsTrue(results.Item2.Length > 0, "Column check"); - Assert.IsTrue(results.Item3.Length > 0, "Body check"); return results; } - internal static Tuple GetLogisticsColumnsAndBody(IFileRead fileRead, Logistics logistics, Tuple> extractResult, Tuple pdsf) + public IFileRead Get(MethodBase methodBase, string sourceFileLocation, string sourceFileFilter, bool useCyclicalForDescription) { - Tuple results; - string text = ProcessDataStandardFormat.GetPDSFText(fileRead, logistics, extractResult.Item3, logisticsText: pdsf.Item1); - string[] lines = text.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); - results = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(logistics.ReportFullPath, lines); - Assert.IsFalse(string.IsNullOrEmpty(results.Item1)); - Assert.IsTrue(results.Item2.Length > 0, "Column check"); - Assert.IsTrue(results.Item3.Length > 0, "Body check"); - return results; - } - - internal static string[] GetItem2(Tuple pdsf, Tuple pdsfNew) - { - JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; - string jsonOld = JsonSerializer.Serialize(pdsf.Item2, pdsf.Item2.GetType(), jsonSerializerOptions); - string jsonNew = JsonSerializer.Serialize(pdsfNew.Item2, pdsfNew.Item2.GetType(), jsonSerializerOptions); - return new string[] { jsonOld, jsonNew }; - } - - internal static string[] GetItem3(Tuple pdsf, Tuple pdsfNew) - { - string joinOld = string.Join(System.Environment.NewLine, from l in pdsf.Item3 select string.Join('\t', from t in l.Split('\t') where !t.Contains(@"\\") select t)); - string joinNew = string.Join(System.Environment.NewLine, from l in pdsfNew.Item3 select string.Join('\t', from t in l.Split('\t') where !t.Contains(@"\\") select t)); - return new string[] { joinOld, joinNew }; - } - - internal static void UpdatePassDirectory(string searchDirectory) - { - DateTime dateTime = DateTime.Now; - try - { Directory.SetLastWriteTime(searchDirectory, dateTime); } - catch (Exception) { } - string ticksDirectory = Path.GetDirectoryName(searchDirectory); - try - { Directory.SetLastWriteTime(ticksDirectory, dateTime); } - catch (Exception) { } - string[] directories = Directory.GetDirectories(searchDirectory, "*", SearchOption.TopDirectoryOnly); - foreach (string directory in directories) + IFileRead result; + MethodBaseName mbn = GetMethodBaseName(methodBase); + FileInfo fileInfo = new(mbn.FileFullName); + Dictionary fileParameter = new(); + if (!string.IsNullOrEmpty(mbn.CellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName)) + _ = Directory.CreateDirectory(fileInfo.Directory.FullName); + Dictionary> dummyRuns = new(); + Dictionary> staticRuns = new(); + Tuple cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); + Tuple fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, mbn.CellInstanceConnectionName); + Tuple equipmentTypeVersionTuple = GetEquipmentTypeVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName); + Tuple parameterizedModelObjectDefinitionTypeTuple = GetParameterizedModelObjectDefinitionTypeTuple(equipmentTypeVersionTuple); + Tuple> modelObjectParametersTuple = GetModelObjectParameters(equipmentTypeVersionTuple); + Tuple equipmentDictionaryVersionTuple = GetEquipmentDictionaryVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName, equipmentTypeVersionTuple.Item4); + _ = GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(equipmentDictionaryVersionTuple); + if (!string.IsNullOrEmpty(sourceFileLocation) && sourceFileLocation != fileConnectorConfigurationTuple.Item2.SourceFileLocation) + fileConnectorConfigurationTuple.Item2.SourceFileLocation = sourceFileLocation; + if (!string.IsNullOrEmpty(sourceFileFilter) && sourceFileFilter != fileConnectorConfigurationTuple.Item2.SourceFileFilter) + { + fileConnectorConfigurationTuple.Item2.SourceFileFilter = sourceFileFilter; + fileConnectorConfigurationTuple.Item2.SourceFileFilters = sourceFileFilter.Split('|').ToList(); + } + if (_TestContext.FullyQualifiedTestClassName.Contains(nameof(Extract))) { try - { Directory.SetLastWriteTime(directory, dateTime); } - catch (Exception) { } + { + if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.ErrorTargetFileLocation)) + { + if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.ErrorTargetFileLocation)) + _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.ErrorTargetFileLocation); + } + if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.SourceFileLocation)) + { + if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.SourceFileLocation)) + _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.SourceFileLocation); + } + if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.TargetFileLocation)) + { + if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.TargetFileLocation)) + _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.TargetFileLocation); + } + if (!string.IsNullOrEmpty(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder)) + { + if (!Directory.Exists(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder.Split('|')[0])) + _ = Directory.CreateDirectory(fileConnectorConfigurationTuple.Item2.AlternateTargetFolder.Split('|')[0]); + } + } + catch (IOException ex) + { + if (!ex.Message.Contains("SMB1")) + throw; + } } + result = FileHandlers.CellInstanceConnectionName.Get(this, fileParameter, mbn.CellInstanceName, mbn.CellInstanceConnectionName, fileConnectorConfigurationTuple.Item2, equipmentTypeVersionTuple.Item2, parameterizedModelObjectDefinitionTypeTuple.Item2, modelObjectParametersTuple.Item2, equipmentDictionaryVersionTuple.Item2, dummyRuns, staticRuns, useCyclicalForDescription, connectionCount: cellInstanceVersionTuple.Item2.EquipmentConnections.Length); + return result; + } + + internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string fileFullName) + { + ProcessDataStandardFormat result; + result = ProcessDataStandardFormat.GetProcessDataStandardFormat(fileFullName); + Assert.IsTrue(result.Logistics.Count > 0, "Logistics check"); + Assert.IsFalse(string.IsNullOrEmpty(result.Logistics[0])); + Assert.IsTrue(result.Columns.Count > 0, "Column check"); + Assert.IsTrue(result.Body.Count > 0, "Body check"); + return result; + } + + internal static ProcessDataStandardFormat GetProcessDataStandardFormat(IFileRead fileRead, Logistics logistics, Tuple> extractResult, ProcessDataStandardFormat processDataStandardFormat) + { + ProcessDataStandardFormat result; + string text = ProcessDataStandardFormat.GetPDSFText(fileRead, logistics, extractResult.Item3, logisticsText: processDataStandardFormat.Logistics[0]); + string[] lines = text.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + result = ProcessDataStandardFormat.GetProcessDataStandardFormat(logistics.ReportFullPath, lines); + Assert.IsTrue(result.Logistics.Count > 0, "Logistics check"); + Assert.IsFalse(string.IsNullOrEmpty(result.Logistics[0])); + Assert.IsTrue(result.Columns.Count > 0, "Column check"); + Assert.IsTrue(result.Body.Count > 0, "Body check"); + return result; } internal static string GetFileName(MethodBase methodBase) @@ -1199,6 +1084,25 @@ public class AdaptationTesting : ISMTP return result; } + internal static void UpdatePassDirectory(string searchDirectory) + { + DateTime dateTime = DateTime.Now; + try + { Directory.SetLastWriteTime(searchDirectory, dateTime); } + catch (Exception) { } + string ticksDirectory = Path.GetDirectoryName(searchDirectory); + try + { Directory.SetLastWriteTime(ticksDirectory, dateTime); } + catch (Exception) { } + string[] directories = Directory.GetDirectories(searchDirectory, "*", SearchOption.TopDirectoryOnly); + foreach (string directory in directories) + { + try + { Directory.SetLastWriteTime(directory, dateTime); } + catch (Exception) { } + } + } + internal static void CompareSaveTSV(string textFileDirectory, string[] join) { if (join[0] != join[1]) @@ -1219,14 +1123,25 @@ public class AdaptationTesting : ISMTP } } - internal static void CompareSave(string textFileDirectory, Tuple pdsf, Tuple pdsfNew) + internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string searchDirectory, string searchPattern) { - if (pdsf.Item1 != pdsfNew.Item1) + ProcessDataStandardFormat result; + if (searchPattern.Length > 3 && !searchPattern.Contains('*') && File.Exists(searchPattern)) + result = GetProcessDataStandardFormat(searchPattern); + else { - _ = Process.Start("explorer.exe", textFileDirectory); - File.WriteAllText(Path.Combine(textFileDirectory, "0.dat"), pdsf.Item1); - File.WriteAllText(Path.Combine(textFileDirectory, "1.dat"), pdsfNew.Item1); + string[] pdsfFiles; + pdsfFiles = Directory.GetFiles(searchDirectory, searchPattern, SearchOption.TopDirectoryOnly); + if (pdsfFiles.Length == 0) + _ = Process.Start("explorer.exe", searchDirectory); + Assert.AreNotEqual(0, pdsfFiles.Length, "GetFiles check"); + result = GetProcessDataStandardFormat(pdsfFiles[0]); } + Assert.IsTrue(result.Logistics.Count > 0, "Logistics check"); + Assert.IsFalse(string.IsNullOrEmpty(result.Logistics[0])); + Assert.IsTrue(result.Columns.Count > 0, "Column check"); + Assert.IsTrue(result.Body.Count > 0, "Body check"); + return result; } internal static IFileRead GetWriteConfigurationGetFileRead(MethodBase methodBase, string check, AdaptationTesting adaptationTesting) @@ -1240,6 +1155,21 @@ public class AdaptationTesting : ISMTP return result; } + internal static string[] GetItem2(ProcessDataStandardFormat processDataStandardFormat, ProcessDataStandardFormat processDataStandardFormatNew) + { + JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; + string jsonOld = JsonSerializer.Serialize(processDataStandardFormat.Columns, processDataStandardFormat.Columns.GetType(), jsonSerializerOptions); + string jsonNew = JsonSerializer.Serialize(processDataStandardFormatNew.Columns, processDataStandardFormatNew.Columns.GetType(), jsonSerializerOptions); + return new string[] { jsonOld, jsonNew }; + } + + internal static string[] GetItem3(ProcessDataStandardFormat processDataStandardFormat, ProcessDataStandardFormat processDataStandardFormatNew) + { + string joinOld = string.Join(System.Environment.NewLine, from l in processDataStandardFormat.Body select string.Join('\t', from t in l.Split('\t') where !t.Contains(@"\\") select t)); + string joinNew = string.Join(System.Environment.NewLine, from l in processDataStandardFormatNew.Body select string.Join('\t', from t in l.Split('\t') where !t.Contains(@"\\") select t)); + return new string[] { joinOld, joinNew }; + } + internal static string ReExtractCompareUpdatePassDirectory(string[] variables, IFileRead fileRead, Logistics logistics, bool validatePDSF = true) { string result; @@ -1252,20 +1182,20 @@ public class AdaptationTesting : ISMTP Assert.IsNotNull(extractResult.Item3); Assert.IsNotNull(extractResult.Item4); if (!validatePDSF) - _ = GetLogisticsColumnsAndBody(fileRead, logistics, extractResult, new(string.Empty, Array.Empty(), Array.Empty())); + _ = GetProcessDataStandardFormat(fileRead, logistics, extractResult, ProcessDataStandardFormat.GetEmpty(logistics)); else { Assert.IsTrue(extractResult.Item3.Length > 0, "extractResult Array Length check!"); - Tuple pdsf = GetLogisticsColumnsAndBody(variables[2], variables[4]); - Tuple pdsfNew = GetLogisticsColumnsAndBody(fileRead, logistics, extractResult, pdsf); - CompareSave(variables[5], pdsf, pdsfNew); - Assert.IsTrue(pdsf.Item1 == pdsfNew.Item1, "Item1 check!"); - string[] json = GetItem2(pdsf, pdsfNew); + ProcessDataStandardFormat processDataStandardFormat = GetProcessDataStandardFormat(variables[2], variables[4]); + ProcessDataStandardFormat processDataStandardFormatNew = GetProcessDataStandardFormat(fileRead, logistics, extractResult, processDataStandardFormat); + CompareSave(variables[5], processDataStandardFormat, processDataStandardFormatNew); + Assert.AreEqual(processDataStandardFormatNew.Logistics, processDataStandardFormat.Logistics, "Item1 check!"); + string[] json = GetItem2(processDataStandardFormat, processDataStandardFormatNew); CompareSaveJSON(variables[5], json); - Assert.IsTrue(json[0] == json[1], "Item2 check!"); - string[] join = GetItem3(pdsf, pdsfNew); + Assert.AreEqual(json[1], json[0], "Item2 check!"); + string[] join = GetItem3(processDataStandardFormat, processDataStandardFormatNew); CompareSaveTSV(variables[5], join); - Assert.IsTrue(join[0] == join[1], "Item3 (Join) check!"); + Assert.AreEqual(join[1], join[0], "Item3 (Join) check!"); } UpdatePassDirectory(variables[2]); } @@ -1273,6 +1203,89 @@ public class AdaptationTesting : ISMTP return result; } -} -// namespace Adaptation._Tests.Helpers { public class AdaptationTesting { } } -// 2022-08-05 -> AdaptationTesting \ No newline at end of file + internal static void CompareSave(string textFileDirectory, ProcessDataStandardFormat processDataStandardFormat, ProcessDataStandardFormat processDataStandardFormatNew) + { + if (processDataStandardFormat.Logistics[0] != processDataStandardFormatNew.Logistics[0]) + { + _ = Process.Start("explorer.exe", textFileDirectory); + File.WriteAllText(Path.Combine(textFileDirectory, "0.dat"), processDataStandardFormat.Logistics[0]); + File.WriteAllText(Path.Combine(textFileDirectory, "1.dat"), processDataStandardFormatNew.Logistics[0]); + } + } + + protected static Stream ToStream(string @this) + { + MemoryStream memoryStream = new(); + StreamWriter streamWriter = new(memoryStream); + streamWriter.Write(@this); + streamWriter.Flush(); + memoryStream.Position = 0; + return memoryStream; + } + + protected Tuple GetParameterizedModelObjectDefinitionTypeTuple(Tuple equipmentTypeVersionTuple) + { + Tuple result; + string parameterizedModelObjectDefinitionType; + if (_FileConnectorConfigurations.ContainsKey(equipmentTypeVersionTuple.Item1)) + parameterizedModelObjectDefinitionType = _ParameterizedModelObjectDefinitionTypes[equipmentTypeVersionTuple.Item1]; + else + parameterizedModelObjectDefinitionType = equipmentTypeVersionTuple.Item4.FileHandlerObjectTypes.ParameterizedModelObjectDefinition.Type; + result = new Tuple(equipmentTypeVersionTuple.Item1, parameterizedModelObjectDefinitionType); + return result; + } + + protected Tuple> GetModelObjectParameters(Tuple equipmentTypeVersionTuple) + { + Tuple> result; + IList modelObjectParameters; + if (_FileConnectorConfigurations.ContainsKey(equipmentTypeVersionTuple.Item1)) + modelObjectParameters = _ModelObjectParameters[equipmentTypeVersionTuple.Item1]; + else + { + string json = JsonSerializer.Serialize(equipmentTypeVersionTuple.Item4, new JsonSerializerOptions { WriteIndented = true }); + modelObjectParameters = GetModelObjectParameters(json); + } + result = new Tuple>(equipmentTypeVersionTuple.Item1, modelObjectParameters); + return result; + } + + protected Tuple>> GetEquipmentDictionaryIsAlwaysEnabledEventsTuple(Tuple equipmentDictionaryVersionTuple) + { + Tuple>> result; + List> results; + List> collection; + if (_SkipEquipmentDictionary) + results = new List>(); + else if (string.IsNullOrEmpty(equipmentDictionaryVersionTuple.Item1)) + throw new Exception(); + else if (equipmentDictionaryVersionTuple?.Item4?.Events?.Event is null) + results = new List>(); + else if (_EquipmentDictionaryEventDescriptions.TryGetValue(equipmentDictionaryVersionTuple.Item1, out collection)) + results = collection; + else + { + results = new List>(); + foreach (EquipmentDictionaryVersionEventsEvent equipmentDictionaryVersionEventsEvent in equipmentDictionaryVersionTuple.Item4.Events.Event) + { + if (string.IsNullOrEmpty(equipmentDictionaryVersionEventsEvent.Description)) + continue; + if (!equipmentDictionaryVersionEventsEvent.IsAlwaysEnabled) + continue; + results.Add(new Tuple(equipmentDictionaryVersionEventsEvent.Name, equipmentDictionaryVersionEventsEvent.Description)); + } + } + result = new Tuple>>(equipmentDictionaryVersionTuple.Item1, results); + return result; + } + + public (string i, string v, string c, string n, int p, string f) GetCellInstanceVersionCore(string testName) + { + (string, string, string, string, int, string) results; + MethodBaseName mbn = GetMethodBaseName(_DummyRoot, _Environment, _HasWaitForProperty, testName, @"D:\Tmp\Phares"); + Tuple cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); + results = new(mbn.CellInstanceName, mbn.CellInstanceVersionName, cellInstanceVersionTuple.Item2.CellCommunicatingRule, cellInstanceVersionTuple.Item2.CellNotCommunicatingRule, cellInstanceVersionTuple.Item2.EdaConnection.PortNumber, cellInstanceVersionTuple.Item2.FrozenBy); + return results; + } + +} \ No newline at end of file diff --git a/Adaptation/_Tests/Static/MET08AWCT.cs b/Adaptation/_Tests/Static/MET08AWCT.cs index d66a3af..a5fae1d 100644 --- a/Adaptation/_Tests/Static/MET08AWCT.cs +++ b/Adaptation/_Tests/Static/MET08AWCT.cs @@ -51,7 +51,7 @@ public class MET08AWCT : LoggingUnitTesting, IDisposable public void TestDateTime() { DateTime dateTime = DateTime.Now; - Assert.IsTrue(dateTime.ToString("M/d/yyyy h:mm:ss tt") == dateTime.ToString()); + Assert.AreEqual(dateTime.ToString(), dateTime.ToString("M/d/yyyy h:mm:ss tt")); } #if DEBUG diff --git a/Adaptation/_Tests/Static/WC.cs b/Adaptation/_Tests/Static/WC.cs index 1bbe73c..899c944 100644 --- a/Adaptation/_Tests/Static/WC.cs +++ b/Adaptation/_Tests/Static/WC.cs @@ -51,7 +51,7 @@ public class WC : LoggingUnitTesting, IDisposable public void TestDateTime() { DateTime dateTime = DateTime.Now; - Assert.IsTrue(dateTime.ToString("M/d/yyyy h:mm:ss tt") == dateTime.ToString()); + Assert.AreEqual(dateTime.ToString(), dateTime.ToString("M/d/yyyy h:mm:ss tt")); } #if DEBUG diff --git a/FileHandlers/FileRead.cs b/FileHandlers/FileRead.cs index 568f49f..939da55 100644 --- a/FileHandlers/FileRead.cs +++ b/FileHandlers/FileRead.cs @@ -37,7 +37,7 @@ public partial class FileRead : FileReaderHandler, ISMTP private FilePathGenerator _FilePathGeneratorForTarget; private readonly List _EquipmentParameters; private static readonly Dictionary> _DummyRuns; - private static readonly Dictionary> _StaticRuns; + private static readonly Dictionary> _StaticRuns; static FileRead() { diff --git a/MET08AWCT.csproj b/MET08AWCT.csproj index 6e48f67..d29931e 100644 --- a/MET08AWCT.csproj +++ b/MET08AWCT.csproj @@ -138,6 +138,7 @@ +