CheckClientRateLimitAsync(string clientid, string path)
        {
            var region      = _option.RedisKeyPrefix + "CheckClientRateLimitAsync";
            var key         = region + clientid + path;
            var cacheResult = _rateLimitRuleCache.Get(key, region);

            if (cacheResult != null)
            {
                //提取缓存数据
                return(cacheResult.RateLimit, cacheResult.RateLimitOptions);
            }
            else
            {
                //重新获取限流策略
                var result = await _clientRateLimitRepository.CheckClientRateLimitAsync(clientid, path);

                _rateLimitRuleCache.Add(key,
                                        new RateLimitRuleModel()
                {
                    RateLimit = result.RateLimit, RateLimitOptions = result.rateLimitOptions
                },
                                        TimeSpan.FromSeconds(_option.ClientRateLimitCacheTime), region);
                return(result);
            }
        }
        /// <summary>
        /// 校验当前的请求地址客户端是否有权限访问
        /// </summary>
        /// <param name="clientid">客户端ID</param>
        /// <param name="path">请求地址</param>
        /// <returns></returns>
        public async Task <bool> CheckClientAuthenticationAsync(string clientid, string path)
        {
            var enablePrefix = _options.RedisKeyPrefix + "ClientAuthentication";
            var key          = AhphOcelotHelper.ComputeCounterKey(enablePrefix, clientid, "", path);
            var cacheResult  = _ocelotCache.Get(key, enablePrefix);

            if (cacheResult != null)
            {//提取缓存数据
                return(cacheResult.Role);
            }
            else
            {
                //重新获取认证信息
                var result = await _clientAuthenticationRepository.ClientAuthenticationAsync(clientid, path);

                //TODO:for test
                result = true;
                //添加到缓存里
                _ocelotCache.Add(key, new ClientRoleModel()
                {
                    CacheTime = DateTime.Now, Role = result
                }, TimeSpan.FromMinutes(_options.ClientAuthorizationCacheTime), enablePrefix);
                return(result);
            }
        }
Beispiel #3
0
        private void ThenTheContentTypeHeaderIsCached()
        {
            var result = _cacheManager.Get("GET-https://some.url/blah?abcd=123", "kanken");
            var header = result.ContentHeaders["Content-Type"];

            header.First().ShouldBe("application/json");
        }
        private void ThenTheContentTypeHeaderIsCached()
        {
            string cacheKey = MD5Helper.GenerateMd5("GET-https://some.url/blah?abcd=123");
            var    result   = _ocelotCache.Get(cacheKey, "kanken");
            var    header   = result.ContentHeaders["Content-Type"];

            header.First().ShouldBe("application/json");
        }
        public async Task Process(HttpContext context, Func <HttpContext, Task> next)
        {
            var downstreamRoute = context.Items.DownstreamRoute();

            if (!downstreamRoute.IsCached)
            {
                await next.Invoke(context);

                return;
            }

            try
            {
                var downstreamRequest         = context.Items.DownstreamRequest();
                var downstreamUrlKey          = $"{downstreamRequest.Method}-{downstreamRequest.OriginalString}";
                var downStreamRequestCacheKey = _cacheGenerator.GenerateRequestCacheKey(downstreamRequest);

                _logger.LogDebug("Started checking cache for {Url}", downstreamUrlKey);

                var cached = _outputCache.Get(downStreamRequestCacheKey, downstreamRoute.CacheOptions.Region);

                if (cached != null)
                {
                    _logger.LogDebug("cache entry exists for {Url}. Data length {length}", downstreamUrlKey, cached.Body?.Length ?? 0);

                    context.Response.ContentType = MediaTypeNames.Application.Json;
                    context.Items.UpsertDownstreamResponse(CreateHttpResponseMessage(cached));

                    _logger.LogDebug("finished returned cached response for {Url}", downstreamUrlKey);
                    return;
                }

                _logger.LogDebug("no response cached for {Url}", downstreamUrlKey);

                await next.Invoke(context);

                // prevent caching errors
                var downstreamResponse = context.Items.DownstreamResponse();
                if (downstreamResponse == null || (int)downstreamResponse.StatusCode >= 400)
                {
                    _logger.LogDebug("there was a pipeline error for {Url}", downstreamUrlKey);
                    return;
                }

                cached = await CreateCachedResponse(downstreamResponse);

                _outputCache.Add(downStreamRequestCacheKey, cached,
                                 TimeSpan.FromSeconds(downstreamRoute.CacheOptions.TtlSeconds),
                                 downstreamRoute.CacheOptions.Region);

                _logger.LogDebug("finished response added to cache for {Url}. Data length {length}", downstreamUrlKey, cached?.Body?.Length ?? 0);
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
                throw;
            }
        }
Beispiel #6
0
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <returns></returns>
        public Task <Response <FileConfiguration> > Get()
        {
            FileConfiguration fileConfiguration;

            lock (_lock)
            {
                fileConfiguration = _cache.Get(options.Value.CacheKey, default);
            }
            return(Task.FromResult <Response <FileConfiguration> >(new OkResponse <FileConfiguration>(fileConfiguration)));
        }
        /// <summary>
        /// 校验是否设置了路由白名单
        /// </summary>
        /// <param name="clientid">客户端ID</param>
        /// <param name="path">请求地址</param>
        /// <returns></returns>
        private async Task <bool> CheckClientReRouteWhiteListAsync(string clientid, string path)
        {
            var region      = _option.RedisKeyPrefix + "CheckClientReRouteWhiteListAsync";
            var key         = region + clientid + path;
            var cacheResult = _ocelotCache.Get(key, region);

            if (cacheResult != null)
            {//提取缓存数据
                return(cacheResult.Role);
            }
            else
            {//重新获取限流策略
                var result = await _clientRateLimitRepository.CheckClientReRouteWhiteListAsync(clientid, path);

                _ocelotCache.Add(key, new ClientRoleModel()
                {
                    CacheTime = DateTime.Now, Role = result
                }, TimeSpan.FromSeconds(_option.ClientRateLimitCacheTime), region);
                return(result);
            }
        }
        /// <summary>
        /// 检验是否启用限流规则
        /// </summary>
        /// <param name="path">请求地址</param>
        /// <returns></returns>
        private async Task <bool> CheckReRouteRuleAsync(string path)
        {
            var region      = CzarCacheRegion.ClientRoleModelRegion;
            var key         = path;
            var cacheResult = _ocelotCache.Get(key, region);

            if (cacheResult != null)
            {//提取缓存数据
                return(cacheResult.Role);
            }
            else
            {//重新获取限流策略
                var result = await _clientRateLimitRepository.CheckReRouteRuleAsync(path);

                _ocelotCache.Add(key, new ClientRoleModel()
                {
                    CacheTime = DateTime.Now, Role = result
                }, TimeSpan.FromSeconds(_options.CzarCacheTime), region);
                return(result);
            }
        }
        /// <summary>
        /// 校验完整的限流规则
        /// </summary>
        /// <param name="rateLimitOptions"></param>
        /// <returns></returns>
        private bool CheckRateLimitResult(List <AhphClientRateLimitOptions> rateLimitOptions)
        {
            bool result = true;

            if (rateLimitOptions != null && rateLimitOptions.Count > 0)
            {
                //校验策略
                foreach (var op in rateLimitOptions)
                {
                    AhphClientRateLimitCounter counter = new AhphClientRateLimitCounter();
                    //分别对每个策略校验
                    var enablePrefix    = _option.RedisKeyPrefix + "RateLimitRule";
                    var key             = AhphOcelotHelper.ComputeCounterKey(enablePrefix, op.ClientId, op.Period, op.RateLimitPath);
                    var periodTimestamp = AhphOcelotHelper.ConvertToSecond(op.Period);
                    lock (_processLocker)
                    {
                        var rateLimitCounter = _clientRateLimitCounter.Get(key, enablePrefix);
                        if (rateLimitCounter.HasValue)
                        {
                            //提取当前的计数情况
                            //请求次数增长
                            var totalRequests = rateLimitCounter.Value.TotalRequests + 1;
                            // 深拷贝
                            counter = new AhphClientRateLimitCounter(rateLimitCounter.Value.Timestamp,
                                                                     totalRequests);
                        }
                        else
                        {
                            // 写入限流策略
                            _clientRateLimitCounter.Add(key, counter, TimeSpan.FromSeconds(periodTimestamp), enablePrefix);
                        }
                    }

                    if (counter.TotalRequests > op.Limit)
                    {
                        // 更新请求记录,并标记为失败
                        result = false;
                    }

                    if (counter.TotalRequests > 1 && counter.TotalRequests <= op.Limit)
                    {
                        // 更新缓存配置信息
                        //获取限流剩余时间
                        var cur = (int)(counter.Timestamp.AddSeconds(periodTimestamp) - DateTime.UtcNow).TotalSeconds;
                        _clientRateLimitCounter.Add(key, counter, TimeSpan.FromSeconds(cur), enablePrefix);
                    }
                }
            }

            return(result);
        }
        public async Task Invoke(HttpContext httpContext)
        {
            var downstreamRoute = httpContext.Items.DownstreamRoute();

            if (!downstreamRoute.IsCached)
            {
                await _next.Invoke(httpContext);

                return;
            }

            var downstreamRequest = httpContext.Items.DownstreamRequest();

            var    downstreamUrlKey          = $"{downstreamRequest.Method}-{downstreamRequest.OriginalString}";
            string downStreamRequestCacheKey = _cacheGenerator.GenerateRequestCacheKey(downstreamRequest);

            Logger.LogDebug($"Started checking cache for {downstreamUrlKey}");

            var cached = _outputCache.Get(downStreamRequestCacheKey, downstreamRoute.CacheOptions.Region);

            if (cached != null)
            {
                Logger.LogDebug($"cache entry exists for {downstreamUrlKey}");

                var response = CreateHttpResponseMessage(cached);
                SetHttpResponseMessageThisRequest(httpContext, response);

                Logger.LogDebug($"finished returned cached response for {downstreamUrlKey}");

                return;
            }

            Logger.LogDebug($"no resonse cached for {downstreamUrlKey}");

            await _next.Invoke(httpContext);

            if (httpContext.Items.Errors().Count > 0)
            {
                Logger.LogDebug($"there was a pipeline error for {downstreamUrlKey}");

                return;
            }

            var downstreamResponse = httpContext.Items.DownstreamResponse();

            cached = await CreateCachedResponse(downstreamResponse);

            _outputCache.Add(downStreamRequestCacheKey, cached, TimeSpan.FromSeconds(downstreamRoute.CacheOptions.TtlSeconds), downstreamRoute.CacheOptions.Region);

            Logger.LogDebug($"finished response added to cache for {downstreamUrlKey}");
        }
Beispiel #11
0
        /// <summary>
        /// 获取数据
        /// </summary>
        /// <returns></returns>
        public Task <Response <FileConfiguration> > Get()
        {
            FileConfiguration fileConfiguration;

            lock (_lock)
            {
                fileConfiguration = _cache.Get(options.Value.CacheKey, options.Value.CacheKey);
                if (fileConfiguration == null)
                {
                    fileConfiguration = GetFileConfiguration();
                }
            }
            return(Task.FromResult <Response <FileConfiguration> >(new OkResponse <FileConfiguration>(fileConfiguration)));
        }
Beispiel #12
0
        /// <summary>
        /// 从缓存中获取配置信息
        /// </summary>
        /// <returns></returns>
        public Response <IInternalConfiguration> Get()
        {
            var key    = CzarCacheRegion.InternalConfigurationRegion;
            var result = _ocelotCache.Get(key, "");

            if (result != null)
            {
                return(new OkResponse <IInternalConfiguration>(result));
            }
            var fileconfig     = _fileConfigurationRepository.Get().Result;
            var internalConfig = _internalConfigurationCreator.Create(fileconfig.Data).Result;

            AddOrReplace(internalConfig.Data);
            return(new OkResponse <IInternalConfiguration>(internalConfig.Data));
        }
Beispiel #13
0
        /// <summary>
        /// 从缓存中获取配置信息
        /// </summary>
        /// <returns></returns>
        public Response <IInternalConfiguration> Get()
        {
            var key    = _options.RedisOcelotKeyPrefix + nameof(InternalConfiguration);
            var result = _ocelotCache.Get(key, "");

            if (result != null)
            {
                return(new OkResponse <IInternalConfiguration>(result));
            }
            var fileconfig     = _fileConfigurationRepository.Get().Result;
            var internalConfig = _internalConfigurationCreator.Create(fileconfig.Data).Result;

            AddOrReplace(internalConfig.Data);
            return(new OkResponse <IInternalConfiguration>(internalConfig.Data));
        }
Beispiel #14
0
        public async Task Invoke(HttpContext context)
        {
            if (!DownstreamRoute.ReRoute.IsCached)
            {
                await _next.Invoke(context);

                return;
            }

            var downstreamUrlKey = DownstreamRequest.RequestUri.OriginalString;

            _logger.LogDebug("started checking cache for {downstreamUrlKey}", downstreamUrlKey);

            var cached = _outputCache.Get(downstreamUrlKey);

            if (cached != null)
            {
                _logger.LogDebug("cache entry exists for {downstreamUrlKey}", downstreamUrlKey);

                SetHttpResponseMessageThisRequest(cached);

                _logger.LogDebug("finished returned cached response for {downstreamUrlKey}", downstreamUrlKey);

                return;
            }

            _logger.LogDebug("no resonse cached for {downstreamUrlKey}", downstreamUrlKey);

            await _next.Invoke(context);

            _logger.LogDebug("succesfully called next middleware");

            if (PipelineError)
            {
                _logger.LogDebug("there was a pipeline error for {downstreamUrlKey}", downstreamUrlKey);

                return;
            }

            var response = HttpResponseMessage;

            _outputCache.Add(downstreamUrlKey, response, TimeSpan.FromSeconds(DownstreamRoute.ReRoute.FileCacheOptions.TtlSeconds));

            _logger.LogDebug("finished response added to cache for {downstreamUrlKey}", downstreamUrlKey);
        }
Beispiel #15
0
        /// <summary>
        /// 根据模板地址获取RPC请求方法
        /// </summary>
        /// <param name="UpUrl">上游模板</param>
        /// <returns></returns>
        public async Task <RemoteInvokeMessage> GetRemoteMethodAsync(string UpUrl)
        {
            var region      = CzarCacheRegion.RemoteInvokeMessageRegion;
            var key         = UpUrl;
            var cacheResult = _ocelotCache.Get(key, region);

            if (cacheResult != null)
            {//提取缓存数据
                return(cacheResult);
            }
            else
            {
                cacheResult = await _rpcRepository.GetRemoteMethodAsync(UpUrl);

                _ocelotCache.Add(key, cacheResult, TimeSpan.FromSeconds(_options.CzarCacheTime), region);
                return(cacheResult);
            }
        }
        public async Task <Response <FileConfiguration> > Get()
        {
            var config = _cache.Get(_option.CachePrefix + "FileConfiguration", "");

            if (config != null)
            {
                return(new OkResponse <FileConfiguration>(config));
            }
            var file = await _abpFileConfigurationRepository.GetFileConfiguration(_option.GatewayName);

            if (file.Routes == null || file.Routes.Count == 0)
            {
                return(new OkResponse <FileConfiguration>(null));
            }
            _logger.LogDebug(JsonConvert.SerializeObject(file));

            return(new OkResponse <FileConfiguration>(file));
        }
Beispiel #17
0
        /// <summary>
        /// 根据模板地址获取RPC请求方法
        /// </summary>
        /// <param name="UpUrl">上游模板</param>
        /// <returns></returns>
        public async Task <RemoteInvokeMessage> GetRemoteMethodAsync(string UpUrl)
        {
            var region      = _options.RedisKeyPrefix + "GetRemoteMethodAsync";
            var key         = region + UpUrl;
            var cacheResult = _ocelotCache.Get(key, region);

            if (cacheResult != null)
            {//提取缓存数据
                return(cacheResult);
            }
            else
            {
                cacheResult = await _rpcRepository.GetRemoteMethodAsync(UpUrl);

                _ocelotCache.Add(key, cacheResult, TimeSpan.FromSeconds(_options.ClientRateLimitCacheTime), region);
                return(cacheResult);
            }
        }
Beispiel #18
0
        public async Task Invoke(DownstreamContext context)
        {
            if (!context.DownstreamReRoute.IsCached)
            {
                await _next.Invoke(context);

                return;
            }

            var downstreamUrlKey = $"{context.DownstreamRequest.Method.Method}-{context.DownstreamRequest.RequestUri.OriginalString}";

            _logger.LogDebug("started checking cache for {downstreamUrlKey}", downstreamUrlKey);

            var cached = _outputCache.Get(downstreamUrlKey, context.DownstreamReRoute.CacheOptions.Region);

            if (cached != null)
            {
                _logger.LogDebug("cache entry exists for {downstreamUrlKey}", downstreamUrlKey);

                var response = CreateHttpResponseMessage(cached);
                SetHttpResponseMessageThisRequest(context, response);

                _logger.LogDebug("finished returned cached response for {downstreamUrlKey}", downstreamUrlKey);

                return;
            }

            _logger.LogDebug("no resonse cached for {downstreamUrlKey}", downstreamUrlKey);

            await _next.Invoke(context);

            if (context.IsError)
            {
                _logger.LogDebug("there was a pipeline error for {downstreamUrlKey}", downstreamUrlKey);

                return;
            }

            cached = await CreateCachedResponse(context.DownstreamResponse);

            _outputCache.Add(downstreamUrlKey, cached, TimeSpan.FromSeconds(context.DownstreamReRoute.CacheOptions.TtlSeconds), context.DownstreamReRoute.CacheOptions.Region);

            _logger.LogDebug("finished response added to cache for {downstreamUrlKey}", downstreamUrlKey);
        }
        /// <summary>
        /// 校验客户端限流规则
        /// </summary>
        /// <param name="clientid">客户端ID</param>
        /// <param name="path">请求地址</param>
        /// <returns></returns>
        private async Task <(bool RateLimit, List <CzarClientRateLimitOptions> rateLimitOptions)> CheckClientRateLimitAsync(string clientid, string path)
        {
            var region      = CzarCacheRegion.RateLimitRuleModelRegion;
            var key         = clientid + path;
            var cacheResult = _rateLimitRuleCache.Get(key, region);

            if (cacheResult != null)
            {//提取缓存数据
                return(cacheResult.RateLimit, cacheResult.rateLimitOptions);
            }
            else
            {//重新获取限流策略
                var result = await _clientRateLimitRepository.CheckClientRateLimitAsync(clientid, path);

                _rateLimitRuleCache.Add(key, new RateLimitRuleModel()
                {
                    RateLimit = result.RateLimit, rateLimitOptions = result.rateLimitOptions
                }, TimeSpan.FromSeconds(_options.CzarCacheTime), region);
                return(result);
            }
        }
        /// <summary>
        /// 从数据库中提取配置信息
        /// </summary>
        /// <returns></returns>
        public async Task <Response <FileConfiguration> > Get()
        {
            var config = _cache.Get(_option.CachePrefix + "FileConfiguration", "");

            if (config != null)
            {
                return(new OkResponse <FileConfiguration>(config));
            }

            #region 提取配置信息

            var configuration = _hostingEnvironment.GetAppConfiguration();
            var gatewayName   = configuration["ServiceDiscovery:ServiceName"];
            var file          = new FileConfiguration();
            using (var connection = new MySqlConnection(_option.DbConnectionStrings))
            {
                string glbSql =
                    "SELECT * FROM t_ocelot_global_configuration WHERE GatewayName=@GatewayName and IsDeleted=0";

                //提取全局配置信息
                var result =
                    await connection.QueryFirstOrDefaultAsync <OcelotGlobalConfiguration>(glbSql,
                                                                                          new { GatewayName = gatewayName });

                if (result != null)
                {
                    var glb = new FileGlobalConfiguration()
                    {
                        BaseUrl          = result.BaseUrl,
                        DownstreamScheme = result.DownstreamScheme,
                        RequestIdKey     = result.RequestIdKey
                    };
                    if (!string.IsNullOrEmpty(result.HttpHandlerOptions))
                    {
                        glb.HttpHandlerOptions = result.LoadBalancerOptions.ToObject <FileHttpHandlerOptions>();
                    }

                    if (!string.IsNullOrEmpty(result.LoadBalancerOptions))
                    {
                        glb.LoadBalancerOptions = result.LoadBalancerOptions.ToObject <FileLoadBalancerOptions>();
                    }

                    if (!string.IsNullOrEmpty(result.QoSOptions))
                    {
                        glb.QoSOptions = result.QoSOptions.ToObject <FileQoSOptions>();
                    }

                    if (!string.IsNullOrEmpty(result.ServiceDiscoveryProvider))
                    {
                        glb.ServiceDiscoveryProvider =
                            result.ServiceDiscoveryProvider.ToObject <FileServiceDiscoveryProvider>();
                    }

                    file.GlobalConfiguration = glb;

                    string routeSql =
                        "select * from t_ocelot_re_routes where OcelotGlobalConfigurationId=@OcelotGlobalConfigurationId and IsDeleted=0";
                    var routeresult =
                        (await connection.QueryAsync <OcelotReRoutes>(routeSql,
                                                                      new { OcelotGlobalConfigurationId = result.Id })).AsList();
                    if (routeresult != null && routeresult.Count > 0)
                    {
                        var reroutelist = new List <FileReRoute>();
                        foreach (var model in routeresult)
                        {
                            var m = new FileReRoute();
                            if (!string.IsNullOrEmpty(model.AuthenticationOptions))
                            {
                                m.AuthenticationOptions =
                                    model.AuthenticationOptions.ToObject <FileAuthenticationOptions>();
                            }

                            if (!string.IsNullOrEmpty(model.CacheOptions))
                            {
                                m.FileCacheOptions = model.CacheOptions.ToObject <FileCacheOptions>();
                            }

                            if (!string.IsNullOrEmpty(model.DelegatingHandlers))
                            {
                                m.DelegatingHandlers = model.DelegatingHandlers.ToObject <List <string> >();
                            }

                            if (!string.IsNullOrEmpty(model.LoadBalancerOptions))
                            {
                                m.LoadBalancerOptions = model.LoadBalancerOptions.ToObject <FileLoadBalancerOptions>();
                            }

                            if (!string.IsNullOrEmpty(model.QoSOptions))
                            {
                                m.QoSOptions = model.QoSOptions.ToObject <FileQoSOptions>();
                            }

                            if (!string.IsNullOrEmpty(model.DownstreamHostAndPorts))
                            {
                                m.DownstreamHostAndPorts =
                                    model.DownstreamHostAndPorts.ToObject <List <FileHostAndPort> >();
                            }

                            if (!string.IsNullOrEmpty(model.RouteClaimsRequirement))
                            {
                                m.RouteClaimsRequirement =
                                    model.RouteClaimsRequirement.ToObject <Dictionary <string, string> >();
                            }

                            //开始赋值
                            m.DownstreamPathTemplate = model.DownstreamPathTemplate;
                            m.DownstreamScheme       = model.DownstreamScheme;
                            m.Key          = model.Key;
                            m.Priority     = model.Priority ?? 0;
                            m.RequestIdKey = model.RequestIdKey;
                            m.ServiceName  = model.ServiceName;
                            m.Timeout      = model.Timeout ?? 0;
                            m.UpstreamHost = model.UpstreamHost;
                            if (!string.IsNullOrEmpty(model.UpstreamHttpMethod))
                            {
                                m.UpstreamHttpMethod = model.UpstreamHttpMethod.ToObject <List <string> >();
                            }

                            m.UpstreamPathTemplate = model.UpstreamPathTemplate;
                            reroutelist.Add(m);
                        }

                        file.ReRoutes = reroutelist;
                    }
                }
            }
            #endregion

            if (file.ReRoutes == null || file.ReRoutes.Count == 0)
            {
                return(new OkResponse <FileConfiguration>(null));
            }

            return(new OkResponse <FileConfiguration>(file));
        }
Beispiel #21
0
        public async Task <Response <FileConfiguration> > Get()
        {
            var config = _cache.Get(_option.CachePrefix + "FileConfiguration", "");

            if (config != null)
            {
                return(new OkResponse <FileConfiguration>(config));
            }

            var file = new FileConfiguration();

            // 提取全局配置信息
            var globalResult = await _ocelotGlobalConfigurationRepository.FindByNameAsync(_option.GatewayName);

            if (globalResult != null)
            {
                var fileGlobalConfig = new FileGlobalConfiguration
                {
                    BaseUrl          = globalResult.BaseUrl,
                    DownstreamScheme = globalResult.DownstreamScheme,
                    RequestIdKey     = globalResult.RequestIdKey
                };

                if (globalResult.HttpHandlerOption != null)
                {
                    var httpHandlerOption = globalResult.HttpHandlerOption;
                    fileGlobalConfig.HttpHandlerOptions = new FileHttpHandlerOptions
                    {
                        AllowAutoRedirect       = httpHandlerOption.AllowAutoRedirect,
                        UseCookieContainer      = httpHandlerOption.UseCookieContainer,
                        UseProxy                = httpHandlerOption.UseProxy,
                        UseTracing              = httpHandlerOption.UseTracing,
                        MaxConnectionsPerServer = httpHandlerOption.MaxConnectionsPerServer
                    };
                }
                if (globalResult.LoadBalancerOption != null)
                {
                    var loadBalancerOption = globalResult.LoadBalancerOption;
                    fileGlobalConfig.LoadBalancerOptions = new FileLoadBalancerOptions
                    {
                        Expiry = loadBalancerOption.Expiry,
                        Key    = loadBalancerOption.Key,
                        Type   = loadBalancerOption.Type
                    };
                }
                if (globalResult.QoSOption != null)
                {
                    var qoSOption = globalResult.QoSOption;
                    fileGlobalConfig.QoSOptions = new FileQoSOptions
                    {
                        ExceptionsAllowedBeforeBreaking = qoSOption.ExceptionsAllowedBeforeBreaking,
                        DurationOfBreak = qoSOption.DurationOfBreak,
                        TimeoutValue    = qoSOption.TimeoutValue
                    };
                }
                if (globalResult.ServiceDiscoveryProvider != null)
                {
                    var serviceDiscoveryProvider = globalResult.ServiceDiscoveryProvider;
                    fileGlobalConfig.ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
                    {
                        ConfigurationKey = serviceDiscoveryProvider.ConfigurationKey,
                        Host             = serviceDiscoveryProvider.Host,
                        Namespace        = serviceDiscoveryProvider.Namespace,
                        PollingInterval  = serviceDiscoveryProvider.PollingInterval,
                        Port             = serviceDiscoveryProvider.Port,
                        Token            = serviceDiscoveryProvider.Token,
                        Type             = serviceDiscoveryProvider.Type
                    };
                }
                if (globalResult.RateLimitOption != null)
                {
                    var rateLimitOption = globalResult.RateLimitOption;
                    fileGlobalConfig.RateLimitOptions = new FileRateLimitOptions
                    {
                        ClientIdHeader          = rateLimitOption.ClientIdHeader,
                        DisableRateLimitHeaders = rateLimitOption.DisableRateLimitHeaders,
                        HttpStatusCode          = rateLimitOption.HttpStatusCode,
                        QuotaExceededMessage    = rateLimitOption.QuotaExceededMessage,
                        RateLimitCounterPrefix  = rateLimitOption.RateLimitCounterPrefix
                    };
                }

                file.GlobalConfiguration = fileGlobalConfig;
                //TODO: Optimize code structure
                if (globalResult?.ReRoutes?.Count > 0)
                {
                    _logger.LogInformation($"ReRoute Count:{ globalResult?.ReRoutes?.Count }");
                    //提取路由信息
                    var reRoutes = globalResult.ReRoutes.OrderBy(c => c.Sort);

                    List <FileReRoute> fileReRoutes = new List <FileReRoute>();
                    foreach (var route in reRoutes)
                    {
                        _logger.LogInformation($"Loading ReRoute: {route.Name}");
                        var r = new FileReRoute
                        {
                            Key                    = route.Key,
                            Priority               = route.Priority,
                            ServiceName            = route.ServiceName,
                            Timeout                = route.Timeout,
                            DownstreamPathTemplate = route.DownstreamPathTemplate,
                            DownstreamScheme       = route.DownstreamScheme,
                            UpstreamHost           = route.UpstreamHost,
                            DangerousAcceptAnyServerCertificateValidator = route.DangerousAcceptAnyServerCertificateValidator,
                            DownstreamHttpMethod         = route.DownstreamHttpMethod,
                            RequestIdKey                 = route.RequestIdKey,
                            UpstreamPathTemplate         = route.UpstreamPathTemplate,
                            ServiceNamespace             = route.ServiceNamespace,
                            ReRouteIsCaseSensitive       = route.ReRouteIsCaseSensitive,
                            AddClaimsToRequest           = route.AddClaimsToRequests,
                            AddHeadersToRequest          = route.AddHeadersToRequests,
                            AddQueriesToRequest          = route.AddQueriesToRequests,
                            ChangeDownstreamPathTemplate = route.ChangeDownstreamPathTemplates,
                            DownstreamHeaderTransform    = route.DownstreamHeaderTransforms,
                            RouteClaimsRequirement       = route.RouteClaimsRequirements,
                            UpstreamHeaderTransform      = route.UpstreamHeaderTransforms,
                            // AuthenticationOptions = null,
                            // DelegatingHandlers = null,
                            // DownstreamHostAndPorts = null,
                            // FileCacheOptions = null,
                            // HttpHandlerOptions = null,
                            // LoadBalancerOptions = null,
                            // QoSOptions = null,
                            // RateLimitOptions = null,
                            // SecurityOptions = null,
                            // UpstreamHttpMethod = null
                        };
                        if (route.AuthenticationOption != null)
                        {
                            var authenticationOption = route.AuthenticationOption;
                            r.AuthenticationOptions = new FileAuthenticationOptions
                            {
                                AuthenticationProviderKey = authenticationOption.AuthenticationProviderKey,
                                AllowedScopes             = authenticationOption.AllowedScopes.Select(c => c.Scope).ToList()
                            };
                        }
                        if (route.DelegatingHandlers != null && route.DelegatingHandlers.Count > 0)
                        {
                            r.DelegatingHandlers = route.DelegatingHandlers.Select(c => c.Delegating).ToList();
                        }
                        if (route.DownstreamHostAndPorts != null && route.DownstreamHostAndPorts.Count > 0)
                        {
                            var downstreamHostAndPorts = new List <FileHostAndPort>();
                            foreach (var host in route.DownstreamHostAndPorts)
                            {
                                downstreamHostAndPorts.Add(new FileHostAndPort
                                {
                                    Host = host.Host,
                                    Port = host.Port
                                });
                            }
                            r.DownstreamHostAndPorts = downstreamHostAndPorts;
                        }
                        if (route.CacheOption != null)
                        {
                            var cacheOption = route.CacheOption;
                            r.FileCacheOptions = new FileCacheOptions
                            {
                                TtlSeconds = cacheOption.TtlSeconds,
                                Region     = cacheOption.Region
                            };
                        }
                        if (route.HttpHandlerOption != null)
                        {
                            var httpHandlerOption = route.HttpHandlerOption;
                            r.HttpHandlerOptions = new FileHttpHandlerOptions
                            {
                                AllowAutoRedirect       = httpHandlerOption.AllowAutoRedirect,
                                UseCookieContainer      = httpHandlerOption.UseCookieContainer,
                                UseProxy                = httpHandlerOption.UseProxy,
                                UseTracing              = httpHandlerOption.UseTracing,
                                MaxConnectionsPerServer = httpHandlerOption.MaxConnectionsPerServer
                            };
                        }
                        if (route.LoadBalancerOption != null)
                        {
                            var loadBalancerOptions = route.LoadBalancerOption;
                            r.LoadBalancerOptions = new FileLoadBalancerOptions
                            {
                                Expiry = loadBalancerOptions.Expiry,
                                Key    = loadBalancerOptions.Key,
                                Type   = loadBalancerOptions.Type
                            };
                        }
                        if (route.QoSOption != null)
                        {
                            var qoSOption = route.QoSOption;
                            r.QoSOptions = new FileQoSOptions
                            {
                                ExceptionsAllowedBeforeBreaking = qoSOption.ExceptionsAllowedBeforeBreaking,
                                DurationOfBreak = qoSOption.DurationOfBreak,
                                TimeoutValue    = qoSOption.TimeoutValue
                            };
                        }
                        if (route.RateLimitOption != null)
                        {
                            var rateLimitOption = route.RateLimitOption;
                            r.RateLimitOptions = new FileRateLimitRule
                            {
                                ClientWhitelist    = rateLimitOption.ClientWhitelist.Select(c => c.Whitelist).ToList(),
                                EnableRateLimiting = rateLimitOption.EnableRateLimiting,
                                Limit          = rateLimitOption.Limit,
                                Period         = rateLimitOption.Period,
                                PeriodTimespan = rateLimitOption.PeriodTimespan
                            };
                        }
                        if (route.SecurityOption != null)
                        {
                            var securityOption = route.SecurityOption;
                            r.SecurityOptions = new FileSecurityOptions
                            {
                                IPAllowedList = securityOption.IPAllowedList.Select(c => c.IP).ToList(),
                                IPBlockedList = securityOption.IPBlockedList.Select(c => c.IP).ToList()
                            };
                        }

                        if (route.UpstreamHttpMethods != null)
                        {
                            r.UpstreamHttpMethod = route.UpstreamHttpMethods.Select(c => c.Method).ToList();
                        }
                        r.UpstreamPathTemplate = route.UpstreamPathTemplate;

                        file.ReRoutes.Add(r);
                    }
                }
                else
                {
                    _logger.LogWarning($"Not Found ReRoute");
                }
            }
            else
            {
                throw new Exception(string.Format("Not found '{0}' gateway name config", _option.GatewayName));
            }
            if (file.ReRoutes == null || file.ReRoutes.Count == 0)
            {
                return(new OkResponse <FileConfiguration>(null));
            }
            _logger.LogDebug(JsonConvert.SerializeObject(file));

            return(new OkResponse <FileConfiguration>(file));
        }
Beispiel #22
0
        /// <summary>
        /// 提取配置信息
        /// </summary>
        /// <returns></returns>
        public async Task <Response <FileConfiguration> > Get()
        {
            var config = _cache.Get(_option.CachePrefix + "FileConfiguration", "");

            if (config != null)
            {
                return(new OkResponse <FileConfiguration>(config));
            }
            #region 提取配置信息
            var    file   = new FileConfiguration();
            string glbsql = "select top 1 * from OcelotGlobalConfiguration where IsDefault=1";
            //提取全局配置信息
            using (var connection = new SqlConnection(_option.DbConnectionStrings))
            {
                var result = await connection.QueryFirstOrDefaultAsync <OcelotGlobalConfiguration>(glbsql);

                if (result != null)
                {
                    var glb = new FileGlobalConfiguration();
                    glb.BaseUrl          = result.BaseUrl;
                    glb.DownstreamScheme = result.DownstreamScheme;
                    glb.RequestIdKey     = result.RequestIdKey;
                    if (!String.IsNullOrEmpty(result.HttpHandlerOptions))
                    {
                        glb.HttpHandlerOptions = result.HttpHandlerOptions.ToObject <FileHttpHandlerOptions>();
                    }
                    if (!String.IsNullOrEmpty(result.LoadBalancerOptions))
                    {
                        glb.LoadBalancerOptions = result.LoadBalancerOptions.ToObject <FileLoadBalancerOptions>();
                    }
                    if (!String.IsNullOrEmpty(result.QoSOptions))
                    {
                        glb.QoSOptions = result.QoSOptions.ToObject <FileQoSOptions>();
                    }
                    if (!String.IsNullOrEmpty(result.ServiceDiscoveryProvider))
                    {
                        glb.ServiceDiscoveryProvider = result.ServiceDiscoveryProvider.ToObject <FileServiceDiscoveryProvider>();
                    }
                    file.GlobalConfiguration = glb;

                    //提取路由信息

                    string routesql    = "select * from OcelotReRoutes where OcelotGlobalConfigurationId=@OcelotGlobalConfigurationId and IsStatus=1";
                    var    routeresult = (await connection.QueryAsync <OcelotReRoutes>(routesql, new { OcelotGlobalConfigurationId = result.Id })).AsList();
                    if (routeresult != null && routeresult.Count > 0)
                    {
                        var reroutelist = new List <FileReRoute>();
                        foreach (var model in routeresult)
                        {
                            var m = new FileReRoute();
                            if (!String.IsNullOrEmpty(model.AuthenticationOptions))
                            {
                                m.AuthenticationOptions = model.AuthenticationOptions.ToObject <FileAuthenticationOptions>();
                            }
                            if (!String.IsNullOrEmpty(model.CacheOptions))
                            {
                                m.FileCacheOptions = model.CacheOptions.ToObject <FileCacheOptions>();
                            }
                            if (!String.IsNullOrEmpty(model.DelegatingHandlers))
                            {
                                m.DelegatingHandlers = model.DelegatingHandlers.ToObject <List <string> >();
                            }
                            if (!String.IsNullOrEmpty(model.LoadBalancerOptions))
                            {
                                m.LoadBalancerOptions = model.LoadBalancerOptions.ToObject <FileLoadBalancerOptions>();
                            }
                            if (!String.IsNullOrEmpty(model.QoSOptions))
                            {
                                m.QoSOptions = model.QoSOptions.ToObject <FileQoSOptions>();
                            }
                            if (!String.IsNullOrEmpty(model.DownstreamHostAndPorts))
                            {
                                m.DownstreamHostAndPorts = model.DownstreamHostAndPorts.ToObject <List <FileHostAndPort> >();
                            }
                            //开始赋值
                            m.DownstreamPathTemplate = model.DownstreamPathTemplate;
                            m.DownstreamScheme       = model.DownstreamScheme;
                            m.Key          = model.Key;
                            m.Priority     = model.Priority ?? 0;
                            m.RequestIdKey = model.RequestIdKey;
                            m.ServiceName  = model.ServiceName;
                            m.Timeout      = model.Timeout ?? 0;
                            m.UpstreamHost = model.UpstreamHost;
                            if (!String.IsNullOrEmpty(model.UpstreamHttpMethod))
                            {
                                m.UpstreamHttpMethod = model.UpstreamHttpMethod.ToObject <List <string> >();
                            }
                            m.UpstreamPathTemplate = model.UpstreamPathTemplate;
                            reroutelist.Add(m);
                        }
                        file.ReRoutes = reroutelist;
                    }
                }
                else
                {
                    throw new Exception("未监测到配置信息");
                }
            }
            #endregion
            if (file.ReRoutes == null || file.ReRoutes.Count == 0)
            {
                return(new OkResponse <FileConfiguration>(null));
            }
            return(new OkResponse <FileConfiguration>(file));
        }