Separated Wafer-Counter
JsonElement instead of Request body Attachment Class Bump Ready to test GetLastGroupIdWithValue Changed to v4
This commit is contained in:
1
Wafer-Counter/.vscode/format-report.json
vendored
Normal file
1
Wafer-Counter/.vscode/format-report.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
[]
|
38
Wafer-Counter/.vscode/launch.json
vendored
Normal file
38
Wafer-Counter/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||
// Use hover for the description of the existing attributes
|
||||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||
"name": ".NET Core Launch (web)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/bin/Debug/net8.0/OI.Metrology.Wafer.Counter.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)",
|
||||
"uriFormat": "%s/swagger/index.html"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"preLaunchTask": "watch",
|
||||
"processName": "OI.Metrology.Wafer.Counter.exe"
|
||||
}
|
||||
]
|
||||
}
|
5
Wafer-Counter/.vscode/settings.json
vendored
Normal file
5
Wafer-Counter/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"Infineon"
|
||||
]
|
||||
}
|
163
Wafer-Counter/.vscode/tasks.json
vendored
Normal file
163
Wafer-Counter/.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,163 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/OI.Metrology.Wafer.Counter.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "buildTests",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/../Tests/OI.Metrology.Tests.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "testDebug",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"test",
|
||||
"${workspaceFolder}/../Tests/OI.Metrology.Tests.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "testRelease",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"test",
|
||||
"${workspaceFolder}/../Tests/OI.Metrology.Tests.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary",
|
||||
"-c",
|
||||
"Release"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Format",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"format",
|
||||
"--report",
|
||||
".vscode",
|
||||
"--verbosity",
|
||||
"detailed",
|
||||
"--severity",
|
||||
"warn"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Format-Whitespace",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"format",
|
||||
"whitespace"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "publish",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/OI.Metrology.Wafer.Counter.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary",
|
||||
"--configuration",
|
||||
"Release",
|
||||
"--runtime",
|
||||
"win-x64",
|
||||
"--self-contained",
|
||||
"-o",
|
||||
"D:/web-sites/OI-Metrology/oo-8e5dd137-_______-OI-Metrology-Release/Wafer-Counter"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Publish AOT",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/OI.Metrology.Wafer.Counter.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary",
|
||||
"--configuration",
|
||||
"Release",
|
||||
"--runtime",
|
||||
"win-x64",
|
||||
"-p:PublishAot=true",
|
||||
"/property:GenerateFullPaths=true"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "old-watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"run",
|
||||
"--project",
|
||||
"${workspaceFolder}/OI.Metrology.Wafer.Counter.csproj"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"--launch-profile",
|
||||
"http",
|
||||
"run",
|
||||
"--project",
|
||||
"${workspaceFolder}/OI.Metrology.Wafer.Counter.csproj",
|
||||
"--verbose"
|
||||
],
|
||||
"isBackground": true,
|
||||
"dependsOn": [
|
||||
"build"
|
||||
],
|
||||
"problemMatcher": {
|
||||
"fileLocation": "relative",
|
||||
"pattern": {
|
||||
"regexp": "^([^\\s].*)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(error|warning|info)\\s+(TS\\d+)\\s*:\\s*(.*)$",
|
||||
"file": 1,
|
||||
"location": 2,
|
||||
"severity": 3,
|
||||
"code": 4,
|
||||
"message": 5
|
||||
},
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": "^.*Shutdown requested.*",
|
||||
"endsPattern": "^.*Application started.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
24
Wafer-Counter/ApiControllers/AppSettingsController.cs
Normal file
24
Wafer-Counter/ApiControllers/AppSettingsController.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter.ApiControllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class AppSettingsController : ControllerBase, IAppSettingsController<ActionResult>
|
||||
{
|
||||
|
||||
private readonly IAppSettingsRepository<Models.Binder.AppSettings> _AppSettingsRepository;
|
||||
|
||||
public AppSettingsController(IAppSettingsRepository<Models.Binder.AppSettings> AppSettingsRepository) =>
|
||||
_AppSettingsRepository = AppSettingsRepository;
|
||||
|
||||
[HttpGet(nameof(IAppSettingsController<ActionResult>.Action.App))]
|
||||
public ActionResult GetAppSettings() =>
|
||||
Ok(_AppSettingsRepository.GetAppSettings());
|
||||
|
||||
[HttpGet(nameof(IAppSettingsController<ActionResult>.Action.DevOps))]
|
||||
public ActionResult GetBuildNumberAndGitCommitSeven() =>
|
||||
Ok(_AppSettingsRepository.GetBuildNumberAndGitCommitSeven());
|
||||
|
||||
}
|
36
Wafer-Counter/ApiControllers/FileShareController.cs
Normal file
36
Wafer-Counter/ApiControllers/FileShareController.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter.ApiControllers;
|
||||
|
||||
[Route("api/v1/file-share")]
|
||||
public class FileShareController : Controller, IFileShareController<IResult>
|
||||
{
|
||||
|
||||
private readonly IFileShareRepository _FileShareRepository;
|
||||
|
||||
public FileShareController(IFileShareRepository fileShareRepository) =>
|
||||
_FileShareRepository = fileShareRepository;
|
||||
|
||||
[HttpGet("copy-file")]
|
||||
public IResult CopyFile(string from, string to)
|
||||
{
|
||||
_FileShareRepository.CopyFile(from, to);
|
||||
return Results.Ok();
|
||||
}
|
||||
|
||||
[HttpGet("move-file")]
|
||||
public IResult MoveFile(string from, string to)
|
||||
{
|
||||
_FileShareRepository.MoveFile(from, to);
|
||||
return Results.Ok();
|
||||
}
|
||||
|
||||
[HttpGet("file-write")]
|
||||
public IResult FileWrite(string path, string contents)
|
||||
{
|
||||
_FileShareRepository.FileWrite(path, contents);
|
||||
return Results.Ok();
|
||||
}
|
||||
|
||||
}
|
18
Wafer-Counter/ApiControllers/WaferCounterController.cs
Normal file
18
Wafer-Counter/ApiControllers/WaferCounterController.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter.ApiControllers;
|
||||
|
||||
[Route("api/v1/[controller]")]
|
||||
public class WaferCounterController : Controller, IWaferCounterController<IActionResult>
|
||||
{
|
||||
|
||||
private readonly IWaferCounterRepository _WaferCounterRepository;
|
||||
|
||||
public WaferCounterController(IWaferCounterRepository waferCounterRepository) =>
|
||||
_WaferCounterRepository = waferCounterRepository;
|
||||
|
||||
[HttpGet("{waferSize}/last-quantity-and-slot-map")]
|
||||
public IActionResult GetLastQuantityAndSlotMap(string area, string waferSize) =>
|
||||
Json(_WaferCounterRepository.GetLastQuantityAndSlotMap(area, waferSize));
|
||||
}
|
27
Wafer-Counter/Models/AppSettings.cs
Normal file
27
Wafer-Counter/Models/AppSettings.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter.Models;
|
||||
|
||||
public record AppSettings(string BuildNumber,
|
||||
string Company,
|
||||
string EcCharacterizationSi,
|
||||
string EcMesaFileShareCharacterizationSi,
|
||||
string GitCommitSeven,
|
||||
bool IsDevelopment,
|
||||
bool IsStaging,
|
||||
string MockRoot,
|
||||
string MonAResource,
|
||||
string MonASite,
|
||||
string URLs,
|
||||
string WaferCounterDestinationDirectory,
|
||||
int WaferCounterTwoFileSecondsWait,
|
||||
string WorkingDirectoryName)
|
||||
{
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
2
Wafer-Counter/Models/Binder/.editorconfig
Normal file
2
Wafer-Counter/Models/Binder/.editorconfig
Normal file
@ -0,0 +1,2 @@
|
||||
[*.cs]
|
||||
csharp_preserve_single_line_statements = true
|
99
Wafer-Counter/Models/Binder/AppSettings.cs
Normal file
99
Wafer-Counter/Models/Binder/AppSettings.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter.Models.Binder;
|
||||
|
||||
public class AppSettings
|
||||
{
|
||||
|
||||
public string? BuildNumber { get; set; }
|
||||
public string? Company { get; set; }
|
||||
public string? EcCharacterizationSi { get; set; }
|
||||
public string? EcMesaFileShareCharacterizationSi { get; set; }
|
||||
public string? GitCommitSeven { get; set; }
|
||||
public bool? IsDevelopment { get; set; }
|
||||
public bool? IsStaging { get; set; }
|
||||
public string? MockRoot { get; set; }
|
||||
public string? MonAResource { get; set; }
|
||||
public string? MonASite { get; set; }
|
||||
public string? URLs { get; set; }
|
||||
public string? WaferCounterDestinationDirectory { get; set; }
|
||||
public int? WaferCounterTwoFileSecondsWait { get; set; }
|
||||
public string? WorkingDirectoryName { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void PreVerify(IConfigurationRoot configurationRoot, AppSettings? appSettings)
|
||||
{
|
||||
if (appSettings?.Company is null)
|
||||
{
|
||||
List<string> paths = new();
|
||||
foreach (IConfigurationProvider configurationProvider in configurationRoot.Providers)
|
||||
{
|
||||
if (configurationProvider is not Microsoft.Extensions.Configuration.Json.JsonConfigurationProvider jsonConfigurationProvider)
|
||||
continue;
|
||||
if (jsonConfigurationProvider.Source.FileProvider is not Microsoft.Extensions.FileProviders.PhysicalFileProvider physicalFileProvider)
|
||||
continue;
|
||||
paths.Add(physicalFileProvider.Root);
|
||||
}
|
||||
throw new NotSupportedException($"Not found!{Environment.NewLine}{string.Join(Environment.NewLine, paths.Distinct())}");
|
||||
}
|
||||
}
|
||||
|
||||
private static Models.AppSettings Get(AppSettings? appSettings)
|
||||
{
|
||||
Models.AppSettings result;
|
||||
if (appSettings is null) throw new NullReferenceException(nameof(appSettings));
|
||||
if (appSettings.BuildNumber is null) throw new NullReferenceException(nameof(BuildNumber));
|
||||
if (appSettings.Company is null) throw new NullReferenceException(nameof(Company));
|
||||
if (appSettings.EcCharacterizationSi is null) throw new NullReferenceException(nameof(EcCharacterizationSi));
|
||||
if (appSettings.EcMesaFileShareCharacterizationSi is null) throw new NullReferenceException(nameof(EcMesaFileShareCharacterizationSi));
|
||||
if (appSettings.GitCommitSeven is null) throw new NullReferenceException(nameof(GitCommitSeven));
|
||||
if (appSettings.IsDevelopment is null) throw new NullReferenceException(nameof(IsDevelopment));
|
||||
if (appSettings.IsStaging is null) throw new NullReferenceException(nameof(IsStaging));
|
||||
if (appSettings.MockRoot is null) throw new NullReferenceException(nameof(MockRoot));
|
||||
if (appSettings.MonAResource is null) throw new NullReferenceException(nameof(MonAResource));
|
||||
if (appSettings.MonASite is null) throw new NullReferenceException(nameof(MonASite));
|
||||
if (appSettings.URLs is null) throw new NullReferenceException(nameof(URLs));
|
||||
if (appSettings.WaferCounterDestinationDirectory is null) throw new NullReferenceException(nameof(WaferCounterDestinationDirectory));
|
||||
if (appSettings.WaferCounterTwoFileSecondsWait is null) throw new NullReferenceException(nameof(WaferCounterTwoFileSecondsWait));
|
||||
if (appSettings.WorkingDirectoryName is null) throw new NullReferenceException(nameof(WorkingDirectoryName));
|
||||
result = new(appSettings.BuildNumber,
|
||||
appSettings.Company,
|
||||
appSettings.EcCharacterizationSi,
|
||||
appSettings.EcMesaFileShareCharacterizationSi,
|
||||
appSettings.GitCommitSeven,
|
||||
appSettings.IsDevelopment.Value,
|
||||
appSettings.IsStaging.Value,
|
||||
appSettings.MockRoot,
|
||||
appSettings.MonAResource,
|
||||
appSettings.MonASite,
|
||||
appSettings.URLs,
|
||||
appSettings.WaferCounterDestinationDirectory,
|
||||
appSettings.WaferCounterTwoFileSecondsWait.Value,
|
||||
appSettings.WorkingDirectoryName);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||
{
|
||||
Models.AppSettings result;
|
||||
#pragma warning disable IL3050, IL2026
|
||||
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
|
||||
#pragma warning restore IL3050, IL2026
|
||||
PreVerify(configurationRoot, appSettings);
|
||||
result = Get(appSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(AppSettings))]
|
||||
internal partial class BinderAppSettingsSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
38
Wafer-Counter/OI.Metrology.Wafer.Counter.csproj
Normal file
38
Wafer-Counter/OI.Metrology.Wafer.Counter.csproj
Normal file
@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup Label="Globals">
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<UserSecretsId>2a0acd34-8f61-47a3-8818-73fa8fe04902</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dapper" Version="2.1.44" />
|
||||
<PackageReference Include="EntityFramework" Version="6.4.4" />
|
||||
<PackageReference Include="jQuery" Version="3.7.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="8.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.1" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\OI.Metrology.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
90
Wafer-Counter/Program.cs
Normal file
90
Wafer-Counter/Program.cs
Normal file
@ -0,0 +1,90 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Hosting.WindowsServices;
|
||||
using OI.Metrology.Wafer.Counter.Models;
|
||||
using OI.Metrology.Wafer.Counter.Repository;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter;
|
||||
|
||||
public class Program
|
||||
{
|
||||
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
ILogger<Program>? logger = null;
|
||||
WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args);
|
||||
_ = webApplicationBuilder.Configuration.AddUserSecrets<Program>();
|
||||
AppSettings appSettings = Models.Binder.AppSettings.Get(webApplicationBuilder.Configuration);
|
||||
if (string.IsNullOrEmpty(appSettings.Company))
|
||||
throw new Exception("Company name must have a value!");
|
||||
if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName))
|
||||
throw new Exception("Working directory name must have a value!");
|
||||
try
|
||||
{
|
||||
_ = webApplicationBuilder.Services.AddMemoryCache();
|
||||
_ = webApplicationBuilder.Services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);
|
||||
_ = webApplicationBuilder.Services.AddControllers();
|
||||
_ = webApplicationBuilder.Services.AddDistributedMemoryCache();
|
||||
|
||||
AppSettingsRepository appSettingsRepository = new(appSettings);
|
||||
|
||||
_ = webApplicationBuilder.Services.AddHttpClient();
|
||||
_ = webApplicationBuilder.Services.AddSingleton(_ => appSettings);
|
||||
_ = webApplicationBuilder.Services.AddSingleton<IFileShareRepository, FileShareRepository>();
|
||||
_ = webApplicationBuilder.Services.AddSingleton<IWaferCounterRepository, WaferCounterRepository>();
|
||||
_ = webApplicationBuilder.Services.AddSingleton<IAppSettingsRepository<Models.Binder.AppSettings>>(_ => appSettingsRepository);
|
||||
|
||||
_ = webApplicationBuilder.Services.AddSwaggerGen();
|
||||
_ = webApplicationBuilder.Services.AddSession(sessionOptions =>
|
||||
{
|
||||
sessionOptions.IdleTimeout = TimeSpan.FromSeconds(2000);
|
||||
sessionOptions.Cookie.HttpOnly = true;
|
||||
sessionOptions.Cookie.IsEssential = true;
|
||||
}
|
||||
);
|
||||
if (WindowsServiceHelpers.IsWindowsService())
|
||||
{
|
||||
_ = webApplicationBuilder.Services.AddSingleton<IHostLifetime, WindowsServiceLifetime>();
|
||||
_ = webApplicationBuilder.Logging.AddEventLog(settings =>
|
||||
{
|
||||
#pragma warning disable CA1416
|
||||
if (string.IsNullOrEmpty(settings.SourceName))
|
||||
settings.SourceName = webApplicationBuilder.Environment.ApplicationName;
|
||||
#pragma warning restore
|
||||
});
|
||||
}
|
||||
WebApplication webApplication = webApplicationBuilder.Build();
|
||||
logger = webApplication.Services.GetRequiredService<ILogger<Program>>();
|
||||
_ = webApplication.UseCors(corsPolicyBuilder => corsPolicyBuilder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
|
||||
if (!webApplicationBuilder.Environment.IsDevelopment())
|
||||
{
|
||||
_ = webApplication.UseExceptionHandler("/Error");
|
||||
_ = webApplication.UseHttpsRedirection();
|
||||
_ = webApplication.UseHsts();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(appSettings.URLs))
|
||||
{
|
||||
Environment.ExitCode = -1;
|
||||
webApplication.Lifetime.StopApplication();
|
||||
}
|
||||
_ = webApplication.UseSwagger();
|
||||
_ = webApplication.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Server V1"));
|
||||
}
|
||||
_ = webApplication.UseSession();
|
||||
_ = webApplication.MapControllers();
|
||||
logger.LogInformation("Starting Web Application");
|
||||
webApplication.Run();
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{ logger?.LogCritical(ex, "Host terminated unexpectedly"); }
|
||||
catch (Exception) { }
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
31
Wafer-Counter/Properties/launchSettings.json
Normal file
31
Wafer-Counter/Properties/launchSettings.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "http://localhost:5126",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:7130;http://localhost:5126",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https-prod": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:7130;http://localhost:5126",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Production"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
Wafer-Counter/Repositories/AppSettingsRepository.cs
Normal file
40
Wafer-Counter/Repositories/AppSettingsRepository.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using OI.Metrology.Wafer.Counter.Models;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter.Repository;
|
||||
|
||||
public class AppSettingsRepository : IAppSettingsRepository<Models.Binder.AppSettings>
|
||||
{
|
||||
|
||||
private readonly AppSettings _AppSettings;
|
||||
|
||||
public AppSettingsRepository(AppSettings appSettings) => _AppSettings = appSettings;
|
||||
|
||||
internal Models.Binder.AppSettings GetAppSettings()
|
||||
{
|
||||
Models.Binder.AppSettings result = new()
|
||||
{
|
||||
BuildNumber = _AppSettings.BuildNumber,
|
||||
Company = _AppSettings.Company,
|
||||
GitCommitSeven = _AppSettings.GitCommitSeven,
|
||||
IsDevelopment = _AppSettings.IsDevelopment,
|
||||
IsStaging = _AppSettings.IsStaging,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
Models.Binder.AppSettings IAppSettingsRepository<Models.Binder.AppSettings>.GetAppSettings() => GetAppSettings();
|
||||
|
||||
internal string GetBuildNumberAndGitCommitSeven()
|
||||
{
|
||||
string result = string.Concat(_AppSettings.BuildNumber, '-', _AppSettings.GitCommitSeven);
|
||||
return result;
|
||||
}
|
||||
|
||||
string IAppSettingsRepository<Models.Binder.AppSettings>.GetBuildNumberAndGitCommitSeven() =>
|
||||
GetBuildNumberAndGitCommitSeven();
|
||||
|
||||
void IAppSettingsRepository<Models.Binder.AppSettings>.VerifyConnectionStrings() =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
99
Wafer-Counter/Repositories/FileShareRepository.cs
Normal file
99
Wafer-Counter/Repositories/FileShareRepository.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using OI.Metrology.Shared.Models;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter.Repository;
|
||||
|
||||
public class FileShareRepository : IFileShareRepository
|
||||
{
|
||||
|
||||
Uri IFileShareRepository.Append(Uri uri, params string[] paths) =>
|
||||
new(paths.Aggregate(uri.AbsoluteUri, (current, path) =>
|
||||
string.Format("{0}/{1}", current.TrimEnd('/'), path.TrimStart('/'))));
|
||||
|
||||
private Uri GetEndPoint(HttpClient httpClient, string method)
|
||||
{
|
||||
Uri result;
|
||||
if (httpClient.BaseAddress is null)
|
||||
throw new NullReferenceException(nameof(httpClient.BaseAddress));
|
||||
IFileShareRepository fileShareRepository = this;
|
||||
result = fileShareRepository.Append(httpClient.BaseAddress, "api", "v1", "file-share", method);
|
||||
return result;
|
||||
}
|
||||
|
||||
void IFileShareRepository.CopyFile(string from, string to)
|
||||
{
|
||||
string directory = Path.GetDirectoryName(to) ?? throw new NullReferenceException();
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
File.Copy(from, to);
|
||||
}
|
||||
|
||||
void IFileShareRepository.MoveFile(string from, string to)
|
||||
{
|
||||
string directory = Path.GetDirectoryName(to) ?? throw new NullReferenceException();
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
if (File.Exists(to))
|
||||
File.Move(to, $"{to}.{DateTime.Now.Ticks}.old");
|
||||
File.Move(from, to);
|
||||
}
|
||||
|
||||
void IFileShareRepository.FileWrite(string path, string contents)
|
||||
{
|
||||
string directory = Path.GetDirectoryName(path) ?? throw new NullReferenceException();
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
File.WriteAllText(path, contents);
|
||||
}
|
||||
|
||||
void IFileShareRepository.CopyFile(HttpClient httpClient, string from, string to)
|
||||
{
|
||||
Uri uri = GetEndPoint(httpClient, "copy-file");
|
||||
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(uri);
|
||||
httpResponseMessage.Wait();
|
||||
if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK)
|
||||
throw new Exception(httpResponseMessage.Result.StatusCode.ToString());
|
||||
}
|
||||
|
||||
void IFileShareRepository.MoveFile(HttpClient httpClient, string from, string to)
|
||||
{
|
||||
Uri uri = GetEndPoint(httpClient, "move-file");
|
||||
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(uri);
|
||||
httpResponseMessage.Wait();
|
||||
if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK)
|
||||
throw new Exception(httpResponseMessage.Result.StatusCode.ToString());
|
||||
}
|
||||
|
||||
HttpResponseMessage IFileShareRepository.ReadFile(HttpClient httpClient, Uri uri)
|
||||
{
|
||||
HttpResponseMessage result;
|
||||
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(uri);
|
||||
httpResponseMessage.Wait();
|
||||
result = httpResponseMessage.Result;
|
||||
return result;
|
||||
}
|
||||
|
||||
List<NginxFileSystemSortable> IFileShareRepository.GetNginxFileSystemSortableCollection(HttpClient httpClient, Uri uri, string? endsWith)
|
||||
{
|
||||
List<NginxFileSystemSortable> results = new();
|
||||
Task<HttpResponseMessage> httpResponseMessage = httpClient.GetAsync(uri);
|
||||
httpResponseMessage.Wait();
|
||||
if (httpResponseMessage.Result.StatusCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
FileShareRepository fileShareRepository = this;
|
||||
Task<string> json = httpResponseMessage.Result.Content.ReadAsStringAsync();
|
||||
json.Wait();
|
||||
NginxFileSystem[]? nginxFileSystemCollection = JsonSerializer.Deserialize(json.Result, NginxFileSystemCollectionSourceGenerationContext.Default.NginxFileSystemArray);
|
||||
List<NginxFileSystemSortable> nginxFileSystemSortableCollection = NginxFileSystemSortable.Convert(fileShareRepository, uri, nginxFileSystemCollection);
|
||||
foreach (NginxFileSystemSortable nginxFileSystemSortable in nginxFileSystemSortableCollection.OrderByDescending(l => l.DateTime))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(endsWith) && !nginxFileSystemSortable.Name.EndsWith(endsWith))
|
||||
continue;
|
||||
results.Add(nginxFileSystemSortable);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
186
Wafer-Counter/Repositories/WaferCounterRepository.cs
Normal file
186
Wafer-Counter/Repositories/WaferCounterRepository.cs
Normal file
@ -0,0 +1,186 @@
|
||||
using OI.Metrology.Wafer.Counter.Models;
|
||||
using OI.Metrology.Shared.DataModels;
|
||||
using OI.Metrology.Shared.Models;
|
||||
using OI.Metrology.Shared.Models.Stateless;
|
||||
using OI.Metrology.Shared.Repositories;
|
||||
using System.Globalization;
|
||||
|
||||
namespace OI.Metrology.Wafer.Counter.Repository;
|
||||
|
||||
public class WaferCounterRepository : IWaferCounterRepository
|
||||
{
|
||||
|
||||
private record Record(int Check,
|
||||
int Total,
|
||||
string? SlotMap);
|
||||
|
||||
private readonly string _MockRoot;
|
||||
private readonly string _RepositoryName;
|
||||
private readonly AppSettings _AppSettings;
|
||||
private readonly IHttpClientFactory _HttpClientFactory;
|
||||
private readonly IDbConnectionFactory _DBConnectionFactory;
|
||||
private readonly IFileShareRepository _FileShareRepository;
|
||||
|
||||
public WaferCounterRepository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository)
|
||||
{
|
||||
_AppSettings = appSettings;
|
||||
_MockRoot = appSettings.MockRoot;
|
||||
_HttpClientFactory = httpClientFactory;
|
||||
_DBConnectionFactory = dbConnectionFactory;
|
||||
_FileShareRepository = fileShareRepository;
|
||||
_RepositoryName = nameof(WaferCounterRepository)[..^10];
|
||||
}
|
||||
|
||||
private void MoveFile(string waferSizeDirectory, NginxFileSystemSortable nginxFileSystemSortable)
|
||||
{
|
||||
Calendar calendar = new CultureInfo("en-US").Calendar;
|
||||
string from = Path.Combine(waferSizeDirectory, nginxFileSystemSortable.Name);
|
||||
string weekOfYear = $"{nginxFileSystemSortable.DateTime:yyyy}_Week_{calendar.GetWeekOfYear(nginxFileSystemSortable.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
|
||||
string to = Path.Combine(waferSizeDirectory, "Archive", weekOfYear, nginxFileSystemSortable.Name);
|
||||
_FileShareRepository.MoveFile(from, to);
|
||||
}
|
||||
|
||||
private static Record GetRecord(string line1, string line2)
|
||||
{
|
||||
Record result;
|
||||
string? slotMap = string.IsNullOrEmpty(line2) || line2.Length != 8 ? null : line2.Substring(1, 1);
|
||||
int check = slotMap == "1" ? 1 : 0;
|
||||
#pragma warning disable IDE0057
|
||||
int total = int.Parse(line1.Substring(1));
|
||||
foreach (char item in line2.Substring(2))
|
||||
#pragma warning restore IDE0057
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case '0':
|
||||
check += 0;
|
||||
slotMap += "0000";
|
||||
break;
|
||||
case '1':
|
||||
check += 1;
|
||||
slotMap += "0001";
|
||||
break;
|
||||
case '2':
|
||||
check += 1;
|
||||
slotMap += "0010";
|
||||
break;
|
||||
case '3':
|
||||
check += 2;
|
||||
slotMap += "0011";
|
||||
break;
|
||||
case '4':
|
||||
check += 1;
|
||||
slotMap += "0100";
|
||||
break;
|
||||
case '5':
|
||||
check += 2;
|
||||
slotMap += "0101";
|
||||
break;
|
||||
case '6':
|
||||
check += 2;
|
||||
slotMap += "0110";
|
||||
break;
|
||||
case '7':
|
||||
check += 3;
|
||||
slotMap += "0111";
|
||||
break;
|
||||
case '8':
|
||||
check += 1;
|
||||
slotMap += "1000";
|
||||
break;
|
||||
case '9':
|
||||
check += 2;
|
||||
slotMap += "1001";
|
||||
break;
|
||||
case 'A':
|
||||
check += 2;
|
||||
slotMap += "1010";
|
||||
break;
|
||||
case 'B':
|
||||
check += 3;
|
||||
slotMap += "1011";
|
||||
break;
|
||||
case 'C':
|
||||
check += 2;
|
||||
slotMap += "1100";
|
||||
break;
|
||||
case 'D':
|
||||
check += 3;
|
||||
slotMap += "1101";
|
||||
break;
|
||||
case 'E':
|
||||
check += 3;
|
||||
slotMap += "1110";
|
||||
break;
|
||||
case 'F':
|
||||
check += 4;
|
||||
slotMap += "1111";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = new(check, total, slotMap);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Uri GetWaferSizeUri(string area, string waferSize) =>
|
||||
_FileShareRepository.Append(new Uri(_AppSettings.EcMesaFileShareCharacterizationSi), "WaferCounter", area, waferSize);
|
||||
|
||||
private string GetWaferSizeDirectory(string area, string waferSize, bool destination) =>
|
||||
destination ? Path.Combine(_AppSettings.WaferCounterDestinationDirectory, area, waferSize) : Path.Combine(_AppSettings.EcCharacterizationSi, "WaferCounter", area, waferSize);
|
||||
|
||||
string? IWaferCounterRepository.GetSlotMap(string line1, string line2) =>
|
||||
GetRecord(line1, line2).SlotMap;
|
||||
|
||||
private List<NginxFileSystemSortable> GetNginxFileSystemSortableCollection(HttpClient httpClient, Uri waferSizeUri)
|
||||
{
|
||||
List<NginxFileSystemSortable> results = new();
|
||||
DateTime dateTime = DateTime.Now;
|
||||
long ticks = dateTime.AddSeconds(_AppSettings.WaferCounterTwoFileSecondsWait).Ticks;
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
results = _FileShareRepository.GetNginxFileSystemSortableCollection(httpClient, waferSizeUri, ".wc");
|
||||
if (results.Count > 0 || DateTime.Now.Ticks > ticks)
|
||||
break;
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static WaferCounter GetLastQuantityAndSlotMap(string waferSize, HttpClient httpClient, NginxFileSystemSortable nginxFileSystemSortable)
|
||||
{
|
||||
WaferCounter result;
|
||||
string text = string.Empty;
|
||||
Task<string> value = httpClient.GetStringAsync(nginxFileSystemSortable.Uri);
|
||||
value.Wait();
|
||||
string[] lines = value.Result.Split("\r\n");
|
||||
if (lines.Length <= 1)
|
||||
throw new Exception("Incomplete file length!");
|
||||
string[] segments = nginxFileSystemSortable.Name.Split('-');
|
||||
Record record = GetRecord(lines[0], lines[1]);
|
||||
string equipmentId = segments.Length <= 1 ? nginxFileSystemSortable.Name : segments[1].Split('.')[0];
|
||||
if (string.IsNullOrEmpty(record.SlotMap) || record.SlotMap.Length != 25)
|
||||
throw new Exception("Wrong length for slot-map!");
|
||||
if (record.Total != record.Check)
|
||||
throw new Exception($"Invalid {record.Total} != {record.Check}");
|
||||
result = new(nginxFileSystemSortable.DateTime, nginxFileSystemSortable.DateTime.ToString("yyyy-MM-dd hh:mm tt"), $"WC{waferSize}{equipmentId}", text, record.Total, record.SlotMap);
|
||||
return result;
|
||||
}
|
||||
|
||||
WaferCounter IWaferCounterRepository.GetLastQuantityAndSlotMap(string area, string waferSize)
|
||||
{
|
||||
WaferCounter result;
|
||||
Uri waferSizeUri = GetWaferSizeUri(area, waferSize);
|
||||
HttpClient httpClient = _HttpClientFactory.CreateClient();
|
||||
string waferSizeDirectory = GetWaferSizeDirectory(area, waferSize, destination: false);
|
||||
List<NginxFileSystemSortable> nginxFileSystemSortableCollection = GetNginxFileSystemSortableCollection(httpClient, waferSizeUri);
|
||||
if (nginxFileSystemSortableCollection.Count < 1)
|
||||
throw new Exception("No files!");
|
||||
result = GetLastQuantityAndSlotMap(waferSize, httpClient, nginxFileSystemSortableCollection[0]);
|
||||
for (int i = 0; i < nginxFileSystemSortableCollection.Count; i++)
|
||||
MoveFile(waferSizeDirectory, nginxFileSystemSortableCollection[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user