json in process-data-standard-format process-data-standard-format with HeaderId and SubgroupId process-data-standard-format with pipes UniqueId replacement for attachments Write input PDSF in output after EOF ProcessDataStandardFormat over Tuple MoveMatchingFiles to use ProcessDataStandardFormatMapping
		
			
				
	
	
		
			355 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			355 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
 | |
| using Adaptation.FileHandlers;
 | |
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
 | |
| using Adaptation.Shared;
 | |
| using Adaptation.Shared.Methods;
 | |
| using Eaf.Core;
 | |
| using Eaf.Core.Smtp;
 | |
| using Eaf.EquipmentCore.DataCollection.Reporting;
 | |
| using Eaf.EquipmentCore.SelfDescription.ElementDescription;
 | |
| using Eaf.EquipmentCore.SelfDescription.EquipmentStructure;
 | |
| using Eaf.EquipmentCore.SelfDescription.ParameterTypes;
 | |
| using Ifx.Eaf.EquipmentConnector.File.Component.Reader;
 | |
| using Ifx.Eaf.EquipmentConnector.File.SelfDescription;
 | |
| using log4net;
 | |
| using Shared;
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Diagnostics;
 | |
| using System.IO;
 | |
| using System.Linq;
 | |
| using System.Reflection;
 | |
| using System.Text;
 | |
| using System.Text.Json;
 | |
| using System.Text.Json.Serialization;
 | |
| using System.Threading;
 | |
| 
 | |
| namespace DEP08CEPIEPSILON.FileHandlers;
 | |
| 
 | |
| public partial class FileRead : FileReaderHandler, ISMTP
 | |
| {
 | |
| 
 | |
|     private readonly ILog _Log;
 | |
|     private IFileRead _FileRead;
 | |
|     private EquipmentEvent _EquipmentEvent;
 | |
|     private readonly bool _UseCyclicalForDescription;
 | |
|     private FilePathGenerator _FilePathGeneratorForError;
 | |
|     private FilePathGenerator _FilePathGeneratorForTarget;
 | |
|     private readonly List<EquipmentParameter> _EquipmentParameters;
 | |
|     private static readonly Dictionary<string, List<long>> _DummyRuns;
 | |
|     private static readonly Dictionary<long, List<Adaptation.Shared.Metrology.WS.Results>> _StaticRuns;
 | |
| 
 | |
|     static FileRead()
 | |
|     {
 | |
|         _DummyRuns = new();
 | |
|         _StaticRuns = new();
 | |
|     }
 | |
| 
 | |
|     public FileRead()
 | |
|     {
 | |
|         if (FileParameter is null)
 | |
|             FileParameter = new Dictionary<string, string>();
 | |
|         _FileRead = null;
 | |
|         _UseCyclicalForDescription = false;
 | |
|         _Log = LogManager.GetLogger(typeof(FileRead));
 | |
|         _EquipmentParameters = new List<EquipmentParameter>();
 | |
|     }
 | |
| 
 | |
|     public override void CreateSelfDescription()
 | |
|     {
 | |
|         MethodBase methodBase = new StackFrame().GetMethod();
 | |
|         _Log.Debug(string.Concat(methodBase.Name, " - Entry"));
 | |
|         try
 | |
|         {
 | |
|             if (Equipment is null)
 | |
|                 throw new Exception();
 | |
|             CreateSelfDescription(methodBase);
 | |
|             _Log.Debug(string.Concat(methodBase.Name, " - Try - Exit"));
 | |
|         }
 | |
|         catch (Exception ex)
 | |
|         {
 | |
|             _Log.Error(string.Concat(methodBase.Name, " - Catch - Entry {", ex.Message, "}", Environment.NewLine, Environment.NewLine, ex.StackTrace));
 | |
|             long breakAfter = DateTime.Now.AddSeconds(30).Ticks;
 | |
|             for (short i = 0; i < short.MaxValue; i++)
 | |
|             {
 | |
|                 if (DateTime.Now.Ticks > breakAfter)
 | |
|                     break;
 | |
|                 Thread.Sleep(500);
 | |
|             }
 | |
|             throw;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public override bool Extract(string reportFullPath, string eventName)
 | |
|     {
 | |
|         MethodBase methodBase = new StackFrame().GetMethod();
 | |
|         _Log.Debug(string.Concat(methodBase.Name, " - Entry - {", reportFullPath, "}"));
 | |
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults = null;
 | |
|         try
 | |
|         {
 | |
|             extractResults = _FileRead.GetExtractResult(reportFullPath, eventName);
 | |
|             TriggerEvents(extractResults);
 | |
|             _FileRead.Move(extractResults);
 | |
|             FilePathGeneratorInfoMove(extractResults);
 | |
|             _FileRead.WaitForThread();
 | |
|             _Log.Debug(string.Concat(methodBase.Name, " - Try - Exit"));
 | |
|             return true;
 | |
|         }
 | |
|         catch (Exception ex)
 | |
|         {
 | |
|             _Log.Error(string.Concat(methodBase.Name, " - Catch - Entry {", ex.Message, "}", Environment.NewLine, Environment.NewLine, ex.StackTrace));
 | |
|             _FileRead.Move(extractResults, exception: ex);
 | |
|             FilePathGeneratorInfoMove(extractResults, exception: ex);
 | |
|             return false;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private void Send(EmailMessage emailMessage)
 | |
|     {
 | |
|         ISmtp smtp = Backbone.Instance.GetBackboneComponentsOfType<ISmtp>().SingleOrDefault();
 | |
|         if (smtp is not null)
 | |
|             smtp.Send(emailMessage);
 | |
|     }
 | |
| 
 | |
|     void ISMTP.SendLowPriorityEmailMessage(string subject, string body)
 | |
|     {
 | |
|         EmailMessage emailMessage = new(subject, body, MailPriority.Low);
 | |
|         Send(emailMessage);
 | |
|     }
 | |
| 
 | |
|     void ISMTP.SendHighPriorityEmailMessage(string subject, string body)
 | |
|     {
 | |
|         EmailMessage emailMessage = new(subject, body, MailPriority.High);
 | |
|         Send(emailMessage);
 | |
|     }
 | |
| 
 | |
|     void ISMTP.SendNormalPriorityEmailMessage(string subject, string body)
 | |
|     {
 | |
|         EmailMessage emailMessage = new(subject, body, MailPriority.Normal);
 | |
|         Send(emailMessage);
 | |
|     }
 | |
| 
 | |
|     private void AddParameterRangeAndEvent()
 | |
|     {
 | |
|         string description;
 | |
|         bool allowNull = false;
 | |
|         EquipmentParameter equipmentParameter;
 | |
|         JsonProperty[] jsonProperties = _FileRead.GetDefault();
 | |
|         Dictionary<string, string> keyValuePairs = _FileRead.GetDisplayNamesJsonElement();
 | |
|         Dictionary<JsonValueKind, ParameterTypeDefinition> parameterTypeDefinitions = new();
 | |
|         FileConnectorParameterTypeDefinitionProvider fileConnectorParameterTypeDefinitionProvider = new();
 | |
|         foreach (ParameterTypeDefinition parameterTypeDefinition in fileConnectorParameterTypeDefinitionProvider.GetAllParameterTypeDefinition())
 | |
|         {
 | |
|             switch (parameterTypeDefinition.Name)
 | |
|             {
 | |
|                 case nameof(String):
 | |
|                     parameterTypeDefinitions.Add(JsonValueKind.String, parameterTypeDefinition);
 | |
|                     break;
 | |
|                 case nameof(Double):
 | |
|                     parameterTypeDefinitions.Add(JsonValueKind.Number, parameterTypeDefinition);
 | |
|                     break;
 | |
|                 case nameof(Boolean):
 | |
|                     parameterTypeDefinitions.Add(JsonValueKind.True, parameterTypeDefinition);
 | |
|                     parameterTypeDefinitions.Add(JsonValueKind.False, parameterTypeDefinition);
 | |
|                     break;
 | |
|                 default:
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
|         foreach (JsonProperty jsonProperty in jsonProperties)
 | |
|         {
 | |
|             if (jsonProperty.Value.ValueKind == JsonValueKind.Object && !parameterTypeDefinitions.ContainsKey(JsonValueKind.Object))
 | |
|             {
 | |
|                 StructuredType structuredType = new(nameof(StructuredType), string.Empty, new List<Field>());
 | |
|                 parameterTypeDefinitions.Add(JsonValueKind.Object, structuredType);
 | |
|                 Equipment.SelfDescriptionBuilder.AddParameterTypeDefinition(structuredType);
 | |
|             }
 | |
|             if (!parameterTypeDefinitions.ContainsKey(jsonProperty.Value.ValueKind))
 | |
|                 throw new Exception(string.Concat('<', jsonProperty.Name, "> {", jsonProperty.Value.ValueKind, "} is not mapped!"));
 | |
|         }
 | |
|         foreach (JsonProperty jsonProperty in jsonProperties)
 | |
|         {
 | |
|             if (jsonProperty.Value.ValueKind == JsonValueKind.Null && !allowNull)
 | |
|                 throw new Exception();
 | |
|             if (jsonProperty.Value.ValueKind != JsonValueKind.String || !keyValuePairs.ContainsKey(jsonProperty.Name))
 | |
|                 description = string.Empty;
 | |
|             else
 | |
|                 description = keyValuePairs[jsonProperty.Name].Split('|')[0];
 | |
|             equipmentParameter = new EquipmentParameter(jsonProperty.Name, parameterTypeDefinitions[jsonProperty.Value.ValueKind], description);
 | |
|             _EquipmentParameters.Add(equipmentParameter);
 | |
|         }
 | |
|         _ = Equipment.SelfDescriptionBuilder.RootEquipmentElementBuilder.AddParameterRange(_EquipmentParameters);
 | |
|         _EquipmentEvent = new EquipmentEvent(_FileRead.EventName, _FileRead.GetEventDescription(), _EquipmentParameters);
 | |
|         _ = Equipment.SelfDescriptionBuilder.RootEquipmentElementBuilder.AddEvent(_EquipmentEvent);
 | |
|     }
 | |
| 
 | |
|     private void CreateSelfDescription(MethodBase methodBase)
 | |
|     {
 | |
|         string cellInstanceName;
 | |
|         string equipmentTypeName = string.Empty;
 | |
|         string equipmentDictionaryName = string.Empty;
 | |
|         EquipmentElement equipmentElement = Equipment.SelfDescriptionBuilder.RootEquipmentElementBuilder.Item;
 | |
|         if (Backbone.Instance?.CellName is null)
 | |
|             cellInstanceName = string.Empty;
 | |
|         else
 | |
|             cellInstanceName = Backbone.Instance.CellName;
 | |
|         string cellInstanceConnectionName = equipmentElement.Name;
 | |
|         FileConnectorConfiguration fileConnectorConfiguration = Mapper.Map(Configuration);
 | |
|         string parameterizedModelObjectDefinitionType = methodBase.DeclaringType.FullName;
 | |
|         IList<ModelObjectParameterDefinition> modelObjectParameters = Mapper.Map(ConfiguredParameters);
 | |
|         _FileRead = CellInstanceConnectionName.Get(this, FileParameter, cellInstanceName, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, _DummyRuns, _StaticRuns, _UseCyclicalForDescription, connectionCount: null);
 | |
|         if (_FileRead.IsEvent)
 | |
|             AddParameterRangeAndEvent();
 | |
|     }
 | |
| 
 | |
|     private object GetFilePathGeneratorInfo(string reportFullPath, bool isErrorFile)
 | |
|     {
 | |
|         FilePathGeneratorInfo result;
 | |
|         FilePathGenerator filePathGeneratorOriginal;
 | |
|         if (Configuration is null)
 | |
|             result = null;
 | |
|         else
 | |
|         {
 | |
|             if (isErrorFile)
 | |
|             {
 | |
|                 if (_FilePathGeneratorForError is null)
 | |
|                     _FilePathGeneratorForError = new FilePathGenerator(Configuration, reportFullPath, isErrorFile: true);
 | |
|                 filePathGeneratorOriginal = _FilePathGeneratorForError;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (_FilePathGeneratorForTarget is null)
 | |
|                     _FilePathGeneratorForTarget = new FilePathGenerator(Configuration, reportFullPath, isErrorFile: false);
 | |
|                 filePathGeneratorOriginal = _FilePathGeneratorForTarget;
 | |
|             }
 | |
|             result = new FilePathGeneratorInfo(filePathGeneratorOriginal, reportFullPath, isErrorFile, FileParameter);
 | |
|         }
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     private void FilePathGeneratorInfoMove(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception = null)
 | |
|     {
 | |
|         bool isErrorFile = exception is not null;
 | |
|         object filePathGeneratorInfo = GetFilePathGeneratorInfo(_FileRead.ReportFullPath, isErrorFile);
 | |
|         if (filePathGeneratorInfo is not null and FilePathGeneratorInfo filePathGenerator)
 | |
|         {
 | |
|             string[] exceptionLines = _FileRead.Move(extractResults, filePathGenerator.To, filePathGenerator.From, filePathGenerator.ResolvedFileLocation, exception);
 | |
|             if (isErrorFile)
 | |
|             {
 | |
|                 try
 | |
|                 {
 | |
|                     StringBuilder stringBuilder = new();
 | |
|                     foreach (string item in exceptionLines)
 | |
|                         _ = stringBuilder.Append("<").Append(item).AppendLine(">");
 | |
|                     ISmtp smtp = Backbone.Instance.GetBackboneComponentsOfType<ISmtp>().SingleOrDefault();
 | |
|                     EmailMessage emailMessage = new(_FileRead.ExceptionSubject, stringBuilder.ToString(), MailPriority.High);
 | |
|                     smtp.Send(emailMessage);
 | |
|                 }
 | |
|                 catch (Exception) { }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     private List<ParameterValue> GetParameterValues(List<string> headerNames, JsonElement[] jsonElements, int i)
 | |
|     {
 | |
|         List<ParameterValue> results = new();
 | |
|         if (_UseCyclicalForDescription && i > 0)
 | |
|             throw new Exception();
 | |
|         object value;
 | |
|         List<object[]> list;
 | |
|         JsonProperty[] jsonProperties = jsonElements[i].EnumerateObject().ToArray();
 | |
|         if (jsonProperties.Length != _EquipmentParameters.Count)
 | |
|             throw new Exception();
 | |
|         for (int p = 0; p < jsonProperties.Length; p++)
 | |
|         {
 | |
|             if (!_UseCyclicalForDescription || headerNames.Contains(jsonProperties[p].Name))
 | |
|                 value = jsonProperties[p].Value.ToString();
 | |
|             else
 | |
|             {
 | |
|                 list = new List<object[]>();
 | |
|                 for (int z = 0; z < jsonElements.Length; z++)
 | |
|                     list.Add(new object[] { z, jsonElements[z].GetProperty(jsonProperties[p].Name).ToString() });
 | |
|                 value = list;
 | |
|             }
 | |
|             results.Add(new ParameterValue(_EquipmentParameters[p], value, DateTime.Now));
 | |
|         }
 | |
|         return results;
 | |
|     }
 | |
| 
 | |
|     private void TriggerEvents(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults)
 | |
|     {
 | |
|         List<string> headerNames;
 | |
|         List<ParameterValue> parameters;
 | |
|         if (!_UseCyclicalForDescription)
 | |
|             headerNames = null;
 | |
|         else
 | |
|             headerNames = _FileRead.GetHeaderNames();
 | |
|         for (int i = 0; i < extractResults.Item3.Length; i++)
 | |
|         {
 | |
|             if (_EquipmentEvent is not null)
 | |
|             {
 | |
|                 _Log.Debug(string.Concat("TriggerEvent - {", _FileRead.ReportFullPath, "} ", i, " of ", extractResults.Item3.Length));
 | |
|                 parameters = GetParameterValues(headerNames, extractResults.Item3, i);
 | |
|                 if (_EquipmentEvent is not null)
 | |
|                     Equipment.DataCollection.TriggerEvent(_EquipmentEvent, parameters);
 | |
|                 if (_UseCyclicalForDescription)
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public Tuple<string, Test[], JsonElement[], List<FileInfo>> ReExtract(string json)
 | |
|     {
 | |
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
 | |
|         string cellInstanceName;
 | |
|         if (!json.Contains(nameof(cellInstanceName)))
 | |
|             throw new Exception();
 | |
|         string equipmentTypeName;
 | |
|         if (!json.Contains(nameof(equipmentTypeName)))
 | |
|             throw new Exception();
 | |
|         string equipmentDictionaryName;
 | |
|         if (!json.Contains(nameof(equipmentDictionaryName)))
 | |
|             throw new Exception();
 | |
|         string cellInstanceConnectionName;
 | |
|         if (!json.Contains(nameof(cellInstanceConnectionName)))
 | |
|             throw new Exception();
 | |
|         if (!json.Contains(nameof(FileConnectorConfiguration)))
 | |
|             throw new Exception();
 | |
|         if (!json.Contains(nameof(IList<ModelObjectParameterDefinition>)))
 | |
|             throw new Exception();
 | |
|         string parameterizedModelObjectDefinitionType;
 | |
|         if (!json.Contains(nameof(parameterizedModelObjectDefinitionType)))
 | |
|             throw new Exception();
 | |
|         Dictionary<string, List<long>> dummyRuns = new();
 | |
|         Dictionary<string, string> fileParameter = new();
 | |
|         MethodBase methodBase = new StackFrame().GetMethod();
 | |
|         JsonElement jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
 | |
|         cellInstanceName = jsonElement.GetProperty(nameof(cellInstanceName)).ToString();
 | |
|         equipmentTypeName = jsonElement.GetProperty(nameof(equipmentTypeName)).ToString();
 | |
|         equipmentDictionaryName = jsonElement.GetProperty(nameof(equipmentDictionaryName)).ToString();
 | |
|         cellInstanceConnectionName = jsonElement.GetProperty(nameof(cellInstanceConnectionName)).ToString();
 | |
|         JsonElement fileConnectorConfigurationJsonElement = jsonElement.GetProperty(nameof(FileConnectorConfiguration));
 | |
|         parameterizedModelObjectDefinitionType = jsonElement.GetProperty(nameof(parameterizedModelObjectDefinitionType)).ToString();
 | |
|         if (fileConnectorConfigurationJsonElement.ValueKind != JsonValueKind.Object)
 | |
|             throw new Exception();
 | |
|         JsonSerializerOptions jsonSerializerOptions = new() { Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) } };
 | |
|         FileConnectorConfiguration fileConnectorConfiguration = JsonSerializer.Deserialize<FileConnectorConfiguration>(fileConnectorConfigurationJsonElement.ToString(), jsonSerializerOptions);
 | |
|         JsonElement modelObjectParameterDefinitionJsonElement = jsonElement.GetProperty(nameof(IList<ModelObjectParameterDefinition>));
 | |
|         if (modelObjectParameterDefinitionJsonElement.ValueKind != JsonValueKind.Array)
 | |
|             throw new Exception();
 | |
|         IList<ModelObjectParameterDefinition> modelObjectParameters = JsonSerializer.Deserialize<IList<ModelObjectParameterDefinition>>(modelObjectParameterDefinitionJsonElement.ToString(), jsonSerializerOptions);
 | |
|         _FileRead = CellInstanceConnectionName.Get(this, FileParameter, cellInstanceName, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, _DummyRuns, _StaticRuns, _UseCyclicalForDescription, connectionCount: null);
 | |
|         results = _FileRead.ReExtract();
 | |
|         if (results?.Item2 is null)
 | |
|             throw new Exception();
 | |
|         else
 | |
|         {
 | |
|             TriggerEvents(results);
 | |
|             _FileRead.Move(results);
 | |
|             FilePathGeneratorInfoMove(results);
 | |
|         }
 | |
|         return results;
 | |
|     }
 | |
| 
 | |
| }
 | |
| // 2022-02-15 -> FileRead |