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); }
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}") })); } }
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); }
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); }
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; }
private void GivenThereIsAQoSProvider(ReRoute reRoute, IQoSProvider qoSProvider) { _reRoute = reRoute; _qoSProvider = qoSProvider; _factory.Setup(x => x.Get(_reRoute)).Returns(_qoSProvider); _getResult = _qosProviderHouse.Get(reRoute); }
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); } } }
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}") })); } }
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); }
public IQoSProvider Get(ReRoute reRoute) { if (reRoute.IsQos) { return(new PollyQoSProvider(reRoute, _loggerFactory)); } return(new NoQoSProvider()); }
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))); }
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]); } }
/// <summary> /// 编辑信息 /// </summary> public async Task EditModel(ReRoute input) { if (input.ReRouteId > 0) { await _dbContext.Updateable(input).ExecuteCommandAsync(); return; } await _dbContext.Insertable(input).ExecuteCommandAsync(); }
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); } }
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); }
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); } }
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); }
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); } }
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); }
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); }
private void GivenTheReRoute(ReRoute reRoute) { _reRoute = reRoute; }
private void GivenTheFollowing(ReRoute reRoute) { _reRoute = reRoute; }
private static bool IsAuthenticatedRoute(ReRoute reRoute) { return(reRoute.IsAuthenticated); }
private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(ReRoute reRoute) { _reRoute = reRoute; _factory.Setup(x => x.Get(_reRoute)).Returns(new FakePollyQoSProvider()); _getResult = _qosProviderHouse.Get(_reRoute); }