This commit is contained in:
2023-11-02 14:41:32 -07:00
parent 3dd4034a84
commit 03bd20fc8c
16 changed files with 142 additions and 143 deletions

View File

@ -35,8 +35,8 @@ public class InboundController : ControllerBase
{
public bool Success { get; set; }
public long HeaderID { get; set; }
public List<string> Errors { get; set; }
public List<string> Warnings { get; set; }
public List<string>? Errors { get; set; }
public List<string>? Warnings { get; set; }
}
// this is the main endpoint, it accepts a JSON message that contains both the header and data records together
@ -86,7 +86,7 @@ public class InboundController : ControllerBase
else
r.Errors.Add("Invalid json");
if (r.Errors.Count == 0)
if (r.Errors.Count == 0 && jsonbody is not null)
{
try
{
@ -147,14 +147,14 @@ public class InboundController : ControllerBase
if (string.IsNullOrWhiteSpace(_AppSettings.InboundApiAllowedIPList))
return true;
System.Net.IPAddress remoteIP = HttpContext.Connection.RemoteIpAddress;
byte[] remoteIPBytes = remoteIP.GetAddressBytes();
System.Net.IPAddress? remoteIP = HttpContext.Connection.RemoteIpAddress;
byte[]? remoteIPBytes = remoteIP?.GetAddressBytes();
string[] allowedIPs = _AppSettings.InboundApiAllowedIPList.Split(';');
foreach (string ip in allowedIPs)
{
System.Net.IPAddress parsedIP;
if (System.Net.IPAddress.TryParse(ip, out parsedIP))
System.Net.IPAddress? parsedIP;
if (remoteIPBytes is not null && System.Net.IPAddress.TryParse(ip, out parsedIP))
{
if (parsedIP.GetAddressBytes().SequenceEqual(remoteIPBytes))
return true;

View File

@ -203,7 +203,7 @@ public class ToolTypesController : Controller
if (ds.Tables[0].Rows.Count != 1)
throw new Exception("Error exporting, invalid filename");
string filename = Convert.ToString(ds.Tables[0].Rows[0][0]);
string? filename = Convert.ToString(ds.Tables[0].Rows[0][0]);
// The second table has the header data
if (ds.Tables[1].Rows.Count != 1)
@ -211,7 +211,7 @@ public class ToolTypesController : Controller
System.Text.StringBuilder sb = new();
foreach (object o in ds.Tables[1].Rows[0].ItemArray)
foreach (object? o in ds.Tables[1].Rows[0].ItemArray)
{
if ((o is not null) && (!Convert.IsDBNull(o)))
_ = sb.Append(Convert.ToString(o));
@ -221,7 +221,7 @@ public class ToolTypesController : Controller
// The third table has the detail data
foreach (System.Data.DataRow dr in ds.Tables[2].Rows)
{
foreach (object o in dr.ItemArray)
foreach (object? o in dr.ItemArray)
{
if ((o is not null) && (!Convert.IsDBNull(o)))
_ = sb.Append(Convert.ToString(o));

View File

@ -43,7 +43,8 @@ public class ApiLoggingMiddleware
else
{
// if there are content type filters configured, only log is the request begins with one of them
doLogging = _AppSettings.ApiLoggingContentTypes.Split(';').Any(ct => httpContext.Request.ContentType.StartsWith(ct));
string? contentType = httpContext.Request.ContentType;
doLogging = contentType is not null && _AppSettings.ApiLoggingContentTypes.Split(';').Any(ct => contentType.StartsWith(ct));
}
}
}

View File

@ -14,7 +14,7 @@ public class ErrorHandlerController : Controller
public IActionResult Index()
{
IExceptionHandlerFeature error = HttpContext.Features.Get<IExceptionHandlerFeature>();
IExceptionHandlerFeature? error = HttpContext.Features.Get<IExceptionHandlerFeature>();
if (error is null)
{
return Redirect("~/");

View File

@ -52,7 +52,7 @@ public class ExportController : Controller
[Route("/ExportData")]
public ActionResult ExportData(Export model)
{
ToolType toolType = null;
ToolType? toolType = null;
if (string.IsNullOrEmpty(model.ToolType))
ModelState.AddModelError("Exception", "Invalid selection");
else
@ -66,7 +66,7 @@ public class ExportController : Controller
else if (string.IsNullOrWhiteSpace(toolType.ExportSPName))
ModelState.AddModelError("ToolType", "Tool type is not exportable");
}
if (ModelState.IsValid)
if (ModelState.IsValid && toolType?.ToolTypeName is not null && toolType.ExportSPName is not null)
{
try
{
@ -114,10 +114,13 @@ public class ExportController : Controller
{
if (i > 0)
_ = r.Append(',');
object v = dr[i];
if (!Convert.IsDBNull(v))
_ = r.Append(FormatForCSV(Convert.ToString(v)));
{
string? c = Convert.ToString(v);
if (c is not null)
_ = r.Append(FormatForCSV(c));
}
}
return r.ToString();
}

View File

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

View File

@ -1,6 +1,5 @@
using Microsoft.Extensions.Configuration;
using System;
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
namespace OI.Metrology.Archive.Models.Binder;
@ -8,25 +7,21 @@ namespace OI.Metrology.Archive.Models.Binder;
public class AppSettings
{
#nullable disable
[Display(Name = "Api Logging Content Types"), Required] public string ApiLoggingContentTypes { get; set; }
[Display(Name = "Api Logging Path Prefixes"), Required] public string ApiLoggingPathPrefixes { get; set; }
[Display(Name = "Api Log Path"), Required] public string ApiLogPath { get; set; }
[Display(Name = "Attachment Path"), Required] public string AttachmentPath { get; set; }
[Display(Name = "Build Number"), Required] public string BuildNumber { get; set; }
[Display(Name = "Company"), Required] public string Company { get; set; }
[Display(Name = "Connection String"), Required] public string ConnectionString { get; set; }
[Display(Name = "Git Commit Seven"), Required] public string GitCommitSeven { get; set; }
[Display(Name = "Inbound Api Allowed IP List"), Required] public string InboundApiAllowedIPList { get; set; }
[Display(Name = "MonA Resource"), Required] public string MonAResource { get; set; }
[Display(Name = "MonA Site"), Required] public string MonASite { get; set; }
[Display(Name = "Oi 2 Sql Connection String"), Required] public string Oi2SqlConnectionString { get; set; }
[Display(Name = "OI Export Path"), Required] public string OIExportPath { get; set; }
[Display(Name = "URLs"), Required] public string URLs { get; set; }
[Display(Name = "Working Directory Name"), Required] public string WorkingDirectoryName { get; set; }
#nullable restore
public string? ApiLoggingContentTypes { get; set; }
public string? ApiLoggingPathPrefixes { get; set; }
public string? ApiLogPath { get; set; }
public string? AttachmentPath { get; set; }
public string? BuildNumber { get; set; }
public string? Company { get; set; }
public string? ConnectionString { get; set; }
public string? GitCommitSeven { get; set; }
public string? InboundApiAllowedIPList { get; set; }
public string? MonAResource { get; set; }
public string? MonASite { get; set; }
public string? Oi2SqlConnectionString { get; set; }
public string? OIExportPath { get; set; }
public string? URLs { get; set; }
public string? WorkingDirectoryName { get; set; }
public override string ToString()
{
@ -34,41 +29,25 @@ public class AppSettings
return result;
}
private static Models.AppSettings Get(AppSettings appSettings)
private static Models.AppSettings Get(AppSettings? appSettings)
{
Models.AppSettings result;
if (appSettings is null)
throw new NullReferenceException(nameof(appSettings));
if (appSettings.ApiLoggingContentTypes is null)
throw new NullReferenceException(nameof(ApiLoggingContentTypes));
if (appSettings.ApiLoggingPathPrefixes is null)
throw new NullReferenceException(nameof(ApiLoggingPathPrefixes));
if (appSettings.ApiLogPath is null)
throw new NullReferenceException(nameof(ApiLogPath));
if (appSettings.AttachmentPath is null)
throw new NullReferenceException(nameof(AttachmentPath));
if (appSettings.BuildNumber is null)
throw new NullReferenceException(nameof(BuildNumber));
if (appSettings.Company is null)
throw new NullReferenceException(nameof(Company));
if (appSettings.ConnectionString is null)
throw new NullReferenceException(nameof(ConnectionString));
if (appSettings.GitCommitSeven is null)
throw new NullReferenceException(nameof(GitCommitSeven));
if (appSettings.InboundApiAllowedIPList is null)
throw new NullReferenceException(nameof(InboundApiAllowedIPList));
if (appSettings.MonAResource is null)
throw new NullReferenceException(nameof(MonAResource));
if (appSettings.MonASite is null)
throw new NullReferenceException(nameof(MonASite));
if (appSettings.Oi2SqlConnectionString is null)
throw new NullReferenceException(nameof(Oi2SqlConnectionString));
if (appSettings.OIExportPath is null)
throw new NullReferenceException(nameof(OIExportPath));
if (appSettings.URLs is null)
throw new NullReferenceException(nameof(URLs));
if (appSettings.WorkingDirectoryName is null)
throw new NullReferenceException(nameof(WorkingDirectoryName));
if (appSettings is null) throw new NullReferenceException(nameof(appSettings));
if (appSettings.ApiLoggingContentTypes is null) throw new NullReferenceException(nameof(ApiLoggingContentTypes));
if (appSettings.ApiLoggingPathPrefixes is null) throw new NullReferenceException(nameof(ApiLoggingPathPrefixes));
if (appSettings.ApiLogPath is null) throw new NullReferenceException(nameof(ApiLogPath));
if (appSettings.AttachmentPath is null) throw new NullReferenceException(nameof(AttachmentPath));
if (appSettings.BuildNumber is null) throw new NullReferenceException(nameof(BuildNumber));
if (appSettings.Company is null) throw new NullReferenceException(nameof(Company));
if (appSettings.ConnectionString is null) throw new NullReferenceException(nameof(ConnectionString));
if (appSettings.GitCommitSeven is null) throw new NullReferenceException(nameof(GitCommitSeven));
if (appSettings.InboundApiAllowedIPList is null) throw new NullReferenceException(nameof(InboundApiAllowedIPList));
if (appSettings.MonAResource is null) throw new NullReferenceException(nameof(MonAResource));
if (appSettings.MonASite is null) throw new NullReferenceException(nameof(MonASite));
if (appSettings.Oi2SqlConnectionString is null) throw new NullReferenceException(nameof(Oi2SqlConnectionString));
if (appSettings.OIExportPath is null) throw new NullReferenceException(nameof(OIExportPath));
if (appSettings.URLs is null) throw new NullReferenceException(nameof(URLs));
if (appSettings.WorkingDirectoryName is null) throw new NullReferenceException(nameof(WorkingDirectoryName));
result = new(
appSettings.ApiLoggingContentTypes,
appSettings.ApiLoggingPathPrefixes,
@ -91,7 +70,23 @@ public class AppSettings
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
{
Models.AppSettings result;
AppSettings appSettings = configurationRoot.Get<AppSettings>();
#pragma warning disable IL3050, IL2026
AppSettings? appSettings = configurationRoot.Get<AppSettings>();
#pragma warning restore IL3050, IL2026
if (appSettings?.ApiLoggingContentTypes is null)
{
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;
if (!physicalFileProvider.Root.Contains("UserSecrets"))
continue;
throw new NotSupportedException(physicalFileProvider.Root);
}
throw new NotSupportedException("Not found!");
}
result = Get(appSettings);
return result;
}

View File

@ -8,8 +8,7 @@
<PropertyGroup>
<ImplicitUsings>disable</ImplicitUsings>
<IsPackable>false</IsPackable>
<LangVersion>10.0</LangVersion>
<Nullable>disable</Nullable>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetFramework>net7.0</TargetFramework>
@ -35,11 +34,6 @@
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="6.0.0" />
<PackageReference Include="Serilog.AspNetCore.Ingestion" Version="1.0.0-dev-00032" />
<PackageReference Include="Serilog.Settings.Configuration" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
</ItemGroup>

View File

@ -12,7 +12,6 @@ using OI.Metrology.Shared.Models;
using OI.Metrology.Shared.Models.Stateless;
using OI.Metrology.Shared.Repositories;
using OI.Metrology.Shared.Services;
using Serilog;
using System;
using System.IO;
using System.Reflection;
@ -22,13 +21,11 @@ namespace OI.Metrology.Archive;
public class Program
{
internal readonly AppSettings _AppSettings;
private static (string, WebApplicationOptions) Get(string[] args)
{
string webRootPath;
Assembly assembly = Assembly.GetExecutingAssembly();
string assemblyName = assembly.GetName()?.Name;
string? assemblyName = assembly.GetName()?.Name;
if (string.IsNullOrEmpty(assemblyName))
throw new Exception();
string baseAssemblyName = assemblyName.Split('.')[0];
@ -49,7 +46,7 @@ public class Program
public static int Main(string[] args)
{
LoggerConfiguration loggerConfiguration = new();
ILogger<Program>? logger = null;
(string assemblyName, WebApplicationOptions _) = Get(args);
WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(args);
_ = webApplicationBuilder.Configuration.AddUserSecrets<Program>();
@ -58,10 +55,6 @@ public class Program
throw new Exception("Working directory name must have a value!");
string workingDirectory = IWorkingDirectory.GetWorkingDirectory(assemblyName, _AppSettings.WorkingDirectoryName);
Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
_ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, webApplicationBuilder.Configuration);
_ = SerilogHostBuilderExtensions.UseSerilog(webApplicationBuilder.Host);
Log.Logger = loggerConfiguration.CreateLogger();
Serilog.ILogger log = Log.ForContext<Program>();
try
{
_ = webApplicationBuilder.Services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);
@ -95,6 +88,7 @@ public class Program
#pragma warning restore
}
WebApplication webApplication = webApplicationBuilder.Build();
logger = webApplication.Services.GetRequiredService<ILogger<Program>>();
if (!webApplicationBuilder.Environment.IsDevelopment())
{
_ = webApplication.UseExceptionHandler("/Error");
@ -110,27 +104,22 @@ public class Program
_ = webApplication.UseSwagger();
_ = webApplication.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Archive V1"));
}
_ = webApplication.Lifetime.ApplicationStopped.Register(Log.CloseAndFlush);
_ = ApplicationBuilderSerilogClientExtensions.UseSerilogIngestion(webApplication);
_ = SerilogApplicationBuilderExtensions.UseSerilogRequestLogging(webApplication);
_ = webApplication.UseFileServer(enableDirectoryBrowsing: true);
_ = webApplication.UseStaticFiles();
_ = webApplication.UseSession();
_ = webApplication.UseHttpsRedirection();
_ = webApplication.UseMiddleware<ApiLoggingMiddleware>();
_ = webApplication.MapControllers();
log.Information("Starting Web Application");
logger.LogInformation("Starting Web Application");
webApplication.Run();
return 0;
}
catch (Exception ex)
{
log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
try
{ logger?.LogCritical(ex, "Host terminated unexpectedly"); }
catch (Exception) { }
throw;
}
}

View File

@ -13,6 +13,8 @@ using System.Transactions;
namespace OI.Metrology.Archive.Repositories;
#nullable disable
public class MetrologyRepository : IMetrologyRepository
{
private readonly IDbConnectionFactory _DBConnectionFactory;

View File

@ -11,6 +11,8 @@ using System.Text;
namespace OI.Metrology.Archive.Repositories;
#nullable disable
public class RdsMaxRepo : IRdsMaxRepo
{

View File

@ -6,6 +6,8 @@ using System.Data.SqlClient;
namespace OI.Metrology.Archive.Repositories;
#nullable disable
public class SQLDbConnectionFactory : IDbConnectionFactory
{
private readonly AppSettings _AppSettings;

View File

@ -4,6 +4,8 @@ using System.IO;
namespace OI.Metrology.Archive.Services;
#nullable disable
using OI.Metrology.Archive.Models;
using OI.Metrology.Shared.DataModels;
using OI.Metrology.Shared.Models.Stateless;

View File

@ -8,6 +8,8 @@ using System.Linq;
namespace OI.Metrology.Archive.Services;
#nullable disable
public class InboundDataService : IInboundDataService
{
private readonly IMetrologyRepository _MetrologyRepository;