Weighted Shortest Job First Hub

This commit is contained in:
Mike Phares 2025-01-28 13:29:28 -07:00
parent ca4ebff54c
commit 08a23114c9
15 changed files with 834 additions and 270 deletions

View File

@ -224,7 +224,7 @@ public class FileRead : Shared.FileRead, IFileRead
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
try
{
_SMTP.SendHighPriorityEmailMessage(subject, body);
_SMTP.SendHighPriorityEmailMessage(subject, body);
File.WriteAllText(".email", body);
}
catch (Exception) { }
@ -242,7 +242,7 @@ public class FileRead : Shared.FileRead, IFileRead
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
try
{
_SMTP.SendHighPriorityEmailMessage(subject, body);
_SMTP.SendHighPriorityEmailMessage(subject, body);
File.WriteAllText(".email", body);
}
catch (Exception) { }

View File

@ -138,7 +138,7 @@ public class FileRead : Shared.FileRead, IFileRead
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
try
{
_SMTP.SendHighPriorityEmailMessage(subject, body);
_SMTP.SendHighPriorityEmailMessage(subject, body);
File.WriteAllText(".email", body);
}
catch (Exception) { }
@ -269,7 +269,7 @@ public class FileRead : Shared.FileRead, IFileRead
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
try
{
_SMTP.SendHighPriorityEmailMessage(subject, body);
_SMTP.SendHighPriorityEmailMessage(subject, body);
File.WriteAllText(".email", body);
}
catch (Exception) { }
@ -285,7 +285,7 @@ public class FileRead : Shared.FileRead, IFileRead
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
try
{
_SMTP.SendHighPriorityEmailMessage(subject, body);
_SMTP.SendHighPriorityEmailMessage(subject, body);
File.WriteAllText(".email", body);
}
catch (Exception) { }

View File

@ -110,6 +110,8 @@ public class ProcessData : IProcessData
private static FileInfo GetFileInfoAndMaybeWriteFile(string directory, WorkItem workItem)
{
FileInfo result;
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
string json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem);
string singletonDirectory = Path.Combine(directory, $"{workItem.Id}");
if (Directory.Exists(singletonDirectory))
@ -213,9 +215,13 @@ public class ProcessData : IProcessData
{
string old;
string checkFile;
string checkDirectory;
foreach (string iterationPath in distinct)
{
checkFile = Path.Combine(destinationDirectory, iterationPath, "[].json");
checkDirectory = Path.Combine(destinationDirectory, iterationPath);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
checkFile = Path.Combine(checkDirectory, "[].json");
old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty;
if (old != json)
File.WriteAllText(checkFile, json);

View File

@ -1,38 +1,192 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.Priority;
#nullable enable
public class Aggregation
{
[JsonConstructor]
public Aggregation(
string average,
int count,
int? inverse,
int maximum,
int minimum,
ReadOnlyCollection<Record> records,
int sum
)
public Aggregation(double inverseAverage,
int valueCount,
double fibonacciAverage,
int? inverseValue,
int valueMaximum,
int valueMinimum,
Notification[] notifications,
int valueSum)
{
Average = average;
Count = count;
Inverse = inverse;
Maximum = maximum;
Minimum = minimum;
Records = records;
Sum = sum;
InverseAverage = inverseAverage;
ValueCount = valueCount;
FibonacciAverage = fibonacciAverage;
InverseValue = inverseValue;
ValueMaximum = valueMaximum;
ValueMinimum = valueMinimum;
Notifications = notifications;
ValueSum = valueSum;
}
[JsonPropertyName("Average")] public string Average { get; }
[JsonPropertyName("Count")] public int Count { get; }
[JsonPropertyName("Inverse")] public int? Inverse { get; }
[JsonPropertyName("Maximum")] public int Maximum { get; }
[JsonPropertyName("Minimum")] public int Minimum { get; }
[JsonPropertyName("Records")] public ReadOnlyCollection<Record> Records { get; }
[JsonPropertyName("Sum")] public int Sum { get; }
public double InverseAverage { get; } // [JsonPropertyName("InverseAverage")]
public int ValueCount { get; } // [JsonPropertyName("ValueCount")]
public double FibonacciAverage { get; } // [JsonPropertyName("Fibonacci")]
public int? InverseValue { get; } // [JsonPropertyName("InverseValue")]
public int ValueMaximum { get; } // [JsonPropertyName("ValueMaximum")]
public int ValueMinimum { get; } // [JsonPropertyName("ValueMinimum")]
public Notification[] Notifications { get; } // [JsonPropertyName("Notifications")]
public int ValueSum { get; } // [JsonPropertyName("ValueSum")]
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Dictionary<int, List<Notification>> keyValuePairs)
{
Dictionary<int, Aggregation> results = new();
int? inverseValue;
double inverseAverage;
Aggregation aggregation;
double fibonacciAverage;
List<int> collection = new();
int averageFromInverseCeiling;
List<int> inverseCollection = new();
List<int> fibonacciCollection = new();
foreach (KeyValuePair<int, List<Notification>> keyValuePair in keyValuePairs)
{
collection.Clear();
inverseCollection.Clear();
fibonacciCollection.Clear();
foreach (Notification notification in keyValuePair.Value)
{
collection.Add(notification.Value);
if (notification.Inverse is null)
continue;
inverseCollection.Add(notification.Inverse.Value);
if (notification.Fibonacci is null)
continue;
fibonacciCollection.Add(notification.Fibonacci.Value);
}
if (inverseCollection.Count == 0 || fibonacciCollection.Count == 0)
continue;
inverseAverage = Math.Round(inverseCollection.Average(), settings.Digits);
averageFromInverseCeiling = (int)Math.Ceiling(inverseAverage);
inverseValue = Notification.GetInverse(averageFromInverseCeiling);
fibonacciAverage = Math.Round(fibonacciCollection.Average(), settings.Digits);
aggregation = new(inverseAverage: inverseAverage,
valueCount: collection.Count,
fibonacciAverage: fibonacciAverage,
inverseValue: inverseValue,
valueMaximum: collection.Max(),
valueMinimum: collection.Min(),
notifications: keyValuePair.Value.ToArray(),
valueSum: collection.Sum());
results.Add(keyValuePair.Key, aggregation);
}
return new(results);
}
private static ReadOnlyCollection<Notification> GetNotifications(Settings settings, string directory)
{
List<Notification> results = new();
string text;
string[] files;
Notification? notification;
List<Notification>? collection;
Dictionary<string, List<Notification>> keyValuePairs = new();
string[] directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string subDirectory in directories)
{
keyValuePairs.Clear();
files = Directory.GetFiles(subDirectory, settings.SourceFileFilter, SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
text = File.ReadAllText(file);
if (string.IsNullOrEmpty(text) || text[0] == '[')
continue;
notification = JsonSerializer.Deserialize(text, NotificationSourceGenerationContext.Default.Notification);
if (notification is null || notification.Id == 0)
continue;
if (string.IsNullOrEmpty(notification.RemoteIpAddress))
continue;
if (!keyValuePairs.TryGetValue(notification.RemoteIpAddress, out collection))
{
keyValuePairs.Add(notification.RemoteIpAddress, new());
if (!keyValuePairs.TryGetValue(notification.RemoteIpAddress, out collection))
throw new Exception();
}
collection.Add(notification);
}
foreach (KeyValuePair<string, List<Notification>> keyValuePair in keyValuePairs)
{
if (keyValuePair.Value.Count == 1)
results.Add(keyValuePair.Value[0]);
else
{
notification = keyValuePair.Value.Select(record => new KeyValuePair<long, Notification>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value;
results.Add(notification);
}
}
}
return new(results);
}
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, string directory)
{
ReadOnlyDictionary<int, Aggregation> results;
List<Notification>? collection;
Dictionary<int, List<Notification>> keyValuePairs = new();
ReadOnlyCollection<Notification> notifications = GetNotifications(settings, directory);
foreach (Notification notification in notifications)
{
if (!keyValuePairs.TryGetValue(notification.Id, out collection))
{
keyValuePairs.Add(notification.Id, new());
if (!keyValuePairs.TryGetValue(notification.Id, out collection))
throw new Exception();
}
collection.Add(notification);
}
results = GetKeyValuePairs(settings, keyValuePairs);
return results;
}
internal static ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> GetKeyValuePairsAndWriteFiles(Settings settings)
{
Dictionary<string, ReadOnlyDictionary<int, Aggregation>> results = new();
string json;
string jsonOld;
string jsonFile;
string directoryName;
ReadOnlyDictionary<int, Aggregation> keyValuePairs;
if (!Directory.Exists(settings.SourceFileLocation))
_ = Directory.CreateDirectory(settings.SourceFileLocation);
if (!Directory.Exists(settings.TargetFileLocation))
_ = Directory.CreateDirectory(settings.TargetFileLocation);
string[] directories = Directory.GetDirectories(settings.SourceFileLocation, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
keyValuePairs = GetKeyValuePairs(settings, directory);
jsonFile = Path.Combine(settings.TargetFileLocation, $"{directoryName}.json");
json = JsonSerializer.Serialize(keyValuePairs, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation);
// keyValuePairs = JsonSerializer.Deserialize(json, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation);
jsonOld = File.Exists(jsonFile) ? File.ReadAllText(jsonFile) : string.Empty;
if (json != jsonOld)
File.WriteAllText(jsonFile, json);
results.Add(directoryName, keyValuePairs);
}
return new(results);
}
internal static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Notification notification)
{
ReadOnlyDictionary<int, Aggregation> results;
Dictionary<int, List<Notification>> keyValuePairs = new() { { notification.Id, new Notification[] { notification }.ToList() } };
results = GetKeyValuePairs(settings, keyValuePairs);
return results;
}
}
@ -46,4 +200,10 @@ internal partial class AggregationSourceGenerationContext : JsonSerializerContex
[JsonSerializable(typeof(Aggregation[]))]
internal partial class AggregationCollectionSourceGenerationContext : JsonSerializerContext
{
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ReadOnlyDictionary<int, Aggregation>))]
internal partial class AggregationReadOnlyDictionarySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -3,28 +3,36 @@ using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
using Adaptation.Shared;
using Adaptation.Shared.Duplicator;
using Adaptation.Shared.Methods;
using log4net;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading;
namespace Adaptation.FileHandlers.Priority;
#nullable enable
public class FileRead : Shared.FileRead, IFileRead
{
private readonly Timer _Timer;
internal static ILog Log => _Log;
internal static Settings Settings => _Settings;
internal static Dictionary<int, WorkItem> WorkItems => _WorkItems;
#pragma warning disable IDE0032, CS8618
private static new ILog _Log;
private static Settings _Settings;
private static Dictionary<int, WorkItem> _WorkItems;
#pragma warning restore IDE0032, CS8618
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, 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, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null)
{
_WorkItems = new();
_MinFileLength = 10;
_NullData = string.Empty;
_Logistics = new(this);
_NullData = string.Empty;
_Log = LogManager.GetLogger(typeof(FileRead));
if (_FileParameter is null)
throw new Exception(cellInstanceConnectionName);
if (_ModelObjectParameterDefinitions is null)
@ -33,12 +41,23 @@ public class FileRead : Shared.FileRead, IFileRead
throw new Exception(cellInstanceConnectionName);
if (_IsEAFHosted)
NestExistingFiles(_FileConnectorConfiguration);
if (!Debugger.IsAttached && fileConnectorConfiguration.PreProcessingMode != FileConnectorConfiguration.PreProcessingModeEnum.Process)
_Timer = new Timer(Callback, null, (int)(fileConnectorConfiguration.FileScanningIntervalInSeconds * 1000), Timeout.Infinite);
else
string parentDirectory = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation) ?? throw new Exception();
_Settings = new(digits: 5,
parentDirectory: parentDirectory,
priorities: 3,
priorityGroups: 9,
sourceFileFilter: _FileConnectorConfiguration.SourceFileFilter,
sourceFileLocation: _FileConnectorConfiguration.SourceFileLocation,
targetFileLocation: _FileConnectorConfiguration.TargetFileLocation);
string? json = WeightedShortestJobFirstHub.PopulatedWorkItemsAndGetJson(_Settings);
if (!string.IsNullOrEmpty(json))
WeightedShortestJobFirstHub.WriteJson(json);
string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType);
string url = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Microsoft.Owin.Hosting.WebApp.Start.URL");
if (_IsEAFHosted)
{
_Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite);
Callback(null);
_ = Microsoft.Owin.Hosting.WebApp.Start(url);
_Log.Info($"Server running on {url}");
}
}
@ -91,7 +110,7 @@ public class FileRead : Shared.FileRead, IFileRead
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);
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]") ?? throw new Exception(), results.Item4);
if (results.Item3.Length > 0 && _IsEAFHosted)
WritePDSF(this, results.Item3);
UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks);
@ -107,187 +126,6 @@ public class FileRead : Shared.FileRead, IFileRead
return results;
}
#nullable enable
private static ReadOnlyCollection<Record> GetRecords(string directory, string searchPattern)
{
List<Record> results = new();
string text;
Record? record;
string[] files;
List<Record>? collection;
Dictionary<string, List<Record>> keyValuePairs = new();
string[] directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string subDirectory in directories)
{
keyValuePairs.Clear();
files = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
text = File.ReadAllText(file);
if (string.IsNullOrEmpty(text) || text[0] == '[')
continue;
record = JsonSerializer.Deserialize<Record>(text);
if (record is null || record.Id == 0)
continue;
if (!keyValuePairs.TryGetValue(record.RemoteIpAddress, out collection))
{
keyValuePairs.Add(record.RemoteIpAddress, new());
if (!keyValuePairs.TryGetValue(record.RemoteIpAddress, out collection))
throw new Exception();
}
collection.Add(record);
}
foreach (KeyValuePair<string, List<Record>> keyValuePair in keyValuePairs)
{
if (keyValuePair.Value.Count == 1)
results.Add(keyValuePair.Value[0]);
else
{
record = keyValuePair.Value.Select(record => new KeyValuePair<long, Record>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value;
results.Add(record);
}
}
}
return new(results);
}
private static int? GetInverse(int value) =>
value switch
{
1 => 3,
2 => 2,
3 => 1,
_ => null
};
private static int? GetInverse(double value)
{
int? result;
if (value > 3)
result = null;
else if (value > 2)
result = 1;
else if (value > 1)
result = 2;
else if (value > 0)
result = 3;
else
result = null;
return result;
}
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Dictionary<int, List<Record>> keyValuePairs)
{
Dictionary<int, Aggregation> results = new();
Aggregation aggregation;
int? inverse;
double average;
List<int> collection = new();
foreach (KeyValuePair<int, List<Record>> keyValuePair in keyValuePairs)
{
collection.Clear();
foreach (Record record in keyValuePair.Value)
{
inverse = GetInverse(record.Value);
if (inverse is null)
continue;
collection.Add(inverse.Value);
}
average = collection.Average();
inverse = GetInverse(average);
aggregation = new(average.ToString("0.000"),
keyValuePair.Value.Count,
inverse,
keyValuePair.Value.Max(record => record.Value),
keyValuePair.Value.Min(record => record.Value),
new(keyValuePair.Value),
keyValuePair.Value.Sum(record => record.Value));
results.Add(keyValuePair.Key, aggregation);
}
return new(results);
}
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(string directory, string searchPattern)
{
ReadOnlyDictionary<int, Aggregation> results;
List<Record>? collection;
Dictionary<int, List<Record>> keyValuePairs = new();
ReadOnlyCollection<Record> records = GetRecords(directory, searchPattern);
foreach (Record record in records)
{
if (!keyValuePairs.TryGetValue(record.Id, out collection))
{
keyValuePairs.Add(record.Id, new());
if (!keyValuePairs.TryGetValue(record.Id, out collection))
throw new Exception();
}
collection.Add(record);
}
results = GetKeyValuePairs(keyValuePairs);
return results;
}
private static void WriteFiles(string sourceFileLocation, string sourceFileFilter, string targetFileLocation)
{
string json;
string jsonFile;
string directoryName;
if (!Directory.Exists(sourceFileLocation))
_ = Directory.CreateDirectory(sourceFileLocation);
if (!Directory.Exists(targetFileLocation))
_ = Directory.CreateDirectory(targetFileLocation);
ReadOnlyDictionary<int, Aggregation> keyValuePairs;
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
string[] directories = Directory.GetDirectories(sourceFileLocation, "*", SearchOption.TopDirectoryOnly);
foreach (string directory in directories)
{
directoryName = Path.GetFileName(directory);
keyValuePairs = GetKeyValuePairs(directory, sourceFileFilter);
jsonFile = Path.Combine(targetFileLocation, $"{directoryName}.json");
json = JsonSerializer.Serialize(keyValuePairs, jsonSerializerOptions);
File.WriteAllText(jsonFile, json);
}
}
private void Callback(object state)
{
try
{
if (_IsEAFHosted)
WriteFiles(_FileConnectorConfiguration.SourceFileLocation, _FileConnectorConfiguration.SourceFileFilter, _FileConnectorConfiguration.TargetFileLocation);
}
catch (Exception exception)
{
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
try
{
_SMTP.SendHighPriorityEmailMessage(subject, body);
File.WriteAllText(".email", body);
}
catch (Exception) { }
}
try
{
if (_FileConnectorConfiguration?.FileScanningIntervalInSeconds is null)
throw new Exception();
TimeSpan timeSpan = new(DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value).Ticks - DateTime.Now.Ticks);
_ = _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite);
}
catch (Exception exception)
{
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
try
{
_SMTP.SendHighPriorityEmailMessage(subject, body);
File.WriteAllText(".email", body);
}
catch (Exception) { }
}
}
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
{
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;

View File

@ -0,0 +1,82 @@
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.Priority;
#nullable enable
public class Notification
{
[JsonConstructor]
public Notification(int? fibonacci,
int id,
int? inverse,
string page,
string? remoteIpAddress,
string? site,
long time,
int value)
{
int? i = inverse is not null ? inverse : GetInverse(value);
Fibonacci = fibonacci is not null ? fibonacci : i is null ? null : GetFibonacci(i.Value);
Id = id;
Inverse = i;
Page = page;
RemoteIpAddress = remoteIpAddress is not null ? remoteIpAddress : null;
Site = site is not null ? site : "MES";
Time = time;
Value = value;
}
[JsonPropertyName("id")] public int Id { get; }
[JsonPropertyName("fibonacci")] public int? Fibonacci { get; }
[JsonPropertyName("inverse")] public int? Inverse { get; }
[JsonPropertyName("page")] public string Page { get; }
[JsonPropertyName("RemoteIpAddress")] public string? RemoteIpAddress { get; }
[JsonPropertyName("site")] public string? Site { get; }
[JsonPropertyName("time")] public long Time { get; }
[JsonPropertyName("value")] public int Value { get; }
internal static int? GetInverse(int value) =>
value switch
{
1 => 5,
2 => 4,
3 => 3,
4 => 2,
5 => 1,
_ => null
};
private static int? GetFibonacci(int value) =>
value switch
{
9 => 55,
8 => 34,
7 => 21,
6 => 13,
5 => 8,
4 => 5,
3 => 3,
2 => 2,
1 => 1,
_ => null
};
internal static Notification GetNotification(Notification notification, string? remoteIpAddress, string? connectionId) =>
new(notification.Fibonacci,
notification.Id,
notification.Inverse,
notification.Page,
remoteIpAddress ?? connectionId,
notification.Site,
notification.Time,
notification.Value);
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Notification))]
public partial class NotificationSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -1,37 +0,0 @@
using System.Collections.ObjectModel;
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.Priority;
public class Record
{
[JsonConstructor]
public Record(
string json,
int id,
string page,
string queryString,
string remoteIpAddress,
long time,
int value
)
{
Json = json;
Id = id;
Page = page;
QueryString = queryString;
RemoteIpAddress = remoteIpAddress;
Time = time;
Value = value;
}
[JsonPropertyName("Json")] public string Json { get; }
[JsonPropertyName("id")] public int Id { get; }
[JsonPropertyName("page")] public string Page { get; }
[JsonPropertyName("QueryString")] public string QueryString { get; }
[JsonPropertyName("RemoteIpAddress")] public string RemoteIpAddress { get; }
[JsonPropertyName("time")] public long Time { get; }
[JsonPropertyName("value")] public int Value { get; }
}

View File

@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.Priority;
#nullable enable
public class Settings
{
[JsonConstructor]
public Settings(int digits,
string parentDirectory,
int priorities,
int priorityGroups,
string sourceFileFilter,
string sourceFileLocation,
string targetFileLocation)
{
Digits = digits;
ParentDirectory = parentDirectory;
Priorities = priorities;
PriorityGroups = priorityGroups;
SourceFileFilter = sourceFileFilter;
SourceFileLocation = sourceFileLocation;
TargetFileLocation = targetFileLocation;
}
public int Digits { get; } // [JsonPropertyName("Digits")]
public string ParentDirectory { get; } // [JsonPropertyName("ParentDirectory")]
public int Priorities { get; } // [JsonPropertyName("Priorities")]
public int PriorityGroups { get; } // [JsonPropertyName("PriorityGroups")]
public string SourceFileFilter { get; } // [JsonPropertyName("SourceFileFilter")]
public string SourceFileLocation { get; } // [JsonPropertyName("SourceFileLocation")]
public string TargetFileLocation { get; } // [JsonPropertyName("TargetFileLocation")]
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Dictionary<int, Settings>))]
internal partial class SettingsDictionarySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,13 @@
using Microsoft.Owin.Cors;
using Owin;
public class Startup
{
public void Configuration(IAppBuilder app)
{
_ = app.UseCors(CorsOptions.AllowAll);
_ = app.MapSignalR();
}
}

View File

@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text.Json;
#nullable enable
namespace Adaptation.FileHandlers.Priority;
public class WeightedShortestJobFirstHub : Microsoft.AspNet.SignalR.Hub
{
// public async Task Send(int n)
// {
// await Clients.All.send(n);
// }
private string? GetRemoteIpAddress() =>
Context?.Headers?.Get("X-Real-IP");
public void Send(string name, string message)
{
Console.WriteLine($"{name}:{message};");
// FileRead.Logger.LogWarning($"{name}:{message};");
// FileRead.Log?.Info($"{name}:{message};");
Console.WriteLine(Context?.ConnectionId);
// FileRead.Logger.LogWarning(Context?.ConnectionId);
// FileRead.Log?.Info(Context?.ConnectionId);
string? remoteIpAddress = GetRemoteIpAddress();
Console.WriteLine(remoteIpAddress);
// FileRead.Logger.LogWarning(remoteIpAddress);
// FileRead.Log?.Info(remoteIpAddress);
Clients.All.addMessage(name, message);
}
private static void FileWriteAllText(Settings settings, Notification n)
{
string json = JsonSerializer.Serialize(n, NotificationSourceGenerationContext.Default.Notification);
string directory = Path.Combine(settings.SourceFileLocation, n.Page, n.Id.ToString());
if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory);
string checkFile = Path.Combine(directory, $"{n.Time}.json");
File.WriteAllText(checkFile, json);
}
internal static void WriteJson(string json)
{
string jsonFile = Path.Combine(FileRead.Settings.ParentDirectory, "{}.json");
string jsonFileWith = Path.Combine(FileRead.Settings.ParentDirectory, "{[]}.json");
string jsonOld = File.Exists(jsonFileWith) ? File.ReadAllText(jsonFileWith) : string.Empty;
if (json != jsonOld)
{
File.WriteAllText(jsonFileWith, json);
Dictionary<int, WorkItem> w = JsonSerializer.Deserialize(json.Replace($"\"{nameof(Aggregation.Notifications)}\":", "\"ignore\":"), WorkItemDictionarySourceGenerationContext.Default.DictionaryInt32WorkItem) ?? throw new Exception();
json = JsonSerializer.Serialize(w, WorkItemDictionarySourceGenerationContext.Default.DictionaryInt32WorkItem);
File.WriteAllText(jsonFile, json);
}
}
internal static string? PopulatedWorkItemsAndGetJson(Settings settings)
{
string? result = null;
ReadOnlyDictionary<int, WorkItem?> workItems = WorkItem.GetKeyValuePairs(settings);
int useCount = (from l in workItems where l.Value.CostOfDelay is not null select true).Count();
double prioritySize = useCount / settings.Priorities;
double priorityGroupSize = useCount / settings.PriorityGroups;
WorkItem[] sorted = (from l in workItems
where l.Value is not null
orderby l.Value.Site is not null,
l.Value.Site descending,
l.Value.CostOfDelay is not null,
l.Value.CostOfDelay descending,
l.Value.BusinessValue?.FibonacciAverage is not null,
l.Value.BusinessValue?.FibonacciAverage descending,
l.Key
select l.Value).ToArray();
lock (FileRead.WorkItems)
{
int j = 0;
WorkItem w;
double value;
int lastId = -1;
int? sortBeforeId;
WorkItem workItem;
int? sortPriority;
int? sortPriorityGroup;
FileRead.WorkItems.Clear();
for (int i = 0; i < sorted.Length; i++)
{
w = sorted[i];
if (w.CostOfDelay is null)
{
sortBeforeId = null;
sortPriority = null;
sortPriorityGroup = null;
}
else
{
j += 1;
sortBeforeId = lastId;
value = (j / prioritySize) + 1;
sortPriority = (int)Math.Floor(value);
if (sortPriority > settings.Priorities)
sortPriority = settings.Priorities;
value = (j / priorityGroupSize) + 1;
sortPriorityGroup = (int)Math.Floor(value);
if (sortPriorityGroup > settings.PriorityGroups)
sortPriorityGroup = settings.PriorityGroups;
}
workItem = WorkItem.GetWorkItem(w, i, sortBeforeId, sortPriority, sortPriorityGroup);
FileRead.WorkItems.Add(workItem.Id, workItem);
lastId = w.Id;
}
result = JsonSerializer.Serialize(FileRead.WorkItems, WorkItemDictionarySourceGenerationContext.Default.DictionaryInt32WorkItem);
}
return result;
}
private static WorkItem GetWorkItem(Notification notification)
{
WorkItem? result;
lock (FileRead.WorkItems)
{
if (!FileRead.WorkItems.TryGetValue(notification.Id, out result))
throw new Exception();
}
return result;
}
public void NotifyAll(Notification notification)
{
try
{
string? json = null;
string? remoteIpAddress = GetRemoteIpAddress();
Notification n = Notification.GetNotification(notification, remoteIpAddress, Context?.ConnectionId);
Console.WriteLine(n.ToString());
// FileRead.Logger.LogWarning(n.ToString());
// FileRead.Log?.Info(n.ToString());
FileWriteAllText(FileRead.Settings, n);
json = PopulatedWorkItemsAndGetJson(FileRead.Settings);
if (!string.IsNullOrEmpty(json))
WriteJson(json);
if (!string.IsNullOrEmpty(n.RemoteIpAddress))
{
WorkItem workItem = GetWorkItem(n);
Clients.All.updateWorkItem(n.Page, workItem);
}
}
catch (Exception ex)
{ Console.WriteLine($"{ex.Message}{Environment.NewLine}{ex.StackTrace}"); }
// { FileRead.Logger.LogError(ex, "Error!"); }
// { FileRead.Log?.Error("Error!", ex); }
}
}

View File

@ -0,0 +1,205 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.Priority;
#nullable enable
public class WorkItem
{
[JsonConstructor]
public WorkItem(double? costOfDelay,
Aggregation? businessValue,
Aggregation? effort,
int id,
int? sortBeforeId,
int? sortPriority,
int? sortPriorityGroup,
Aggregation? riskReductionOpportunityEnablement,
string? site,
int? sortOrder,
Aggregation? timeCriticality,
double? weightedShortestJobFirst)
{
CostOfDelay = costOfDelay;
BusinessValue = businessValue;
Effort = effort;
Id = id;
Site = site;
SortBeforeId = sortBeforeId;
SortPriority = sortPriority;
SortPriorityGroup = sortPriorityGroup;
RiskReductionOpportunityEnablement = riskReductionOpportunityEnablement;
SortOrder = sortOrder;
TimeCriticality = timeCriticality;
WeightedShortestJobFirst = weightedShortestJobFirst;
}
const string _PageEffort = "effort";
const string _PageTimeCriticality = "time";
const string _PageBusinessValue = "business";
const string _PageRiskReductionOpportunityEnablement = "risk";
public double? CostOfDelay { get; } // [JsonPropertyName("CostOfDelay")]
public Aggregation? BusinessValue { get; } // [JsonPropertyName("BusinessValue")]
public Aggregation? Effort { get; } // [JsonPropertyName("Effort")]
public int Id { get; } // [JsonPropertyName("Id")]
public string? Site { get; } // [JsonPropertyName("Site")]
public int? SortBeforeId { get; } // [JsonPropertyName("SortBeforeId")]
public int? SortPriority { get; } // [JsonPropertyName("SortPriority")]
public int? SortPriorityGroup { get; } // [JsonPropertyName("SortPriorityGroup")]
public Aggregation? RiskReductionOpportunityEnablement { get; } // [JsonPropertyName("RiskReductionOpportunityEnablement")]
public int? SortOrder { get; } // [JsonPropertyName("SortOrder")]
public Aggregation? TimeCriticality { get; } // [JsonPropertyName("TimeCriticality")]
public double? WeightedShortestJobFirst { get; } // [JsonPropertyName("WeightedShortestJobFirst")]
internal static WorkItem GetWorkItem(WorkItem workItem, int i, int? sortBeforeId, int? sortPriority, int? sortPriorityGroup) =>
new(workItem.CostOfDelay,
workItem.BusinessValue,
workItem.Effort,
workItem.Id,
sortBeforeId,
sortPriority,
sortPriorityGroup,
workItem.RiskReductionOpportunityEnablement,
workItem.Site,
i,
workItem.TimeCriticality,
workItem.WeightedShortestJobFirst);
private static string? GetSite(Aggregation? effort, Aggregation? businessValue, Aggregation? timeCriticality, Aggregation? riskReductionOpportunityEnablement)
{
string? result = null;
if (result is null && effort is not null)
{
foreach (Notification notification in effort.Notifications)
{
if (notification.Site is not null)
{
result = notification.Site;
break;
}
}
}
if (result is null && businessValue is not null)
{
foreach (Notification notification in businessValue.Notifications)
{
if (notification.Site is not null)
{
result = notification.Site;
break;
}
}
}
if (result is null && timeCriticality is not null)
{
foreach (Notification notification in timeCriticality.Notifications)
{
if (notification.Site is not null)
{
result = notification.Site;
break;
}
}
}
if (result is null && riskReductionOpportunityEnablement is not null)
{
foreach (Notification notification in riskReductionOpportunityEnablement.Notifications)
{
if (notification.Site is not null)
{
result = notification.Site;
break;
}
}
}
return result;
}
internal static ReadOnlyDictionary<int, WorkItem?> GetWorkItems(Settings settings, ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> keyValuePairs)
{
Dictionary<int, WorkItem?> results = new();
string? site;
WorkItem? workItem;
double? costOfDelay;
Aggregation? effort;
List<int> ids = new();
Aggregation? businessValue;
Aggregation? timeCriticality;
double? weightedShortestJobFirst;
Aggregation? riskReductionOpportunityEnablement;
Dictionary<int, Aggregation?> effortCollection = new();
Dictionary<int, Aggregation?> businessValueCollection = new();
Dictionary<int, Aggregation?> timeCriticalityCollection = new();
Dictionary<int, Aggregation?> riskReductionOpportunityEnablementCollection = new();
foreach (KeyValuePair<string, ReadOnlyDictionary<int, Aggregation>> keyValuePair in keyValuePairs)
{
foreach (KeyValuePair<int, Aggregation> keyValue in keyValuePair.Value)
{
if (!ids.Contains(keyValue.Key))
ids.Add(keyValue.Key);
if (keyValuePair.Key == _PageEffort)
effortCollection.Add(keyValue.Key, keyValue.Value);
else if (keyValuePair.Key == _PageTimeCriticality)
timeCriticalityCollection.Add(keyValue.Key, keyValue.Value);
else if (keyValuePair.Key == _PageBusinessValue)
businessValueCollection.Add(keyValue.Key, keyValue.Value);
else if (keyValuePair.Key == _PageRiskReductionOpportunityEnablement)
riskReductionOpportunityEnablementCollection.Add(keyValue.Key, keyValue.Value);
else
throw new NotImplementedException();
}
}
foreach (int id in ids)
{
if (!effortCollection.TryGetValue(id, out effort))
effort = null;
if (!businessValueCollection.TryGetValue(id, out businessValue))
businessValue = null;
if (!timeCriticalityCollection.TryGetValue(id, out timeCriticality))
timeCriticality = null;
if (!riskReductionOpportunityEnablementCollection.TryGetValue(id, out riskReductionOpportunityEnablement))
riskReductionOpportunityEnablement = null;
site = GetSite(effort, businessValue, timeCriticality, riskReductionOpportunityEnablement);
costOfDelay = businessValue is null
|| timeCriticality is null
|| riskReductionOpportunityEnablement is null ? null : businessValue.FibonacciAverage
+ timeCriticality.FibonacciAverage
+ riskReductionOpportunityEnablement.FibonacciAverage;
weightedShortestJobFirst = costOfDelay is null || effort is null ? null : Math.Round(costOfDelay.Value / effort.FibonacciAverage, settings.Digits);
workItem = new(costOfDelay: costOfDelay,
businessValue: businessValue,
effort: effort,
id: id,
sortBeforeId: null,
sortPriority: null,
sortPriorityGroup: null,
riskReductionOpportunityEnablement: riskReductionOpportunityEnablement,
site: site,
sortOrder: null,
timeCriticality: timeCriticality,
weightedShortestJobFirst: weightedShortestJobFirst);
results.Add(id, workItem);
}
return new(results);
}
internal static ReadOnlyDictionary<int, WorkItem?> GetKeyValuePairs(Settings settings)
{
ReadOnlyDictionary<int, WorkItem?> results;
ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> keyValuePairs = Aggregation.GetKeyValuePairsAndWriteFiles(settings);
results = GetWorkItems(settings, keyValuePairs);
return results;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Dictionary<int, WorkItem>))]
internal partial class WorkItemDictionarySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -37,13 +37,27 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.3" />
<PackageReference Include="FFMpegCore" Version="5.1.0" />
<PackageReference Include="IKVM.AWT.WinForms" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="IKVM.OpenJDK.Core" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="IKVM.OpenJDK.Media" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="IKVM.OpenJDK.Text" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="IKVM.OpenJDK.Util" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="IKVM.OpenJDK.XML.API" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="IKVM.Runtime" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="IKVM.AWT.WinForms" Version="7.2.4630.5">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="IKVM.OpenJDK.Core" Version="7.2.4630.5">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="IKVM.OpenJDK.Media" Version="7.2.4630.5">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="IKVM.OpenJDK.Text" Version="7.2.4630.5">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="IKVM.OpenJDK.Util" Version="7.2.4630.5">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="IKVM.OpenJDK.XML.API" Version="7.2.4630.5">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="IKVM.Runtime" Version="7.2.4630.5">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="Instances" Version="3.0.1" />
<PackageReference Include="log4net" Version="3.0.3"></PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0" />
@ -60,7 +74,9 @@
<PackageReference Include="Microsoft.Win32.SystemEvents" Version="9.0.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.7.0" />
<PackageReference Include="MSTest.TestFramework" Version="3.7.0" />
<PackageReference Include="Pdfbox" Version="1.1.1"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="Pdfbox" Version="1.1.1">
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="RoboSharp" Version="1.6.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.0" />
<PackageReference Include="System.Data.OleDb" Version="9.0.0" />
@ -78,7 +94,9 @@
<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.205.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Infineon.Mesa.PDF.Text.Stripper" Version="4.8.0.1"><NoWarn>NU1701</NoWarn></PackageReference>
<PackageReference Include="Infineon.Mesa.PDF.Text.Stripper" Version="4.8.0.1">
<NoWarn>NU1701</NoWarn>
</PackageReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Infineon.Yoda.DotNetCore" Version="5.4.3" />
@ -87,6 +105,15 @@
<ItemGroup>
<PackageReference Include="Tesseract" Version="5.2.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.3" />
<PackageReference Include="Microsoft.AspNet.SignalR.Core" Version="2.4.3" />
<PackageReference Include="Microsoft.Owin" Version="4.2.2" />
<PackageReference Include="Microsoft.Owin.Cors" Version="4.2.2" />
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.2.2" />
<PackageReference Include="Microsoft.Owin.Security" Version="4.2.2" />
<PackageReference Include="Owin" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<None Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>

View File

@ -87,5 +87,18 @@ public class MESAFIBACKLOG : EAFLoggingUnitTesting
EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit"));
}
#if DEBUG
[Ignore]
#endif
[TestMethod]
public void Development__v2_58_0__MESAFIBACKLOG__Priority()
{
string check = "*.json";
MethodBase methodBase = new StackFrame().GetMethod();
EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration"));
_ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting);
EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit"));
}
}
#endif

View File

@ -1,5 +1,6 @@
#if true
using Adaptation.FileHandlers.json.WorkItems;
using Adaptation.FileHandlers.Priority;
using Adaptation.Shared;
using Adaptation.Shared.Methods;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@ -173,8 +174,8 @@ public class MESAFIBACKLOG
{
string check = "*.json";
bool validatePDSF = false;
_MESAFIBACKLOG.Development__v2_58_0__MESAFIBACKLOG__ADO();
MethodBase methodBase = new StackFrame().GetMethod();
_MESAFIBACKLOG.Development__v2_58_0__MESAFIBACKLOG__ADO();
Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName));
string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF);
IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false);
@ -185,5 +186,35 @@ public class MESAFIBACKLOG
NonThrowTryCatch();
}
#if DEBUG
[Ignore]
#endif
[TestMethod]
public void Development__v2_58_0__MESAFIBACKLOG__Priority638323658386612552__Normal()
{
string check = "*.json";
bool validatePDSF = false;
MethodBase methodBase = new StackFrame().GetMethod();
_MESAFIBACKLOG.Development__v2_58_0__MESAFIBACKLOG__Priority();
Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName));
string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF);
IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false);
Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract();
Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1));
Assert.IsNotNull(extractResult.Item3);
Assert.IsNotNull(extractResult.Item4);
WeightedShortestJobFirstHub weightedShortestJobFirstHub = new();
Notification notification = new(fibonacci: null,
id: 1107438888,
inverse: null,
page: "effort",
remoteIpAddress: "10.95.36.87",
site: "MES",
time: 1737573418926,
value: 1);
weightedShortestJobFirstHub.NotifyAll(notification);
NonThrowTryCatch();
}
}
#endif

View File

@ -150,7 +150,11 @@
<Compile Include="Adaptation\FileHandlers\OpenInsightMetrologyViewerAttachments\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\Priority\Aggregation.cs" />
<Compile Include="Adaptation\FileHandlers\Priority\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\Priority\Record.cs" />
<Compile Include="Adaptation\FileHandlers\Priority\Notification.cs" />
<Compile Include="Adaptation\FileHandlers\Priority\Settings.cs" />
<Compile Include="Adaptation\FileHandlers\Priority\Startup.cs" />
<Compile Include="Adaptation\FileHandlers\Priority\WeightedShortestJobFirstHub.cs" />
<Compile Include="Adaptation\FileHandlers\Priority\WorkItem.cs" />
<Compile Include="Adaptation\FileHandlers\Processed\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\SPaCe\FileRead.cs" />
<Compile Include="Adaptation\Ifx\Eaf\Common\Configuration\ConnectionSetting.cs" />
@ -209,6 +213,27 @@
<PackageReference Include="Infineon.EAF.Runtime">
<Version>2.58.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.AspNet.SignalR.SelfHost">
<Version>2.4.3</Version>
</PackageReference>
<PackageReference Include="Microsoft.AspNet.SignalR.Core">
<Version>2.4.3</Version>
</PackageReference>
<PackageReference Include="Owin">
<Version>1.0.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.Owin">
<Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.Owin.Cors">
<Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.Owin.Security">
<Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.Owin.Hosting">
<Version>2.1.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.TeamFoundationServer.Client">
<Version>16.205.1</Version>
</PackageReference>