Refactoring project

parent 5e824dba
......@@ -11,13 +11,21 @@ using RouteHandler = IntegrationKSSS.WebService.Infrastructure.RouteHandlers.Rou
using IRouteHandler = IntegrationKSSS.WebService.Infrastructure.RouteHandlers.IRouteHandler;
using NLog.Config;
using ILogger = NLog.ILogger;
using System.Reflection;
using Microsoft.AspNetCore.Authorization;
namespace IntegrationKSSS.WebService.Infrastructure.Configurations
namespace IntegrationKSSS.WebService.Infrastructure.Configurations;
/// <summary>
/// Configuration of the WEB API
/// </summary>
public static class ApplicationConfiguration
{
public static class ApplicationConfiguration
{
public static ILogger GetLogger()
#region Methods
/// <summary>
/// Getting a logger
/// </summary>
/// <returns>Logger</returns>
private static ILogger GetLogger()
{
string fileName = string.Empty;
#if DEBUG
......@@ -31,7 +39,10 @@ namespace IntegrationKSSS.WebService.Infrastructure.Configurations
LogManager.Configuration = new XmlLoggingConfiguration(fileName);
return LogManager.GetCurrentClassLogger();
}
/// <summary>
/// Adding middleware, services and functions
/// </summary>
/// <param name="webApplicationBuilder"></param>
public static void RegisterBuilder(WebApplicationBuilder webApplicationBuilder)
{
var logger = GetLogger();
......@@ -43,9 +54,6 @@ namespace IntegrationKSSS.WebService.Infrastructure.Configurations
webApplicationBuilder.Host.UseNLog();
webApplicationBuilder.Services.AddSwaggerGen();
webApplicationBuilder.Services.AddSingleton(logger);
webApplicationBuilder.Services.AddAuthorization();
webApplicationBuilder.Services.AddAuthentication("BasicAuthentication")
.AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);
var connectionString = webApplicationBuilder.Configuration["ConnectionStrings:MicrosoftSqlServer"]
.DecryptString(AesConfiguration.Key, AesConfiguration.IV);
......@@ -54,6 +62,12 @@ namespace IntegrationKSSS.WebService.Infrastructure.Configurations
webApplicationBuilder.Services.AddScoped<IAuthService, AuthService>();
webApplicationBuilder.Services.AddScoped<IKsssRepository, KsssRepository>();
webApplicationBuilder.Services.AddTransient<IRouteHandler, RouteHandler>();
webApplicationBuilder.Services.AddAuthentication("BasicAuthentication")
.AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", options => { });
webApplicationBuilder.Services.AddAuthorization(options =>
{
options.AddPolicy("BasicAuthentication", new AuthorizationPolicyBuilder("BasicAuthentication").RequireAuthenticatedUser().Build());
});
}
catch (Exception ex)
{
......@@ -66,6 +80,10 @@ namespace IntegrationKSSS.WebService.Infrastructure.Configurations
}
}
/// <summary>
/// Using middleware, services and functions
/// </summary>
/// <param name="webApplication"></param>
public static void RegisterApplication(WebApplication webApplication)
{
if (webApplication.Environment.IsDevelopment())
......@@ -73,10 +91,11 @@ namespace IntegrationKSSS.WebService.Infrastructure.Configurations
webApplication.UseSwagger();
webApplication.UseSwaggerUI();
}
webApplication.UseAuthorization();
webApplication.UseAuthentication();
webApplication.UseAuthorization();
webApplication.Services.GetServices<IRouteHandler>().ToList().ForEach(c => c.Register(webApplication));
}
}
#endregion
}
namespace IntegrationKSSS.WebService.Infrastructure.Cryptography;
internal static class AesConfiguration
{
#region Variables
public const string Key = "da983189246a4520a94764a751fa466a";
public static byte[] IV = new byte[16];
#endregion
}
using System.Security.Cryptography;
using System.Text;
namespace IntegrationKSSS.WebService.Infrastructure.Cryptography
namespace IntegrationKSSS.WebService.Infrastructure.Cryptography;
internal static class AesExtension
{
public static class AesConfiguration
{
public const string Key = "da983189246a4520a94764a751fa466a";
public static byte[] IV = new byte[16];
}
public static class AesExtension
{
public static string DecryptString(this string cipherText, string key, byte[] IV)
#region Methods
internal static string DecryptString(this string cipherText, string key, byte[] IV)
{
if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException(nameof(cipherText));
if (key == null || key.Length <= 0) throw new ArgumentNullException(nameof(key));
......@@ -37,5 +32,5 @@ namespace IntegrationKSSS.WebService.Infrastructure.Cryptography
return plaintext;
}
}
#endregion
}
\ No newline at end of file
using IntegrationKSSS.WebService.Infrastructure.Models;
using Microsoft.EntityFrameworkCore;
namespace IntegrationKSSS.WebService.Infrastructure.Data
namespace IntegrationKSSS.WebService.Infrastructure.Data;
public class RDnLDbContext : DbContext
{
public class RDnLDbContext : DbContext
{
public RDnLDbContext(DbContextOptions dbContextOptions) : base(dbContextOptions) {}
#region Constructors
public RDnLDbContext(DbContextOptions dbContextOptions) : base(dbContextOptions) { }
#endregion
#region Properties
public DbSet<RndtSp> RndtSp => Set<RndtSp>();
public DbSet<RndtSpIc> RndtSpIc => Set<RndtSpIc>();
public DbSet<RndtSpIi> RndtSpIi => Set<RndtSpIi>();
public DbSet<RndtIpIeAu> RndtIpIeAu => Set<RndtIpIeAu>();
#endregion
#region Methods
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("RndSuite");
......@@ -19,10 +25,13 @@ namespace IntegrationKSSS.WebService.Infrastructure.Data
.HasKey(c => new { c.SP, c.SP_VERSION });
modelBuilder.Entity<RndtSpIc>()
.HasKey(c => new { c.SP, c.SP_VERSION, c.IC, c.ICNODE});
.HasKey(c => new { c.SP, c.SP_VERSION, c.IC, c.ICNODE });
modelBuilder.Entity<RndtSpIi>()
.HasKey(c => new {c.SP, c.SP_VERSION, c.IC, c.ICNODE, c.IINODE});
}
.HasKey(c => new { c.SP, c.SP_VERSION, c.IC, c.ICNODE, c.IINODE });
modelBuilder.Entity<RndtIpIeAu>()
.HasKey(c => new { c.IP, c.SEQ, c.AUSEQ, c.AU, c.VERSION, c.IE });
}
#endregion
}
\ No newline at end of file
......@@ -7,26 +7,31 @@ using System.Text.Encodings.Web;
using System.Text;
using IntegrationKSSS.WebService.Infrastructure.Services;
namespace IntegrationKSSS.WebService.Infrastructure.Handlers
namespace IntegrationKSSS.WebService.Infrastructure.Handlers;
/// <summary>
/// Basic authorization handler
/// </summary>
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
private readonly IAuthService _authService;
#region Consturctors
public BasicAuthenticationHandler(
IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock,
IAuthService authService)
: base(options, logger, encoder, clock)
IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock,
IAuthService authService)
: base(options, logger, encoder, clock)
{
_authService = authService;
}
#endregion
#region Methods
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
// skip authentication if endpoint has [AllowAnonymous] attribute
var endpoint = Context.GetEndpoint();
if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null)
return AuthenticateResult.NoResult();
......@@ -58,5 +63,5 @@ namespace IntegrationKSSS.WebService.Infrastructure.Handlers
return AuthenticateResult.Success(ticket);
}
}
#endregion
}
namespace IntegrationKSSS.WebService.Infrastructure.Models;
/// <summary>
/// List of internal messages
/// </summary>
internal static class MessageList
{
#region Variables
public const string SpecificationNotFound = "Specification not found";
public const string KsssInfoCardNotFound = "KSSS info card not found";
public const string KsssInfoCardEmpty = "There are no info fields on the KSSS info card";
public const string SuccessfullyKsssInfoCardRecord = "Successfully recorded data on the KSSS info card";
public const string AcceptedDataPackage = "The data package has been accepted for processing";
#endregion
}
\ No newline at end of file
namespace IntegrationKSSS.WebService.Infrastructure.Models;
public class RndtIpIeAu
{
#region Properties
public decimal IP { get; set; }
public decimal VERSION { get; set; }
public decimal IE { get; set; }
public decimal SEQ { get; set; }
public decimal AU { get; set; }
public decimal AUSEQ { get; set; }
public string? VALUE { get; set; }
#endregion
}
\ No newline at end of file
namespace IntegrationKSSS.WebService.Infrastructure.Models
namespace IntegrationKSSS.WebService.Infrastructure.Models;
public class RndtSp
{
public class RndtSp
{
#region Properties
public decimal SP { get; set; }
public decimal SP_VERSION { get; set; }
public string DESCRIPTION { get; set; }
......@@ -9,6 +10,6 @@
public char? ALLOW_MODIFY { get; set; }
public char? ACTIVE { get; set; }
public string? LAST_COMMENT { get; set; }
#endregion
}
}
\ No newline at end of file
namespace IntegrationKSSS.WebService.Infrastructure.Models
namespace IntegrationKSSS.WebService.Infrastructure.Models;
public class RndtSpIc
{
public class RndtSpIc
{
#region Properties
public decimal SP { get; set; }
public decimal SP_VERSION { get; set; }
public decimal IC { get; set; }
......@@ -9,5 +10,5 @@
public decimal ICNODE { get; set; }
public decimal? IP_VERSION { get; set; }
public decimal? SS { get; set; }
}
#endregion
}
\ No newline at end of file
namespace IntegrationKSSS.WebService.Infrastructure.Models
namespace IntegrationKSSS.WebService.Infrastructure.Models;
public class RndtSpIi
{
public class RndtSpIi
{
#region Properties
public decimal SP { get; set; }
public decimal SP_VERSION { get; set; }
public decimal IC { get; set; }
......@@ -12,5 +13,5 @@
public decimal? IE_VERSION { get; set; }
public string? IIVALUE { get; set; }
public decimal? SS { get; set; }
}
#endregion
}
\ No newline at end of file
namespace IntegrationKSSS.WebService.Infrastructure.Repositories
namespace IntegrationKSSS.WebService.Infrastructure.Repositories;
/// <summary>
/// A set of repository functions
/// </summary>
public interface IKsssRepository
{
public interface IKsssRepository
{
Task<string> WriteKsssData(Dictionary<string, string> ksss);
}
Task WriteKsssData(Dictionary<string, string> ksss);
}
\ No newline at end of file
using IntegrationKSSS.Models;
using IntegrationKSSS.WebService.Infrastructure.Data;
using IntegrationKSSS.WebService.Infrastructure.Data;
using IntegrationKSSS.WebService.Infrastructure.Models;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using ILogger = NLog.ILogger;
namespace IntegrationKSSS.WebService.Infrastructure.Repositories
namespace IntegrationKSSS.WebService.Infrastructure.Repositories;
/// <summary>
/// A set of repository function implementations
/// </summary>
public class KsssRepository : KsssRepositoryBase, IKsssRepository
{
public class KsssRepository : KsssRepositoryBase, IKsssRepository
{
#region Constructors
public KsssRepository(RDnLDbContext rDnLDbContext, ILogger logger) : base(rDnLDbContext, logger) { }
#endregion
public async Task<string> WriteKsssData(Dictionary<string, string> ksssDictionary)
#region Methods
/// <summary>
/// Data recording on the specification infocard
/// </summary>
/// <param name="ksssDictionary"></param>
/// <returns></returns>
public async Task WriteKsssData(Dictionary<string, string> ksssDictionary)
{
try
{
decimal specificationId = 0;
decimal.TryParse(ksssDictionary["SP"], out specificationId);
if(specificationId == 0)
if (specificationId == 0)
{
Logger.Info("Not found specification id");
return "Not found specification id";
Logger.Info(MessageList.SpecificationNotFound);
return;
}
decimal ssDev = 1000012;
string nameInfoCard = "KSSS_Data";
......@@ -23,12 +38,10 @@ namespace IntegrationKSSS.WebService.Infrastructure.Repositories
var specification = RDnLDbContext.RndtSp.FirstOrDefault(c => c.SP == specificationId &&
c.ALLOW_MODIFY == '1' &&
c.SS == ssDev);
if (specification == null)
{
Logger.Info($"Not found specification {specificationId}");
return $"Not found specification {specificationId}";
Logger.Info(MessageList.SpecificationNotFound);
return;
}
......@@ -36,40 +49,77 @@ namespace IntegrationKSSS.WebService.Infrastructure.Repositories
infoCard.IC_SHORT_DESC == nameInfoCard &&
infoCard.SP_VERSION == specification.SP_VERSION);
if(infoCardKsss == null)
if (infoCardKsss == null)
{
Logger.Info($"Not found info card {nameInfoCard}");
return $"Not found info card {nameInfoCard}";
Logger.Info(MessageList.KsssInfoCardNotFound);
return;
}
var infoFields = RDnLDbContext.RndtSpIi.Where(infoField => infoField.IC == infoCardKsss.IC &&
infoField.SP == specificationId);
if(infoFields.Count() == 0)
if (infoFields.Count() == 0)
{
Logger.Info($"There are no info fields on the info card {nameInfoCard}");
return $"There are no info fields on the info card {nameInfoCard}";
Logger.Info(MessageList.KsssInfoCardEmpty);
return;
}
foreach (var ksssValuePair in ksssDictionary)
{
if(ksssValuePair.Key == "SP")
if (ksssValuePair.Key == "SP")
{
continue;
}
var foundedInfoField = infoFields.FirstOrDefault(infoField => infoField.II_SHORT_DESC == ksssValuePair.Key);
if(foundedInfoField == null)
if (foundedInfoField == null)
{
continue;
}
var relationValue = GetRelationValue(foundedInfoField, ksssValuePair.Value);
if (string.IsNullOrEmpty(relationValue))
{
foundedInfoField.IIVALUE = ksssValuePair.Value;
}
else
{
foundedInfoField.IIVALUE = relationValue;
}
}
await RDnLDbContext.SaveChangesAsync();
Logger.Info($"Successfully recorded data on the info card {nameInfoCard}");
return $"Successfully recorded data on the info card {nameInfoCard}";
Logger.Info(MessageList.SuccessfullyKsssInfoCardRecord);
}
catch (Exception ex)
{
Logger.Error(ex);
}
}
/// <summary>
/// Getting the value relation
/// </summary>
/// <param name="rndtSpIi"></param>
/// <param name="tableValue"></param>
/// <returns></returns>
private string GetRelationValue(RndtSpIi rndtSpIi, string tableValue)
{
string result = string.Empty;
var rndvIpIeAu = RDnLDbContext.RndtIpIeAu.Where(c => c.IE == rndtSpIi.II)
.OrderByDescending(c => c.VERSION)
.FirstOrDefault();
var tableName = rndvIpIeAu?.VALUE;
if (!string.IsNullOrEmpty(tableName) && !string.IsNullOrEmpty(tableValue))
{
var sqlQuery = $"SELECT Name FROM [RndSuite].[{tableName}] WHERE [Id] = @TableId";
var tableId = new SqlParameter("@TableId", tableValue);
result = RDnLDbContext.Database.SqlQueryRaw<string>(sqlQuery, tableId)
.ToList()
.FirstOrDefault();
}
return result;
}
#endregion
}
using IntegrationKSSS.WebService.Infrastructure.Data;
using ILogger = NLog.ILogger;
namespace IntegrationKSSS.WebService.Infrastructure.Repositories
namespace IntegrationKSSS.WebService.Infrastructure.Repositories;
/// <summary>
/// A set of variables repository
/// </summary>
public class KsssRepositoryBase
{
public class KsssRepositoryBase
{
#region Variables
internal readonly RDnLDbContext RDnLDbContext;
internal readonly ILogger Logger;
#endregion
#region Constructors
public KsssRepositoryBase(RDnLDbContext rDnLDbContext, ILogger logger)
{
RDnLDbContext = rDnLDbContext;
Logger = logger;
}
}
#endregion
}
\ No newline at end of file
using IntegrationKSSS.WebService.Infrastructure.Repositories;
using IntegrationKSSS.WebService.Infrastructure.Models;
using IntegrationKSSS.WebService.Infrastructure.Repositories;
using Microsoft.AspNetCore.Authorization;
namespace IntegrationKSSS.WebService.Infrastructure.RequestHandlers
namespace IntegrationKSSS.WebService.Infrastructure.RequestHandlers;
internal static class RequestHandler
{
internal static class KsssFunctions
{
/// <summary>
/// KSSS data recording function
/// </summary>
/// <returns></returns>
#region Methods
internal static Func<IKsssRepository, Dictionary<string, string>, Task<IResult>> WriteKsssData()
{
return /*[Authorize] */async (IKsssRepository ksssRepository, Dictionary<string,string> ksss) =>
{
var message = await ksssRepository.WriteKsssData(ksss)/*.ConfigureAwait(false)*/;
if(message.Contains("Successfully"))
{
return Results.Ok(message);
}
else
return [Authorize] async (IKsssRepository ksssRepository, Dictionary<string, string> ksss) =>
{
return Results.BadRequest(message);
}
await ksssRepository.WriteKsssData(ksss);
return Results.Accepted("/api/ksss", MessageList.AcceptedDataPackage);
};
}
}
#endregion
}
\ No newline at end of file
namespace IntegrationKSSS.WebService.Infrastructure.RouteHandlers;
public interface IRouteHandler
{
#region Methods
void Register(WebApplication webApplication);
#endregion
}
\ No newline at end of file
using IntegrationKSSS.WebService.Infrastructure.RequestHandlers;
namespace IntegrationKSSS.WebService.Infrastructure.RouteHandlers
namespace IntegrationKSSS.WebService.Infrastructure.RouteHandlers;
public class RouteHandler : RouteHandlerBase, IRouteHandler
{
public interface IRouteHandler
{
void Register(WebApplication webApplication);
}
public abstract class KsssRouteHandlerBase
{
internal WebApplication WebApplication { get; set; }
}
public class RouteHandler : KsssRouteHandlerBase, IRouteHandler
{
#region Methods
public void Register(WebApplication webApplication)
{
WebApplication = webApplication;
Creators();
}
private void Creators()
{
WebApplication.MapPost("/api/ksss", KsssFunctions.WriteKsssData());
}
WebApplication.MapPost("/api/ksss", RequestHandler.WriteKsssData());
}
#endregion
}
namespace IntegrationKSSS.WebService.Infrastructure.RouteHandlers;
public abstract class RouteHandlerBase
{
#region Properties
internal WebApplication WebApplication { get; set; }
#endregion
}
\ No newline at end of file
using IntegrationKSSS.WebService.Infrastructure.Cryptography;
namespace IntegrationKSSS.WebService.Infrastructure.Services
namespace IntegrationKSSS.WebService.Infrastructure.Services;
public class AuthService : IAuthService
{
public interface IAuthService
{
Task<bool> Auth(string login, string password);
}
public class AuthService : IAuthService
{
#region Methods
public async Task<bool> Auth(string login, string password)
{
string _login = "5WndfpUBeL21vPl1T52S2w==",
......@@ -19,5 +15,5 @@ namespace IntegrationKSSS.WebService.Infrastructure.Services
true :
false);
}
}
#endregion
}
\ No newline at end of file
namespace IntegrationKSSS.WebService.Infrastructure.Services;
public interface IAuthService
{
#region Methods
Task<bool> Auth(string login, string password);
#endregion
}
......@@ -29,6 +29,12 @@
<ProjectReference Include="..\IntegrationKSSS\IntegrationKSSS.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="RnD.Model.EF">
<HintPath>..\..\..\..\Distr\OpcenterRDnL_9.1.0.0.3\Implementation\ABP\Opcenter_RDnL_V9.1.0.3_applied_best_practices\OpcenterRDnLLibrary_Builds\Siemens.OpcenterRDnLLibrary.Dependencies\RnD.Model.EF.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Update="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
......
......@@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
<PropertyGroup>
<History>True|2023-01-26T11:17:24.0239724Z;True|2023-01-25T14:06:16.9243865+03:00;True|2023-01-25T14:00:39.9266437+03:00;True|2023-01-25T12:51:23.5799247+03:00;True|2023-01-25T12:35:08.8563117+03:00;False|2023-01-25T12:34:04.6686340+03:00;False|2023-01-25T12:33:57.8005398+03:00;False|2023-01-25T12:33:39.5203110+03:00;</History>
<History>True|2023-02-10T11:33:33.5625719Z;True|2023-02-09T18:01:25.0874999+03:00;True|2023-02-09T16:04:11.0766065+03:00;True|2023-01-26T14:17:24.0239724+03:00;True|2023-01-25T14:06:16.9243865+03:00;True|2023-01-25T14:00:39.9266437+03:00;True|2023-01-25T12:51:23.5799247+03:00;True|2023-01-25T12:35:08.8563117+03:00;False|2023-01-25T12:34:04.6686340+03:00;False|2023-01-25T12:33:57.8005398+03:00;False|2023-01-25T12:33:39.5203110+03:00;</History>
<LastFailureDetails />
<_PublishTargetUrl>C:\Bryzgalov\Projects\IntegrationKSSS\IntegrationKSSS.WebService\bin\Release\net6.0\publish\</_PublishTargetUrl>
</PropertyGroup>
......
......@@ -17,7 +17,8 @@
"NLog.Config": "4.7.15",
"NLog.Web.AspNetCore": "5.2.0",
"Newtonsoft.Json": "13.0.2",
"Swashbuckle.AspNetCore": "6.2.3"
"Swashbuckle.AspNetCore": "6.2.3",
"RnD.Model.EF": "9.1.0.0"
},
"runtime": {
"IntegrationKSSS.WebService.dll": {}
......@@ -804,6 +805,30 @@
"runtime": {
"IntegrationKSSS.dll": {}
}
},
"RnD.Model.EF/9.1.0.0": {
"runtime": {
"RnD.Model.EF.dll": {
"assemblyVersion": "9.1.0.0",
"fileVersion": "901.0.300.11"
}
}
},
"RnD.Common/9.1.0.0": {
"runtime": {
"RnD.Common.dll": {
"assemblyVersion": "9.1.0.0",
"fileVersion": "901.0.300.11"
}
}
},
"RDnL.Logger/9.1.0.0": {
"runtime": {
"RDnL.Logger.dll": {
"assemblyVersion": "9.1.0.0",
"fileVersion": "901.0.300.11"
}
}
}
}
},
......@@ -1377,6 +1402,21 @@
"type": "project",
"serviceable": false,
"sha512": ""
},
"RnD.Model.EF/9.1.0.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
},
"RnD.Common/9.1.0.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
},
"RDnL.Logger/9.1.0.0": {
"type": "reference",
"serviceable": false,
"sha512": ""
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment