MemDbServerMessageService.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using Dapper;
  2. using EVCB_OCPP.DBAPI.ConnectionFactory;
  3. using EVCB_OCPP.DBAPI.Models.DBContext;
  4. using EVCB_OCPP.DBAPI.Services.DbService;
  5. using EVCB_OCPP.Domain.Models.MainDb;
  6. using Microsoft.Data.Sqlite;
  7. using Newtonsoft.Json;
  8. using System.Data;
  9. namespace EVCB_OCPP.DBAPI.Services.ServerMessageServices;
  10. public class MemDbServerMessageService : IServerMessageService
  11. {
  12. public MemDbServerMessageService(
  13. ISqliteConnectionConnectionFactory<MemDBContext> memDbConnectionFactory,
  14. IMainDbService mainDbService,
  15. ILogger<MemDbServerMessageService> logger)
  16. {
  17. this.memDbConnectionFactory = memDbConnectionFactory;
  18. this.mainDbService = mainDbService;
  19. this.logger = logger;
  20. }
  21. private readonly ISqliteConnectionConnectionFactory<MemDBContext> memDbConnectionFactory;
  22. private readonly IMainDbService mainDbService;
  23. private readonly ILogger<MemDbServerMessageService> logger;
  24. public async Task<string> AddServerMessage(
  25. string ChargeBoxId,
  26. string OutAction,
  27. string OutRequest,
  28. string CreatedBy,
  29. DateTime? CreatedOn = null,
  30. string SerialNo = "",
  31. string InMessage = "",
  32. CancellationToken token = default)
  33. {
  34. if (string.IsNullOrEmpty(SerialNo))
  35. {
  36. SerialNo = Guid.NewGuid().ToString();
  37. }
  38. var _CreatedOn = CreatedOn ?? DateTime.UtcNow;
  39. string _OutRequest = OutRequest is not null ? OutRequest : "";
  40. var data = new ServerMessage()
  41. {
  42. ChargeBoxId = ChargeBoxId,
  43. CreatedBy = CreatedBy,
  44. CreatedOn = _CreatedOn,
  45. OutAction = OutAction,
  46. OutRequest = _OutRequest,
  47. SerialNo = SerialNo,
  48. InMessage = InMessage
  49. };
  50. await AddServerMessage(data, token: token);
  51. return SerialNo;
  52. }
  53. public async Task<List<ServerMessage>> GetNeedSendToClientServerMessages()
  54. {
  55. DateTime dt = new DateTime(1991, 1, 1);
  56. DateTime dateTimeNow = DateTime.UtcNow;
  57. DateTime startDt = dateTimeNow.AddSeconds(-30);
  58. var parms = new DynamicParameters();
  59. parms.Add("ReceivedOn", dt);
  60. parms.Add("UpdatedOn", dt);
  61. parms.Add("CreatedOnStart", startDt);
  62. parms.Add("CreatedOnEnd", dateTimeNow);
  63. var cmd = """
  64. SELECT * FROM ServerMessage
  65. WHERE
  66. ReceivedOn = @ReceivedOn and
  67. UpdatedOn = @UpdatedOn and
  68. CreatedOn >= @CreatedOnStart and
  69. CreatedOn <= @CreatedOnEnd
  70. """;
  71. using var connection = await memDbConnectionFactory.CreateAsync();
  72. var datas = await connection.QueryAsync<ServerMessage>(cmd, parms);
  73. return datas.ToList();
  74. }
  75. public async Task<bool> SetServerMessageResponseReceived(int id, string InMessage = "", DateTime ReceivedOn = default)
  76. {
  77. DateTime _ReceivedOn = ReceivedOn == default ? DateTime.UtcNow : ReceivedOn;
  78. var parms = new DynamicParameters();
  79. parms.Add("Id", id);
  80. parms.Add("InMessage", InMessage);
  81. parms.Add("ReceivedOn", _ReceivedOn);
  82. var cmd = """
  83. UPDATE ServerMessage
  84. SET InMessage = @InMessage , ReceivedOn = @ReceivedOn
  85. WHERE Id = @Id
  86. """;
  87. using var connection = await memDbConnectionFactory.CreateAsync();
  88. var cnts = await connection.ExecuteAsync(cmd, parms);
  89. var success = cnts > 0;
  90. if (!success)
  91. {
  92. logger.LogError("SetServerMessageResponseReceived failed {msg}", InMessage);
  93. }
  94. return success;
  95. }
  96. public async Task<bool> SetServerMessageServerHandling(int id, DateTime UpdatedOn = default)
  97. {
  98. DateTime _UpdatedOn = UpdatedOn == default ? DateTime.UtcNow : UpdatedOn;
  99. var parms = new DynamicParameters();
  100. parms.Add("Id", id);
  101. parms.Add("UpdatedOn", _UpdatedOn);
  102. var cmd = """
  103. UPDATE ServerMessage
  104. SET UpdatedOn = @UpdatedOn
  105. WHERE Id = @Id
  106. """;
  107. using var connection = await memDbConnectionFactory.CreateAsync();
  108. var cnts = await connection.ExecuteAsync(cmd, parms);
  109. var success = cnts > 0;
  110. if (!success)
  111. {
  112. logger.LogError("SetServerMessageServerHandling failed {msgid}", id);
  113. }
  114. return success;
  115. }
  116. public async Task<List<ServerMessage>> GetServerMessages()
  117. {
  118. string cmd = """
  119. SELECT * FROM ServerMessage
  120. """;
  121. using var connection = await memDbConnectionFactory.CreateAsync();
  122. var datas = await connection.QueryAsync<ServerMessage>(cmd);
  123. return datas.ToList();
  124. }
  125. public static async Task IinitMemDbAsync(SqliteConnection connection)
  126. {
  127. var createTableResult = await connection.ExecuteAsync("""
  128. CREATE TABLE IF NOT EXISTS ServerMessage (
  129. Id INTEGER PRIMARY KEY NOT NULL,
  130. SerialNo VARCHAR(36),
  131. OutAction VARCHAR(30),
  132. OutRequest TEXT,
  133. InMessage TEXT,
  134. CreatedOn DATE TIME NOT NULL,
  135. CreatedBy VARCHAR(36),
  136. ReceivedOn DATE TIME NOT NULL,
  137. ChargeBoxId VARCHAR(50),
  138. UpdatedOn DATE TIME NOT NULL
  139. )
  140. """);
  141. }
  142. public async Task SaveCompletedMessageToDb()
  143. {
  144. List<ServerMessage> completedMessages = await GetCompletedServerMessageFromMemDb();
  145. List<Task<int>> addServerMessageTasks = new List<Task<int>>();
  146. foreach (var msg in completedMessages)
  147. {
  148. addServerMessageTasks.Add(AsyncAddServerMessage(msg));
  149. }
  150. await Task.WhenAll(addServerMessageTasks);
  151. var addedServerMessageId = addServerMessageTasks.Select(x => x.Result).Where(x => x > 0).ToList();
  152. var removeResult = await RmoveSavedServerMessageFromMemDb(addedServerMessageId);
  153. }
  154. private async Task<int> AsyncAddServerMessage(ServerMessage message)
  155. {
  156. var memMessageId = message.Id;
  157. var addServerMessageResult = await mainDbService.AddServerMessage(message);
  158. if (!string.IsNullOrEmpty(addServerMessageResult))
  159. {
  160. return memMessageId;
  161. }
  162. return -1;
  163. }
  164. private Task<string> AddServerMessage(ServerMessage message, CancellationToken token = default)
  165. {
  166. return AddServerMessageDapper(message);
  167. }
  168. private async Task<string> AddServerMessageDapper(ServerMessage message)
  169. {
  170. var parameters = new DynamicParameters();
  171. parameters.Add("@SerialNo", message.SerialNo, DbType.String, ParameterDirection.Input, 36);
  172. parameters.Add("@OutAction", message.OutAction, DbType.String, ParameterDirection.Input, 30);
  173. parameters.Add("@OutRequest", message.OutRequest, DbType.String, ParameterDirection.Input);
  174. parameters.Add("@InMessage", message.InMessage, DbType.String, ParameterDirection.Input);
  175. parameters.Add("@CreatedOn", message.CreatedOn, DbType.DateTime, ParameterDirection.Input);
  176. parameters.Add("@CreatedBy", message.CreatedBy, DbType.String, ParameterDirection.Input, 36);
  177. parameters.Add("@ReceivedOn", message.ReceivedOn, DbType.DateTime, ParameterDirection.Input);
  178. parameters.Add("@ChargeBoxId", message.ChargeBoxId, DbType.String, ParameterDirection.Input, 30);
  179. parameters.Add("@UpdatedOn", message.UpdatedOn, DbType.DateTime, ParameterDirection.Input);
  180. using var conn = await memDbConnectionFactory.CreateAsync();
  181. var resultCnt = await conn.ExecuteAsync("""
  182. INSERT INTO ServerMessage
  183. (SerialNo, OutAction, OutRequest, InMessage, CreatedOn, CreatedBy, ReceivedOn, ChargeBoxId, UpdatedOn)
  184. VALUES (@SerialNo, @OutAction, @OutRequest, @InMessage, @CreatedOn, @CreatedBy, @ReceivedOn, @ChargeBoxId, @UpdatedOn)
  185. """, parameters);
  186. if (resultCnt != 1)
  187. {
  188. logger.LogError("AddServerMessageDapper failed msg:{msg}", JsonConvert.SerializeObject(message));
  189. return string.Empty;
  190. }
  191. return message.SerialNo;
  192. }
  193. private async Task<List<ServerMessage>> GetCompletedServerMessageFromMemDb()
  194. {
  195. DateTime dateTimeNow = DateTime.UtcNow;
  196. DateTime startDt = dateTimeNow.AddSeconds(-30);
  197. DateTime dt = new DateTime(1991, 1, 1);
  198. var cmd = """
  199. SELECT * FROM ServerMessage
  200. WHERE ReceivedOn != @NullDateTime or CreatedOn < @CreatedOnStart
  201. """;
  202. var parm = new DynamicParameters();
  203. parm.Add("NullDateTime", dt);
  204. parm.Add("CreatedOnStart", startDt);
  205. using var connection = await memDbConnectionFactory.CreateAsync();
  206. var datas = await connection.QueryAsync<ServerMessage>(cmd, parm);
  207. return datas.ToList();
  208. }
  209. private async Task<bool> RmoveSavedServerMessageFromMemDb(List<int> ids)
  210. {
  211. var cmd = """
  212. DELETE FROM ServerMessage
  213. WHERE Id in @Ids
  214. """;
  215. var parm = new DynamicParameters();
  216. parm.Add("Ids", ids);
  217. using var connection = await memDbConnectionFactory.CreateAsync();
  218. var datasCnt = await connection.ExecuteAsync(cmd, parm);
  219. var success = datasCnt == ids.Count;
  220. if (!success)
  221. {
  222. logger.LogError("RmoveSavedServerMessageFromMemDb failed {ids}", JsonConvert.SerializeObject(ids));
  223. }
  224. return datasCnt == ids.Count;
  225. }
  226. }