From 3cd24965046eff35d7b3999481f5a227cbfcfec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Zieliski?= Date: Thu, 6 Jun 2024 20:59:30 +0200 Subject: [PATCH] Log powerBI requests --- WebAPI/Controllers/LayersController.cs | 181 ++++++++++++++++++------- WebAPI/Controllers/LogsController.cs | 3 + WebAPI/Models/LogEntry.cs | 3 +- 3 files changed, 135 insertions(+), 52 deletions(-) diff --git a/WebAPI/Controllers/LayersController.cs b/WebAPI/Controllers/LayersController.cs index 6cec597..d98516e 100644 --- a/WebAPI/Controllers/LayersController.cs +++ b/WebAPI/Controllers/LayersController.cs @@ -13,7 +13,6 @@ namespace WebAPI.Controllers { [ApiController] [Route("api/[controller]")] - public class LayersController : Controller { private readonly AppDbContext db; @@ -22,6 +21,7 @@ namespace WebAPI.Controllers private GoogleSheetsHelper googleSheetsHelper; private readonly IConfiguration configuration; private readonly LogsController logsController; + public LayersController( AppDbContext _db, GoogleSheetsHelper _googleSheetsHelper, @@ -33,6 +33,7 @@ namespace WebAPI.Controllers { googleSheetValues = _googleSheetsHelper.Service.Spreadsheets.Values; } + googleSheetsHelper = _googleSheetsHelper; googleDriveHelper = _googleDriveHelper; configuration = _configuration; @@ -49,6 +50,7 @@ namespace WebAPI.Controllers { response = response.Where(x => x.Name != null && x.Name.Contains(name)); } + if (type != null) { response = response.Where(x => x.Type == type); @@ -57,13 +59,13 @@ namespace WebAPI.Controllers return Ok(response .OrderByDescending(x => x.Number) .Skip(start).Take(limit).ToList()); - } catch (Exception e) { return BadRequest(e.ToString()); } } + [HttpPost] public IActionResult Save(Layer input) { @@ -80,6 +82,7 @@ namespace WebAPI.Controllers return BadRequest(e.ToString()); } } + [HttpGet] [Route("{id}")] public IActionResult Get(Guid id) @@ -96,35 +99,74 @@ namespace WebAPI.Controllers return BadRequest(e.ToString()); } } + [HttpGet] [Route("getForPowerBI/{apiKey}/{number}")] public IActionResult GetByNumber(string apiKey, int number) { if (apiKey != configuration["apiKey"]) { + logsController.AddEntry(new LogEntry + { + Title = $"Unauthorized request - wrong apiKey ({number})", + Type = LogEntryType.warning, + LogType = LogType.powerBI, + CreatedAt = DateTime.UtcNow, + }); return Unauthorized(); } - if ( - !Request.Headers.TryGetValue("Authorization", out var authHeader)) - { - return Unauthorized(); - } - string[] credentialsArr = authHeader.ToString().Split(" "); - if (credentialsArr.Length != 2) - { - return Unauthorized(); - } - var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1])); - var username = authValue.Split(':')[0]; - var password = authValue.Split(':')[1]; - if (username != configuration["powerBI-user"] || password != configuration["powerBI-pass"]) - { - return Unauthorized(); - } - try { + if ( + !Request.Headers.TryGetValue("Authorization", out var authHeader)) + { + logsController.AddEntry(new LogEntry + { + Title = $"Unauthorized request - no authorization header ({number})", + Type = LogEntryType.warning, + LogType = LogType.powerBI, + CreatedAt = DateTime.UtcNow, + }); + return Unauthorized(); + } + + string[] credentialsArr = authHeader.ToString().Split(" "); + if (credentialsArr.Length != 2) + { + logsController.AddEntry(new LogEntry + { + Title = $"Unauthorized request - wrong auth header format ({number})", + Type = LogEntryType.warning, + LogType = LogType.powerBI, + CreatedAt = DateTime.UtcNow, + }); + return Unauthorized(); + } + + var authValue = Encoding.UTF8.GetString(Convert.FromBase64String(credentialsArr[1])); + var username = authValue.Split(':')[0]; + var password = authValue.Split(':')[1]; + if (username != configuration["powerBI-user"] || password != configuration["powerBI-pass"]) + { + logsController.AddEntry(new LogEntry + { + Title = $"Unauthorized request - bad credentials ({number})", + Type = LogEntryType.warning, + LogType = LogType.powerBI, + CreatedAt = DateTime.UtcNow, + }); + return Unauthorized(); + } + + logsController.AddEntry(new LogEntry + { + Title = $"Sending data for layer {number}", + Type = LogEntryType.info, + LogType = LogType.powerBI, + CreatedAt = DateTime.UtcNow, + }); + return Ok(db.Layers .Include(x => x.CreatedBy) .Include(x => x.Records) @@ -132,9 +174,17 @@ namespace WebAPI.Controllers } catch (Exception e) { + logsController.AddEntry(new LogEntry + { + Title = e.ToString(), + Type = LogEntryType.error, + LogType = LogType.powerBI, + CreatedAt = DateTime.UtcNow, + }); return BadRequest(e.ToString()); } } + [HttpGet] [Route("exportToGoogleSheet/{id}")] public IActionResult ExportToGoogleSheet(Guid id) @@ -143,9 +193,10 @@ namespace WebAPI.Controllers { throw new Exception("Google Sheets API not initialized"); } + Layer layer = db.Layers - .Include(x => x.Records!.OrderByDescending(x => x.Code)) - .Where(x => x.Id == id && !x.IsDeleted).First(); + .Include(x => x.Records!.OrderByDescending(x => x.Code)) + .Where(x => x.Id == id && !x.IsDeleted).First(); var export = new googleSheetExport(googleDriveHelper, googleSheetValues, configuration); export.export(layer); @@ -161,20 +212,22 @@ namespace WebAPI.Controllers { return Unauthorized(); } + if (googleSheetValues is null) { throw new Exception("Google Sheets API not initialized"); } + try { List importWorkerLayers; importWorkerLayers = db.Layers .Include(x => x.Records) .Where(x => - x.Records!.Any(x => x.Code == "Type" && x.Desc1 == "ImportWorker") && - x.Records!.Any(x => x.Code == "IsEnabled" && x.Desc1 == "True") + x.Records!.Any(x => x.Code == "Type" && x.Desc1 == "ImportWorker") && + x.Records!.Any(x => x.Code == "IsEnabled" && x.Desc1 == "True") //&& x.Records!.Any(x => x.Code == "ImportType" && x.Desc1 == "FK2") - ) + ) .OrderBy(x => x.CreatedAt) .ToList(); @@ -204,7 +257,7 @@ namespace WebAPI.Controllers { MorskaFk2Importer importer = new MorskaFk2Importer(db, googleSheetValues, this); importer.import(importWorker); - + logsController.AddEntry(new LogEntry { Title = $"{importWorker!.Name}, {importWorker.Id}", @@ -216,9 +269,6 @@ namespace WebAPI.Controllers } else { - - - string? startDate = importWorker.Records!.FirstOrDefault(x => x.Code == "StartDate")?.Desc1; if (startDate == null) { @@ -289,6 +339,7 @@ namespace WebAPI.Controllers }); } } + return Ok(); } catch (Exception e) @@ -304,6 +355,7 @@ namespace WebAPI.Controllers return BadRequest(e.ToString()); } } + [HttpGet] [Route("AutoProcess/{apiKey}")] [AllowAnonymous] @@ -313,18 +365,20 @@ namespace WebAPI.Controllers { return Unauthorized(); } + if (googleSheetValues is null) { throw new Exception("Google Sheets API not initialized"); } - string[] processTypes = new string[] { - "T3-SingleSource", + string[] processTypes = new string[] + { + "T3-SingleSource", "T3-SourceYearSummary", "T3-MultiSourceSummary", // AA "T3-MultiSourceYearSummary", // AA/13 "T3-R1" - }; + }; foreach (string type in processTypes) { @@ -344,7 +398,7 @@ namespace WebAPI.Controllers x.Records!.Any(x => x.Code == "Type" && x.Desc1 == "ProcessWorker") && x.Records!.Any(x => x.Code == "IsEnabled" && x.Desc1 == "True") && x.Records!.Any(x => x.Code == "ProcessType" && x.Desc1 == type) - ) + ) .OrderBy(x => x.CreatedAt) .ToList(); @@ -390,14 +444,17 @@ namespace WebAPI.Controllers }); } } + return Ok(); } + internal void ProcessLayer(Layer processWorker) { if (googleSheetValues == null) { throw new Exception("Google Sheets API not initialized"); } + string? name = processWorker.Name; string? year = processWorker?.Records?.SingleOrDefault(x => x.Code == "Year")?.Desc1; if (year == null) @@ -410,6 +467,7 @@ namespace WebAPI.Controllers { throw new Exception("ProcessType record not found"); } + if (processType == "T3-SourceYearSummary") { T3SourceYearSummaryProcessor processor = new T3SourceYearSummaryProcessor(db, googleSheetValues, this); @@ -425,9 +483,11 @@ namespace WebAPI.Controllers }); return; } + if (processType == "T3-MultiSourceYearSummary") { - T3MultiSourceYearSummaryProcessor processor = new T3MultiSourceYearSummaryProcessor(db, googleSheetValues, this, logsController); + T3MultiSourceYearSummaryProcessor processor = + new T3MultiSourceYearSummaryProcessor(db, googleSheetValues, this, logsController); processor.process(processWorker!); logsController.AddEntry(new LogEntry @@ -440,9 +500,11 @@ namespace WebAPI.Controllers }); return; } + if (processType == "T3-MultiSourceCopySelectedCodesYearSummary") { - T3MultiSourceCopySelectedCodesYearSummaryProcessor processor = new T3MultiSourceCopySelectedCodesYearSummaryProcessor(db, googleSheetValues, this); + T3MultiSourceCopySelectedCodesYearSummaryProcessor processor = + new T3MultiSourceCopySelectedCodesYearSummaryProcessor(db, googleSheetValues, this); processor.process(processWorker!); logsController.AddEntry(new LogEntry @@ -455,6 +517,7 @@ namespace WebAPI.Controllers }); return; } + if (processType == "T3-R1") { T3R1Processor processor = new T3R1Processor(db, googleSheetValues, this, logsController); @@ -470,32 +533,37 @@ namespace WebAPI.Controllers }); return; } + string? month = processWorker?.Records?.SingleOrDefault(x => x.Code == "Month")?.Desc1; if (month == null) { throw new Exception("Month record not found"); } + switch (processType!) { case "T3-SingleSource": - { - T3SingleSourceProcessor processor = new T3SingleSourceProcessor(db, googleSheetValues, this); - processor.process(processWorker!); - break; - } + { + T3SingleSourceProcessor processor = new T3SingleSourceProcessor(db, googleSheetValues, this); + processor.process(processWorker!); + break; + } case "T3-MultiSourceSummary": - { - T3MultiSourceSummaryProcessor processor = new T3MultiSourceSummaryProcessor(db, googleSheetValues, this, logsController); - processor.process(processWorker!); - break; - } + { + T3MultiSourceSummaryProcessor processor = + new T3MultiSourceSummaryProcessor(db, googleSheetValues, this, logsController); + processor.process(processWorker!); + break; + } case "T3-MultiSourceCopySelectedCodes": - { - T3MultiSourceCopySelectedCodesProcessor processor = new T3MultiSourceCopySelectedCodesProcessor(db, googleSheetValues, this); - processor.process(processWorker!); - break; - } + { + T3MultiSourceCopySelectedCodesProcessor processor = + new T3MultiSourceCopySelectedCodesProcessor(db, googleSheetValues, this); + processor.process(processWorker!); + break; + } } + logsController.AddEntry(new LogEntry { Title = $"{processWorker!.Name}, {processWorker.Id}", @@ -505,6 +573,7 @@ namespace WebAPI.Controllers CreatedAt = DateTime.UtcNow }); } + internal void SaveRecords(Guid id, ICollection records, Guid currentUserId) { try @@ -514,6 +583,7 @@ namespace WebAPI.Controllers { db.Records.RemoveRange(toDelete); } + foreach (Record record in records) { record.CreatedById = currentUserId; @@ -529,6 +599,7 @@ namespace WebAPI.Controllers throw; } } + internal void WriteToConsole(params string[] messages) { foreach (string message in messages) @@ -536,6 +607,7 @@ namespace WebAPI.Controllers Console.WriteLine($"DiunaLog: {message}"); } } + private bool IsImportedLayerUpToDate(Layer importWorker) { if (googleSheetValues is null) @@ -559,16 +631,19 @@ namespace WebAPI.Controllers { throw new Exception($"SheetId not found, {importWorker.Name}"); } + string? sheetTabName = importWorker.Records!.Where(x => x.Code == "SheetTabName").FirstOrDefault()?.Desc1; if (sheetTabName == null) { throw new Exception($"SheetTabName not found, {importWorker.Name}"); } + string? dataRange = importWorker.Records!.Where(x => x.Code == "DataRange").FirstOrDefault()?.Desc1; if (dataRange == null) { throw new Exception($"DataRange not found, {importWorker.Name}"); } + var dataRangeResponse = googleSheetValues.Get(sheetId, $"{sheetTabName}!{dataRange}").Execute(); var data = dataRangeResponse.Values; @@ -590,20 +665,24 @@ namespace WebAPI.Controllers double.TryParse(data[1][i].ToString(), CultureInfo.GetCultureInfo("pl-PL"), out value) && record.Value1 != value) { - WriteToConsole($"Code: {data[0][i]}. DiunaBI: {string.Format("{0:N2}", record.Value1)}. GoogleSheet: {data[1][i]}"); + WriteToConsole( + $"Code: {data[0][i]}. DiunaBI: {string.Format("{0:N2}", record.Value1)}. GoogleSheet: {data[1][i]}"); isUpToDate = false; } } } + foreach (Record record in newestLayer.Records!) { if (data[0].Contains(record.Code)) { continue; } + WriteToConsole($"Code not found in GoogleSheet: {record.Code}"); isUpToDate = false; } + return isUpToDate; } } diff --git a/WebAPI/Controllers/LogsController.cs b/WebAPI/Controllers/LogsController.cs index e0a77c1..d96e7ba 100644 --- a/WebAPI/Controllers/LogsController.cs +++ b/WebAPI/Controllers/LogsController.cs @@ -40,6 +40,9 @@ namespace WebAPI.Controllers case LogType.process: type = "Process"; break; + case LogType.powerBI: + type = "PowerBIAccess"; + break; default: type = "Other"; // should never happen break; diff --git a/WebAPI/Models/LogEntry.cs b/WebAPI/Models/LogEntry.cs index 487d7e6..54e227e 100644 --- a/WebAPI/Models/LogEntry.cs +++ b/WebAPI/Models/LogEntry.cs @@ -11,7 +11,8 @@ namespace WebAPI.Models public enum LogType { import, backup, - process + process, + powerBI } public class LogEntry {