Пример #1
0
        public void should_call_scoped_data_repository_correctly()
        {
            var downstreamRoute = new DownstreamRoute(new List <UrlPathPlaceholderNameAndValue>(),
                                                      new ReRouteBuilder()
                                                      .WithRequestIdKey("LSRequestId")
                                                      .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                      .Build());

            this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
            .And(x => x.GivenTheQosProviderHouseReturns(new OkResponse <IQoSProvider>(new NoQoSProvider())))
            .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider())))
            .When(x => x.WhenICallTheMiddleware())
            .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
            .BDDfy();
        }
        public void should_call_middleware_withWhitelistClient()
        {
            var downstreamRoute = new DownstreamRoute(new List <Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
                                                      new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
                                                          new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List <string>()
            {
                "ocelotclient2"
            }, false, "", "", new  RateLimitRule("1s", 100, 3), 429))
                                                      .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                      .Build());

            this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .When(x => x.WhenICallTheMiddlewareWithWhiteClient())
            .Then(x => x.ThenresponseStatusCodeIs200())
            .BDDfy();
        }
        public void should_call_add_queries_correctly()
        {
            var downstreamRoute = new DownstreamRoute(new List <UrlPathPlaceholderNameAndValue>(),
                                                      new ReRouteBuilder()
                                                      .WithDownstreamPathTemplate("any old string")
                                                      .WithClaimsToQueries(new List <ClaimToThing>
            {
                new ClaimToThing("UserId", "Subject", "", 0)
            })
                                                      .WithUpstreamHttpMethod("Get")
                                                      .Build());

            this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .And(x => x.GivenTheAddHeadersToRequestReturnsOk())
            .When(x => x.WhenICallTheMiddleware())
            .Then(x => x.ThenTheAddQueriesToRequestIsCalledCorrectly())
            .BDDfy();
        }
Пример #4
0
        public void should_call_claims_to_request_correctly()
        {
            var downstreamRoute = new DownstreamRoute(new List <UrlPathPlaceholderNameAndValue>(),
                                                      new ReRouteBuilder()
                                                      .WithDownstreamPathTemplate("any old string")
                                                      .WithClaimsToClaims(new List <ClaimToThing>
            {
                new ClaimToThing("sub", "UserType", "|", 0)
            })
                                                      .WithUpstreamHttpMethod("Get")
                                                      .Build());

            this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .And(x => x.GivenTheAddClaimsToRequestReturns())
            .When(x => x.WhenICallTheMiddleware())
            .Then(x => x.ThenTheClaimsToRequestIsCalledCorrectly())
            .BDDfy();
        }
Пример #5
0
        public Response <ILoadBalancer> Get(DownstreamRoute route, ServiceProviderConfiguration config)
        {
            try
            {
                Response <ILoadBalancer> result;

                if (_loadBalancers.TryGetValue(route.LoadBalancerKey, out var loadBalancer))
                {
                    loadBalancer = _loadBalancers[route.LoadBalancerKey];

                    if (route.LoadBalancerOptions.Type != loadBalancer.GetType().Name)
                    {
                        result = _factory.Get(route, config);
                        if (result.IsError)
                        {
                            return(new ErrorResponse <ILoadBalancer>(result.Errors));
                        }

                        loadBalancer = result.Data;
                        AddLoadBalancer(route.LoadBalancerKey, loadBalancer);
                    }

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

                result = _factory.Get(route, config);

                if (result.IsError)
                {
                    return(new ErrorResponse <ILoadBalancer>(result.Errors));
                }

                loadBalancer = result.Data;
                AddLoadBalancer(route.LoadBalancerKey, 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 {route.LoadBalancerKey} exception is {ex}"),
                }));
            }
        }
Пример #6
0
        public void should_pass_down_request_id_from_upstream_request()
        {
            var downstreamRoute = new DownstreamRoute(new List <UrlPathPlaceholderNameAndValue>(),
                                                      new ReRouteBuilder()
                                                      .WithDownstreamPathTemplate("any old string")
                                                      .WithRequestIdKey("LSRequestId")
                                                      .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                      .Build());

            var requestId = Guid.NewGuid().ToString();

            this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .And(x => x.GivenTheRequestIdIsAddedToTheRequest("LSRequestId", requestId))
            .When(x => x.WhenICallTheMiddleware())
            .Then(x => x.ThenTheTraceIdIs(requestId))
            .BDDfy();
        }
        private void GivenTheDownstreamRouteIs()
        {
            var reRoute = new ReRouteBuilder()
                          .WithDownstreamReRoute(new DownstreamReRouteBuilder()
                                                 .WithIsCached(true)
                                                 .WithCacheOptions(new CacheOptions(100, "kanken"))
                                                 .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                 .Build())
                          .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                          .Build();

            var downstreamRoute = new DownstreamRoute(new List <PlaceholderNameAndValue>(), reRoute);

            _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
        }
Пример #8
0
        private static OpenApiOperation BuildOperation(Operation descriptor, DownstreamRoute route)
        {
            var httpPath = GetHttpPath(route);

            var operation = new OpenApiOperation
            {
                Tags = descriptor.Tags.Select(x => new OpenApiTag {
                    Name = x
                }).ToList(),
                Summary     = descriptor.Summary,
                Description = descriptor.Description,
                Parameters  = BuildParametersList(descriptor, httpPath),
                RequestBody = BuildRequestBody(descriptor.RequestBody),
                Responses   = BuildResponses(descriptor.Responses)
            };

            AppendAuthErrorResponses(operation, route);

            return(operation);
        }
Пример #9
0
        /// <summary>
        /// 获取下游请求信息
        /// </summary>
        /// <param name="routeConfiguration"></param>
        /// <param name="upstreamQueryString">上游请求的查询字符串</param>
        /// <returns></returns>
        private DownstreamRoute GetDownstreamRoute(FileRouteConfiguration routeConfiguration, string upstreamQueryString)
        {
            DownstreamRoute downstreamRoute = new DownstreamRoute();

            var downstreamHostInfo = GetDownstreamHostString(routeConfiguration.DownstreamHostInfo);

            downstreamRoute.Host = downstreamHostInfo.IP;

            downstreamRoute.Port = int.Parse(downstreamHostInfo.Port);

            downstreamRoute.Scheme = routeConfiguration.DownstreamScheme;

            downstreamRoute.PathTemplate = UriMapper.GetRestfullUri(routeConfiguration.DownstreamPathTemplate, upstreamQueryString);

            downstreamRoute.QueryString = upstreamQueryString;

            downstreamRoute.Authentication = routeConfiguration.Authentication;

            return(downstreamRoute);
        }
Пример #10
0
        public void should_set_pipeline_error_if_cannot_get_load_balancer()
        {
            var downstreamRoute = new DownstreamRoute(new List <Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
                                                      new ReRouteBuilder()
                                                      .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                      .Build());

            var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
                                        .Build();

            this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
            .And(x => GivenTheConfigurationIs(serviceProviderConfig))
            .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .And(x => x.GivenTheLoadBalancerHouseReturnsAnError())
            .When(x => x.WhenICallTheMiddleware())
            .Then(x => x.ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline())
            .BDDfy();
        }
Пример #11
0
        public void should_add_request_id_scoped_repo_for_logging_later()
        {
            var downstreamRoute = new DownstreamRoute(new List <PlaceholderNameAndValue>(),
                                                      new ReRouteBuilder()
                                                      .WithDownstreamPathTemplate("any old string")
                                                      .WithRequestIdKey("LSRequestId")
                                                      .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                      .Build());

            var requestId = Guid.NewGuid().ToString();

            this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .And(x => GivenThereIsNoGlobalRequestId())
            .And(x => x.GivenTheRequestIdIsAddedToTheRequest("LSRequestId", requestId))
            .When(x => x.WhenICallTheMiddleware())
            .Then(x => x.ThenTheTraceIdIs(requestId))
            .And(x => ThenTheRequestIdIsSaved())
            .BDDfy();
        }
Пример #12
0
        public void should_call_scoped_data_repository_correctly()
        {
            var downstreamRoute = new DownstreamRoute(new List <Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
                                                      new ReRouteBuilder()
                                                      .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                      .Build());

            var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
                                        .Build();

            this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
            .And(x => GivenTheConfigurationIs(serviceProviderConfig))
            .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .And(x => x.GivenTheLoadBalancerHouseReturns())
            .And(x => x.GivenTheLoadBalancerReturns())
            .When(x => x.WhenICallTheMiddleware())
            .Then(x => x.ThenTheDownstreamUrlIsReplacedWith("http://127.0.0.1:80/abc?q=123"))
            .BDDfy();
        }
        public async Task <Response <HttpRequestMessage> > Map(HttpRequest request, DownstreamRoute downstreamRoute)
        {
            try
            {
                var requestMessage = new HttpRequestMessage()
                {
                    Content    = await MapContent(request),
                    Method     = MapMethod(request, downstreamRoute),
                    RequestUri = MapUri(request),
                    Version    = downstreamRoute.DownstreamHttpVersion,
                };

                MapHeaders(request, requestMessage);

                return(new OkResponse <HttpRequestMessage>(requestMessage));
            }
            catch (Exception ex)
            {
                return(new ErrorResponse <HttpRequestMessage>(new UnmappableRequestError(ex)));
            }
        }
Пример #14
0
        /// <summary>
        /// 根据上游请求找到下游请求对象
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public DownstreamRoute Get(DownstreamContext context)
        {
            var configuration = context.Configuration;

            var httpContextRequest = context.HttpContext.Request;

            var upstreamUrlPath = httpContextRequest.Path.ToString();

            var upstreamQueryString = httpContextRequest.QueryString.ToString();

            var upstreamHost = httpContextRequest.Headers["Host"];


            var configRoutes = configuration.Routes;

            if (configRoutes == null || configRoutes.Count == 0)
            {
                var error = new ConfigurationError(upstreamUrlPath);
                _errors.Add(error);

                return(null);
            }

            var upstreamUri = $"{upstreamHost}{upstreamUrlPath}";

            //从配置文件里面查找进行
            var configRoute = configRoutes.FirstOrDefault(x => x.UpstreamHost + x.UpstreamPathTemplate == upstreamUri);

            if (configRoute == null)
            {
                var error = new ConfigurationError(upstreamUrlPath);
                _errors.Add(error);

                return(null);
            }

            DownstreamRoute route = GetDownstreamRoute(configRoute, upstreamQueryString);

            return(route);
        }
Пример #15
0
        public PollyQoSProvider(DownstreamRoute route, IOcelotLoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger <PollyQoSProvider>();

            Enum.TryParse(route.QosOptions.TimeoutStrategy, out TimeoutStrategy strategy);

            _timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(route.QosOptions.TimeoutValue), strategy);

            if (route.QosOptions.ExceptionsAllowedBeforeBreaking > 0)
            {
                _circuitBreakerPolicy = Policy
                                        .Handle <HttpRequestException>()
                                        .Or <TimeoutRejectedException>()
                                        .Or <TimeoutException>()
                                        .CircuitBreakerAsync(
                    exceptionsAllowedBeforeBreaking: route.QosOptions.ExceptionsAllowedBeforeBreaking,
                    durationOfBreak: TimeSpan.FromMilliseconds(route.QosOptions.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.");
                }
                    );
            }
            else
            {
                _circuitBreakerPolicy = null;
            }

            CircuitBreaker = new CircuitBreaker(_circuitBreakerPolicy, _timeoutPolicy);
        }
Пример #16
0
        public void should_add_request_id_when_not_on_upstream_request()
        {
            var downstreamRoute = new DownstreamRoute(new List <PlaceholderNameAndValue>(),
                                                      new ReRouteBuilder()
                                                      .WithDownstreamReRoute(new DownstreamReRouteBuilder()
                                                                             .WithDownstreamPathTemplate("any old string")
                                                                             .WithRequestIdKey("LSRequestId")
                                                                             .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                                             .Build())
                                                      .WithUpstreamHttpMethod(new List <string> {
                "Get"
            })
                                                      .Build());

            this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
            .And(x => GivenThereIsNoGlobalRequestId())
            .When(x => x.WhenICallTheMiddleware())
            .Then(x => x.ThenTheTraceIdIsAnything())
            .BDDfy();
        }
        private (string path, string query) CreateServiceFabricUri(DownstreamRequest downstreamRequest, DownstreamRoute downstreamRoute, List <PlaceholderNameAndValue> templatePlaceholderNameAndValues, Response <DownstreamPath> dsPath)
        {
            var query        = downstreamRequest.Query;
            var serviceName  = _replacer.Replace(downstreamRoute.ServiceName, templatePlaceholderNameAndValues);
            var pathTemplate = $"/{serviceName.Data.Value}{dsPath.Data.Value}";

            return(pathTemplate, query);
        }
 public IHttpClient Get(DownstreamRoute key)
 {
     //todo handle error?
     return(_httpClientsCache.TryGetValue(key, out var client) ? client : null);
 }
Пример #19
0
 private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 {
     _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
     _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 }
Пример #20
0
 public Response <ILoadBalancer> Create(DownstreamRoute route, IServiceDiscoveryProvider serviceProvider)
 {
     return(new OkResponse <ILoadBalancer>(new RoundRobin(async() => await serviceProvider.Get())));
 }
 public void Set(DownstreamRoute key, IHttpClient client, TimeSpan expirationTime)
 {
     _httpClientsCache.AddOrUpdate(key, client, (k, oldValue) => client);
 }
Пример #22
0
 private void GivenARoute(DownstreamRoute route)
 {
     _route = route;
 }
Пример #23
0
 private void GivenTheFollowingRequest(DownstreamRoute request)
 {
     _downstreamRoute = request;
 }
Пример #24
0
 private static bool IsAuthenticatedRoute(DownstreamRoute route)
 {
     return(route.IsAuthenticated);
 }
Пример #25
0
        private HttpMessageHandler CreateHttpMessageHandler(HttpMessageHandler httpMessageHandler, DownstreamRoute request)
        {
            //todo handle error
            var handlers = _factory.Get(request).Data;

            handlers
            .Select(handler => handler)
            .Reverse()
            .ToList()
            .ForEach(handler =>
            {
                var delegatingHandler          = handler();
                delegatingHandler.InnerHandler = httpMessageHandler;
                httpMessageHandler             = delegatingHandler;
            });
            return(httpMessageHandler);
        }
Пример #26
0
 private void GivenTheRoute(ServiceProviderConfiguration serviceConfig, DownstreamRoute route)
 {
     _serviceConfig = serviceConfig;
     _route         = route;
 }
Пример #27
0
 public void SetDownstreamRouteForThisRequest(DownstreamRoute downstreamRoute)
 {
     _requestScopedDataRepository.Add("DownstreamRoute", downstreamRoute);
 }
 private static bool ServiceFabricRequest(IInternalConfiguration config, DownstreamRoute downstreamRoute)
 {
     return(config.ServiceProviderConfiguration.Type?.ToLower() == "servicefabric" && downstreamRoute.UseServiceDiscovery);
 }
 private void GivenThereIsAUrlMatch(DownstreamRoute downstreamRoute)
 {
     _downstreamRoute = downstreamRoute;
 }
Пример #30
0
        public static IDictionary <string, string> BuildRequestHeaders(this HttpContext context, DownstreamRoute downstreamRoute, DownstreamRequest downstreamRequest)
        {
            var headers = new Dictionary <string, string>();

            foreach (var key in context.Request.Headers.Keys)
            {
                if (HeadersFilter.IsMatch(key))
                {
                    headers.Add(key, context.Request.Headers[key].FirstOrDefault());
                }
            }

            foreach (var claimToHeader in downstreamRoute.ClaimsToHeaders)
            {
                if (downstreamRequest.Headers.TryGetValues(claimToHeader.ExistingKey, out var values))
                {
                    headers.Add(claimToHeader.ExistingKey, values.FirstOrDefault());
                }
            }

            if (!headers.ContainsKey(_requestIdHeaderName))
            {
                headers[_requestIdHeaderName] = Guid.NewGuid().ToString("N");
            }

            return(headers);
        }