private void GivenTheDependenciesAreSetUpCorrectly() { _rro = new ReRouteOptions(false, false, false, false, false); _requestId = "testy"; _rrk = "besty"; _upt = new UpstreamPathTemplateBuilder().Build(); _ao = new AuthenticationOptionsBuilder().Build(); _ctt = new List <ClaimToThing>(); _qoso = new QoSOptionsBuilder().Build(); _rlo = new RateLimitOptionsBuilder().Build(); _region = "vesty"; _hho = new HttpHandlerOptionsBuilder().Build(); _ht = new HeaderTransformations(new List <HeaderFindAndReplace>(), new List <HeaderFindAndReplace>(), new List <AddHeader>(), new List <AddHeader>()); _dhp = new List <DownstreamHostAndPort>(); _lbo = new LoadBalancerOptionsBuilder().Build(); _rroCreator.Setup(x => x.Create(It.IsAny <FileReRoute>())).Returns(_rro); _ridkCreator.Setup(x => x.Create(It.IsAny <FileReRoute>(), It.IsAny <FileGlobalConfiguration>())).Returns(_requestId); _rrkCreator.Setup(x => x.Create(It.IsAny <FileReRoute>())).Returns(_rrk); _utpCreator.Setup(x => x.Create(It.IsAny <IReRoute>())).Returns(_upt); _aoCreator.Setup(x => x.Create(It.IsAny <FileReRoute>())).Returns(_ao); _cthCreator.Setup(x => x.Create(It.IsAny <Dictionary <string, string> >())).Returns(_ctt); _qosoCreator.Setup(x => x.Create(It.IsAny <FileQoSOptions>(), It.IsAny <string>(), It.IsAny <List <string> >())).Returns(_qoso); _rloCreator.Setup(x => x.Create(It.IsAny <FileRateLimitRule>(), It.IsAny <FileGlobalConfiguration>())).Returns(_rlo); _rCreator.Setup(x => x.Create(It.IsAny <FileReRoute>())).Returns(_region); _hhoCreator.Setup(x => x.Create(It.IsAny <FileHttpHandlerOptions>())).Returns(_hho); _hfarCreator.Setup(x => x.Create(It.IsAny <FileReRoute>())).Returns(_ht); _daCreator.Setup(x => x.Create(It.IsAny <FileReRoute>())).Returns(_dhp); _lboCreator.Setup(x => x.Create(It.IsAny <FileLoadBalancerOptions>())).Returns(_lbo); }
private void ProcessWithInnerSwaggerForManyDestinationDownstream( ReRouteOptions route, SwaggerDescriptor descriptor, OpenApiDocument innerDocument) { var version = descriptor.Version.ToString(); var upstreamTemplate = RemoveEverything(ReplaceVersion(route.UpstreamPathTemplate, version)); var downstreamTemplate = RemoveEverything(ReplaceVersion(route.DownstreamPathTemplate, version)); var reRoutedPaths = innerDocument.Paths .Select(p => new { path = ReplaceVersion(p.Key, version), openApiPathItem = p.Value }) .Where(p => p.path.StartsWith(downstreamTemplate, StringComparison.OrdinalIgnoreCase)) .ToDictionary(p => p.path.Replace(downstreamTemplate, upstreamTemplate), p => p.openApiPathItem); foreach (var path in reRoutedPaths) { var operations = GetOperationsForPath(route, path.Value); if (operations != null) { AddAuth(route, operations); AddOperations(path.Key, operations); } } }
private async Task <Uri> GetSwaggerUri(SwaggerEndPointConfig endPoint, ReRouteOptions reRoute) { var conf = _configurationCreator.Create(_options.CurrentValue.GlobalConfiguration); var downstreamReroute = new DownstreamReRouteBuilder() .WithUseServiceDiscovery(true) .WithServiceName(endPoint.Service.Name) .WithServiceNamespace(reRoute.ServiceNamespace) .Build(); var serviceProvider = _serviceDiscovery.Get(conf, downstreamReroute); if (serviceProvider.IsError) { throw new InvalidOperationException(GetErrorMessage(endPoint)); } ServiceHostAndPort service = (await serviceProvider.Data.Get()).FirstOrDefault()?.HostAndPort; if (service is null) { throw new InvalidOperationException(GetErrorMessage(endPoint)); } var builder = new UriBuilder(GetScheme(service, reRoute), service.DownstreamHost, service.DownstreamPort); builder.Path = endPoint.Service.Path; return(builder.Uri); }
private void ThenTheFollowingIsReturned(ReRouteOptions expected) { _result.IsAuthenticated.ShouldBe(expected.IsAuthenticated); _result.IsAuthorised.ShouldBe(expected.IsAuthorised); _result.IsCached.ShouldBe(expected.IsCached); _result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting); }
private void AddAuth(ReRouteOptions route, OpenApiPathItem operations) { var req = new OpenApiSecurityRequirement(); var sch = new OpenApiSecurityScheme(); sch.Reference = new OpenApiReference() { Id = "oauth2", Type = ReferenceType.SecurityScheme }; req.TryAdd(sch, new List <string>()); if (!string.IsNullOrEmpty(route.AuthenticationOptions?.AuthenticationProviderKey)) { foreach (var operation in operations.Operations) { operation.Value.Security = new List <OpenApiSecurityRequirement>(); operation.Value.Security.Add(req); operation.Value.Responses.TryAdd("401", new OpenApiResponse() { Description = "Unauthorized" }); } } }
private void RenameAndRemovePaths(IEnumerable <ReRouteOptions> reRoutes, JToken paths, string basePath) { var forRemove = new List <JProperty>(); for (int i = 0; i < paths.Count(); i++) { var path = paths.ElementAt(i) as JProperty; string downstreamPath = path.Name.RemoveSlashFromEnd(); ReRouteOptions reRoute = FindReRoute(reRoutes, path.Name.WithShashEnding(), basePath); if (reRoute != null && RemoveMethods(path, reRoute)) { RenameToken(path, ConvertDownstreamPathToUpstreamPath(downstreamPath, reRoute.DownstreamPath, reRoute.UpstreamPath, basePath)); } else { forRemove.Add(path); } } foreach (JProperty p in forRemove) { p.Remove(); } }
private void ProcessWithInnerSwaggerForSingleDestinationDownstream( ReRouteOptions route, SwaggerDescriptor descriptor, OpenApiDocument innerDocument) { var version = descriptor.Version.ToString(); var upstreamTemplate = ReplaceVersion(route.UpstreamPathTemplate, version); var downstreamTemplate = ReplaceVersion(route.DownstreamPathTemplate, version); if (!innerDocument.Paths .Select(s => ReplaceVersion(s.Key, version).ToLower()) .Contains(downstreamTemplate.ToLower())) { return; } var path = innerDocument.Paths.FirstOrDefault(p => string.Equals( ReplaceVersion(p.Key, version), downstreamTemplate, StringComparison.CurrentCultureIgnoreCase)); var operations = GetOperationsForPath(route, path.Value); if (operations != null) { AddAuth(route, operations); AddOperations(upstreamTemplate, operations); } }
private string GetScheme(ServiceHostAndPort service, ReRouteOptions reRoute) => !reRoute.DownstreamScheme.IsNullOrEmpty() ? reRoute.DownstreamScheme : !service.Scheme.IsNullOrEmpty() ? service.Scheme : service.DownstreamPort switch { 443 => Uri.UriSchemeHttps,
/// <inheritdoc /> public async Task <Uri> GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, ReRouteOptions reRoute) { if (!endPoint.Url.IsNullOrEmpty()) { return(new Uri(endPoint.Url)); } else { return(await GetSwaggerUri(endPoint, reRoute)); } }
/// <summary> /// Goups the re routes by paths. /// </summary> /// <param name="reRouteOptions">The re route options.</param> public static IEnumerable <ReRouteOptions> GroupByPaths(this IEnumerable <ReRouteOptions> reRouteOptions) => reRouteOptions .GroupBy(p => new { p.SwaggerKey, p.UpstreamPathTemplate, p.DownstreamPathTemplate, p.VirtualDirectory }) .Select(p => { ReRouteOptions route = p.First(); return(new ReRouteOptions( p.Key.SwaggerKey, route.UpstreamPathTemplate, route.DownstreamPathTemplate, p.Key.VirtualDirectory, p.Where(r => r.UpstreamHttpMethod != null).SelectMany(r => r.UpstreamHttpMethod))); });
private void ProcessReroute(ReRouteOptions route) { if (string.IsNullOrEmpty(route.SwaggerKey)) { return; } var keysForInnerDoc = _innerDocs.Keys.Where(x => x.Name == route.SwaggerKey); _innerDocs .Where(kv => keysForInnerDoc.Contains(kv.Key)) .Where(kv => kv.Value != null) .ForEach(tuple => ProcessWithInnerSwagger(route, tuple.Key, tuple.Value)); }
private void ProcessWithInnerSwagger( ReRouteOptions route, SwaggerDescriptor descriptor, OpenApiDocument innerDocument) { if (!route.DownstreamPathTemplate.Contains(Constants.EverythingAnchor)) { ProcessWithInnerSwaggerForSingleDestinationDownstream(route, descriptor, innerDocument); return; } if (!route.UpstreamPathTemplate.Contains(Constants.EverythingAnchor)) { throw new InvalidOperationException( $"Can't map upstream ({route.UpstreamPathTemplate}) to downstream ({route.DownstreamPathTemplate})"); } ProcessWithInnerSwaggerForManyDestinationDownstream(route, descriptor, innerDocument); }
private bool RemoveMethods(JProperty path, ReRouteOptions reRoute) { var forRemove = new List <JProperty>(); var method = path.First.First as JProperty; while (method != null) { if (!reRoute.ContainsHttpMethod(method.Name)) { forRemove.Add(method); } method = method.Next as JProperty; } foreach (JProperty m in forRemove) { m.Remove(); } return(path.First.Any()); }
private OpenApiPathItem GetOperationsForPath(ReRouteOptions route, OpenApiPathItem path) { IDictionary <OperationType, OpenApiOperation> operationsByTypes = route.UpstreamHttpMethod == null ? path.Operations : route.UpstreamHttpMethod .Select(x => Enum.TryParse <OperationType>(x, out var result) ? result : (OperationType?)null) .OfType <OperationType>() .ToDictionary( x => x, x => path.Operations.TryGetValue(x, out var result) ? result : null); var operations = new OpenApiPathItem(); foreach (var operationItem in operationsByTypes) { var typedVerb = operationItem.Key; var operation = operationItem.Value; if (operation == null) { _logger.LogWarning($"{typedVerb} not found for {route.DownstreamPath}"); return(null); } var predefinedParams = route.ChangeDownstreamPathTemplate.Keys.Select(s => s.ToLower()).ToList(); predefinedParams.Add(Constants.VersionVariableName); var filteredParameters = operation.Parameters .Where(p => !predefinedParams.Contains(p.Name.ToLower())) .Where(p => !route.AddQueriesToRequest.Keys.Select(k => k.ToLower()).Contains(p.Name.ToLower())); operation.Parameters = filteredParameters.ToList(); operations.AddOperation(typedVerb, operation); } return(operations); }
public Task <Uri> GetSwaggerUriAsync(SwaggerEndPointConfig endPoint, ReRouteOptions reRoute) => Task.FromResult(new Uri(endPoint.Url));
private void GivenTheFollowingOptionsAreReturned(ReRouteOptions fileReRouteOptions) { _fileReRouteOptionsCreator .Setup(x => x.Create(It.IsAny <FileReRoute>())) .Returns(fileReRouteOptions); }
private void WhenICreate() { _result = _creator.Create(_reRoute); }