400 lines
14 KiB
C#
400 lines
14 KiB
C#
using EgwCoreLib.Lux.Core.RestPayload;
|
|
using EgwCoreLib.Lux.Data.Controllers;
|
|
using EgwCoreLib.Lux.Data.DbModel;
|
|
using EgwMultiEngineManager.Data;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Newtonsoft.Json;
|
|
using NLog;
|
|
using StackExchange.Redis;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
|
|
namespace EgwCoreLib.Lux.Data.Services
|
|
{
|
|
public class DataLayerServices : BaseServ
|
|
{
|
|
#region Public Constructors
|
|
|
|
public DataLayerServices(IConfiguration configuration, IConnectionMultiplexer RedisConn) : base(configuration, RedisConn)
|
|
{
|
|
// conf DB
|
|
string connStr = BaseServ.configuration.GetConnectionString("Lux.All") ?? "";
|
|
if (string.IsNullOrEmpty(connStr))
|
|
{
|
|
Log.Error("ConnString empty!");
|
|
}
|
|
else
|
|
{
|
|
dbController = new LuxController();
|
|
//dbController = new Controllers.LuxController(configuration);
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.AppendLine($"DataLayerServices | LuxController OK");
|
|
Log.Info(sb.ToString());
|
|
}
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Properties
|
|
|
|
public static LuxController dbController { get; set; } = null!;
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Elenco completo Customers
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<CustomerModel> CustomersGetAll()
|
|
{
|
|
string source = "DB";
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
List<CustomerModel>? result = new List<CustomerModel>();
|
|
// cerco in redis...
|
|
string currKey = $"{redisBaseKey}:Customers:ALL";
|
|
RedisValue rawData = redisDb.StringGet(currKey);
|
|
if (rawData.HasValue)
|
|
{
|
|
result = JsonConvert.DeserializeObject<List<CustomerModel>>($"{rawData}");
|
|
source = "REDIS";
|
|
}
|
|
else
|
|
{
|
|
result = dbController.CustomersGetAll();
|
|
// serializzo e salvo...
|
|
rawData = JsonConvert.SerializeObject(result);
|
|
redisDb.StringSet(currKey, rawData, LongCache);
|
|
}
|
|
if (result == null)
|
|
{
|
|
result = new List<CustomerModel>();
|
|
}
|
|
sw.Stop();
|
|
Log.Debug($"CustomersGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms");
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco completo dealers
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<DealerModel> DealersGetAll()
|
|
{
|
|
string source = "DB";
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
List<DealerModel>? result = new List<DealerModel>();
|
|
// cerco in redis...
|
|
string currKey = $"{redisBaseKey}:Dealers:ALL";
|
|
RedisValue rawData = redisDb.StringGet(currKey);
|
|
if (rawData.HasValue)
|
|
{
|
|
result = JsonConvert.DeserializeObject<List<DealerModel>>($"{rawData}");
|
|
source = "REDIS";
|
|
}
|
|
else
|
|
{
|
|
result = dbController.DealersGetAll();
|
|
// serializzo e salvo...
|
|
rawData = JsonConvert.SerializeObject(result);
|
|
redisDb.StringSet(currKey, rawData, LongCache);
|
|
}
|
|
if (result == null)
|
|
{
|
|
result = new List<DealerModel>();
|
|
}
|
|
sw.Stop();
|
|
Log.Debug($"DealersGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms");
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset completo cache sistema
|
|
/// </summary>
|
|
public bool FlushCache()
|
|
{
|
|
bool answ = false;
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
RedisValue pattern = new RedisValue($"{redisBaseKey}:*");
|
|
answ = ExecFlushRedisPattern(pattern);
|
|
stopWatch.Stop();
|
|
Log.Debug($"FlushCache in {stopWatch.Elapsed.TotalMilliseconds} ms");
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset completo cache sistema modalità async
|
|
/// </summary>
|
|
public async Task<bool> FlushCacheAsync()
|
|
{
|
|
bool answ = false;
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
RedisValue pattern = new RedisValue($"{redisBaseKey}:*");
|
|
answ = await ExecFlushRedisPatternAsync(pattern);
|
|
sw.Stop();
|
|
Log.Debug($"FlushCacheAsync in {sw.Elapsed.TotalMilliseconds} ms");
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco completo offerte da DB
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<OfferModel> OfferGetAll()
|
|
{
|
|
string source = "DB";
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
List<OfferModel>? result = new List<OfferModel>();
|
|
// cerco in redis...
|
|
string currKey = $"{redisBaseKey}:Offers:ALL";
|
|
RedisValue rawData = redisDb.StringGet(currKey);
|
|
//if (!string.IsNullOrEmpty($"{rawData}"))
|
|
if (rawData.HasValue)
|
|
{
|
|
result = JsonConvert.DeserializeObject<List<OfferModel>>($"{rawData}");
|
|
source = "REDIS";
|
|
}
|
|
else
|
|
{
|
|
result = dbController.OfferGetAll();
|
|
// serializzo e salvo...
|
|
rawData = JsonConvert.SerializeObject(result);
|
|
redisDb.StringSet(currKey, rawData, LongCache);
|
|
}
|
|
if (result == null)
|
|
{
|
|
result = new List<OfferModel>();
|
|
}
|
|
sw.Stop();
|
|
Log.Debug($"OfferGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms");
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco righe offerta specificata
|
|
/// </summary>
|
|
/// <param name="OfferID"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<OfferRowModel>> OfferRowGetByOffer(int OfferID)
|
|
{
|
|
string source = "DB";
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
List<OfferRowModel>? result = new List<OfferRowModel>();
|
|
// cerco in redis...
|
|
string currKey = $"{redisBaseKey}:OfferRows:{OfferID}";
|
|
RedisValue rawData = await redisDb.StringGetAsync(currKey);
|
|
//if (!string.IsNullOrEmpty($"{rawData}"))
|
|
if (rawData.HasValue)
|
|
{
|
|
result = JsonConvert.DeserializeObject<List<OfferRowModel>>($"{rawData}");
|
|
source = "REDIS";
|
|
}
|
|
else
|
|
{
|
|
result = dbController.OfferRowGetByOffer(OfferID);
|
|
// serializzo e salvo...
|
|
rawData = JsonConvert.SerializeObject(result);
|
|
await redisDb.StringSetAsync(currKey, rawData, LongCache);
|
|
}
|
|
if (result == null)
|
|
{
|
|
result = new List<OfferRowModel>();
|
|
}
|
|
sw.Stop();
|
|
Log.Debug($"OfferRowGetByOffer | {source} | {sw.Elapsed.TotalMilliseconds}ms");
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua update dei costi di tutte le righe dell'offerta indicata
|
|
/// </summary>
|
|
/// <param name="OfferID">Key</param>
|
|
/// <returns></returns>
|
|
public async Task<bool> OffertUpdateCost(int OfferID)
|
|
{
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
// calcolo
|
|
bool fatto = await dbController.OffertUpdateCost(OfferID);
|
|
// svuoto cache...
|
|
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Offers:*");
|
|
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OfferRows:*");
|
|
sw.Stop();
|
|
Log.Debug($"OffertUpdateCost in {sw.Elapsed.TotalMilliseconds} ms");
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue salvataggio BOM sul DB
|
|
/// </summary>
|
|
/// <param name="uID">UID dell'item offerta di cui si è ricevuto la BOM</param>
|
|
/// <param name="execEnvironment">Environment dell'item</param>
|
|
/// <param name="bomContent">BOM serializzata</param>
|
|
/// <returns></returns>
|
|
public async Task SaveBomAsync(string uID, Constants.EXECENVIRONMENTS execEnvironment, string bomContent)
|
|
{
|
|
// salvo sul DB il risultato della BOM
|
|
if (!string.IsNullOrEmpty(bomContent))
|
|
{
|
|
try
|
|
{
|
|
// deserializzo la Bom...
|
|
var bomList = JsonConvert.DeserializeObject<List<BomItemDTO>>(bomContent);
|
|
if (bomList != null)
|
|
{
|
|
// verifico 1:1 gli item ricevuti dalla BOM sul DB con eventuale insert
|
|
dbController.ItemUpsertFromBom(bomList);
|
|
// salvo la BOM nel record del DB relativo all'oggetto richiesto
|
|
dbController.OfferUpsertFromBom(uID, bomList);
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
await Task.Delay(1);
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
/// <summary>
|
|
/// Numero di operazioni parallele che si possono svolgere... (se 0 NON usa cicli paralleli)
|
|
/// </summary>
|
|
protected int numPar = 0;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Esegue flush memoria redis dato pattern
|
|
/// </summary>
|
|
/// <param name="pattern"></param>
|
|
/// <returns></returns>
|
|
protected bool ExecFlushRedisPattern(RedisValue pattern)
|
|
{
|
|
bool answ = false;
|
|
/*******************************
|
|
* Recupero elenco dei server da cui cancellare le chaivi:
|
|
* - prendo solo i server connessi
|
|
* - prendo solo NON repliche (= master)
|
|
* - me ne aspetto 1 in uscita cmq
|
|
*******************************/
|
|
var connServ = redisConn.GetEndPoints()
|
|
.Select(endpoint =>
|
|
{
|
|
var server = redisConn.GetServer(endpoint);
|
|
return server;
|
|
})
|
|
.Where(x => x.IsConnected && !x.IsReplica)
|
|
.ToList();
|
|
|
|
// ciclo (anche se me ne aspetto 1 solo)
|
|
foreach (var mServer in connServ)
|
|
{
|
|
try
|
|
{
|
|
var keyList = mServer.Keys(redisDb.Database, pattern);
|
|
if (numPar > 0)
|
|
{
|
|
var options = new ParallelOptions { MaxDegreeOfParallelism = numPar };
|
|
Parallel.ForEachAsync(keyList, async (item, token) =>
|
|
{
|
|
// cancello
|
|
redisDb.KeyDelete(item);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
foreach (var item in keyList)
|
|
{
|
|
redisDb.KeyDelete(item);
|
|
}
|
|
}
|
|
answ = true;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione durante ExecFlushRedisPattern | pattern: {pattern}{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue flush memoria redis dato pattern
|
|
/// </summary>
|
|
/// <param name="pattern"></param>
|
|
/// <returns></returns>
|
|
protected async Task<bool> ExecFlushRedisPatternAsync(RedisValue pattern)
|
|
{
|
|
bool answ = false;
|
|
/*******************************
|
|
* Recupero elenco dei server da cui cancellare le chaivi:
|
|
* - prendo solo i server connessi
|
|
* - prendo solo NON repliche (= master)
|
|
* - me ne aspetto 1 in uscita cmq
|
|
*******************************/
|
|
var connServ = redisConn.GetEndPoints()
|
|
.Select(endpoint =>
|
|
{
|
|
var server = redisConn.GetServer(endpoint);
|
|
return server;
|
|
})
|
|
.Where(x => x.IsConnected && !x.IsReplica)
|
|
.ToList();
|
|
|
|
// ciclo (anche se me ne aspetto 1 solo)
|
|
foreach (var mServer in connServ)
|
|
{
|
|
try
|
|
{
|
|
var keyList = mServer.Keys(redisDb.Database, pattern);
|
|
if (numPar > 0)
|
|
{
|
|
var options = new ParallelOptions { MaxDegreeOfParallelism = numPar };
|
|
await Parallel.ForEachAsync(keyList, async (item, token) =>
|
|
{
|
|
// cancello
|
|
await redisDb.KeyDeleteAsync(item);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
foreach (var item in keyList)
|
|
{
|
|
await redisDb.KeyDeleteAsync(item);
|
|
}
|
|
}
|
|
answ = true;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione durante ExecFlushRedisPatternAsync | pattern: {pattern}{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Private Fields
|
|
|
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
|
private string redisBaseKey = "Lux:Cache";
|
|
|
|
#endregion Private Fields
|
|
}
|
|
} |