public void Set_And_Get_Should_Succeed() { var cacheKey = $"{_namespace}_{Guid.NewGuid().ToString()}"; hybridCaching_1.Set(cacheKey, "val", TimeSpan.FromSeconds(30)); var res = hybridCaching_1.Get <string>(cacheKey); Assert.Equal("val", res.Value); }
public void Add(string key, T value, TimeSpan ttl, string region) { var cacheKey = $"{region}:{key}"; if (!_options.EnableHybrid) { _provider.Set(cacheKey, value, ttl); } else { _hybridProvider.Set(cacheKey, value, ttl); } }
public ActionResult <string> Set() { // the same key for different value of _hybrid.Set("cacheKey", "val-from app1", TimeSpan.FromMinutes(1)); return("ok"); }
public string Get(string str) { var method = str.ToLower(); switch (method) { case "get": { var res = _provider.Get <string>("demo"); return($"cached value : {res}"); } case "getset": { var res = _provider.Get("demo", () => "1-456", TimeSpan.FromHours(1)); return($"cached value : {res}"); } case "set": _provider.Set("demo", "1-123", TimeSpan.FromHours(1)); return("seted"); case "remove": _provider.Remove("demo"); return("removed"); default: return("default"); } }
public void Set(string key, byte[] value, DistributedCacheEntryOptions options) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } var expiration = GetEasyCacheExpiration(options); _expirations.TryAdd(key, expiration); _hybridCachingProvider.Set(key, value, expiration); }
/// <summary> /// 保存token /// </summary> /// <param name="context"></param> /// <param name="next"></param> /// <returns></returns> private async Task SaveToken(HttpContext context, RequestDelegate next) { string responseContent; var originalBodyStream = context.Response.Body; using (var fakeResponseBody = new MemoryStream()) { context.Response.Body = fakeResponseBody; await next(context); fakeResponseBody.Seek(0, SeekOrigin.Begin); using (var reader = new StreamReader(fakeResponseBody)) { responseContent = await reader.ReadToEndAsync(); fakeResponseBody.Seek(0, SeekOrigin.Begin); await fakeResponseBody.CopyToAsync(originalBodyStream); } } if (StatusCodeChecker.Is2xx(context.Response.StatusCode)) { var tokenTxt = JObject.Parse(responseContent).GetValue("token")?.ToString(); if (tokenTxt.IsNullOrWhiteSpace()) { return; } //refreshTokenTxt = JObject.Parse(responseContent).GetValue("refreshToken").ToString(); var claimsInfo = GetClaimsInfo(tokenTxt); if (claimsInfo.Account.IsNotNullOrWhiteSpace()) { var tokenKey = $"{tokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; _cache.Set(tokenKey, claimsInfo.Token, claimsInfo.Expire - DateTime.Now); //var refreshTokenKey = $"{refreshTokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; //_cache.Set(refreshTokenKey, refreshTokenTxt, TimeSpan.FromSeconds(_jwtConfig.RefreshTokenExpire)); } } }
public string Get(int type = 1) { if (type == 1) { _provider.Remove("demo"); return("removed"); } else if (type == 2) { _provider.Set("demo", "123", TimeSpan.FromMinutes(1)); return("seted"); } else if (type == 3) { var res = _provider.Get("demo", () => "456", TimeSpan.FromMinutes(1)); return($"cached value : {res}"); } else { return("error"); } }
/// <summary> /// Proceeds the able. /// </summary> /// <param name="invocation">Invocation.</param> private void ProceedAble(IInvocation invocation) { var serviceMethod = invocation.Method ?? invocation.MethodInvocationTarget; if (GetMethodAttributes(serviceMethod).FirstOrDefault(x => typeof(EasyCachingAbleAttribute).IsAssignableFrom(x.GetType())) is EasyCachingAbleAttribute attribute) { var returnType = serviceMethod.IsReturnTask() ? serviceMethod.ReturnType.GetGenericArguments().First() : serviceMethod.ReturnType; var cacheKey = string.IsNullOrEmpty(attribute.CacheKey) ? _keyGenerator.GetCacheKey(serviceMethod, invocation.Arguments, attribute.CacheKeyPrefix) : attribute.CacheKey; object cacheValue = null; var isAvailable = true; try { if (attribute.IsHybridProvider) { cacheValue = _hybridCachingProvider.GetAsync(cacheKey, returnType).GetAwaiter().GetResult(); } else { var _cacheProvider = _cacheProviderFactory.GetCachingProvider(attribute.CacheProviderName ?? _options.Value.CacheProviderName); cacheValue = _cacheProvider.GetAsync(cacheKey, returnType).GetAwaiter().GetResult(); } } catch (Exception ex) { if (!attribute.IsHighAvailability) { throw; } else { isAvailable = false; _logger?.LogError(new EventId(), ex, $"Cache provider get error."); } } if (cacheValue != null) { if (serviceMethod.IsReturnTask()) { invocation.ReturnValue = TypeofTaskResultMethod.GetOrAdd(returnType, t => typeof(Task).GetMethods().First(p => p.Name == "FromResult" && p.ContainsGenericParameters).MakeGenericMethod(returnType)).Invoke(null, new object[] { cacheValue }); } else { invocation.ReturnValue = cacheValue; } } else { // Invoke the method if we don't have a cache hit invocation.Proceed(); if (!string.IsNullOrWhiteSpace(cacheKey) && invocation.ReturnValue != null && isAvailable) { // get the result var returnValue = serviceMethod.IsReturnTask() ? invocation.UnwrapAsyncReturnValue().Result : invocation.ReturnValue; // should we do something when method return null? // 1. cached a null value for a short time // 2. do nothing if (returnValue != null) { if (attribute.IsHybridProvider) { _hybridCachingProvider.Set(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } else { var _cacheProvider = _cacheProviderFactory.GetCachingProvider(attribute.CacheProviderName ?? _options.Value.CacheProviderName); _cacheProvider.Set(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } } } } } else { // Invoke the method if we don't have EasyCachingAbleAttribute invocation.Proceed(); } }
public async Task Invoke(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var endpoint = context.GetEndpoint(); if (endpoint == null) { await _next(context); return; } var requiredValues = ((RouteEndpoint)endpoint).RoutePattern.RequiredValues; if (requiredValues.Count() == 0) { await _next(context); return; } var controller = requiredValues["controller"]?.ToString(); var action = requiredValues["action"]?.ToString(); if (string.IsNullOrEmpty(controller)) { await _next(context); return; } string tokenTxt = string.Empty; string refreshTokenTxt = string.Empty; //读取Request //context.Request.EnableBuffering(); //var requestReader = new StreamReader(context.Request.Body); //var requestContent = requestReader.ReadToEnd(); //context.Request.Body.Position = 0; // Allow Anonymous skips all authorization if (endpoint?.Metadata.GetMetadata <IAllowAnonymous>() != null) { //如果是调用登陆API并且调用成功,需要保存accesstoken道cache if (string.Equals(controller, "account", StringComparison.InvariantCultureIgnoreCase) && (string.Equals(action, "login", StringComparison.InvariantCultureIgnoreCase) || string.Equals(action, "refreshaccesstoken", StringComparison.InvariantCultureIgnoreCase)) ) { string responseContent; var originalBodyStream = context.Response.Body; using (var fakeResponseBody = new MemoryStream()) { context.Response.Body = fakeResponseBody; await _next(context); fakeResponseBody.Seek(0, SeekOrigin.Begin); using (var reader = new StreamReader(fakeResponseBody)) { responseContent = await reader.ReadToEndAsync(); fakeResponseBody.Seek(0, SeekOrigin.Begin); await fakeResponseBody.CopyToAsync(originalBodyStream); } } if (context.Response.StatusCode == 200) { tokenTxt = JObject.Parse(responseContent).GetValue("token").ToString(); refreshTokenTxt = JObject.Parse(responseContent).GetValue("refreshToken").ToString(); var claimsInfo = GetClaimsInfo(tokenTxt); if (!string.IsNullOrEmpty(claimsInfo.Account)) { var key = $"{tokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; //_cache.SetString(key, claimsInfo.Token, new DistributedCacheEntryOptions { AbsoluteExpiration = claimsInfo.Expire }); _cache.Set(key, claimsInfo.Token, claimsInfo.Expire - DateTime.Now); var refreshTokenKey = $"{refreshTokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; //_cache.SetString(refreshTokenKey, refreshTokenTxt, new DistributedCacheEntryOptions { AbsoluteExpiration = DateTime.Now.AddMinutes(_jwtConfig.RefreshTokenExpire) }); _cache.Set(refreshTokenKey, refreshTokenTxt, TimeSpan.FromSeconds(_jwtConfig.RefreshTokenExpire)); } } } return; } tokenTxt = await context.GetTokenAsync("access_token"); //如果是调用注销API并且调用成功,需要从cahce移除accesstoken if (string.Equals(controller, "account", StringComparison.InvariantCultureIgnoreCase) && string.Equals(action, "logout", StringComparison.InvariantCultureIgnoreCase)) { await _next(context); if (context.Response.StatusCode == 200) { var claimsInfo = GetClaimsInfo(tokenTxt); if (!string.IsNullOrEmpty(claimsInfo.Account)) { var key = $"{tokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; var refreshTokenKey = $"{refreshTokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; //可以考虑事务操作,以后再优化 _cache.Remove(key); _cache.Remove(refreshTokenKey); } } return; } //如果是其他需要授权的API并且调用成功,需要从检查accesstoken是否在缓存中。 if (context.Response.StatusCode == 200) { var claimsInfo = GetClaimsInfo(tokenTxt); if (!string.IsNullOrEmpty(claimsInfo.Account)) { var key = $"{tokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; //var cahceToken = _cache.GetString(key); var cahceToken = _cache.Get <string>(key).Value; if (cahceToken != claimsInfo.Token) { await context.ForbidAsync(); } else { await _next(context); } } return; } }
public ActionResult <string> Set() { _hybrid.Set("cacheKey", "val--from app2", TimeSpan.FromMinutes(1)); return("ok"); }