using EVCB_OCPP.DBAPI.Services.DbService; using EVCB_OCPP.Domain.Models.MainDb; using ServiceStack; using ServiceStack.Redis; namespace EVCB_OCPP.DBAPI.Services.ServerMessageServices; public class RedisServerMessageService : IServerMessageService { private readonly IMainDbService mainDbService; private readonly IRedisClientsManager redisClientsManager; public RedisServerMessageService( IMainDbService mainDbService, IRedisClientsManager redisClientsManager ) { this.mainDbService = mainDbService; this.redisClientsManager = redisClientsManager; } public async Task AddServerMessage( string ChargeBoxId, string OutAction, string OutRequest, string CreatedBy, DateTime? CreatedOn = null, string SerialNo = "", string InMessage = "", CancellationToken token = default) { if (string.IsNullOrEmpty(SerialNo)) { SerialNo = Guid.NewGuid().ToString(); } var _CreatedOn = CreatedOn ?? DateTime.UtcNow; string _OutRequest = OutRequest is not null ? OutRequest : ""; var data = new ServerMessage() { ChargeBoxId = ChargeBoxId, CreatedBy = CreatedBy, CreatedOn = _CreatedOn, OutAction = OutAction, OutRequest = _OutRequest, SerialNo = SerialNo, InMessage = InMessage }; await StoreIntoRedis(data); return SerialNo; } public async Task> GetNeedSendToClientServerMessages() { var allServerMessage = await GetServerMessages(); DateTime startDt = DateTime.UtcNow.AddSeconds(-30); var seperatedServerMessage = allServerMessage.GroupBy(x => x.CreatedOn < startDt).ToDictionary(x => x.Key, x => x?.ToList()); var deprecatedServerMessage = seperatedServerMessage.GetValueOrDefault(true, null); if (deprecatedServerMessage is not null) { var deprecatedServerMessageIds = deprecatedServerMessage.Select(x => x.Id); await RemoveFromRedis(deprecatedServerMessageIds); foreach (var servermessage in deprecatedServerMessage) { _ = AddServerMessageToDbAsync(servermessage); } } return seperatedServerMessage.GetValueOrDefault(false, new List())!; } public async Task SetServerMessageResponseReceived(int id, string InMessage = "", DateTime ReceivedOn = default) { DateTime _ReceivedOn = ReceivedOn == default ? DateTime.UtcNow : ReceivedOn; IRedisClientAsync redisClient = await redisClientsManager.GetClientAsync(); var redisServerMessage = redisClient.As(); var msg = await redisServerMessage.GetByIdAsync(id); await redisServerMessage.DeleteByIdAsync(id); await redisClient.DisposeAsync(); msg.Id = 0; msg.InMessage = InMessage; msg.ReceivedOn = _ReceivedOn; var addServerMessageResult = await mainDbService.AddServerMessage(msg); return !string.IsNullOrEmpty(addServerMessageResult); } public async Task SetServerMessageServerHandling(int id, DateTime UpdatedOn = default) { DateTime _UpdatedOn = UpdatedOn == default ? DateTime.UtcNow : UpdatedOn; IRedisClientAsync redisClient = await redisClientsManager.GetClientAsync(); var redisServerMessage = redisClient.As(); var msg = await redisServerMessage.GetByIdAsync(id); msg.UpdatedOn = _UpdatedOn; await redisServerMessage.StoreAsync(msg); await redisClient.DisposeAsync(); return true; } public async Task> GetServerMessages() { IRedisClientAsync redisClient = await redisClientsManager.GetClientAsync(); var allMessages = await redisClient.As().GetAllAsync(); await redisClient.DisposeAsync(); return allMessages?.ToList(); } public Task SaveCompletedMessageToDb() { return Task.CompletedTask; } private async Task AddServerMessageToDbAsync(ServerMessage message) { var memMessageId = message.Id; var addServerMessageResult = await mainDbService.AddServerMessage(message); if (!string.IsNullOrEmpty(addServerMessageResult)) { return memMessageId; } return -1; } private async Task StoreIntoRedis(ServerMessage data) { await using IRedisClientAsync redisClient = await redisClientsManager.GetClientAsync(); var redisServerMessage = redisClient.As(); data.Id = (int)await redisServerMessage.GetNextSequenceAsync(); await redisServerMessage.StoreAsync(data); } private async Task RemoveFromRedis(int id) { await using IRedisClientAsync redisClient = await redisClientsManager.GetClientAsync(); var redisServerMessage = redisClient.As(); await redisServerMessage.DeleteByIdAsync(id); } private async Task RemoveFromRedis(IEnumerable ids) { await using IRedisClientAsync redisClient = await redisClientsManager.GetClientAsync(); var redisServerMessage = redisClient.As(); await redisServerMessage.DeleteByIdsAsync(ids); } }