103 lines
3.2 KiB
C#
103 lines
3.2 KiB
C#
using System.Text.Json;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using SPMS.Application.Interfaces;
|
|
using SPMS.Application.Settings;
|
|
using StackExchange.Redis;
|
|
|
|
namespace SPMS.Infrastructure.Caching;
|
|
|
|
public class TokenCacheService : ITokenCacheService
|
|
{
|
|
private readonly RedisConnection _redis;
|
|
private readonly RedisSettings _settings;
|
|
private readonly ILogger<TokenCacheService> _logger;
|
|
|
|
private static readonly TimeSpan CacheTtl = TimeSpan.FromHours(1);
|
|
|
|
public TokenCacheService(
|
|
RedisConnection redis,
|
|
IOptions<RedisSettings> settings,
|
|
ILogger<TokenCacheService> logger)
|
|
{
|
|
_redis = redis;
|
|
_settings = settings.Value;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<CachedDeviceInfo?> GetDeviceInfoAsync(long serviceId, string deviceId)
|
|
{
|
|
try
|
|
{
|
|
var db = await _redis.GetDatabaseAsync();
|
|
var value = await db.StringGetAsync(BuildKey(serviceId, deviceId));
|
|
|
|
if (value.IsNullOrEmpty)
|
|
return null;
|
|
|
|
return JsonSerializer.Deserialize<CachedDeviceInfo>(value!);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "토큰 캐시 조회 실패: serviceId={ServiceId}, deviceId={DeviceId}",
|
|
serviceId, deviceId);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task SetDeviceInfoAsync(long serviceId, string deviceId, CachedDeviceInfo info)
|
|
{
|
|
try
|
|
{
|
|
var db = await _redis.GetDatabaseAsync();
|
|
var json = JsonSerializer.Serialize(info);
|
|
await db.StringSetAsync(BuildKey(serviceId, deviceId), json, CacheTtl);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "토큰 캐시 저장 실패: serviceId={ServiceId}, deviceId={DeviceId}",
|
|
serviceId, deviceId);
|
|
}
|
|
}
|
|
|
|
public async Task InvalidateAsync(long serviceId, string deviceId)
|
|
{
|
|
try
|
|
{
|
|
var db = await _redis.GetDatabaseAsync();
|
|
await db.KeyDeleteAsync(BuildKey(serviceId, deviceId));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "토큰 캐시 무효화 실패: serviceId={ServiceId}, deviceId={DeviceId}",
|
|
serviceId, deviceId);
|
|
}
|
|
}
|
|
|
|
public async Task InvalidateByServiceAsync(long serviceId)
|
|
{
|
|
try
|
|
{
|
|
var db = await _redis.GetDatabaseAsync();
|
|
var server = _redis.GetServer();
|
|
if (server == null) return;
|
|
|
|
var pattern = $"{_settings.InstanceName}device:token:{serviceId}:*";
|
|
var keys = server.Keys(pattern: pattern).ToArray();
|
|
|
|
if (keys.Length > 0)
|
|
await db.KeyDeleteAsync(keys);
|
|
|
|
_logger.LogInformation("서비스 토큰 캐시 전체 무효화: serviceId={ServiceId}, 삭제={Count}건",
|
|
serviceId, keys.Length);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "서비스 토큰 캐시 전체 무효화 실패: serviceId={ServiceId}", serviceId);
|
|
}
|
|
}
|
|
|
|
private string BuildKey(long serviceId, string deviceId) =>
|
|
$"{_settings.InstanceName}device:token:{serviceId}:{deviceId}";
|
|
}
|