using System; using System.Security.Cryptography; using System.Text; using System.Text.Json; using GB5Shared.DTO.Framework.CacheLogin; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using static GB5Shared.GB5Constant.Constant; namespace GB5Shared.DaprCache { public class CacheKeyGeneration { // ── Performance: static options — constructing JsonSerializerOptions is expensive. // A single shared instance is safe here because CacheLoginDTO / CriteriaDTO // have no custom converters that carry mutable state. private static readonly JsonSerializerOptions _jsonOptions = new() { WriteIndented = false, PropertyNamingPolicy = null, // preserve exact property names DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.Never }; public string KeyGeneration( object ObjectId, int ObjectTypeId, int CachingKeyLevel, LoginDTO LoginDTO, CriteriaDTO? CriteriaDTO = null) { if (CachingKeyLevel == CacheKeyLevel.NOT_REQUIRED) return "Null"; var CacheLoginDTO = new CacheLoginDTO(); if (CachingKeyLevel == CacheKeyLevel.OVERALL) { CacheLoginDTO.ServerId = -1; CacheLoginDTO.ClientId = -1; CacheLoginDTO.ServerConfigId = -1; CacheLoginDTO.UserId = -1; CacheLoginDTO.RoleId = -1; CacheLoginDTO.LoginEventLogId = -1; CacheLoginDTO.LanguageId = LoginDTO.LanguageId; } else if (CachingKeyLevel == CacheKeyLevel.DB_SERVER) { CacheLoginDTO.ServerId = LoginDTO.ServerId; CacheLoginDTO.ClientId = -1; CacheLoginDTO.ServerConfigId = -1; CacheLoginDTO.UserId = -1; CacheLoginDTO.RoleId = -1; CacheLoginDTO.LoginEventLogId = -1; CacheLoginDTO.LanguageId = LoginDTO.LanguageId; } else if (CachingKeyLevel == CacheKeyLevel.CLIENT_LEVEL) { CacheLoginDTO.ServerId = LoginDTO.ServerId; CacheLoginDTO.ServerConfigId = LoginDTO.ServerConfigId; CacheLoginDTO.ClientId = LoginDTO.ClientId; CacheLoginDTO.UserId = -1; CacheLoginDTO.RoleId = -1; CacheLoginDTO.LoginEventLogId = -1; CacheLoginDTO.LanguageId = LoginDTO.LanguageId; } else if (CachingKeyLevel == CacheKeyLevel.ROLE_LEVEL) { CacheLoginDTO.ServerId = LoginDTO.ServerId; CacheLoginDTO.ClientId = LoginDTO.ClientId; CacheLoginDTO.ServerConfigId = LoginDTO.ServerConfigId; CacheLoginDTO.RoleId = LoginDTO.RoleId; CacheLoginDTO.UserId = -1; CacheLoginDTO.LoginEventLogId = -1; CacheLoginDTO.LanguageId = LoginDTO.LanguageId; } else if (CachingKeyLevel == CacheKeyLevel.USER_LEVEL) { CacheLoginDTO.ServerId = LoginDTO.ServerId; CacheLoginDTO.ClientId = LoginDTO.ClientId; CacheLoginDTO.ServerConfigId = LoginDTO.ServerConfigId; CacheLoginDTO.RoleId = LoginDTO.RoleId; CacheLoginDTO.UserId = LoginDTO.UserId; CacheLoginDTO.LoginEventLogId = -1; CacheLoginDTO.LanguageId = LoginDTO.LanguageId; } else if (CachingKeyLevel == CacheKeyLevel.SESSION_LEVEL) { CacheLoginDTO.ServerId = LoginDTO.ServerId; CacheLoginDTO.ClientId = LoginDTO.ClientId; CacheLoginDTO.ServerConfigId = LoginDTO.ServerConfigId; CacheLoginDTO.RoleId = LoginDTO.RoleId; CacheLoginDTO.UserId = LoginDTO.UserId; CacheLoginDTO.LoginEventLogId = LoginDTO.LoginEventLogId; CacheLoginDTO.LanguageId = LoginDTO.LanguageId; } // System.Text.Json — no reflection overhead per call (options are shared static) string loginJson = JsonSerializer.Serialize(CacheLoginDTO, _jsonOptions); string dataToHash = CriteriaDTO is null ? $"{ObjectId}:{ObjectTypeId}:{loginJson}" : $"{ObjectId}:{ObjectTypeId}:{loginJson}:{JsonSerializer.Serialize(CriteriaDTO, _jsonOptions)}"; // SHA256.HashData — static method, allocates no SHA256 instance byte[] hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(dataToHash)); return Convert.ToBase64String(hashBytes); } } }