private Route SetUpAggregateRoute(IEnumerable <Route> routes, FileAggregateRoute aggregateRoute, FileGlobalConfiguration globalConfiguration) { var applicableRoutes = new List <DownstreamRoute>(); var allRoutes = routes.SelectMany(x => x.DownstreamRoute); foreach (var routeKey in aggregateRoute.RouteKeys) { var selec = allRoutes.FirstOrDefault(q => q.Key == routeKey); if (selec == null) { return(null); } applicableRoutes.Add(selec); } var upstreamTemplatePattern = _creator.Create(aggregateRoute); var route = new RouteBuilder() .WithUpstreamHttpMethod(aggregateRoute.UpstreamHttpMethod) .WithUpstreamPathTemplate(upstreamTemplatePattern) .WithDownstreamRoutes(applicableRoutes) .WithAggregateRouteConfig(aggregateRoute.RouteKeysConfig) .WithUpstreamHost(aggregateRoute.UpstreamHost) .WithAggregator(aggregateRoute.Aggregator) .Build(); return(route); }
private static bool DoesNotContainRoutesWithSpecificRequestIdKeys(FileAggregateRoute fileAggregateRoute, List <FileRoute> routes) { var routesForAggregate = routes.Where(r => fileAggregateRoute.RouteKeys.Contains(r.Key)); return(routesForAggregate.All(r => string.IsNullOrEmpty(r.RequestIdKey))); }
private static bool IsNotDuplicateIn(FileAggregateRoute route, List <FileAggregateRoute> aggregateRoutes) { var matchingRoutes = aggregateRoutes .Where(r => r.UpstreamPathTemplate == route.UpstreamPathTemplate && r.UpstreamHost == route.UpstreamHost) .ToList(); return(matchingRoutes.Count <= 1); }
public async Task <Response <FileConfiguration> > Get() { var fileConfiguration = new FileConfiguration { GlobalConfiguration = _apiGatewayOptions.GlobalConfiguration }; var apiDescriptionModels = await GetApiDescriptionsAsync(); int foundAggrageRouteCount = 0; foreach (var apiDescriptionModel in apiDescriptionModels) { foreach (var moduleModel in apiDescriptionModel.Value.Modules) { foreach (var controllerModel in moduleModel.Value.Controllers) { foreach (var actionModel in controllerModel.Value.Actions) { var action = actionModel.Value; var downstreamUrl = action.Url.EnsureStartsWith('/'); // TODO: 多个相同的下游路由地址应组合为聚合路由 // TODO: 下游路由地址已添加 var route = fileConfiguration.Routes .Where(route => HasBeenAddedRoute(route, downstreamUrl)) .LastOrDefault(); string aggregateKey = ""; if (route != null) { // TODO: 下游方法已添加 if (route.UpstreamHttpMethod.Any(method => method.Equals(action.HttpMethod, StringComparison.CurrentCultureIgnoreCase))) { if (_apiGatewayOptions.AggrageRouteUrls.Any(url => url.Equals(downstreamUrl))) { foundAggrageRouteCount++; var aggregateRoute = fileConfiguration.Aggregates .Where(route => HasBeenAddedAggregateRoute(route, downstreamUrl)) .FirstOrDefault(); if (aggregateRoute == null) { aggregateRoute = new FileAggregateRoute { RouteIsCaseSensitive = false, // TODO: 可实现自定义的聚合提供装置 Aggregator = nameof(AbpResponseMergeAggregator), UpstreamPathTemplate = downstreamUrl, RouteKeys = new List <string>() }; fileConfiguration.Aggregates.Add(aggregateRoute); } if (route.Key.IsNullOrWhiteSpace()) { route.Key = $"aggregate{foundAggrageRouteCount}"; route.UpstreamPathTemplate = $"/{route.Key}{route.UpstreamPathTemplate}"; aggregateRoute.RouteKeys.Add(route.Key); foundAggrageRouteCount++; } aggregateKey = $"aggregate{foundAggrageRouteCount}"; aggregateRoute.RouteKeys.Add(aggregateKey); } else { continue; } } else { route.UpstreamHttpMethod.Add(action.HttpMethod); continue; } } var newRoute = new FileRoute { Key = aggregateKey, UpstreamPathTemplate = (aggregateKey + downstreamUrl).EnsureStartsWith('/'), DownstreamPathTemplate = downstreamUrl, DangerousAcceptAnyServerCertificateValidator = false }; var baseUrl = apiDescriptionModel.Key; baseUrl = baseUrl.StartsWith("http://") ? baseUrl[7..] : baseUrl;
private bool AllRoutesForAggregateExist(FileAggregateRoute fileAggregateRoute, List <FileRoute> routes) { var routesForAggregate = routes.Where(r => fileAggregateRoute.RouteKeys.Contains(r.Key)); return(routesForAggregate.Count() == fileAggregateRoute.RouteKeys.Count); }