fix issue : ระบบลงเวลาต้องมีการเช็คสถานะใน rabbitMQ ด้วยว่ามีการรอรันอยู่ไหม ลงเวลาเข้า/ออกงาน #894
Some checks failed
release-dev / release-dev (push) Failing after 12s

This commit is contained in:
Suphonchai Phoonsawat 2025-01-27 13:32:57 +07:00
parent 7d4642a2f3
commit 7d88493a54
3 changed files with 175 additions and 25 deletions

View file

@ -20,10 +20,12 @@ using Microsoft.Extensions.ObjectPool;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Swashbuckle.AspNetCore.Annotations;
using System.ComponentModel.DataAnnotations;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using SearchProfileResultDto = BMA.EHR.Leave.Service.DTOs.ChangeRound.SearchProfileResultDto;
namespace BMA.EHR.Leave.Service.Controllers
@ -63,6 +65,8 @@ namespace BMA.EHR.Leave.Service.Controllers
private readonly string _fakeCheckInQueue = "fake-bma-checkin-queue";
private readonly string _realCheckInQueue = "bma-checkin-queue";
private readonly HttpClient _httpClient;
#endregion
#region " Constuctor and Destructor "
@ -83,7 +87,8 @@ namespace BMA.EHR.Leave.Service.Controllers
LeaveRequestRepository leaveRequestRepository,
ObjectPool<IModel> objectPool,
PermissionRepository permission,
NotificationRepository notificationRepository)
NotificationRepository notificationRepository,
HttpClient httpClient)
{
_dutyTimeRepository = dutyTimeRepository;
_context = context;
@ -103,6 +108,13 @@ namespace BMA.EHR.Leave.Service.Controllers
_objectPool = objectPool;
_permission = permission;
_httpClient = httpClient;
var authString = $"{_configuration["Rabbit:User"] ?? ""}:{_configuration["Rabbit:Password"] ?? ""}";
var authToken = Convert.ToBase64String(Encoding.ASCII.GetBytes(authString));
_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authToken);
}
#endregion
@ -446,7 +458,7 @@ namespace BMA.EHR.Leave.Service.Controllers
CheckInTime = null,
CheckInId = null,
};
}
}
}
else
{
@ -522,41 +534,97 @@ namespace BMA.EHR.Leave.Service.Controllers
var serializedObject = JsonConvert.SerializeObject(checkData);
var body = Encoding.UTF8.GetBytes(serializedObject);
// add task id for check in queue
string taskId = Guid.NewGuid().ToString();
var properties = channel.CreateBasicProperties();
properties.Persistent = true;
properties.MessageId = taskId; // แนบ Message ID เพื่อใช้ตรวจสอบ
channel.BasicPublish(exchange: "",
routingKey: queue,
basicProperties: null,
basicProperties: properties,
body: body);
return Success(new { date = currentDate });
return Success(new { date = currentDate, taskId = taskId });
}
finally
{
_objectPool.Return(channel);
}
}
//// create connection
//var factory = new ConnectionFactory()
//{
// HostName = _configuration["Rabbit:Host"],
// UserName = _configuration["Rabbit:User"],
// Password = _configuration["Rabbit:Password"],
//};
[HttpGet("check-status/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[AllowAnonymous]
public async Task<ActionResult<ResponseObject>> CheckInCheckStatus(Guid id)
{
var currentDate = DateTime.Now;
var channel = _objectPool.Get();
try
{
var _url = _configuration["Rabbit:URL"] ?? "";
var _queue = _configuration["Rabbit:Queue"] ?? "basic-queue";
//// create channel
//using var connection = factory.CreateConnection();
//using var channel = connection.CreateModel();
//channel.QueueDeclare(queue: "checkin-queue", durable: false, exclusive: false, autoDelete: false, arguments: null);
// Step 1: ตรวจสอบจำนวน message ทั้งหมดในคิว
string queueUrl = $"{_url}{_queue}";
var queueResponse = await _httpClient.GetAsync(queueUrl);
if (!queueResponse.IsSuccessStatusCode)
{
return Error("Error accessing RabbitMQ API", (int)queueResponse.StatusCode);
}
//// แปลง Object เป็น JSON สตริง
//var serializedObject = JsonConvert.SerializeObject(checkData);
var queueContent = await queueResponse.Content.ReadAsStringAsync();
var queueData = JObject.Parse(queueContent);
int totalMessages = queueData["messages"]?.Value<int>() ?? 0;
//// แปลง JSON สตริงเป็น byte array
//var body = Encoding.UTF8.GetBytes(serializedObject);
// Step 2: วนลูปดึง message ทีละ 100 งาน
int batchSize = 100;
var allMessages = new List<string>();
int processedMessages = 0;
//channel.BasicPublish(exchange: "", routingKey: "checkin-queue", basicProperties: null, body: body);
//Console.WriteLine($"Send to Queue: {serializedObject}");
while (processedMessages < totalMessages)
{
var requestBody = new StringContent(
$"{{\"count\":{batchSize},\"requeue\":true,\"encoding\":\"auto\",\"ackmode\":\"ack_requeue_true\"}}",
Encoding.UTF8,
"application/json"
);
//return Success(new { date = currentDate });
string getMessagesUrl = $"{_url}{_queue}/get";
var response = await _httpClient.PostAsync(getMessagesUrl, requestBody);
if (!response.IsSuccessStatusCode)
{
return StatusCode((int)response.StatusCode, "Error retrieving messages from RabbitMQ.");
}
var content = await response.Content.ReadAsStringAsync();
var messages = JArray.Parse(content);
if (messages.Count == 0)
{
break;
}
processedMessages += messages.Count;
allMessages.AddRange(messages.Select(m => m["properties"].ToString()));
}
// Step 3: ค้นหา taskIds ที่อยู่ใน messages ทั้งหมด
var foundTasks = allMessages.FirstOrDefault(x => x.Contains(id.ToString("D")));
return Success(new { taskId = id, InQueue = foundTasks != null });
}
catch (Exception ex)
{
return Error(ex, ex.Message);
}
finally
{
_objectPool.Return(channel);
}
}
/// <summary>
@ -580,16 +648,95 @@ namespace BMA.EHR.Leave.Service.Controllers
{
channel.QueueDeclare(queue: _fakeCheckInQueue, durable: true, exclusive: false, autoDelete: false, arguments: null);
// Create Task ID
string taskId = Guid.NewGuid().ToString();
var properties = channel.CreateBasicProperties();
properties.Persistent = true;
properties.MessageId = taskId; // แนบ Message ID เพื่อใช้ตรวจสอบ
var serializedObject = JsonConvert.SerializeObject(data);
var body = Encoding.UTF8.GetBytes(serializedObject);
channel.BasicPublish(exchange: "",
routingKey: _fakeCheckInQueue,
basicProperties: null,
basicProperties: properties,
body: body);
return Success(new { date = currentDate });
return Success(new { date = currentDate, taskId = taskId });
}
finally
{
_objectPool.Return(channel);
}
}
[HttpGet("fake-check-status/{id:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[AllowAnonymous]
public async Task<ActionResult<ResponseObject>> FakeCheckInCheckStatus(Guid id)
{
var currentDate = DateTime.Now;
var channel = _objectPool.Get();
try
{
var _url = _configuration["Rabbit:URL"] ?? "";
// Step 1: ตรวจสอบจำนวน message ทั้งหมดในคิว
string queueUrl = $"{_url}{_fakeCheckInQueue}";
var queueResponse = await _httpClient.GetAsync(queueUrl);
if (!queueResponse.IsSuccessStatusCode)
{
return Error("Error accessing RabbitMQ API", (int)queueResponse.StatusCode);
}
var queueContent = await queueResponse.Content.ReadAsStringAsync();
var queueData = JObject.Parse(queueContent);
int totalMessages = queueData["messages"]?.Value<int>() ?? 0;
// Step 2: วนลูปดึง message ทีละ 100 งาน
int batchSize = 100;
var allMessages = new List<string>();
int processedMessages = 0;
while (processedMessages < totalMessages)
{
var requestBody = new StringContent(
$"{{\"count\":{batchSize},\"requeue\":true,\"encoding\":\"auto\",\"ackmode\":\"ack_requeue_true\"}}",
Encoding.UTF8,
"application/json"
);
string getMessagesUrl = $"{_url}{_fakeCheckInQueue}/get";
var response = await _httpClient.PostAsync(getMessagesUrl, requestBody);
if (!response.IsSuccessStatusCode)
{
return StatusCode((int)response.StatusCode, "Error retrieving messages from RabbitMQ.");
}
var content = await response.Content.ReadAsStringAsync();
var messages = JArray.Parse(content);
if (messages.Count == 0)
{
break;
}
processedMessages += messages.Count;
allMessages.AddRange(messages.Select(m => m["properties"].ToString()));
}
// Step 3: ค้นหา taskIds ที่อยู่ใน messages ทั้งหมด
var foundTasks = allMessages.FirstOrDefault(x => x.Contains(id.ToString("D")));
return Success(new { taskId = id, InQueue = foundTasks != null });
}
catch (Exception ex)
{
return Error(ex, ex.Message);
}
finally
{

View file

@ -90,6 +90,8 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddPersistence(builder.Configuration);
builder.Services.AddLeavePersistence(builder.Configuration);
builder.Services.AddHttpClient();
builder.Services.AddControllers(options =>
{
options.SuppressAsyncSuffixInActionNames = false;

View file

@ -45,7 +45,8 @@
"Host": "192.168.1.40",
"User": "admin",
"Password": "Test123456",
"Queue": "bma-checkin-queue"
"Queue": "bma-checkin-queue",
"URL": "https://edm-mq.frappet.synology.me/api/queues/%2F/"
},
"Mail": {
"Server": "mail.bangkok.go.th",