Esempio n. 1
0
        /// <summary> Refresh cache by key, TODO: temp</summary>
        public async Task RefreshCacheAsync(string cacheKey = null)
        {
            //using var scope = GeneralContext.CreateServiceScope();
            if (GeneralContext.ServiceScope != null)
            {
                try
                {
                    var cacheItems = this.GetCacheItems <ApiCacheItem>();
                    if (cacheKey != null)
                    {
                        cacheItems = cacheItems.Where(x => x.Key == cacheKey).ToDictionary(k => k.Key, v => v.Value);
                    }

                    CRPMContext dbContext = GeneralContext.ServiceScope.ServiceProvider.GetService <CRPMContext>();

                    var items = cacheItems.Where(x => x.Value?.Query.ToUpper().Contains("SELECT") ?? false);
                    foreach (var item in items)
                    {
                        using var conn = dbContext.Database.GetDbConnection();

                        if (conn.State.Equals(ConnectionState.Closed))
                        {
                            conn.Open();
                        }
                        using var command   = conn.CreateCommand();
                        command.CommandText = item.Value.Query;

                        //var result = command.ExecuteNonQuery();
                        //var result = dbContext.Database.ExecuteSqlRaw(item.Value.Query);

                        var result = dbContext.Set <User>()
                                     .FromSqlRaw <User>(item.Value.Query)
                                     .ToList();

                        var l = dbContext.User.Local;

                        var list = dbContext.GetTrackEntries <User>();

                        using var db = new NpgsqlConnection(conn.ConnectionString);
                        var result1 = db.Query <User>(item.Value.Query);

                        //using var cmd = new NpgsqlCommand(item.Value.Query, con);
                        //cmd.q

                        var cacheItem = new ApiCacheItem(result, true, true, item.ToString());
                        await _cache.SetAsync(item.Key, Util.ConvertObjectToByteArray(cacheItem));

                        //var encodedData = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(data));
                        //await _cache.SetAsync(cacheKey, encodedData, new DistributedCacheEntryOptions());

                        _logger.LogInformation("{cacheKey} cache refreshed", item.Key);
                    }
                }
                catch (System.Exception ex)
                {
                    GeneralContext.Logger.Error(ex.GetApiMessageInfo());
                }
            }
        }
Esempio n. 2
0
        public static ApiCacheItem Get(ApiInputHandler input)
        {
            ApiCacheItem item = cache.Where(x => x.Resource == input.Resource && x.Payload == input.Body).FirstOrDefault();

            if (item == null)
            {
                return(null);
            }

            if (DateTime.Now.Subtract(item.Created).TotalMilliseconds > lifetimeMS)
            {
                lock (LOCK)
                {
                    if (cache.Contains(item))
                    {
                        cache.Remove(item);
                    }
                }

                return(null);
            }

            return(item);
        }
Esempio n. 3
0
        private ApiHandlerOutput Process(ApiInputHandler input)
        {
            string typeName = Business.Resource.GetType(input.Resource);

            if (string.IsNullOrWhiteSpace(typeName))
            {
                throw new ApiNotFoundException(input.Resource);
            }

            bool canAccess = Business.Authorization.CanAccess(input.Resource, Context.Current.User);

            if (!canAccess)
            {
                logger.Warn($"Access denied for resource {input.Resource}");

                throw new SecurityException(Messages.AccessDenied);
            }

            if (Business.Authorization.RequireToken(input.Resource))
            {
                string token = input.Context.Request.Headers["ZestyApiToken"];

                if (string.IsNullOrWhiteSpace(token))
                {
                    token = input.Context.Request.Query["t"];
                }

                if (!Business.Authorization.IsValid(Context.Current.User.Id, input.Context.Session.Id, token))
                {
                    logger.Warn($"Invalid token for resource {input.Resource}");

                    throw new SecurityException(Messages.TokenMissing);
                }
            }

            ApiCacheItem cacheItem = ApiCache.Get(input);

            if (cacheItem != null)
            {
                logger.Info($"Output found in cache for request {input.Resource}");

                return(cacheItem.Output);
            }
            else
            {
                ApiHandlerBase handler = InstanceHelper.Create <ApiHandlerBase>(typeName);

                ApiHandlerOutput output = handler.Process(input);

                if (output.CachePolicy == ApiCachePolicy.Enable)
                {
                    cacheItem = new ApiCacheItem
                    {
                        Created  = DateTime.Now,
                        Output   = output,
                        Payload  = input.Body,
                        Resource = input.Resource
                    };

                    ApiCache.Store(cacheItem);

                    logger.Info($"Output stored in cache for request {input.Resource}");
                }


                if (output.ResourceHistoryOutput != null && output.ResourceHistoryOutput.ResourceHistoryPolicy == ApiResourceHistoryPolicy.Save)
                {
                    Business.History.Save(output.ResourceHistoryOutput.Item);
                }

                return(output);
            }
        }
Esempio n. 4
0
        /// <summary> Set cache</summary>
        public Task SetAsync(string key, string query, object data, bool scoped = true, bool preLoad = true)
        {
            var item = new ApiCacheItem(data, preLoad, scoped, query);

            return(_cache.SetAsync(key.ToLower(), Util.ConvertObjectToByteArray(item)));
        }
Esempio n. 5
0
 public ValueTask WriteAsync(ApiCacheItem item, CancellationToken stoppingToken = default)
 {
     return(_channelWriter.WriteAsync(item, stoppingToken));
 }
Esempio n. 6
0
        /// <summary> Preload data and set cache, TODO: not complete </summary>
        public async Task <bool> PreloadAsync(IServiceProvider serviceProvider)
        {
            this.CacheLoaded = true;

            try
            {
                // get controllers typeOf(ControllerBaseAction), that its have metods with attributes typeOf(ApiCacheAttribute)
                var controllerTypes = Assembly.GetEntryAssembly().ExportedTypes
                                      .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(ControllerBaseAction)))
                                      .Where(t => t.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                                             .Any(method => method.CustomAttributes
                                                  .Any(attr => attr.AttributeType == typeof(ApiCacheAttribute) &&
                                                       attr.ConstructorArguments.Count == 2 &&
                                                       attr.ConstructorArguments.LastOrDefault().ArgumentType == typeof(Boolean) &&
                                                       Convert.ToBoolean(attr.ConstructorArguments.LastOrDefault().Value))
                                                  ));

                foreach (var controllerType in controllerTypes)
                {
                    ConstructorInfo firstConstrutor = controllerType
                                                      .GetConstructors(BindingFlags.Public | BindingFlags.Instance)
                                                      .FirstOrDefault();

                    // get parameters of constructor for DI services
                    var parameters = new List <object>();
                    foreach (var param in firstConstrutor.GetParameters())
                    {
                        var service = serviceProvider.GetService(param.ParameterType);
                        parameters.Add(service);
                    }

                    // get methods typeOf(ApiCacheAttribute) x.GetParameters().Length == 0
                    var methods = controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                                  .Where(x => x.CustomAttributes.Any(attr => attr.AttributeType == typeof(ApiCacheAttribute) &&
                                                                     attr.ConstructorArguments.Count == 2 &&
                                                                     attr.ConstructorArguments.LastOrDefault().ArgumentType == typeof(Boolean) &&
                                                                     Convert.ToBoolean(attr.ConstructorArguments.LastOrDefault().Value)))
                                  .ToList();

                    if (methods.Any())
                    {
                        // create controller object
                        object controllerObject = firstConstrutor.Invoke(parameters.ToArray());

                        foreach (var method in methods)
                        {
                            // method invoke
                            Task <IActionResult> task = method.Invoke(controllerObject, null) as Task <IActionResult>;
                            await task.ConfigureAwait(false);

                            // method result
                            var resultProperty = task.GetType().GetProperty("Result");
                            var resultValue    = resultProperty.GetValue(task) as ObjectResult;

                            if (resultValue != null)
                            {
                                ICacheService cacheService = serviceProvider.GetService <ICacheService>();

                                var attr = method.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(ApiCacheAttribute));
                                if (attr != null && attr.ConstructorArguments.Count == 2)
                                {
                                    //.Where(x => Convert.ToBoolean(x.ConstructorArguments.FirstOrDefault().Value))
                                    var isPreload = Convert.ToBoolean(attr.ConstructorArguments[1].Value);
                                    //var isScoped = Convert.ToBoolean(attr.ConstructorArguments[1].Value);

                                    // create cacheItem from result
                                    var apiServiceName = typeof(ICacheService).Assembly.GetName().Name + "Api";
                                    var cacheValue     = new ApiCacheItem(resultValue.Value, isPreload);
                                    var cacheKey       = cacheService.CreateCacheKey(method, resultValue.Value.GetType());

                                    // set http items for quick access from http context
                                    var httpContext = serviceProvider.GetService <IHttpContextAccessor>().HttpContext;
                                    httpContext.Items[cacheKey.ToLower()] = resultValue.Value;

                                    // set cache
                                    await cacheService.SetAsync(cacheKey, cacheValue);
                                }
                            }
                        }
                    }
                }

                this.CacheLoading = false;
                this.CacheLoaded  = true;

                return(await Task.FromResult <bool>(true));
            }
            catch (Exception ex)
            {
                GeneralContext.Logger.Error(ex.GetApiMessageInfo());
                return(await Task.FromResult <bool>(false));
            }
        }
Esempio n. 7
0
 public static void Store(ApiCacheItem item)
 {
     cache.Add(item);
 }