public async Task <HttpRequestMessage> Map(HttpContext context, ReRoute route)
        {
            var downstreamUri = route.GetDownstreamUri(context);

            var requestMessage = new HttpRequestMessage(route.DownstreamMethod, downstreamUri);

            requestMessage.Content = MapContent(context, route);

            foreach (var header in context.Request.Headers.Where(x => !x.Key.StartsWith("Content-")))
            {
                requestMessage.Headers.Add(header.Key, header.Value.ToArray());
            }


            var headerModifications = route.GetRequestHeaderModifications();

            foreach (var headerAction in headerModifications)
            {
                headerAction(requestMessage.Headers);
            }


            // This could be also done in the startup in headerModifications, but I leave it here for clarity

            TokenBuilder tokenBuilder = TokenBuilder.Instance;
            string       XCToken      = await tokenBuilder.GetXCAccessToken(route.TokenUserId());

            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", XCToken);

            return(requestMessage);
        }
Пример #2
0
        public Response <IQoSProvider> Get(ReRoute reRoute)
        {
            try
            {
                if (_qoSProviders.TryGetValue(reRoute.ReRouteKey, out var qosProvider))
                {
                    if (reRoute.IsQos && qosProvider.CircuitBreaker == null)
                    {
                        qosProvider = _qoSProviderFactory.Get(reRoute);
                        Add(reRoute.ReRouteKey, qosProvider);
                    }

                    return(new OkResponse <IQoSProvider>(_qoSProviders[reRoute.ReRouteKey]));
                }

                qosProvider = _qoSProviderFactory.Get(reRoute);
                Add(reRoute.ReRouteKey, qosProvider);
                return(new OkResponse <IQoSProvider>(qosProvider));
            }
            catch (Exception ex)
            {
                return(new ErrorResponse <IQoSProvider>(new List <Ocelot.Errors.Error>()
                {
                    new UnableToFindQoSProviderError($"unabe to find qos provider for {reRoute.ReRouteKey}, exception was {ex}")
                }));
            }
        }
Пример #3
0
        public async Task Multiplex(DownstreamContext context, ReRoute reRoute, OcelotRequestDelegate next)
        {
            var tasks = new Task <DownstreamContext> [reRoute.DownstreamReRoute.Count];

            for (var i = 0; i < reRoute.DownstreamReRoute.Count; i++)
            {
                var downstreamContext = new DownstreamContext(context.HttpContext)
                {
                    TemplatePlaceholderNameAndValues = context.TemplatePlaceholderNameAndValues,
                    ServiceProviderConfiguration     = context.ServiceProviderConfiguration,
                    DownstreamReRoute = reRoute.DownstreamReRoute[i],
                };

                tasks[i] = Fire(downstreamContext, next);
            }

            await Task.WhenAll(tasks);

            var downstreamContexts = new List <DownstreamContext>();

            foreach (var task in tasks)
            {
                var finished = await task;
                downstreamContexts.Add(finished);
            }

            await _aggregator.Aggregate(reRoute, context, downstreamContexts);
        }
Пример #4
0
        public PollyQoSProvider(ReRoute reRoute, IOcelotLoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger <PollyQoSProvider>();

            _timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(reRoute.QosOptionsOptions.TimeoutValue), reRoute.QosOptionsOptions.TimeoutStrategy);

            _circuitBreakerPolicy = Policy
                                    .Handle <HttpRequestException>()
                                    .Or <TimeoutRejectedException>()
                                    .Or <TimeoutException>()
                                    .CircuitBreakerAsync(
                exceptionsAllowedBeforeBreaking: reRoute.QosOptionsOptions.ExceptionsAllowedBeforeBreaking,
                durationOfBreak: TimeSpan.FromMilliseconds(reRoute.QosOptionsOptions.DurationOfBreak),
                onBreak: (ex, breakDelay) =>
            {
                _logger.LogError(
                    ".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex);
            },
                onReset: () =>
            {
                _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again.");
            },
                onHalfOpen: () =>
            {
                _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.");
            }
                );

            _circuitBreaker = new CircuitBreaker(_circuitBreakerPolicy, _timeoutPolicy);
        }
Пример #5
0
 private void GivenThereIsALoadBalancer(ReRoute reRoute, ILoadBalancer loadBalancer)
 {
     _reRoute      = reRoute;
     _loadBalancer = loadBalancer;
     _factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(loadBalancer);
     _getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
 }
Пример #6
0
 private void GivenThereIsAQoSProvider(ReRoute reRoute, IQoSProvider qoSProvider)
 {
     _reRoute     = reRoute;
     _qoSProvider = qoSProvider;
     _factory.Setup(x => x.Get(_reRoute)).Returns(_qoSProvider);
     _getResult = _qosProviderHouse.Get(reRoute);
 }
Пример #7
0
        protected virtual void ApplyReRouteOptions(ReRoute reRoute, ReRouteDto routeDto)
        {
            reRoute.SetDownstreamHeader(routeDto.DownstreamHeaderTransform);
            reRoute.SetQueriesParamter(routeDto.AddQueriesToRequest);
            reRoute.SetRequestClaims(routeDto.AddClaimsToRequest);
            reRoute.SetRequestHeader(routeDto.AddHeadersToRequest);
            reRoute.SetRouteClaims(routeDto.RouteClaimsRequirement);
            reRoute.SetUpstreamHeader(routeDto.UpstreamHeaderTransform);

            reRoute.AuthenticationOptions.ApplyAuthOptions(routeDto.AuthenticationOptions.AuthenticationProviderKey, routeDto.AuthenticationOptions.AllowedScopes);

            reRoute.CacheOptions.ApplyCacheOption(routeDto.FileCacheOptions.TtlSeconds, routeDto.FileCacheOptions.Region);

            reRoute.HttpHandlerOptions.ApplyAllowAutoRedirect(routeDto.HttpHandlerOptions.AllowAutoRedirect);
            reRoute.HttpHandlerOptions.ApplyCookieContainer(routeDto.HttpHandlerOptions.UseCookieContainer);
            reRoute.HttpHandlerOptions.ApplyHttpProxy(routeDto.HttpHandlerOptions.UseProxy);
            reRoute.HttpHandlerOptions.ApplyHttpTracing(routeDto.HttpHandlerOptions.UseTracing);

            reRoute.LoadBalancerOptions.ApplyLoadBalancerOptions(routeDto.LoadBalancerOptions.Type, routeDto.LoadBalancerOptions.Key, routeDto.LoadBalancerOptions.Expiry);

            reRoute.QoSOptions.ApplyQosOptions(routeDto.QoSOptions.ExceptionsAllowedBeforeBreaking, routeDto.QoSOptions.DurationOfBreak, routeDto.QoSOptions.TimeoutValue);

            reRoute.RateLimitOptions.ApplyRateLimit(routeDto.RateLimitOptions.EnableRateLimiting);
            reRoute.RateLimitOptions.SetPeriodTimespan(routeDto.RateLimitOptions.Period, routeDto.RateLimitOptions.PeriodTimespan, routeDto.RateLimitOptions.Limit);
            reRoute.RateLimitOptions.SetClientWhileList(routeDto.RateLimitOptions.ClientWhitelist);

            reRoute.SecurityOptions.SetAllowIpList(routeDto.SecurityOptions.IPAllowedList);
            reRoute.SecurityOptions.SetBlockIpList(routeDto.SecurityOptions.IPBlockedList);
        }
        public async Task Map(HttpContext context, HttpResponseMessage response, ReRoute route)
        {
            foreach (var header in response.Headers)
            {
                context.Response.Headers.Add(header.Key, new StringValues(header.Value.ToArray()));
            }

            foreach (var header in response.Content.Headers)
            {
                context.Response.Headers.Add(header.Key, new StringValues(header.Value.ToArray()));
            }

            var headerModifications = route.GetResponseHeaderModifications();

            foreach (var headerAction in headerModifications)
            {
                headerAction(context.Response.Headers);
            }

            var content = await response.Content.ReadAsStreamAsync();

            context.Response.HttpContext.Features.Get <IHttpResponseFeature>().ReasonPhrase = response.ReasonPhrase;
            context.Response.Headers.Add("Content-Length", new[] { response.Content.Headers.ContentLength.ToString() });
            context.Response.Headers.Remove("Transfer-Encoding");

            context.Response.StatusCode = (int)response.StatusCode;

            using (content)
            {
                if (response.StatusCode != HttpStatusCode.NotModified && context.Response.ContentLength != 0)
                {
                    await content.CopyToAsync(context.Response.Body);
                }
            }
        }
Пример #9
0
        public async Task <ILoadBalancer> Get(ReRoute reRoute)
        {
            var serviceConfig = new ServiceProviderConfiguraion(
                reRoute.ServiceProviderConfiguraion.ServiceName,
                reRoute.ServiceProviderConfiguraion.DownstreamHost,
                reRoute.ServiceProviderConfiguraion.DownstreamPort,
                reRoute.ServiceProviderConfiguraion.UseServiceDiscovery,
                reRoute.ServiceProviderConfiguraion.ServiceDiscoveryProvider,
                reRoute.ServiceProviderConfiguraion.ServiceProviderHost,
                reRoute.ServiceProviderConfiguraion.ServiceProviderPort);

            var serviceProvider = _serviceProviderFactory.Get(serviceConfig);

            switch (reRoute.LoadBalancer)
            {
            case "RoundRobin":
                return(new RoundRobinLoadBalancer(await serviceProvider.Get()));

            case "LeastConnection":
                return(new LeastConnectionLoadBalancer(async() => await serviceProvider.Get(), reRoute.ServiceProviderConfiguraion.ServiceName));

            default:
                return(new NoLoadBalancer(await serviceProvider.Get()));
            }
        }
        public async Task <Response <ILoadBalancer> > Get(ReRoute reRoute, ServiceProviderConfiguration config)
        {
            try
            {
                if (_loadBalancers.TryGetValue(reRoute.ReRouteKey, out var loadBalancer))
                {
                    loadBalancer = _loadBalancers[reRoute.ReRouteKey];

                    if (reRoute.LoadBalancer != loadBalancer.GetType().Name)
                    {
                        loadBalancer = await _factory.Get(reRoute, config);

                        AddLoadBalancer(reRoute.ReRouteKey, loadBalancer);
                    }

                    return(new OkResponse <ILoadBalancer>(loadBalancer));
                }

                loadBalancer = await _factory.Get(reRoute, config);

                AddLoadBalancer(reRoute.ReRouteKey, loadBalancer);
                return(new OkResponse <ILoadBalancer>(loadBalancer));
            }
            catch (Exception ex)
            {
                return(new ErrorResponse <ILoadBalancer>(new List <Ocelot.Errors.Error>()
                {
                    new UnableToFindLoadBalancerError($"unabe to find load balancer for {reRoute.ReRouteKey} exception is {ex}")
                }));
            }
        }
Пример #11
0
        public async Task <IActionResult> EditAsync([FromBody] ReRoute input)
        {
            await _business.EditModel(input);

            return(Ok(new MsgResultDto {
                Success = true
            }));
        }
        public IResponseAggregator Get(ReRoute reRoute)
        {
            if (!string.IsNullOrEmpty(reRoute.Aggregator))
            {
                return(_userDefined);
            }

            return(_simple);
        }
Пример #13
0
        public IQoSProvider Get(ReRoute reRoute)
        {
            if (reRoute.IsQos)
            {
                return(new PollyQoSProvider(reRoute, _loggerFactory));
            }

            return(new NoQoSProvider());
        }
Пример #14
0
        public Response <IDefinedAggregator> Get(ReRoute reRoute)
        {
            if (_aggregators.ContainsKey(reRoute.Aggregator))
            {
                return(new OkResponse <IDefinedAggregator>(_aggregators[reRoute.Aggregator]));
            }

            return(new ErrorResponse <IDefinedAggregator>(new CouldNotFindAggregatorError(reRoute.Aggregator)));
        }
Пример #15
0
        private void AddPath(SwaggerDocument swaggerDocument,
                             ReRoute reRoute, IReadOnlyDictionary <string, SwaggerDocument> documents)
        {
            var host = reRoute.DownstreamHostAndPorts.First().ToUrl();

            if (!documents.ContainsKey(host))
            {
                Log(new Exception($"不能找到 '{host}' 相对应的 Swagger 文档。"));
                return;
            }

            var document     = documents[host];
            var pathTemplate = reRoute.DownstreamPathTemplate;
            var httpMethods  = reRoute.UpstreamHttpMethod;

            var pathKey = document.Paths.Keys
                          .FirstOrDefault(x => string.Compare(x, pathTemplate, StringComparison.OrdinalIgnoreCase) == 0);

            if (string.IsNullOrWhiteSpace(pathKey))
            {
                Log(new Exception($"在 '{host}' 中不能找到 '{pathTemplate}' 相对应的值。"));
                return;
            }

            var pathItem = document.Paths[pathKey];

            SwaggerPathItem newPathItem = null;

            if (swaggerDocument.Paths.ContainsKey(reRoute.UpstreamPathTemplate))
            {
                newPathItem = swaggerDocument.Paths[reRoute.UpstreamPathTemplate];
            }
            else
            {
                newPathItem = new SwaggerPathItem()
                {
                    Summary     = pathItem.Summary,
                    Description = pathItem.Description,
                    Servers     = pathItem.Servers,
                    Parameters  = pathItem.Parameters,
                };

                swaggerDocument.Paths.Add(reRoute.UpstreamPathTemplate, newPathItem);
            }

            foreach (var httpMethod in httpMethods)
            {
                var operationMethod = ConvertToSwaggerOperationMethod(httpMethod);
                if (!pathItem.ContainsKey(operationMethod))
                {
                    Log(new Exception($"在 '{host}' 中不能找到 '({httpMethod}){pathKey}' 相对应的值。"));
                    continue;
                }

                newPathItem.Add(operationMethod, pathItem[operationMethod]);
            }
        }
Пример #16
0
        /// <summary>
        /// 编辑信息
        /// </summary>
        public async Task EditModel(ReRoute input)
        {
            if (input.ReRouteId > 0)
            {
                await _dbContext.Updateable(input).ExecuteCommandAsync();

                return;
            }
            await _dbContext.Insertable(input).ExecuteCommandAsync();
        }
Пример #17
0
        public async Task Forward(HttpContext context, ReRoute route)
        {
            HttpClient client = new HttpClient();

            var requestMessage = await new RequestMapper().Map(context, route);

            var response = await client.SendAsync(requestMessage);

            await new ResponseMapper().Map(context, response, route);
        }
 public async Task Aggregate(ReRoute reRoute, DownstreamContext originalContext, List <DownstreamContext> downstreamContexts)
 {
     if (reRoute.DownstreamReRoute.Count > 1)
     {
         await MapAggregtes(originalContext, downstreamContexts);
     }
     else
     {
         MapNotAggregate(originalContext, downstreamContexts);
     }
 }
Пример #19
0
        private static async Task Forward(HttpContext context, ReRoute route)
        {
            if (!string.IsNullOrEmpty(route.AuthenticationScheme))
            {
                var result = await context.AuthenticateAsync("test");

                context.User = result.Principal;
            }

            await new Forwarder().Forward(context, route);
        }
Пример #20
0
 private async Task Map(ReRoute reRoute, DownstreamContext context, List <DownstreamContext> contexts)
 {
     if (reRoute.DownstreamReRoute.Count > 1)
     {
         var aggregator = _factory.Get(reRoute);
         await aggregator.Aggregate(reRoute, context, contexts);
     }
     else
     {
         MapNotAggregate(context, contexts);
     }
 }
Пример #21
0
        public async Task Forward(HttpContext context, ReRoute route)
        {
            HttpClient client = new HttpClient();

            var requestMessage = await new RequestMapper().Map(context, route);



            var response = await client.SendAsync(requestMessage);

            Byte[] from    = GetRequestBody(context.Request);
            var    payload = Encoding.Default.GetString(from);

            await new ResponseMapper().Map(context, response, route);
        }
Пример #22
0
        public async Task <ILoadBalancer> Get(ReRoute reRoute)
        {
            var serviceProvider = _serviceProviderFactory.Get(reRoute.ServiceProviderConfiguraion);

            switch (reRoute.LoadBalancer)
            {
            case "RoundRobin":
                return(new RoundRobinLoadBalancer(async() => await serviceProvider.Get()));

            case "LeastConnection":
                return(new LeastConnectionLoadBalancer(async() => await serviceProvider.Get(), reRoute.ServiceProviderConfiguraion.ServiceName));

            default:
                return(new NoLoadBalancer(await serviceProvider.Get()));
            }
        }
        public async Task Aggregate(ReRoute reRoute, DownstreamContext originalContext, List <DownstreamContext> downstreamResponses)
        {
            var aggregator = _provider.Get(reRoute);

            if (!aggregator.IsError)
            {
                var aggregateResponse = await aggregator.Data
                                        .Aggregate(downstreamResponses.Select(x => x.DownstreamResponse).ToList());

                originalContext.DownstreamResponse = aggregateResponse;
            }
            else
            {
                originalContext.Errors.AddRange(aggregator.Errors);
            }
        }
Пример #24
0
        public static IApplicationBuilder UsePoortwachter(this IApplicationBuilder builder, Action <GatewayBuilder> configure)
        {
            var configuration = new Configuration();

            configure(new GatewayBuilder(configuration));

            return(builder.Use(async(context, next) =>
            {
                foreach (ReRouteConfiguration config in configuration.Routes)
                {
                    var route = new ReRoute(configuration, config);

                    if (route.IsMatch(context.Request))
                    {
                        await Forward(context, route);
                    }
                }
            }));
        }
        public async Task <HttpRequestMessage> Map(HttpContext context, ReRoute route)
        {
            var downstreamUri = route.GetDownstreamUri(context);

            var requestMessage = new HttpRequestMessage(route.DownstreamMethod, downstreamUri);

            requestMessage.Content = MapContent(context, route);

            foreach (var header in context.Request.Headers.Where(x => !x.Key.StartsWith("Content-")))
            {
                requestMessage.Headers.Add(header.Key, header.Value.ToArray());
            }

            var headerModifications = route.GetRequestHeaderModifications();

            foreach (var headerAction in headerModifications)
            {
                headerAction(requestMessage.Headers);
            }

            return(requestMessage);
        }
Пример #26
0
        private HttpContent MapContent(HttpContext context, ReRoute route)
        {
            Byte[] from = GetRequestBody(context.Request);

            Byte[] copy = route.TransformRequestBody(context, from);

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

            var content = new ByteArrayContent(copy);

            foreach (var header in context.Request.Headers.Where(x => x.Key.StartsWith("Content-")))
            {
                content.Headers.Add(header.Key, header.Value.ToArray());
            }

            content.Headers.Remove("Content-Length");
            content.Headers.TryAddWithoutValidation("Content-Length", copy.Length.ToString());

            return(content);
        }
Пример #27
0
 private void GivenTheReRoute(ReRoute reRoute)
 {
     _reRoute = reRoute;
 }
Пример #28
0
 private void GivenTheFollowing(ReRoute reRoute)
 {
     _reRoute = reRoute;
 }
Пример #29
0
 private static bool IsAuthenticatedRoute(ReRoute reRoute)
 {
     return(reRoute.IsAuthenticated);
 }
Пример #30
0
 private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(ReRoute reRoute)
 {
     _reRoute = reRoute;
     _factory.Setup(x => x.Get(_reRoute)).Returns(new FakePollyQoSProvider());
     _getResult = _qosProviderHouse.Get(_reRoute);
 }