diff --git a/BMA.EHR.Domain/Middlewares/RequestLoggingMiddleware.cs b/BMA.EHR.Domain/Middlewares/RequestLoggingMiddleware.cs index ef1297ac..55dcf051 100644 --- a/BMA.EHR.Domain/Middlewares/RequestLoggingMiddleware.cs +++ b/BMA.EHR.Domain/Middlewares/RequestLoggingMiddleware.cs @@ -1,49 +1,122 @@ -using Microsoft.AspNetCore.Http; +using BMA.EHR.Domain.Models.HR; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging.Abstractions; using Nest; +using Newtonsoft.Json; using Serilog; using System.Diagnostics; using System.IO; +using System.Net.Http.Headers; +using System.Security.Claims; +using System.Text.Encodings.Web; using System.Text.Json; +using JsonSerializer = System.Text.Json.JsonSerializer; namespace BMA.EHR.Domain.Middlewares { public class RequestLoggingMiddleware { private readonly RequestDelegate _next; + private readonly IConfiguration _configuration; - public RequestLoggingMiddleware(RequestDelegate next) + private string Uri = ""; + private string IndexFormat = ""; + private string SystemName = ""; + private string APIKey = ""; + + public RequestLoggingMiddleware(RequestDelegate next, IConfiguration configuration) { _next = next; + _configuration = configuration; + + Uri = _configuration["ElasticConfiguration:Uri"] ?? "http://192.168.1.40:9200"; + IndexFormat = _configuration["ElasticConfiguration:IndexFormat"] ?? "bma-ehr-log-index"; + SystemName = _configuration["ElasticConfiguration:SystemName"] ?? "Unknown"; + } + + protected async Task GetExternalAPIAsync(string apiPath, string accessToken, string apiKey) + { + try + { + using (var client = new HttpClient()) + { + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", "")); + client.DefaultRequestHeaders.Add("api_key", apiKey); + var _res = await client.GetAsync(apiPath); + if (_res.IsSuccessStatusCode) + { + var _result = await _res.Content.ReadAsStringAsync(); + + return _result; + } + return string.Empty; + } + } + catch + { + throw; + } + } + + public async Task GetProfileByKeycloakIdAsync(Guid keycloakId, string? accessToken) + { + try + { + var apiPath = $"{_configuration["API"]}/org/dotnet/keycloak/{keycloakId}"; + var apiKey = _configuration["API_KEY"]; + + var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey); + if (apiResult != null) + { + var raw = JsonConvert.DeserializeObject(apiResult); + if (raw != null) + return raw.Result; + } + + return null; + } + catch + { + throw; + } } public async Task Invoke(HttpContext context) { - var settings = new ConnectionSettings(new Uri("http://192.168.1.40:9200")) - .DefaultIndex("bma-ehr-log-test-net"); + var settings = new ConnectionSettings(new Uri(Uri)) + .DefaultIndex(IndexFormat); var client = new ElasticClient(settings); var startTime = DateTime.UtcNow; var stopwatch = Stopwatch.StartNew(); + string? responseBodyJson = null; + string? requestBodyJson = null; string requestBody = await ReadRequestBodyAsync(context); + if (requestBody != "") + requestBodyJson = JsonSerializer.Serialize(JsonSerializer.Deserialize(requestBody), new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, WriteIndented = true }); + var originalBodyStream = context.Response.Body; - using (var memoryStream = new MemoryStream()) { // เปลี่ยน stream ของ Response เพื่อให้สามารถอ่านได้ context.Response.Body = memoryStream; + + + var keycloakId = context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? Guid.Empty.ToString("D"); + var token = context.Request.Headers["Authorization"]; + + var pf = await GetProfileByKeycloakIdAsync(Guid.Parse(keycloakId), token); + await _next(context); // ดำเนินการต่อไปยัง Middleware อื่น ๆ - - - stopwatch.Stop(); var processTime = stopwatch.ElapsedMilliseconds; var endTime = DateTime.UtcNow; @@ -55,16 +128,26 @@ namespace BMA.EHR.Domain.Middlewares _ => "info" }; + string? message = null; + // อ่านข้อมูลจาก Response หลังจากที่ได้ถูกส่งออกไป memoryStream.Seek(0, SeekOrigin.Begin); var responseBody = new StreamReader(memoryStream).ReadToEnd(); + if (responseBody != "") + responseBodyJson = JsonSerializer.Serialize(JsonSerializer.Deserialize(responseBody), new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, WriteIndented = true }); + + var json = JsonSerializer.Deserialize(responseBody); + if (json.TryGetProperty("message", out var messageElement)) + { + message = messageElement.GetString(); + } var logData = new { logType = logType, ip = context.Connection.RemoteIpAddress?.ToString(), - rootId = context.Items["RootId"] ?? null, - systemName = "test", + rootId = pf == null ? null : pf.RootId, + systemName = SystemName, startTimeStamp = startTime.ToString("o"), endTimeStamp = endTime.ToString("o"), processTime = processTime, @@ -72,9 +155,14 @@ namespace BMA.EHR.Domain.Middlewares method = context.Request.Method, endpoint = context.Request.Path + context.Request.QueryString, responseCode = context.Response.StatusCode == 304 ? "200" : context.Response.StatusCode.ToString(), - responseDescription = context.Items["ResponseMessage"] ?? null, - input = requestBody, - output = responseBody + responseDescription = message, + input = requestBodyJson, + output = responseBodyJson, + + userId = keycloakId, + userName = $"{pf?.Prefix ?? ""}{pf?.FirstName ?? ""} {pf?.LastName ?? ""}", + user = pf?.CitizenId ?? "" + }; // เขียนข้อมูลกลับไปยัง original Response body @@ -85,7 +173,7 @@ namespace BMA.EHR.Domain.Middlewares } - + //Log.Information("API Request Log: {@LogData}", logData); } @@ -98,4 +186,47 @@ namespace BMA.EHR.Domain.Middlewares return body; } } + + public class GetProfileByKeycloakIdLocal + { + public Guid Id { get; set; } + + public string? Prefix { get; set; } + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? CitizenId { get; set; } + + public string? Root { get; set; } + public string? Child1 { get; set; } + public string? Child2 { get; set; } + public string? Child3 { get; set; } + public string? Child4 { get; set; } + public Guid? RootId { get; set; } + public Guid? Child1Id { get; set; } + public Guid? Child2Id { get; set; } + public Guid? Child3Id { get; set; } + public Guid? Child4Id { get; set; } + public Guid? RootDnaId { get; set; } + public Guid? Child1DnaId { get; set; } + public Guid? Child2DnaId { get; set; } + public Guid? Child3DnaId { get; set; } + public Guid? Child4DnaId { get; set; } + public double? Amount { get; set; } + public double? PositionSalaryAmount { get; set; } + public string? Commander { get; set; } + + public Guid? CommanderId { get; set; } + + public Guid? CommanderKeycloak { get; set; } + + } + + public class GetProfileByKeycloakIdResultLocal + { + public string Message { get; set; } = string.Empty; + + public int Status { get; set; } = -1; + + public GetProfileByKeycloakIdLocal? Result { get; set; } + } } diff --git a/BMA.EHR.Leave/Program.cs b/BMA.EHR.Leave/Program.cs index ebe39458..bda6f614 100644 --- a/BMA.EHR.Leave/Program.cs +++ b/BMA.EHR.Leave/Program.cs @@ -162,7 +162,7 @@ app.UseStaticFiles(); app.MapControllers(); app.UseMiddleware(); // Disable ก่อน เพื่อแก้ไขให้เรีบร้อยก่อนการใช้งาน -// app.UseMiddleware(); +app.UseMiddleware(); app.UseHangfireDashboard("/hangfire", new DashboardOptions() diff --git a/BMA.EHR.Leave/appsettings.json b/BMA.EHR.Leave/appsettings.json index e5591a00..b5ad52fe 100644 --- a/BMA.EHR.Leave/appsettings.json +++ b/BMA.EHR.Leave/appsettings.json @@ -9,7 +9,9 @@ } }, "ElasticConfiguration": { - "Uri": "http://localhost:9200" + "Uri": "http://192.168.1.40:9200", + "IndexFormat": "bma-ehr-log-index", + "SystemName": "leave" }, "AllowedHosts": "*", "ConnectionStrings": {