Separated Wafer-Counter

JsonElement instead of Request body
Attachment Class
Bump
Ready to test GetLastGroupIdWithValue
Changed to v4
This commit is contained in:
2024-05-21 12:40:20 -07:00
parent 5c9f0d1aff
commit 6317c385f6
38 changed files with 1231 additions and 476 deletions

View File

@ -66,6 +66,16 @@
],
"problemMatcher": "$msCompile"
},
{
"label": "Format-Whitespace",
"command": "dotnet",
"type": "process",
"args": [
"format",
"whitespace"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
@ -85,6 +95,24 @@
],
"problemMatcher": "$msCompile"
},
{
"label": "Publish AOT",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/OI.Metrology.Server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"--configuration",
"Release",
"--runtime",
"win-x64",
"-p:PublishAot=true",
"/property:GenerateFullPaths=true"
],
"problemMatcher": "$msCompile"
},
{
"label": "old-watch",
"command": "dotnet",

View File

@ -22,7 +22,7 @@ public class FileShareController : Controller, IFileShareController<IResult>
[HttpGet("move-file")]
public IResult MoveFile(string from, string to)
{
_FileShareRepository.CopyFile(from, to);
_FileShareRepository.MoveFile(from, to);
return Results.Ok();
}

View File

@ -4,6 +4,7 @@ using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Services;
using System.Net;
using System.Text.Json;
namespace OI.Metrology.Server.ApiControllers;
@ -29,22 +30,9 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
_MetrologyRepository = metrologyRepository;
}
private static string? GetJson(Stream stream)
{
string? result;
if (!stream.CanRead)
result = null;
else
{
Task<string> task = new StreamReader(stream).ReadToEndAsync();
result = task.Result;
}
return result;
}
[HttpPost]
[Route("{tooltype}")]
public IActionResult Post(string tooltype)
public IActionResult Post(string tooltype, JsonElement? jsonElement)
{
IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress;
if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP))
@ -54,8 +42,7 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
}
else
{
string? json = GetJson(Request.Body);
DataResponse dataResponse = _InboundRepository.Data(_MetrologyRepository, _InboundDataService, tooltype, json);
DataResponse dataResponse = _InboundRepository.Data(_MetrologyRepository, _InboundDataService, tooltype, jsonElement);
if (dataResponse.Errors.Count == 0)
return Ok(dataResponse);
else
@ -65,7 +52,7 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
[HttpPost]
[Route("{tooltype}/attachment")]
public IActionResult AttachFile(string tooltype, [FromQuery] long headerid, [FromQuery] string datauniqueid = "")
public IActionResult AttachFile(string tooltype, Attachment? attachment)
{
IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress;
if (!_InboundRepository.IsIPAddressAllowed(_AppSettings.InboundApiAllowedIPList, remoteIP))
@ -75,16 +62,8 @@ public partial class InboundController : ControllerBase, IInboundController<IAct
}
else
{
if (Request.Form is null)
return BadRequest($"Invalid form");
if (Request.Form.Files.Count != 1)
return BadRequest($"Invalid file count");
IFormFile formFile = Request.Form.Files[0];
string? message = _InboundRepository.AttachFile(_MetrologyRepository, _AttachmentsService, tooltype, headerid, datauniqueid, formFile.FileName, formFile);
if (message is null)
_InboundRepository.AttachFile(_MetrologyRepository, _AttachmentsService, tooltype, attachment);
return Ok();
else
return BadRequest(message);
}
}

View File

@ -79,4 +79,8 @@ public class InfinityQSV4Controller : Controller, IInfinityQSV4Controller<IActio
public IActionResult GetProductionSpecification(string part) =>
Content(_InfinityQSRepositoryV4.GetProductionSpecification(part));
[HttpGet("{process}/last-group-id-with-value")]
public IActionResult GetLastGroupIdWithValue(string process, string? part, int? test) =>
Content(_InfinityQSRepositoryV4.GetLastGroupIdWithValue(process, part, test));
}

View File

@ -25,10 +25,10 @@
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.37" />
<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.3" />
<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" />
@ -38,9 +38,9 @@
<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.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="System.Drawing.Common" Version="8.0.3" />
<PackageReference Include="System.Drawing.Common" Version="8.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\OI.Metrology.Shared.csproj" />

View File

@ -74,7 +74,6 @@ public class Program
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV2Repository, InfinityQSV2Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV3Repository, InfinityQSV3Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IInfinityQSV4Repository, InfinityQSV4Repository>();
_ = webApplicationBuilder.Services.AddSingleton<IWaferCounterRepository, WaferCounterRepository>();
_ = webApplicationBuilder.Services.AddSingleton<IClientSettingsRepository>(_ => clientSettingsRepository);
_ = webApplicationBuilder.Services.AddSingleton<IServiceShopOrderRepository, ServiceShopOrderRepository>();
_ = webApplicationBuilder.Services.AddSingleton<ISpreadingResistanceProfileService, SpreadingResistanceProfileService>();

View File

@ -64,15 +64,6 @@ public class FileShareRepository : IFileShareRepository
throw new Exception(httpResponseMessage.Result.StatusCode.ToString());
}
void IFileShareRepository.FileWrite(HttpClient httpClient, string path, string contents)
{
Uri uri = GetEndPoint(httpClient, "file-write");
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;

View File

@ -31,39 +31,17 @@ public class InboundRepository : IInboundRepository
return false;
}
// this is the main endpoint, it accepts a JSON message that contains both the header and data records together
// tooltype is the ToolTypeName column from the ToolType table
// JToken is how you can accept a JSON message without deserialization.
// Using "string" doesn't work because ASP.NET Core will expect a json encoded string, not give you the actual string.
DataResponse IInboundRepository.Data(IMetrologyRepository metrologyRepository, IInboundDataService inboundDataService, string tooltype, string? json)
DataResponse IInboundRepository.Data(IMetrologyRepository metrologyRepository, IInboundDataService inboundDataService, string toolTypeName, JsonElement? jsonElement)
{
DataResponse result = new();
ToolType? toolType = metrologyRepository.GetToolTypeByName(tooltype);
if (toolType is null)
result.Errors.Add($"Invalid tool type: {tooltype}");
else
{
InboundCommon? inboundCommon = string.IsNullOrEmpty(json) ? null : JsonSerializer.Deserialize<InboundCommon>(json);
if (inboundCommon is null || string.IsNullOrEmpty(inboundCommon.ProcessDataStandardFormat))
result.Errors.Add($"Invalid body: {json}");
else
{
string? sourceDirectory = Path.GetDirectoryName(inboundCommon.ProcessDataStandardFormat);
string? parentDirectory = Path.GetDirectoryName(sourceDirectory);
if (string.IsNullOrEmpty(sourceDirectory) || string.IsNullOrEmpty(parentDirectory) || !Directory.Exists(parentDirectory))
result.Errors.Add($"Invalid body:path: <{inboundCommon.ProcessDataStandardFormat}>");
else
{
JToken jToken = string.IsNullOrEmpty(json) ? JToken.Parse("{}") : JToken.Parse(json);
if (jToken is null)
result.Errors.Add($"Invalid body: {json}");
else
{
if (jsonElement is null || jsonElement.Value.ValueKind != JsonValueKind.Object)
throw new Exception("Invalid body!");
string? json = jsonElement.ToString();
JToken jToken = (string.IsNullOrEmpty(json) ? JToken.Parse("{}") : JToken.Parse(json)) ??
throw new Exception($"Invalid body: {json}");
ToolType toolType = metrologyRepository.GetToolTypeByName(toolTypeName) ??
throw new Exception($"Invalid tool type: {toolTypeName}");
List<ToolTypeMetadata> metaData = metrologyRepository.GetToolTypeMetadataByToolTypeID(toolType.ID).ToList();
if (metaData is null)
result.Errors.Add($"Invalid metadata for tool type: {tooltype}");
else
{
inboundDataService.ValidateJSONFields(jToken, 0, metaData, result.Errors, result.Warnings);
if (result.Errors.Count == 0)
{
@ -71,36 +49,24 @@ public class InboundRepository : IInboundRepository
{
result.HeaderID = inboundDataService.DoSQLInsert(jToken, toolType, metaData);
result.Success = result.HeaderID > 0;
string? destinationDirectory = Path.Combine(parentDirectory, result.HeaderID.ToString());
Directory.Move(sourceDirectory, destinationDirectory);
}
catch (Exception ex) { result.Errors.Add(ex.Message); }
}
}
}
}
}
}
return result;
}
// this is the endpoint for attaching a field. It is not JSON, it is form-data/multipart like an HTML form because that's the normal way.
// header ID is the ID value from the Header table
// datauniqueid is the Title value from the Data/Detail table
string? IInboundRepository.AttachFile(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string tooltype, long headerid, string datauniqueid, string fileName, object uploadedFile)
void IInboundRepository.AttachFile(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string toolTypeName, Attachment? attachment)
{
string? result = null;
ToolType toolType = metrologyRepository.GetToolTypeByName(tooltype);
if (toolType is null)
result = $"Invalid tool type: {tooltype}";
string filename = Path.GetFileName(fileName);
if (string.IsNullOrWhiteSpace(filename))
result = "Empty filename";
if (filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
result = "Invalid filename";
if (result is null && toolType is not null)
attachmentsService.SaveAttachment(toolType, headerid, datauniqueid, filename, uploadedFile);
return result;
if (attachment is null)
throw new Exception("Invalid body!");
ToolType toolType = metrologyRepository.GetToolTypeByName(toolTypeName) ??
throw new Exception($"Invalid tool type: {toolTypeName}");
if (string.IsNullOrWhiteSpace(attachment.DestinationFileName))
throw new Exception("Empty filename");
if (attachment.DestinationFileName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
throw new Exception("Invalid filename");
attachmentsService.SaveAttachment(toolType, attachment);
}
}

View File

@ -37,119 +37,117 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
string IInfinityQSV4Repository.GetCommandText(string subGroupId)
{ // cSpell:disable
StringBuilder result = new();
List<string> results = [];
if (string.IsNullOrEmpty(subGroupId))
throw new ArgumentException(null, nameof(subGroupId));
_ = result
.AppendLine(" select ")
.AppendLine(" sd.f_sgrp sd_sgrp, ")
.AppendLine(" sd.f_tsno sd_tsno, ")
.AppendLine(" dd.f_dsgp dd_dsgp, ")
.AppendLine(" dg.f_name gd_name, ")
.AppendLine(" dd.f_name dd_name ")
.AppendLine(" from [SPCEPIWORLD].[dbo].[SGRP_DSC] sd ")
.AppendLine(" join [SPCEPIWORLD].[dbo].[DESC_DAT] dd ")
.AppendLine(" on sd.f_dsgp = dd.f_dsgp ")
.AppendLine(" and sd.f_desc = dd.f_desc ")
.AppendLine(" join [SPCEPIWORLD].[dbo].[DESC_GRP] dg ")
.AppendLine(" on dd.f_dsgp = dg.f_dsgp ");
_ = result.Append(" where sd.f_sgrp = ").Append(subGroupId).AppendLine(" ");
_ = result.AppendLine(" for json path ");
return result.ToString();
results.Add(" select ");
results.Add(" sd.f_sgrp sd_sgrp, ");
results.Add(" sd.f_tsno sd_tsno, ");
results.Add(" dd.f_dsgp dd_dsgp, ");
results.Add(" dg.f_name gd_name, ");
results.Add(" dd.f_name dd_name ");
results.Add(" from [SPCEPIWORLD].[dbo].[SGRP_DSC] sd ");
results.Add(" join [SPCEPIWORLD].[dbo].[DESC_DAT] dd ");
results.Add(" on sd.f_dsgp = dd.f_dsgp ");
results.Add(" and sd.f_desc = dd.f_desc ");
results.Add(" join [SPCEPIWORLD].[dbo].[DESC_GRP] dg ");
results.Add(" on dd.f_dsgp = dg.f_dsgp ");
results.Add($" where sd.f_sgrp = {subGroupId} ");
results.Add(" for json path ");
return string.Join(' ', results);
} // cSpell:enable
string IInfinityQSV4Repository.GetCommandText(string? subGroupId, string? process, string? job, string? part, string? lot, string? dateTime)
{ // cSpell:disable
StringBuilder result = new();
List<string> results = [];
const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss";
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')) && dateTime.Length != dateTimeFormat.Length)
throw new ArgumentException(null, nameof(dateTime));
_ = result
.AppendLine(" select case when iq.sl_loos is null then 0 else iq.sl_loos end + ")
.AppendLine(" case when iq.sl_uoos is null then 0 else iq.sl_uoos end + ")
.AppendLine(" iq.ev_count as iq_sum, ")
.AppendLine(" iq.sl_aflag, ")
.AppendLine(" iq.sl_loos, ")
.AppendLine(" iq.sl_uoos, ")
.AppendLine(" iq.se_sgrp, ")
.AppendLine(" iq.se_sgtm, ")
.AppendLine(" iq.se_tsno, ")
.AppendLine(" iq.td_test, ")
.AppendLine(" iq.pr_name, ")
.AppendLine(" iq.jd_name, ")
.AppendLine(" iq.pl_name, ")
.AppendLine(" iq.pd_name, ")
.AppendLine(" iq.td_name, ")
.AppendLine(" iq.se_val, ")
.AppendLine(" iq.sl_eflag, ")
.AppendLine(" iq.sl_scal, ")
.AppendLine(" iq.sl_sls, ")
.AppendLine(" iq.sl_usl ")
.AppendLine(" from ( ")
.AppendLine(" select ")
.AppendLine(" se.f_sgrp se_sgrp, ")
.AppendLine(" se.f_sgtm se_sgtm, ")
.AppendLine(" se.f_tsno se_tsno, ")
.AppendLine(" se.f_val se_val, ")
.AppendLine(" pr.f_name pr_name, ")
.AppendLine(" jd.f_name jd_name, ")
.AppendLine(" pl.f_name pl_name, ")
.AppendLine(" pd.f_name pd_name, ")
.AppendLine(" td.f_test td_test, ")
.AppendLine(" td.f_name td_name, ")
.AppendLine(" sl.f_eflag sl_eflag, ")
.AppendLine(" sl.f_aflag sl_aflag, ")
.AppendLine(" sl.f_scal sl_scal, ")
.AppendLine(" sl.f_lsl sl_sls, ")
.AppendLine(" sl.f_usl sl_usl, ")
.AppendLine(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ")
.AppendLine(" case when round(se.f_val, sl.F_scal, 1) < sl.f_lsl then 1 else 0 end ")
.AppendLine(" end as sl_loos, ")
.AppendLine(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ")
.AppendLine(" case when round(se.f_val, sl.F_scal, 1) > sl.f_usl then 1 else 0 end ")
.AppendLine(" end as sl_uoos, ")
.AppendLine(" (select count(ev.f_evnt) ")
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
.AppendLine(" where ev.f_prcs = pr.f_prcs ")
.AppendLine(" and ev.f_part = pd.f_part ")
.AppendLine(" and ev.f_sgtm = se.f_sgtm ")
.AppendLine(" ) ev_count ")
.AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on se.f_prcs = pr.f_prcs ")
.AppendLine(" join [spcepiworld].[dbo].[job_dat] jd ")
.AppendLine(" on se.f_job = jd.f_job ")
.AppendLine(" join [spcepiworld].[dbo].[part_lot] pl ")
.AppendLine(" on se.f_lot = pl.f_lot ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
.AppendLine(" on se.f_part = pd.f_part ")
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
.AppendLine(" on se.f_test = td.f_test ")
.AppendLine(" left join [spcepiworld].[dbo].[spec_lim] sl ")
.AppendLine(" on se.f_part = sl.f_part ")
.AppendLine(" and se.f_test = sl.f_test ")
.AppendLine(" where se.f_flag = 0 ")
.AppendLine(" and (sl.f_prcs is null or se.f_prcs = sl.f_prcs or sl.f_prcs = 0) ");
results.Add(" select case when iq.sl_loos is null then 0 else iq.sl_loos end + ");
results.Add(" case when iq.sl_uoos is null then 0 else iq.sl_uoos end + ");
results.Add(" iq.ev_count as iq_sum, ");
results.Add(" iq.sl_aflag, ");
results.Add(" iq.sl_loos, ");
results.Add(" iq.sl_uoos, ");
results.Add(" iq.se_sgrp, ");
results.Add(" iq.se_sgtm, ");
results.Add(" iq.se_tsno, ");
results.Add(" iq.td_test, ");
results.Add(" iq.pr_name, ");
results.Add(" iq.jd_name, ");
results.Add(" iq.pl_name, ");
results.Add(" iq.pd_name, ");
results.Add(" iq.td_name, ");
results.Add(" iq.se_val, ");
results.Add(" iq.sl_eflag, ");
results.Add(" iq.sl_scal, ");
results.Add(" iq.sl_sls, ");
results.Add(" iq.sl_usl ");
results.Add(" from ( ");
results.Add(" select ");
results.Add(" se.f_sgrp se_sgrp, ");
results.Add(" se.f_sgtm se_sgtm, ");
results.Add(" se.f_tsno se_tsno, ");
results.Add(" se.f_val se_val, ");
results.Add(" pr.f_name pr_name, ");
results.Add(" jd.f_name jd_name, ");
results.Add(" pl.f_name pl_name, ");
results.Add(" pd.f_name pd_name, ");
results.Add(" td.f_test td_test, ");
results.Add(" td.f_name td_name, ");
results.Add(" sl.f_eflag sl_eflag, ");
results.Add(" sl.f_aflag sl_aflag, ");
results.Add(" sl.f_scal sl_scal, ");
results.Add(" sl.f_lsl sl_sls, ");
results.Add(" sl.f_usl sl_usl, ");
results.Add(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ");
results.Add(" case when round(se.f_val, sl.F_scal, 1) < sl.f_lsl then 1 else 0 end ");
results.Add(" end as sl_loos, ");
results.Add(" case when sl.f_aflag is null or sl.f_aflag = 0 then null else ");
results.Add(" case when round(se.f_val, sl.F_scal, 1) > sl.f_usl then 1 else 0 end ");
results.Add(" end as sl_uoos, ");
results.Add(" (select count(ev.f_evnt) ");
results.Add(" from [spcepiworld].[dbo].[evnt_inf] ev ");
results.Add(" where ev.f_prcs = pr.f_prcs ");
results.Add(" and ev.f_part = pd.f_part ");
results.Add(" and ev.f_sgtm = se.f_sgtm ");
results.Add(" ) ev_count ");
results.Add(" from [spcepiworld].[dbo].[sgrp_ext] se ");
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr ");
results.Add(" on se.f_prcs = pr.f_prcs ");
results.Add(" join [spcepiworld].[dbo].[job_dat] jd ");
results.Add(" on se.f_job = jd.f_job ");
results.Add(" join [spcepiworld].[dbo].[part_lot] pl ");
results.Add(" on se.f_lot = pl.f_lot ");
results.Add(" join [spcepiworld].[dbo].[part_dat] pd ");
results.Add(" on se.f_part = pd.f_part ");
results.Add(" join [spcepiworld].[dbo].[test_dat] td ");
results.Add(" on se.f_test = td.f_test ");
results.Add(" left join [spcepiworld].[dbo].[spec_lim] sl ");
results.Add(" on se.f_part = sl.f_part ");
results.Add(" and se.f_test = sl.f_test ");
results.Add(" where se.f_flag = 0 ");
results.Add(" and (sl.f_prcs is null or se.f_prcs = sl.f_prcs or sl.f_prcs = 0) ");
if (!string.IsNullOrEmpty(subGroupId))
_ = result.Append(" and se.f_sgrp = ").Append(subGroupId.Split(" ")[0]).AppendLine(" ");
results.Add($" and se.f_sgrp = {subGroupId.Split(" ")[0]} ");
if (!string.IsNullOrEmpty(process))
_ = result.Append(" and pr.f_name = '").Append(process).AppendLine("' ");
results.Add($" and pr.f_name = '{process}' ");
if (!string.IsNullOrEmpty(part))
_ = result.Append(" and pd.f_name = '").Append(part).AppendLine("' ");
results.Add($" and pd.f_name = '{part}' ");
if (!string.IsNullOrEmpty(job))
_ = result.Append(" and jd.f_name = '").Append(job).AppendLine("' ");
results.Add($" and jd.f_name = '{job}' ");
if (!string.IsNullOrEmpty(lot))
_ = result.Append(" and pl.f_name = '").Append(lot).AppendLine("' ");
results.Add($" and pl.f_name = '{lot}' ");
if (!string.IsNullOrEmpty(dateTime) && (dateTime.Contains('-') || dateTime.Contains(' ') || dateTime.Contains(':')))
_ = result.Append(" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '").Append(dateTime).AppendLine("' ");
_ = result.AppendLine(" ) as iq ")
.AppendLine(" order by iq.sl_loos + iq.sl_uoos + iq.ev_count desc, ")
.AppendLine(" iq.sl_aflag desc, ")
.AppendLine(" iq.se_sgrp, ")
.AppendLine(" iq.se_tsno, ")
.AppendLine(" iq.td_test ")
.AppendLine(" for json path ");
return result.ToString();
results.Add($" and dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgtm), '19700101'))) = '{dateTime}' ");
results.Add(" ) as iq ");
results.Add(" order by iq.sl_loos + iq.sl_uoos + iq.ev_count desc, ");
results.Add(" iq.sl_aflag desc, ");
results.Add(" iq.se_sgrp, ");
results.Add(" iq.se_tsno, ");
results.Add(" iq.td_test ");
results.Add(" for json path ");
return string.Join(' ', results);
} // cSpell:enable
private JsonElement[] GetAllReactorsAsJsonElementElement()
@ -293,33 +291,32 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
string IInfinityQSV4Repository.GetCommandText(InfinityQSV4 infinityQSV4)
{ // cSpell:disable
StringBuilder result = new();
List<string> results = [];
if (string.IsNullOrEmpty(infinityQSV4.Process))
throw new ArgumentException(nameof(infinityQSV4.Process));
if (string.IsNullOrEmpty(infinityQSV4.Part))
throw new ArgumentException(nameof(infinityQSV4.Part));
_ = result
.AppendLine(" select ")
.AppendLine(" ev.f_evnt [ev_evnt], ")
.AppendLine(" ev.f_sgtm [ev_sgtm], ")
.AppendLine(" dateadd(HH, -7, (dateadd(SS, convert(bigint, ev.f_sgtm), '19700101'))) [ev_utc7], ")
.AppendLine(" pr.f_name [pr_name], ")
.AppendLine(" pd.f_name [pd_name], ")
.AppendLine(" td.f_test [td_test], ")
.AppendLine(" td.f_name [td_name], ")
.AppendLine(" ev.f_name [ev_name] ")
.AppendLine(" from [spcepiworld].[dbo].[evnt_inf] ev ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on ev.f_prcs = pr.f_prcs ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
.AppendLine(" on ev.f_part = pd.f_part ")
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
.AppendLine(" on ev.f_test = td.f_test ")
.Append(" where pr.f_name = '").Append(infinityQSV4.Process).AppendLine("' ")
.Append(" and pd.f_name = '").Append(infinityQSV4.Part).AppendLine("' ")
.Append(" and ev.f_sgtm = ").Append(infinityQSV4.SubGroupDateTime).AppendLine(" ")
.AppendLine(" for json path ");
return result.ToString();
results.Add(" select ");
results.Add(" ev.f_evnt [ev_evnt], ");
results.Add(" ev.f_sgtm [ev_sgtm], ");
results.Add(" dateadd(HH, -7, (dateadd(SS, convert(bigint, ev.f_sgtm), '19700101'))) [ev_utc7], ");
results.Add(" pr.f_name [pr_name], ");
results.Add(" pd.f_name [pd_name], ");
results.Add(" td.f_test [td_test], ");
results.Add(" td.f_name [td_name], ");
results.Add(" ev.f_name [ev_name] ");
results.Add(" from [spcepiworld].[dbo].[evnt_inf] ev ");
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr ");
results.Add(" on ev.f_prcs = pr.f_prcs ");
results.Add(" join [spcepiworld].[dbo].[part_dat] pd ");
results.Add(" on ev.f_part = pd.f_part ");
results.Add(" join [spcepiworld].[dbo].[test_dat] td ");
results.Add(" on ev.f_test = td.f_test ");
results.Add($" where pr.f_name = '{infinityQSV4.Process}' ");
results.Add($" and pd.f_name = '{infinityQSV4.Part}' ");
results.Add($" and ev.f_sgtm = {infinityQSV4.SubGroupDateTime} ");
results.Add(" for json path ");
return string.Join(' ', results);
} // cSpell:enable
Result<InfinityQSV4[]> IInfinityQSV4Repository.GetHeader(string subGroupId)
@ -348,28 +345,27 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
string IInfinityQSV4Repository.GetCommandText(string process, string? part)
{ // cSpell:disable
StringBuilder result = new();
List<string> results = [];
if (string.IsNullOrEmpty(process))
throw new ArgumentException(null, nameof(process));
if (string.IsNullOrEmpty(part))
throw new ArgumentException(null, nameof(part));
_ = result
.AppendLine(" select [f_mean] as ProcessMean, ")
.AppendLine(" [f_sp] as ProcessSigma ")
.AppendLine(" from [spcepiworld].[dbo].[test_dat] test ")
.AppendLine(" join [spcepiworld].[dbo].[ctrl_lim] ctrl ")
.AppendLine(" on test.f_test = ctrl.f_test ")
.AppendLine(" and test.f_tsgp = 1104848523 /* Product Data */ ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] part ")
.AppendLine(" on part.f_part = ctrl.f_part ")
.AppendLine(" and ctrl.f_test = 1125073605 /* Average Sum of Defects */ ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] process ")
.AppendLine(" on process.f_prcs = ctrl.f_prcs ")
.AppendLine(" where test.f_name = 'Average Sum of Defects' ")
.Append(" and process.f_name = '").Append(process).AppendLine("' ")
.Append(" and part.f_name = '").Append(part).AppendLine("' ")
.AppendLine(" for json path; ");
return result.ToString();
results.Add(" select [f_mean] as ProcessMean, ");
results.Add(" [f_sp] as ProcessSigma ");
results.Add(" from [spcepiworld].[dbo].[test_dat] test ");
results.Add(" join [spcepiworld].[dbo].[ctrl_lim] ctrl ");
results.Add(" on test.f_test = ctrl.f_test ");
results.Add(" and test.f_tsgp = 1104848523 /* Product Data */ ");
results.Add(" join [spcepiworld].[dbo].[part_dat] part ");
results.Add(" on part.f_part = ctrl.f_part ");
results.Add(" and ctrl.f_test = 1125073605 /* Average Sum of Defects */ ");
results.Add(" join [spcepiworld].[dbo].[prcs_dat] process ");
results.Add(" on process.f_prcs = ctrl.f_prcs ");
results.Add(" where test.f_name = 'Average Sum of Defects' ");
results.Add($" and process.f_name = '{process}' ");
results.Add($" and part.f_name = '{part}' ");
results.Add(" for json path; ");
return string.Join(' ', results);
} // cSpell:enable
string IInfinityQSV4Repository.GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe)
@ -393,53 +389,52 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
string IInfinityQSV4Repository.GetCommandText(List<string> eppReactorNumbers)
{ // cSpell:disable
StringBuilder result = new();
_ = result
.AppendLine(" select se.f_sgrp, ")
.AppendLine(" dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgrp), '19700101'))) date_time, ")
.AppendLine(" iq.pr_name, ")
.AppendLine(" iq.pd_name, ")
.AppendLine(" max(case ")
.AppendLine(" when td.f_test = 1104769646 ")
.AppendLine(" then se.f_val ")
.AppendLine(" else null ")
.AppendLine(" end) as iq_value, ")
.AppendLine(" max(case ")
.AppendLine(" when td.f_test = 1312288843 ")
.AppendLine(" then se.f_val else null ")
.AppendLine(" end) as iq_temp_offset_percent ")
.AppendLine(" from ( ")
.AppendLine(" select ")
.AppendLine(" max(se.f_sgrp) se_max_sgrp, ")
.AppendLine(" se.f_test se_test, ")
.AppendLine(" pr.f_name pr_name, ")
.AppendLine(" pd.f_name pd_name ")
.AppendLine(" from [spcepiworld].[dbo].[sgrp_ext] se ")
.AppendLine(" join [spcepiworld].[dbo].[prcs_dat] pr ")
.AppendLine(" on se.f_prcs = pr.f_prcs ")
.AppendLine(" join [spcepiworld].[dbo].[part_dat] pd ")
.AppendLine(" on se.f_part = pd.f_part ")
.AppendLine(" where se.f_flag = 0 ")
.Append(" and pr.f_name in (").Append(string.Join(',', eppReactorNumbers)).AppendLine(") ")
.AppendLine(" and pd.f_name = '1090 - Full Load' ")
.AppendLine(" and se.f_test in (1104769646, 1312288843) ")
.AppendLine(" group by se.f_test, ")
.AppendLine(" pr.f_name, ")
.AppendLine(" pd.f_name ")
.AppendLine(" ) as iq ")
.AppendLine(" join [spcepiworld].[dbo].[sgrp_ext] se ")
.AppendLine(" on iq.se_max_sgrp = se.f_sgrp ")
.AppendLine(" join [spcepiworld].[dbo].[test_dat] td ")
.AppendLine(" on iq.se_test = td.f_test ")
.AppendLine(" and se.f_test = td.f_test ")
.AppendLine(" where se.f_flag = 0 ")
.AppendLine(" and td.f_test in (1104769646, 1312288843) ")
.AppendLine(" group by se.f_sgrp, ")
.AppendLine(" iq.pr_name, ")
.AppendLine(" iq.pd_name ")
.AppendLine(" order by iq.pr_name ")
.AppendLine(" for json path; ");
return result.ToString();
List<string> results = [];
results.Add(" select se.f_sgrp, ");
results.Add(" dateadd(HH, -7, (dateadd(SS, convert(bigint, se.f_sgrp), '19700101'))) date_time, ");
results.Add(" iq.pr_name, ");
results.Add(" iq.pd_name, ");
results.Add(" max(case ");
results.Add(" when td.f_test = 1104769646 ");
results.Add(" then se.f_val ");
results.Add(" else null ");
results.Add(" end) as iq_value, ");
results.Add(" max(case ");
results.Add(" when td.f_test = 1312288843 ");
results.Add(" then se.f_val else null ");
results.Add(" end) as iq_temp_offset_percent ");
results.Add(" from ( ");
results.Add(" select ");
results.Add(" max(se.f_sgrp) se_max_sgrp, ");
results.Add(" se.f_test se_test, ");
results.Add(" pr.f_name pr_name, ");
results.Add(" pd.f_name pd_name ");
results.Add(" from [spcepiworld].[dbo].[sgrp_ext] se ");
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr ");
results.Add(" on se.f_prcs = pr.f_prcs ");
results.Add(" join [spcepiworld].[dbo].[part_dat] pd ");
results.Add(" on se.f_part = pd.f_part ");
results.Add(" where se.f_flag = 0 ");
results.Add($" and pr.f_name in ({string.Join(',', eppReactorNumbers)} ");
results.Add(" and pd.f_name = '1090 - Full Load' ");
results.Add(" and se.f_test in (1104769646, 1312288843) ");
results.Add(" group by se.f_test, ");
results.Add(" pr.f_name, ");
results.Add(" pd.f_name ");
results.Add(" ) as iq ");
results.Add(" join [spcepiworld].[dbo].[sgrp_ext] se ");
results.Add(" on iq.se_max_sgrp = se.f_sgrp ");
results.Add(" join [spcepiworld].[dbo].[test_dat] td ");
results.Add(" on iq.se_test = td.f_test ");
results.Add(" and se.f_test = td.f_test ");
results.Add(" where se.f_flag = 0 ");
results.Add(" and td.f_test in (1104769646, 1312288843) ");
results.Add(" group by se.f_sgrp, ");
results.Add(" iq.pr_name, ");
results.Add(" iq.pd_name ");
results.Add(" order by iq.pr_name ");
results.Add(" for json path; ");
return string.Join(' ', results);
} // cSpell:enable
List<string[]> IInfinityQSV4Repository.GetEpiProTempVerificationRows(int[] night)
@ -651,4 +646,55 @@ public class InfinityQSV4Repository : IInfinityQSV4Repository
return result;
}
private static string GetCommandText(string process, string? part, int? test)
{ // cSpell:disable
List<string> results = [];
if (string.IsNullOrEmpty(process))
throw new ArgumentException(null, nameof(process));
if (string.IsNullOrEmpty(part))
throw new ArgumentException(null, nameof(part));
if (test is null)
throw new ArgumentException(null, nameof(test));
results.Add(" select se_max_sgrp, se.f_val se_value ");
results.Add(" from ( ");
results.Add(" select ");
results.Add(" max(se.f_sgrp) se_max_sgrp ");
results.Add(" from [spcepiworld].[dbo].[sgrp_ext] se ");
results.Add(" join [spcepiworld].[dbo].[prcs_dat] pr ");
results.Add(" on se.f_prcs = pr.f_prcs ");
results.Add(" join [spcepiworld].[dbo].[part_dat] pd ");
results.Add(" on se.f_part = pd.f_part ");
results.Add(" where se.f_flag = 0 ");
results.Add(" and se.f_tsno = 1 ");
results.Add($" and pr.f_name = '{process}' ");
results.Add($" and pd.f_name = '{part}' ");
results.Add($" and se.f_test = {test.Value} ");
results.Add(" ) as iq ");
results.Add(" join [spcepiworld].[dbo].[sgrp_ext] se ");
results.Add(" on se_max_sgrp = se.f_sgrp ");
results.Add(" where se.f_flag = 0 ");
results.Add(" and se.f_tsno = 1 ");
results.Add($" and se.f_test = {test.Value} ");
results.Add(" for json path ");
return string.Join(' ', results);
} // cSpell:enable
string IInfinityQSV4Repository.GetLastGroupIdWithValue(string process, string? part, int? test)
{
StringBuilder result;
if (!string.IsNullOrEmpty(_MockRoot))
{
string json = File.ReadAllText(Path.Combine(string.Concat(AppContext.BaseDirectory, _MockRoot), $"{_RepositoryName}-{nameof(IInfinityQSV4Repository.GetLastGroupIdWithValue)}.json"));
result = new(json);
}
else
{
string commandText = GetCommandText(process, part, test);
result = GetForJsonPath(_DBConnectionFactory, commandText, useIqsConnection: false);
if (result.Length == 0)
result = new("{}");
}
return result.ToString();
}
}

View File

@ -16,6 +16,7 @@ namespace OI.Metrology.Server.Repositories;
public class MetrologyRepository : IMetrologyRepository
{
private readonly string _MockRoot;
private readonly string _RepositoryName;
private readonly IMemoryCache _MemoryCache;
@ -32,7 +33,8 @@ public class MetrologyRepository : IMetrologyRepository
protected DbProviderFactory GetDbProviderFactory(IDbConnection conn) =>
DbProviderFactories.GetFactory(conn.GetType().Namespace);
internal static TransactionScope StartTransaction() => new();
internal static TransactionScope StartTransaction() =>
new();
protected void CacheItem(string key, object v)
{
@ -56,7 +58,7 @@ public class MetrologyRepository : IMetrologyRepository
return r;
}
internal ToolType GetToolTypeByName(string name)
ToolType IMetrologyRepository.GetToolTypeByName(string name)
{
ToolType cached;
string cacheKey = "GetToolTypeByName_" + name;
@ -107,7 +109,7 @@ public class MetrologyRepository : IMetrologyRepository
return r;
}
internal long InsertToolDataJSON(JToken jsonrow, long headerId, List<ToolTypeMetadata> metaData, string tableName)
long IMetrologyRepository.InsertToolDataJSON(JToken jsonrow, long headerId, List<ToolTypeMetadata> metaData, string tableName)
{
long r = -1;
using (DbConnection conn = _DBConnectionFactory.GetDbConnection())
@ -115,7 +117,8 @@ public class MetrologyRepository : IMetrologyRepository
bool isHeader = headerId <= 0;
// get fields from metadata
List<ToolTypeMetadata> fields = metaData.Where(md => md.Header == isHeader).ToList();
List<ToolTypeMetadata> fields = metaData.Where(md =>
md.Header == isHeader).ToList();
// maps ApiName to ColumnName
Dictionary<string, string> fieldmap = new();
@ -155,7 +158,8 @@ public class MetrologyRepository : IMetrologyRepository
else
{
// Find the container field in the json
JProperty contJP = jsonrow.Children<JProperty>().Where(c => string.Equals(c.Name.Trim(), containerField, StringComparison.OrdinalIgnoreCase)).SingleOrDefault();
JProperty contJP = jsonrow.Children<JProperty>().Where(c =>
string.Equals(c.Name.Trim(), containerField, StringComparison.OrdinalIgnoreCase)).SingleOrDefault();
if ((contJP is not null) && (contJP.Value is JArray array))
{
@ -182,7 +186,7 @@ public class MetrologyRepository : IMetrologyRepository
_ = cmd.Parameters.Add(p);
}
protected long InsertRowFromJSON(
private long InsertRowFromJSON(
IDbConnection conn,
string tableName,
JToken jsonrow,
@ -262,7 +266,7 @@ public class MetrologyRepository : IMetrologyRepository
return Convert.ToInt64(o);
}
internal DataTable ExportData(string spName, DateTime startTime, DateTime endTime)
DataTable IMetrologyRepository.ExportData(string spName, DateTime startTime, DateTime endTime)
{
DataTable dt = new();
DateTime endTimeLocal = endTime.ToLocalTime();
@ -312,7 +316,7 @@ public class MetrologyRepository : IMetrologyRepository
return sb.ToString();
}
internal DataTable GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords)
DataTable IMetrologyRepository.GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerId, out long totalRecords)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -324,7 +328,8 @@ public class MetrologyRepository : IMetrologyRepository
StringBuilder sb = new();
_ = sb.Append(
FormDynamicSelectQuery(
md.Where(m => m.Header == true).ToList(),
md.Where(m =>
m.Header == true).ToList(),
tt.HeaderTableName)
);
@ -401,7 +406,7 @@ public class MetrologyRepository : IMetrologyRepository
return dt;
}
internal DataTable GetData(int toolTypeId, long headerid)
DataTable IMetrologyRepository.GetData(int toolTypeId, long headerid)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -413,7 +418,9 @@ public class MetrologyRepository : IMetrologyRepository
StringBuilder sb = new();
_ = sb.Append(
FormDynamicSelectQuery(
md.Where(m => m.Header == false).OrderBy(m => m.GridDisplayOrder).ToList(),
md.Where(m =>
m.Header == false).OrderBy(m =>
m.GridDisplayOrder).ToList(),
tt.DataTableName)
);
@ -492,17 +499,32 @@ public class MetrologyRepository : IMetrologyRepository
return dt;
}
internal Guid GetHeaderAttachmentID(int toolTypeId, long headerId)
Guid IMetrologyRepository.GetHeaderAttachmentID(int toolTypeId, long headerId)
{
Guid result;
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
$"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID";
result = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId });
return result;
}
void IMetrologyRepository.SetHeaderAttachmentID(int toolTypeId, long headerId, string attachmentId)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
$"UPDATE [{tt.HeaderTableName}] SET AttachmentID = NEWID() WHERE ID = @HeaderID AND AttachmentID IS NULL; " +
$"UPDATE [{tt.HeaderTableName}] SET AttachmentID = @AttachmentID WHERE ID = @HeaderID AND AttachmentID IS NULL; " +
$"SELECT AttachmentID FROM [{tt.HeaderTableName}] WHERE ID = @HeaderID";
return conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId });
Guid guid = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, AttachmentID = attachmentId });
if (attachmentId != guid.ToString())
throw new NotSupportedException($"{attachmentId} != {guid}");
}
internal string GetHeaderInsertDate(int toolTypeId, long headerId)
string IMetrologyRepository.GetHeaderInsertDate(int toolTypeId, long headerId)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -511,7 +533,8 @@ public class MetrologyRepository : IMetrologyRepository
$"SELECT CONVERT(varchar, case when [InsertDate] < [Date] or [Date] is null then [InsertDate] else [Date] end, 120) d FROM[{tt.HeaderTableName}] where ID = @HeaderID";
return conn.ExecuteScalar<string>(sql, param: new { HeaderID = headerId });
}
internal string GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId)
string IMetrologyRepository.GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId)
{
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql = "";
@ -526,24 +549,27 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<string>(sql, param: new { AttachmentID = attachmentId });
}
internal void SetHeaderDirName(string tableName, long headerId, string dateDir)
void IMetrologyRepository.SetHeaderDirName(string tableName, long headerId, string dateDir)
{
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
_ = conn.Execute($"UPDATE [{tableName}] SET AttachDirName = @AttachDirName WHERE ID = @HeaderID;", new { HeaderID = headerId, AttachDirName = dateDir });
}
internal Guid GetDataAttachmentID(int toolTypeId, long headerId, string title)
void IMetrologyRepository.SetDataAttachmentID(int toolTypeId, long headerId, string title, string attachmentId)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
$"UPDATE [{tt.DataTableName}] SET AttachmentID = NEWID() WHERE HeaderID = @HeaderID AND Title = @Title AND AttachmentID IS NULL; " +
$"UPDATE [{tt.DataTableName}] SET AttachmentID = @AttachmentID WHERE HeaderID = @HeaderID AND Title = @Title AND AttachmentID IS NULL; " +
$"SELECT AttachmentID FROM [{tt.DataTableName}] WHERE HeaderID = @HeaderID AND Title = @Title";
return conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, Title = title });
Guid guid = conn.ExecuteScalar<Guid>(sql, param: new { HeaderID = headerId, AttachmentID = attachmentId, Title = title });
if (attachmentId != guid.ToString())
throw new NotSupportedException($"{attachmentId} != {guid}");
}
// J Ouellette Added
internal string GetDataInsertDate(int toolTypeId, long headerId, string title)
string IMetrologyRepository.GetDataInsertDate(int toolTypeId, long headerId, string title)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -560,7 +586,8 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<string>(sql, param: new { HeaderID = headerId, Title = title });
}
internal void SetDataDirName(string tableName, long headerId, string title, string dateDir)
void IMetrologyRepository.SetDataDirName(string tableName, long headerId, string title, string dateDir)
{
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
string sql =
@ -568,13 +595,13 @@ public class MetrologyRepository : IMetrologyRepository
_ = conn.Execute(sql, param: new { HeaderID = headerId, Title = title, AttachDirName = dateDir });
}
internal void PurgeExistingData(int toolTypeId, string title)
void IMetrologyRepository.PurgeExistingData(int toolTypeId, string title)
{
using DbConnection conn = _DBConnectionFactory.GetDbConnection();
_ = conn.Execute("PurgeExistingData", param: new { ToolTypeID = toolTypeId, Title = title }, commandType: CommandType.StoredProcedure);
}
internal DataSet GetOIExportData(int toolTypeId, long headerid)
DataSet IMetrologyRepository.GetOIExportData(int toolTypeId, long headerid)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -626,7 +653,7 @@ public class MetrologyRepository : IMetrologyRepository
return results.ToArray();
}
internal HeaderCommon[] GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords)
HeaderCommon[] IMetrologyRepository.GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords)
{
HeaderCommon[] headers;
if (toolTypeId is not null && (pageNo is not null || pageSize is not null))
@ -662,7 +689,7 @@ public class MetrologyRepository : IMetrologyRepository
return headers;
}
internal IEnumerable<KeyValuePair<string, string>> GetHeaderFields(int toolTypeId, long headerid)
IEnumerable<KeyValuePair<string, string>> IMetrologyRepository.GetHeaderFields(int toolTypeId, long headerid)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -689,7 +716,9 @@ public class MetrologyRepository : IMetrologyRepository
if (dt.Rows.Count > 0)
dr = dt.Rows[0];
foreach (ToolTypeMetadata m in md.Where(m => m.Header == true && m.TableDisplayOrder > 0).OrderBy(m => m.TableDisplayOrder))
foreach (ToolTypeMetadata m in md.Where(m =>
m.Header == true && m.TableDisplayOrder > 0).OrderBy(m =>
m.TableDisplayOrder))
{
string v = "";
if (dr is not null)
@ -705,7 +734,7 @@ public class MetrologyRepository : IMetrologyRepository
return r;
}
internal IEnumerable<AwaitingDisposition> GetAwaitingDisposition()
IEnumerable<AwaitingDisposition> IMetrologyRepository.GetAwaitingDisposition()
{
IEnumerable<AwaitingDisposition>? r;
if (!string.IsNullOrEmpty(_MockRoot))
@ -723,7 +752,7 @@ public class MetrologyRepository : IMetrologyRepository
return r;
}
internal int UpdateReviewDate(int toolTypeId, long headerId, bool clearDate)
int IMetrologyRepository.UpdateReviewDate(int toolTypeId, long headerId, bool clearDate)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -743,7 +772,7 @@ public class MetrologyRepository : IMetrologyRepository
}
}
internal Guid GetHeaderAttachmentIDByTitle(int toolTypeId, string title)
Guid IMetrologyRepository.GetHeaderAttachmentIDByTitle(int toolTypeId, string title)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -753,7 +782,7 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<Guid>(sql, param: new { Title = title });
}
internal Guid GetDataAttachmentIDByTitle(int toolTypeId, string title)
Guid IMetrologyRepository.GetDataAttachmentIDByTitle(int toolTypeId, string title)
{
ToolType tt = GetToolTypeByID(toolTypeId) ?? throw new Exception("Invalid tool type ID");
@ -763,31 +792,13 @@ public class MetrologyRepository : IMetrologyRepository
return conn.ExecuteScalar<Guid>(sql, param: new { Title = title });
}
DataTable IMetrologyRepository.GetDataSharePoint(int toolTypeId, string headerId) => throw new NotImplementedException();
IEnumerable<ToolType> IMetrologyRepository.GetToolTypes() => GetToolTypes();
ToolType IMetrologyRepository.GetToolTypeByName(string name) => GetToolTypeByName(name);
ToolType IMetrologyRepository.GetToolTypeByID(int id) => GetToolTypeByID(id);
IEnumerable<ToolTypeMetadata> IMetrologyRepository.GetToolTypeMetadataByToolTypeID(int id) => GetToolTypeMetadataByToolTypeID(id);
TransactionScope IMetrologyRepository.StartTransaction() => StartTransaction();
void IMetrologyRepository.PurgeExistingData(int toolTypeId, string title) => PurgeExistingData(toolTypeId, title);
long IMetrologyRepository.InsertToolDataJSON(JToken jsonbody, long headerId, List<ToolTypeMetadata> metaData, string tableName) => InsertToolDataJSON(jsonbody, headerId, metaData, tableName);
DataTable IMetrologyRepository.ExportData(string spName, DateTime startTime, DateTime endTime) => ExportData(spName, startTime, endTime);
DataTable IMetrologyRepository.GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerid, out long totalRecords) => GetHeaders(toolTypeId, startTime, endTime, pageNo, pageSize, headerid, out totalRecords);
DataTable IMetrologyRepository.GetData(int toolTypeId, long headerId) => GetData(toolTypeId, headerId);
HeaderCommon[] IMetrologyRepository.GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords) => GetHeaderTitles(toolTypeId, pageNo, pageSize, out totalRecords);
Guid IMetrologyRepository.GetHeaderAttachmentIDByTitle(int toolTypeId, string title) => GetHeaderAttachmentIDByTitle(toolTypeId, title);
Guid IMetrologyRepository.GetDataAttachmentIDByTitle(int toolTypeId, string title) => GetDataAttachmentIDByTitle(toolTypeId, title);
Guid IMetrologyRepository.GetHeaderAttachmentID(int toolTypeId, long headerId) => GetHeaderAttachmentID(toolTypeId, headerId);
string IMetrologyRepository.GetHeaderInsertDate(int toolTypeId, long headerId) => GetHeaderInsertDate(toolTypeId, headerId);
string IMetrologyRepository.GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId) => GetAttachmentInsertDateByGUID(tableName, attachmentId);
void IMetrologyRepository.SetHeaderDirName(string tableName, long headerId, string dateDir) => SetHeaderDirName(tableName, headerId, dateDir);
Guid IMetrologyRepository.GetDataAttachmentID(int toolTypeId, long headerId, string title) => GetDataAttachmentID(toolTypeId, headerId, title);
string IMetrologyRepository.GetDataInsertDate(int toolTypeId, long headerId, string title) => GetDataInsertDate(toolTypeId, headerId, title);
void IMetrologyRepository.SetDataDirName(string tableName, long headerId, string title, string dateDir) => SetDataDirName(tableName, headerId, title, dateDir);
DataSet IMetrologyRepository.GetOIExportData(int toolTypeId, long headerid) => GetOIExportData(toolTypeId, headerid);
IEnumerable<KeyValuePair<string, string>> IMetrologyRepository.GetHeaderFields(int toolTypeId, long headerid) => GetHeaderFields(toolTypeId, headerid);
IEnumerable<AwaitingDisposition> IMetrologyRepository.GetAwaitingDisposition() => GetAwaitingDisposition();
int IMetrologyRepository.UpdateReviewDate(int toolTypeId, long headerId, bool clearDate) => UpdateReviewDate(toolTypeId, headerId, clearDate);
IEnumerable<ToolType> IMetrologyRepository.GetToolTypes() =>
GetToolTypes();
ToolType IMetrologyRepository.GetToolTypeByID(int id) =>
GetToolTypeByID(id);
TransactionScope IMetrologyRepository.StartTransaction() =>
StartTransaction();
IEnumerable<ToolTypeMetadata> IMetrologyRepository.GetToolTypeMetadataByToolTypeID(int id) =>
GetToolTypeMetadataByToolTypeID(id);
}

View File

@ -39,7 +39,7 @@ public class AttachmentsService : IAttachmentsService
HttpClient httpClient = _HttpClientFactory.CreateClient();
Uri mesaFileShareMetrologySi = new(_AppSettings.EcMesaFileShareMetrologySi);
int weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(insertDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
Uri uri = _FileShareRepository.Append(mesaFileShareMetrologySi, $"{tableName}_", year, $"WW{weekNum:00}", attachmentId.ToString(), filename);
Uri uri = _FileShareRepository.Append(mesaFileShareMetrologySi, "MetrologyAttachments", $"{tableName}_", year, $"WW{weekNum:00}", attachmentId.ToString(), filename);
HttpResponseMessage httpResponseMessage = _FileShareRepository.ReadFile(httpClient, uri);
if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception("File not found!");
@ -77,54 +77,49 @@ public class AttachmentsService : IAttachmentsService
return GetAttachmentStream(tableName, attachmentId, filename);
}
private void SaveAttachment(ToolType toolType, long headerId, string dataUniqueId, string filename, IFormFile uploadedFile)
void IAttachmentsService.SaveAttachment(ToolType toolType, Attachment attachment)
{
if (toolType is null)
throw new Exception("Invalid tool type");
if (attachment.HeaderId is null)
throw new NullReferenceException($"{nameof(attachment.HeaderId)}");
if (attachment.AttachmentId is null)
throw new NullReferenceException($"{nameof(attachment.AttachmentId)}");
if (attachment.SourceFileName is null)
throw new NullReferenceException($"{nameof(attachment.SourceFileName)}");
if (attachment.DestinationFileName is null)
throw new NullReferenceException($"{nameof(attachment.DestinationFileName)}");
string? tableName;
DateTime insertDate;
using System.Transactions.TransactionScope trans = _MetrologyRepository.StartTransaction();
Guid attachmentId = Guid.Empty;
DateTime insertDate = new();
string? tableName = "";
if (string.IsNullOrWhiteSpace(dataUniqueId))
if (string.IsNullOrWhiteSpace(attachment.UniqueId))
{
attachmentId = _MetrologyRepository.GetHeaderAttachmentID(toolType.ID, headerId);
insertDate = Convert.ToDateTime(_MetrologyRepository.GetHeaderInsertDate(toolType.ID, headerId));
_MetrologyRepository.SetHeaderAttachmentID(toolType.ID, attachment.HeaderId.Value, attachment.AttachmentId);
insertDate = Convert.ToDateTime(_MetrologyRepository.GetHeaderInsertDate(toolType.ID, attachment.HeaderId.Value));
tableName = toolType.HeaderTableName;
}
else
{
attachmentId = _MetrologyRepository.GetDataAttachmentID(toolType.ID, headerId, dataUniqueId);
insertDate = Convert.ToDateTime(_MetrologyRepository.GetDataInsertDate(toolType.ID, headerId, dataUniqueId));
// Get Date for new directory name
_MetrologyRepository.SetDataAttachmentID(toolType.ID, attachment.HeaderId.Value, attachment.UniqueId, attachment.AttachmentId);
insertDate = Convert.ToDateTime(_MetrologyRepository.GetDataInsertDate(toolType.ID, attachment.HeaderId.Value, attachment.UniqueId));
tableName = toolType.DataTableName;
}
if (Equals(attachmentId, Guid.Empty))
if (Equals(attachment.AttachmentId, Guid.Empty))
{
trans.Dispose();
throw new Exception("Invalid attachment ID!");
}
string year = insertDate.Year.ToString();
HttpClient httpClient = _HttpClientFactory.CreateClient();
Uri mesaFileShareMetrologySi = new(_AppSettings.EcMesaFileShareMetrologySi);
const string asdf = "\\asdf\asdf";
int weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(insertDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
Uri uri = _FileShareRepository.Append(mesaFileShareMetrologySi, $"{tableName}_", year, $"WW{weekNum:00}", attachmentId.ToString(), filename);
HttpResponseMessage httpResponseMessage = _FileShareRepository.ReadFile(httpClient, uri);
if (httpResponseMessage.StatusCode != System.Net.HttpStatusCode.OK)
string checkPath = Path.Combine(asdf, $"{tableName}_", insertDate.Year.ToString(), $"WW{weekNum:00}", attachment.AttachmentId.ToString(), attachment.DestinationFileName);
if (!attachment.SourceFileName.EndsWith(checkPath[asdf.Length..]))
{
trans.Dispose();
throw new Exception("Invalid attachment path!");
}
uploadedFile.CopyTo(httpResponseMessage.Content.ReadAsStream());
trans.Complete();
}
void IAttachmentsService.SaveAttachment(ToolType toolType, long headerId, string dataUniqueId, string filename, object uploadedFile)
{
IFormFile formFile = (IFormFile)uploadedFile;
SaveAttachment(toolType, headerId, dataUniqueId, filename, formFile);
}
string? IAttachmentsService.GetProcessDataStandardFormat(IMetrologyRepository metrologyRepository, int toolTypeId, long headerId)
{
string? result;
@ -144,8 +139,8 @@ public class AttachmentsService : IAttachmentsService
{
year = dateTime.Year.ToString();
weekNum = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
weekDirectory = _FileShareRepository.Append(mesaFileShareMetrologySi, $"{toolType.HeaderTableName}_", year, $"WW{weekNum:00}");
checkDirectory = _FileShareRepository.Append(weekDirectory, headerId.ToString());
weekDirectory = _FileShareRepository.Append(mesaFileShareMetrologySi, "MetrologyAttachments", $"{toolType.HeaderTableName}_", year, $"WW{weekNum:00}");
checkDirectory = _FileShareRepository.Append(weekDirectory, $"-{headerId}");
httpResponseMessage = httpClient.GetAsync(checkDirectory);
httpResponseMessage.Wait();
if (httpResponseMessage.Result.StatusCode != System.Net.HttpStatusCode.OK)

View File

@ -0,0 +1,17 @@
using System.Text.Json.Serialization;
namespace OI.Metrology.Shared.Models;
public record Attachment(string? SubGroupId,
long? HeaderId,
string? HeaderIdDirectory,
string? UniqueId,
string? DestinationFileName,
string? SourceFileName,
string? AttachmentId);
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
[JsonSerializable(typeof(Attachment))]
public partial class AttachmentSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -6,7 +6,9 @@ public interface IFileShareController<T>
enum Action : int
{
Index = 0,
MarkAsPinned = 1
CopyFile = 1,
MoveFile = 2,
FileWrite = 3,
}
static string GetRouteName() => nameof(IFileShareController<T>)[1..^10];

View File

@ -10,7 +10,6 @@ public interface IFileShareRepository
HttpResponseMessage ReadFile(HttpClient httpClient, Uri uri);
void CopyFile(HttpClient httpClient, string from, string to);
void MoveFile(HttpClient httpClient, string from, string to);
void FileWrite(HttpClient httpClient, string path, string contents);
List<NginxFileSystemSortable> GetNginxFileSystemSortableCollection(HttpClient httpClient, Uri uri, string? endsWith);
}

View File

@ -1,3 +1,5 @@
using System.Text.Json;
namespace OI.Metrology.Shared.Models.Stateless;
public interface IInboundController<T>
@ -9,7 +11,7 @@ public interface IInboundController<T>
}
static string GetRouteName() => nameof(IInboundController<T>)[1..^10];
T Post(string tooltype);
T AttachFile(string tooltype, long headerid, string datauniqueid = "");
T Post(string tooltype, JsonElement? jsonElement);
T AttachFile(string tooltype, Attachment? attachment);
}

View File

@ -1,5 +1,6 @@
using OI.Metrology.Shared.Services;
using System.Net;
using System.Text.Json;
namespace OI.Metrology.Shared.Models.Stateless;
@ -7,7 +8,7 @@ public interface IInboundRepository
{
bool IsIPAddressAllowed(string inboundApiAllowedIPList, IPAddress? remoteIP);
DataResponse Data(IMetrologyRepository metrologyRepository, IInboundDataService inboundDataService, string tooltype, string? json);
string? AttachFile(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string tooltype, long headerid, string datauniqueid, string fileName, object uploadedFile);
void AttachFile(IMetrologyRepository metrologyRepository, IAttachmentsService attachmentsService, string toolTypeName, Attachment? attachment);
DataResponse Data(IMetrologyRepository metrologyRepository, IInboundDataService inboundDataService, string toolTypeName, JsonElement? jsonElement);
}

View File

@ -9,12 +9,15 @@ public interface IInfinityQSV4Controller<T>
MarkAsPinned = 1
}
static string GetRouteName() => nameof(IInfinityQSV4Controller<T>)[1..^10];
static string GetRouteName() => nameof(IInfinityQSV4Controller<T>)[1..^12];
static string GetRouteVersion() => nameof(IInfinityQSV4Controller<T>)[1..^10][^2..];
T GetData(string sub_group_id);
T GetHeader(string sub_group_id);
T GetDescriptors(string sub_group_id);
T GetEpiProTempVerification(int[] night);
T GetEpiProTempVerificationRows(int[] night);
T GetLastGroupIdWithValue(string process, string? part, int? test);
T GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe);
T GetCommandText(string sub_group_id, string process, string job, string part, string lot, string date_time);

View File

@ -17,6 +17,7 @@ public interface IInfinityQSV4Repository
string GetCommandText(List<string> eppReactorNumbers);
List<string[]> GetEpiProTempVerificationRows(int[] night);
Result<InfinityQSDescriptorV4[]> GetDescriptors(string subGroupId);
string GetLastGroupIdWithValue(string process, string? part, int? test);
string GetProductDataAverageSumOfDefectsProcessMeanProcessSigma(string process, string? recipe);
string GetCommandText(string? subGroupId, string? process, string? job, string? part, string? lot, string? dateTime);

View File

@ -8,42 +8,30 @@ namespace OI.Metrology.Shared.Models.Stateless;
public interface IMetrologyRepository
{
ToolType GetToolTypeByID(int id);
TransactionScope StartTransaction();
IEnumerable<ToolType> GetToolTypes();
ToolType GetToolTypeByName(string name);
ToolType GetToolTypeByID(int id);
IEnumerable<ToolTypeMetadata> GetToolTypeMetadataByToolTypeID(int id);
TransactionScope StartTransaction();
void PurgeExistingData(int toolTypeId, string title);
long InsertToolDataJSON(JToken jsonbody, long headerId, List<ToolTypeMetadata> metaData, string tableName);
DataTable ExportData(string spName, DateTime startTime, DateTime endTime);
DataTable GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerid, out long totalRecords);
DataTable GetData(int toolTypeId, long headerId);
DataTable GetDataSharePoint(int toolTypeId, string headerId);
HeaderCommon[] GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords);
Guid GetHeaderAttachmentIDByTitle(int toolTypeId, string title);
Guid GetDataAttachmentIDByTitle(int toolTypeId, string title);
Guid GetHeaderAttachmentID(int toolTypeId, long headerId);
string GetHeaderInsertDate(int toolTypeId, long headerId);
string GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId);
void SetHeaderDirName(string tableName, long headerId, string dateDir);
Guid GetDataAttachmentID(int toolTypeId, long headerId, string title);
string GetDataInsertDate(int toolTypeId, long headerId, string title);
void SetDataDirName(string tableName, long headerId, string title, string dateDir);
void PurgeExistingData(int toolTypeId, string title);
DataSet GetOIExportData(int toolTypeId, long headerid);
IEnumerable<KeyValuePair<string, string>> GetHeaderFields(int toolTypeId, long headerid);
Guid GetHeaderAttachmentID(int toolTypeId, long headerId);
IEnumerable<AwaitingDisposition> GetAwaitingDisposition();
string GetHeaderInsertDate(int toolTypeId, long headerId);
Guid GetDataAttachmentIDByTitle(int toolTypeId, string title);
Guid GetHeaderAttachmentIDByTitle(int toolTypeId, string title);
int UpdateReviewDate(int toolTypeId, long headerId, bool clearDate);
IEnumerable<ToolTypeMetadata> GetToolTypeMetadataByToolTypeID(int id);
string GetDataInsertDate(int toolTypeId, long headerId, string title);
void SetHeaderDirName(string tableName, long headerId, string dateDir);
DataTable ExportData(string spName, DateTime startTime, DateTime endTime);
string GetAttachmentInsertDateByGUID(string tableName, Guid attachmentId);
void SetHeaderAttachmentID(int toolTypeId, long headerId, string attachmentId);
void SetDataDirName(string tableName, long headerId, string title, string dateDir);
IEnumerable<KeyValuePair<string, string>> GetHeaderFields(int toolTypeId, long headerid);
void SetDataAttachmentID(int toolTypeId, long headerId, string title, string attachmentId);
HeaderCommon[] GetHeaderTitles(int? toolTypeId, int? pageNo, int? pageSize, out long totalRecords);
long InsertToolDataJSON(JToken jsonbody, long headerId, List<ToolTypeMetadata> metaData, string tableName);
DataTable GetHeaders(int toolTypeId, string? startTime, string? endTime, int? pageNo, int? pageSize, long? headerid, out long totalRecords);
}

View File

@ -1,6 +1,7 @@
namespace OI.Metrology.Shared.Services;
using DataModels;
using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless;
public interface IAttachmentsService
@ -8,5 +9,5 @@ public interface IAttachmentsService
Stream GetAttachmentStreamByTitle(ToolType toolType, bool header, string title, string filename);
Stream GetAttachmentStreamByAttachmentId(ToolType toolType, bool header, Guid attachmentId, string filename);
string? GetProcessDataStandardFormat(IMetrologyRepository metrologyRepository, int toolTypeId, long headerId);
void SaveAttachment(ToolType toolType, long headerId, string dataUniqueId, string filename, object uploadedFile);
void SaveAttachment(ToolType toolType, Attachment attachment);
}

View File

@ -13,6 +13,32 @@
],
"problemMatcher": "$msCompile"
},
{
"label": "testDebug",
"command": "dotnet",
"type": "process",
"args": [
"test",
"${workspaceFolder}/OI.Metrology.Tests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "testRelease",
"command": "dotnet",
"type": "process",
"args": [
"test",
"${workspaceFolder}/OI.Metrology.Tests.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"-c",
"Release"
],
"problemMatcher": "$msCompile"
},
{
"label": "Format",
"command": "dotnet",
@ -28,64 +54,35 @@
],
"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.Tests.csproj",
"${workspaceFolder}/../Server/OI.Metrology.Server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
"/consoleloggerparameters:NoSummary",
"--configuration",
"Release",
"--runtime",
"win-x64",
"--self-contained",
"-o",
"D:/web-sites/OI-Metrology/hh-3498d1da-_______-OI-Metrology-Release/Server"
],
"problemMatcher": "$msCompile"
},
{
"label": "old-watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/OI.Metrology.Tests.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"--launch-profile",
"http",
"run",
"--project",
"${workspaceFolder}/OI.Metrology.Tests.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.*"
}
}
},
{
"label": "File-Folder-Helper AOT s V Repositories",
"type": "shell",

View File

@ -16,6 +16,7 @@ public class UnitTestInfinityQSV4Controller
private static ILogger? _Logger;
private static string _ControllerName;
private static TestContext _TestContext;
private static string _ControllerVersion;
private static WebApplicationFactory<Server.Program>? _WebApplicationFactory;
#pragma warning restore
@ -27,7 +28,8 @@ public class UnitTestInfinityQSV4Controller
_WebApplicationFactory = new WebApplicationFactory<Server.Program>();
IServiceProvider serviceProvider = _WebApplicationFactory.Services.CreateScope().ServiceProvider;
_Logger = serviceProvider.GetRequiredService<ILogger<Server.Program>>();
_ControllerName = nameof(Server.ApiControllers.InfinityQSV4Controller)[..^10];
_ControllerName = nameof(Server.ApiControllers.InfinityQSV4Controller)[..^12];
_ControllerVersion = nameof(Server.ApiControllers.InfinityQSV4Controller)[..^10][^2..];
}
private static void NonThrowTryCatch()
@ -42,6 +44,7 @@ public class UnitTestInfinityQSV4Controller
{
_Logger?.LogInformation("Starting Web Application");
Assert.AreEqual(IInfinityQSV4Controller<string>.GetRouteName(), _ControllerName);
Assert.AreEqual(IInfinityQSV4Controller<string>.GetRouteVersion(), _ControllerVersion);
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
NonThrowTryCatch();
}
@ -64,7 +67,7 @@ public class UnitTestInfinityQSV4Controller
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
_Logger?.LogInformation("Starting Web Application");
Assert.IsTrue(httpClient is not null);
string? json = await httpClient.GetStringAsync($"api/{_ControllerName}/1698497987/commandText/?process=61&job=CDE5&part=5012&lot=575908&date_time=2023-02-24 15:15:00");
string? json = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/1698497987/commandText/?process=61&job=CDE5&part=5012&lot=575908&date_time=2023-02-24 15:15:00");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, $"{_ControllerName}-{nameof(GetCommandText)}.sql"), json);
Assert.IsNotNull(json);
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
@ -95,8 +98,8 @@ public class UnitTestInfinityQSV4Controller
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
_Logger?.LogInformation("Starting Web Application");
Assert.IsTrue(httpClient is not null);
//string? json = await httpClient.GetStringAsync($"api/{_ControllerName}/1698497987 575908_2023-02-24 14-18-05.txt/data");
string? json = await httpClient.GetStringAsync($"api/{_ControllerName}/1698497987/data");
//string? json = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/1698497987 575908_2023-02-24 14-18-05.txt/data");
string? json = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/1698497987/data");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, $"{_ControllerName}-{nameof(GetData)}.json"), json);
Result<InfinityQSV4[]>? result = System.Text.Json.JsonSerializer.Deserialize<Result<InfinityQSV4[]>>(json);
Assert.IsNotNull(result?.Results);
@ -125,8 +128,8 @@ public class UnitTestInfinityQSV4Controller
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
_Logger?.LogInformation("Starting Web Application");
Assert.IsTrue(httpClient is not null);
//string? json = await httpClient.GetStringAsync($"api/{_ControllerName}/1698497987 575908_2023-02-24 14-18-05.txt/descriptors");
string? json = await httpClient.GetStringAsync($"api/{_ControllerName}/1698497987/descriptors");
//string? json = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/1698497987 575908_2023-02-24 14-18-05.txt/descriptors");
string? json = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/1698497987/descriptors");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, $"{_ControllerName}-{nameof(GetDescriptors)}.json"), json);
Result<InfinityQSDescriptorV3[]>? result = System.Text.Json.JsonSerializer.Deserialize<Result<InfinityQSDescriptorV3[]>>(json);
Assert.IsNotNull(result?.Results);
@ -153,7 +156,7 @@ public class UnitTestInfinityQSV4Controller
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
_Logger?.LogInformation("Starting Web Application");
Assert.IsTrue(httpClient is not null);
string? json = await httpClient.GetStringAsync($"api/{_ControllerName}/1698497987/header");
string? json = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/1698497987/header");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, $"{_ControllerName}-{nameof(GetHeader)}.json"), json);
Result<InfinityQSV4[]>? result = System.Text.Json.JsonSerializer.Deserialize<Result<InfinityQSV4[]>>(json);
Assert.IsNotNull(result?.Results);
@ -180,7 +183,7 @@ public class UnitTestInfinityQSV4Controller
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
_Logger?.LogInformation("Starting Web Application");
Assert.IsTrue(httpClient is not null);
string? result = await httpClient.GetStringAsync($"api/{_ControllerName}/41/product-data-average-sum-of-defects-process-mean-process-sigma?recipe=8IN_THIN ROTR");
string? result = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/41/product-data-average-sum-of-defects-process-mean-process-sigma?recipe=8IN_THIN ROTR");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, $"{_ControllerName}-{nameof(GetProductDataAverageSumOfDefectsProcessMeanProcessSigma)}.json"), result);
Assert.IsNotNull(result);
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
@ -206,7 +209,7 @@ public class UnitTestInfinityQSV4Controller
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
_Logger?.LogInformation("Starting Web Application");
Assert.IsTrue(httpClient is not null);
string? result = await httpClient.GetStringAsync($"api/{_ControllerName}/epi-pro-temp-verification-collection/?night=44&night=46&night=52&night=54");
string? result = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/epi-pro-temp-verification-collection/?night=44&night=46&night=52&night=54");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, $"{_ControllerName}-{nameof(GetEpiProTempVerificationRows)}.json"), result);
Assert.IsNotNull(result);
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
@ -232,7 +235,7 @@ public class UnitTestInfinityQSV4Controller
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
_Logger?.LogInformation("Starting Web Application");
Assert.IsTrue(httpClient is not null);
string? result = await httpClient.GetStringAsync($"api/{_ControllerName}/epi-pro-temp-verification/?night=44&night=46&night=52&night=54");
string? result = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/epi-pro-temp-verification/?night=44&night=46&night=52&night=54");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, $"{_ControllerName}-{nameof(GetEpiProTempVerification)}.html"), result);
Assert.IsNotNull(result);
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
@ -295,4 +298,35 @@ public class UnitTestInfinityQSV4Controller
NonThrowTryCatch();
}
[TestMethod]
public void GetLastGroupIdWithValue()
{
const string part = "4610";
const int test = 1228920625;
const string process = "35";
_Logger?.LogInformation("Starting Web Application");
IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider;
IInfinityQSV4Repository? infinityQSV4Repository = serviceProvider?.GetRequiredService<IInfinityQSV4Repository>();
string? result = infinityQSV4Repository?.GetLastGroupIdWithValue(process, part, test);
Assert.IsNotNull(result);
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
NonThrowTryCatch();
}
[TestMethod]
public async Task GetLastGroupIdWithValueApi()
{
const string part = "4610";
const int test = 1228920625;
const string process = "35";
HttpClient? httpClient = _WebApplicationFactory?.CreateClient();
_Logger?.LogInformation("Starting Web Application");
Assert.IsTrue(httpClient is not null);
string? result = await httpClient.GetStringAsync($"api/{_ControllerVersion}/{_ControllerName}/{process}/last-group-id-with-value/?part={part}&test={test}");
File.WriteAllText(Path.Combine(AppContext.BaseDirectory, $"{_ControllerName}-{nameof(GetLastGroupIdWithValue)}.html"), result);
Assert.IsNotNull(result);
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
NonThrowTryCatch();
}
}

View File

@ -0,0 +1 @@
[]

38
Wafer-Counter/.vscode/launch.json vendored Normal file
View 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
View File

@ -0,0 +1,5 @@
{
"cSpell.words": [
"Infineon"
]
}

163
Wafer-Counter/.vscode/tasks.json vendored Normal file
View 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.*"
}
}
}
]
}

View 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());
}

View 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();
}
}

View File

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using OI.Metrology.Shared.Models.Stateless;
namespace OI.Metrology.Server.ApiControllers;
namespace OI.Metrology.Wafer.Counter.ApiControllers;
[Route("api/v1/[controller]")]
public class WaferCounterController : Controller, IWaferCounterController<IActionResult>

View 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;
}
}

View File

@ -0,0 +1,2 @@
[*.cs]
csharp_preserve_single_line_statements = true

View 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
{
}

View 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
View 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;
}
}
}

View 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"
}
}
}
}

View 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();
}

View 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;
}
}

View File

@ -1,11 +1,11 @@
using OI.Metrology.Server.Models;
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.Server.Repository;
namespace OI.Metrology.Wafer.Counter.Repository;
public class WaferCounterRepository : IWaferCounterRepository
{
@ -20,7 +20,6 @@ public class WaferCounterRepository : IWaferCounterRepository
private readonly IHttpClientFactory _HttpClientFactory;
private readonly IDbConnectionFactory _DBConnectionFactory;
private readonly IFileShareRepository _FileShareRepository;
private readonly string _OpenInsightApplicationProgrammingInterface;
public WaferCounterRepository(AppSettings appSettings, IDbConnectionFactory dbConnectionFactory, IHttpClientFactory httpClientFactory, IFileShareRepository fileShareRepository)
{
@ -30,7 +29,6 @@ public class WaferCounterRepository : IWaferCounterRepository
_DBConnectionFactory = dbConnectionFactory;
_FileShareRepository = fileShareRepository;
_RepositoryName = nameof(WaferCounterRepository)[..^10];
_OpenInsightApplicationProgrammingInterface = appSettings.OpenInsightApplicationProgrammingInterface;
}
private void MoveFile(string waferSizeDirectory, NginxFileSystemSortable nginxFileSystemSortable)