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(); }
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(); }
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}"), })); } }
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]; }
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); }
/// <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); }
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(); }
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(); }
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))); } }
/// <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); }
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); }
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); }
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute) { _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues; _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[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); }
private void GivenARoute(DownstreamRoute route) { _route = route; }
private void GivenTheFollowingRequest(DownstreamRoute request) { _downstreamRoute = request; }
private static bool IsAuthenticatedRoute(DownstreamRoute route) { return(route.IsAuthenticated); }
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); }
private void GivenTheRoute(ServiceProviderConfiguration serviceConfig, DownstreamRoute route) { _serviceConfig = serviceConfig; _route = route; }
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; }
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); }