Bug in yml dotnet tool PackageReference arrangement RDS Blank Change int dotnet test nuget ^ [spcepiworld].[dbo].[evnt_inf] Assembly Version WS Result bug fix and Nuget bump, PSN, Reactor and Extra RDS rule OpenInsightApi and testRunTitle editorconfig bugs Fix Type serializerValue RDS oversight PropertyNameCaseInsensitive Save check for file already present NoWaitDirectory MoveArchive allow empty directory and continueOnError for clean files CreatePointerFile and more on NoWaitDirectory
266 lines
12 KiB
C#
266 lines
12 KiB
C#
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
|
|
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
|
|
using Adaptation.Shared;
|
|
using Adaptation.Shared.Duplicator;
|
|
using Adaptation.Shared.Methods;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
|
|
namespace Adaptation.FileHandlers.MoveMatchingFiles;
|
|
|
|
public class FileRead : Shared.FileRead, IFileRead
|
|
{
|
|
|
|
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) :
|
|
base(new Description(), false, smtp, fileParameter, cellInstanceName, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted)
|
|
{
|
|
_MinFileLength = 10;
|
|
_NullData = string.Empty;
|
|
_Logistics = new(this);
|
|
if (_FileParameter is null)
|
|
throw new Exception(cellInstanceConnectionName);
|
|
if (_ModelObjectParameterDefinitions is null)
|
|
throw new Exception(cellInstanceConnectionName);
|
|
if (!_IsDuplicator)
|
|
throw new Exception(cellInstanceConnectionName);
|
|
}
|
|
|
|
void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception)
|
|
{
|
|
bool isErrorFile = exception is not null;
|
|
if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath))
|
|
{
|
|
FileInfo fileInfo = new(_Logistics.ReportFullPath);
|
|
if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime)
|
|
File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime);
|
|
}
|
|
Move(extractResults);
|
|
}
|
|
|
|
void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null);
|
|
|
|
string IFileRead.GetEventDescription()
|
|
{
|
|
string result = _Description.GetEventDescription();
|
|
return result;
|
|
}
|
|
|
|
List<string> IFileRead.GetHeaderNames()
|
|
{
|
|
List<string> results = _Description.GetHeaderNames();
|
|
return results;
|
|
}
|
|
|
|
string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception)
|
|
{
|
|
string[] results = Move(extractResults, to, from, resolvedFileLocation, exception);
|
|
return results;
|
|
}
|
|
|
|
JsonProperty[] IFileRead.GetDefault()
|
|
{
|
|
JsonProperty[] results = _Description.GetDefault(this, _Logistics);
|
|
return results;
|
|
}
|
|
|
|
Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement()
|
|
{
|
|
Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this);
|
|
return results;
|
|
}
|
|
|
|
List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData)
|
|
{
|
|
List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData);
|
|
return results;
|
|
}
|
|
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName)
|
|
{
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
|
if (string.IsNullOrEmpty(eventName))
|
|
throw new Exception();
|
|
_ReportFullPath = reportFullPath;
|
|
DateTime dateTime = DateTime.Now;
|
|
results = GetExtractResult(reportFullPath, dateTime);
|
|
if (results.Item3 is null)
|
|
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4);
|
|
if (results.Item3.Length > 0 && _IsEAFHosted)
|
|
WritePDSF(this, results.Item3);
|
|
UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks);
|
|
return results;
|
|
}
|
|
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract()
|
|
{
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
|
List<string> headerNames = _Description.GetHeaderNames();
|
|
Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this);
|
|
results = ReExtract(this, headerNames, keyValuePairs);
|
|
return results;
|
|
}
|
|
|
|
private static List<string> GetSearchDirectories(int numberLength, string parentDirectory)
|
|
{
|
|
List<string> results = new();
|
|
string[] directories = Directory.GetDirectories(parentDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
foreach (string directory in directories)
|
|
{
|
|
if (Path.GetFileName(directory).Length != numberLength)
|
|
continue;
|
|
results.Add(directory);
|
|
}
|
|
results.Sort();
|
|
return results;
|
|
}
|
|
|
|
private List<string> GetMatchingFiles(long ticks, string reportFullPath, List<string> searchDirectories)
|
|
{
|
|
List<string> results = new();
|
|
string[] found;
|
|
string fileName = Path.GetFileName(reportFullPath);
|
|
foreach (string searchDirectory in searchDirectories)
|
|
{
|
|
for (int i = 0; i < int.MaxValue; i++)
|
|
{
|
|
found = Directory.GetFiles(searchDirectory, fileName, SearchOption.AllDirectories);
|
|
if (found.Any())
|
|
{
|
|
results.AddRange(found);
|
|
break;
|
|
}
|
|
if (new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds > _BreakAfterSeconds)
|
|
break;
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private static List<(string matchingFile, string checkFile)> GetCollection(int numberLength, string parentDirectory, List<string> matchingFiles)
|
|
{
|
|
List<(string matchingFile, string checkFile)> results = new();
|
|
string checkFile;
|
|
int parentDirectoryLength = parentDirectory.Length;
|
|
foreach (string matchingFile in matchingFiles)
|
|
{
|
|
checkFile = $"{matchingFile[0]}{matchingFile.Substring(parentDirectoryLength + numberLength + 1)}";
|
|
results.Add(new(matchingFile, checkFile));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private static List<(string, string, string, string, string)> GetCollection(List<(string matchingFile, string checkFile)> collection)
|
|
{
|
|
List<(string, string, string, string, string)> results = new();
|
|
string errFile;
|
|
string checkDirectory;
|
|
string noWaitDirectory;
|
|
foreach ((string matchingFile, string checkFile) in collection)
|
|
{
|
|
errFile = string.Concat(checkFile, ".err");
|
|
checkDirectory = Path.GetDirectoryName(checkFile);
|
|
if (!Directory.Exists(checkDirectory))
|
|
_ = Directory.CreateDirectory(checkDirectory);
|
|
noWaitDirectory = Path.Combine(checkDirectory, "NoWaitDirectory");
|
|
results.Add(new(matchingFile, checkFile, errFile, checkDirectory, noWaitDirectory));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private void MoveCollection(DateTime dateTime, List<(string matchingFile, string checkFile)> collection)
|
|
{
|
|
long preWait;
|
|
List<(string checkFile, string errFile)> postCollection = new();
|
|
foreach ((string matchingFile, string checkFile, string errFile, string checkDirectory, string noWaitDirectory) in GetCollection(collection))
|
|
{
|
|
File.Move(matchingFile, checkFile);
|
|
if (Directory.Exists(noWaitDirectory))
|
|
{
|
|
postCollection.Add(new(checkFile, errFile));
|
|
continue;
|
|
}
|
|
if (_FileConnectorConfiguration?.FileHandleWaitTime is null)
|
|
preWait = DateTime.Now.AddMilliseconds(1234).Ticks;
|
|
else
|
|
preWait = DateTime.Now.AddMilliseconds(_FileConnectorConfiguration.FileHandleWaitTime.Value).Ticks;
|
|
for (short i = 0; i < short.MaxValue; i++)
|
|
{
|
|
if (DateTime.Now.Ticks > preWait)
|
|
break;
|
|
Thread.Sleep(500);
|
|
}
|
|
for (int i = 0; i < int.MaxValue; i++)
|
|
{
|
|
if (File.Exists(errFile))
|
|
throw new Exception(File.ReadAllText(errFile));
|
|
if (!File.Exists(checkFile))
|
|
break;
|
|
if (new TimeSpan(DateTime.Now.Ticks - dateTime.Ticks).TotalSeconds > _BreakAfterSeconds)
|
|
throw new Exception($"Not all files were consumed after {_BreakAfterSeconds} second(s)!");
|
|
Thread.Sleep(500);
|
|
}
|
|
}
|
|
if (postCollection.Any())
|
|
{
|
|
Thread.Sleep(500);
|
|
StringBuilder stringBuilder = new();
|
|
foreach ((string checkFile, string errFile) in postCollection)
|
|
{
|
|
if (File.Exists(errFile))
|
|
_ = stringBuilder.AppendLine(File.ReadAllText(errFile));
|
|
if (File.Exists(checkFile))
|
|
_ = stringBuilder.AppendLine($"<{checkFile}> was not consumed by the end!");
|
|
}
|
|
if (stringBuilder.Length > 0)
|
|
throw new Exception(stringBuilder.ToString());
|
|
}
|
|
}
|
|
|
|
private static void CreatePointerFile(int numberLength, string parentDirectory, List<string> matchingFiles)
|
|
{
|
|
#nullable enable
|
|
string checkFile;
|
|
string writeFile;
|
|
string? directoryName;
|
|
int parentDirectoryLength = parentDirectory.Length;
|
|
foreach (string matchingFile in matchingFiles)
|
|
{
|
|
directoryName = Path.GetDirectoryName(matchingFile);
|
|
if (directoryName is null)
|
|
continue;
|
|
checkFile = $"{matchingFile[0]}{directoryName.Substring(parentDirectoryLength + numberLength + 1)}";
|
|
writeFile = Path.Combine(parentDirectory, $"{directoryName.Substring(parentDirectory.Length + 1, numberLength)}.txt");
|
|
if (File.Exists(writeFile))
|
|
continue;
|
|
File.AppendAllLines(writeFile, new string[] { parentDirectory, matchingFile, directoryName, checkFile });
|
|
}
|
|
#nullable disable
|
|
}
|
|
|
|
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
|
|
{
|
|
Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>());
|
|
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
|
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
|
SetFileParameterLotIDToLogisticsMID();
|
|
int numberLength = 2;
|
|
long ticks = dateTime.Ticks;
|
|
string parentParentDirectory = GetParentParent(reportFullPath);
|
|
List<string> searchDirectories = GetSearchDirectories(numberLength, parentParentDirectory);
|
|
List<string> matchingFiles = GetMatchingFiles(ticks, reportFullPath, searchDirectories);
|
|
if (matchingFiles.Count != searchDirectories.Count)
|
|
throw new Exception($"Didn't find all files after {_BreakAfterSeconds} second(s)!");
|
|
try
|
|
{ CreatePointerFile(numberLength, parentParentDirectory, matchingFiles); }
|
|
catch (Exception) { }
|
|
List<(string matchingFile, string checkFile)> collection = GetCollection(numberLength, parentParentDirectory, matchingFiles);
|
|
MoveCollection(dateTime, collection);
|
|
return results;
|
|
}
|
|
|
|
} |