public void should_return_response_200_with_simple_url_and_any_upstream_http_method() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, DownstreamScheme = "http", UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string>(), } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_return_response_200_when_global_ignore_case_sensitivity_set() { int port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/api/products/{productId}", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, DownstreamScheme = "http", UpstreamPathTemplate = "/products/{productId}", UpstreamHttpMethod = new List <string> { "Get" }, } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/api/products/1", 200, "Some Product")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .BDDfy(); }
public void should_log_warning_if_downstream_service_returns_internal_server_error() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/", UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, }, }, DownstreamScheme = "http", }, }, }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningWithLogger()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenWarningShouldBeLogged()) .BDDfy(); }
public void should_return_not_found() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/products", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/products/{productId}", UpstreamHttpMethod = new List <string> { "Get" } } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/products", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound)) .BDDfy(); }
public void should_not_add_trailing_slash_to_downstream_url() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/api/products/{productId}", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/products/{productId}", UpstreamHttpMethod = new List <string> { "Get" }, } } }; this.Given(x => GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/api/products/1", 200, "Some Product")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/1")) .Then(x => ThenTheDownstreamUrlPathShouldBe("/api/products/1")) .BDDfy(); }
public void should_not_match_forward_slash_in_pattern_before_next_forward_slash() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/api/v{apiVersion}/cards", DownstreamScheme = "http", UpstreamPathTemplate = "/api/v{apiVersion}/cards", UpstreamHttpMethod = new List <string> { "Get" }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, Priority = 1 } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/api/v1/aaaaaaaaa/cards", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/api/v1/aaaaaaaaa/cards")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound)) .BDDfy(); }
public void should_handle_request_to_poll_consul_for_downstream_service_and_make_request() { int consulPort = RandomPortFinder.GetRandomPort(); const string serviceName = "web"; int downstreamServicePort = RandomPortFinder.GetRandomPort(); var downstreamServiceOneUrl = $"http://localhost:{downstreamServicePort}"; var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}"; var serviceEntryOne = new ServiceEntry() { Service = new AgentService() { Service = serviceName, Address = "localhost", Port = downstreamServicePort, ID = $"web_90_0_2_224_{downstreamServicePort}", Tags = new[] { "version-v1" } }, }; var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/api/home", DownstreamScheme = "http", UpstreamPathTemplate = "/home", UpstreamHttpMethod = new List <string> { "Get", "Options" }, ServiceName = serviceName, LoadBalancerOptions = new FileLoadBalancerOptions { Type = "LeastConnection" }, } }, GlobalConfiguration = new FileGlobalConfiguration() { ServiceDiscoveryProvider = new FileServiceDiscoveryProvider() { Host = "localhost", Port = consulPort, Type = "PollConsul", PollingInterval = 0, Namespace = string.Empty } } }; this.Given(x => x.GivenThereIsAServiceRunningOn(downstreamServiceOneUrl, "/api/home", 200, "Hello from Laura")) .And(x => x.GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, serviceName)) .And(x => x.GivenTheServicesAreRegisteredWithConsul(serviceEntryOne)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningWithConsul()) .When(x => _steps.WhenIGetUrlOnTheApiGatewayWaitingForTheResponseToBeOk("/home")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_return_response_304_when_service_returns_304() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/{everything}", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/{everything}", UpstreamHttpMethod = new List <string> { "Get" }, } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/inline.132.bundle.js", 304)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/inline.132.bundle.js")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotModified)) .BDDfy(); }
public void should_proxy_websocket_input_to_downstream_service() { var downstreamPort = RandomPortFinder.GetRandomPort(); var downstreamHost = "localhost"; var config = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { UpstreamPathTemplate = "/", DownstreamPathTemplate = "/ws", DownstreamScheme = "ws", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = downstreamHost, Port = downstreamPort } } } } }; this.Given(_ => _steps.GivenThereIsAConfiguration(config)) .And(_ => _steps.StartFakeOcelotWithWebSockets()) .And(_ => StartFakeDownstreamService($"http://{downstreamHost}:{downstreamPort}", "/ws")) .When(_ => StartClient("ws://localhost:5000/")) .Then(_ => _firstRecieved.Count.ShouldBe(10)) .BDDfy(); }
public void should_use_token_to_make_request_to_consul() { var token = "abctoken"; var consulPort = RandomPortFinder.GetRandomPort(); var serviceName = "web"; var servicePort = RandomPortFinder.GetRandomPort(); var downstreamServiceOneUrl = $"http://localhost:{servicePort}"; var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}"; var serviceEntryOne = new ServiceEntry() { Service = new AgentService() { Service = serviceName, Address = "localhost", Port = servicePort, ID = "web_90_0_2_224_8080", Tags = new[] { "version-v1" } }, }; var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/api/home", DownstreamScheme = "http", UpstreamPathTemplate = "/home", UpstreamHttpMethod = new List <string> { "Get", "Options" }, ServiceName = serviceName, LoadBalancerOptions = new FileLoadBalancerOptions { Type = "LeastConnection" }, } }, GlobalConfiguration = new FileGlobalConfiguration() { ServiceDiscoveryProvider = new FileServiceDiscoveryProvider() { Host = "localhost", Port = consulPort, Token = token } } }; this.Given(_ => GivenThereIsAServiceRunningOn(downstreamServiceOneUrl, "/api/home", 200, "Hello from Laura")) .And(_ => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, serviceName)) .And(_ => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne)) .And(_ => _steps.GivenThereIsAConfiguration(configuration)) .And(_ => _steps.GivenOcelotIsRunningWithConsul()) .When(_ => _steps.WhenIGetUrlOnTheApiGateway("/home")) .Then(_ => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(_ => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .And(_ => _receivedToken.ShouldBe(token)) .BDDfy(); }
public void should_return_reason_phrase() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/", "some reason")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .And(_ => _steps.ThenTheReasonPhraseIs("some reason")) .BDDfy(); }
public void should_use_consul_service_discovery_and_load_balance_request_no_re_routes() { var consulPort = RandomPortFinder.GetRandomPort(); var serviceName = "product"; var serviceOnePort = RandomPortFinder.GetRandomPort(); var serviceTwoPort = RandomPortFinder.GetRandomPort(); var downstreamServiceOneUrl = $"http://localhost:{serviceOnePort}"; var downstreamServiceTwoUrl = $"http://localhost:{serviceTwoPort}"; var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}"; var serviceEntryOne = new ServiceEntry() { Service = new AgentService() { Service = serviceName, Address = "localhost", Port = serviceOnePort, ID = Guid.NewGuid().ToString(), Tags = new string[0] }, }; var serviceEntryTwo = new ServiceEntry() { Service = new AgentService() { Service = serviceName, Address = "localhost", Port = serviceTwoPort, ID = Guid.NewGuid().ToString(), Tags = new string[0] }, }; var configuration = new FileConfiguration { GlobalConfiguration = new FileGlobalConfiguration() { ServiceDiscoveryProvider = new FileServiceDiscoveryProvider() { Scheme = "http", Host = "localhost", Port = consulPort }, LoadBalancerOptions = new FileLoadBalancerOptions { Type = "LeastConnection" }, DownstreamScheme = "http" } }; this.Given(x => x.GivenProductServiceOneIsRunning(downstreamServiceOneUrl, 200)) .And(x => x.GivenProductServiceTwoIsRunning(downstreamServiceTwoUrl, 200)) .And(x => x.GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, serviceName)) .And(x => x.GivenTheServicesAreRegisteredWithConsul(serviceEntryOne, serviceEntryTwo)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningWithConsul()) .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimes($"/{serviceName}/", 50)) .Then(x => x.ThenTheTwoServicesShouldHaveBeenCalledTimes(50)) .And(x => x.ThenBothServicesCalledRealisticAmountOfTimes(24, 26)) .BDDfy(); }
public void should_return_response_200_authorising_route() { int port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, DownstreamScheme = "http", UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, AuthenticationOptions = new FileAuthenticationOptions { AuthenticationProviderKey = "Test" }, AddHeadersToRequest = { { "CustomerId", "Claims[CustomerId] > value" }, { "LocationId", "Claims[LocationId] > value" }, { "UserType", "Claims[sub] > value[0] > |" }, { "UserId", "Claims[sub] > value[1] > |" } }, AddClaimsToRequest = { { "CustomerId", "Claims[CustomerId] > value" }, { "UserType", "Claims[sub] > value[0] > |" }, { "UserId", "Claims[sub] > value[1] > |" } }, RouteClaimsRequirement = { { "UserType", "registered" } } } } }; this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt)) .And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, "Hello from Laura")) .And(x => _steps.GivenIHaveAToken(_identityServerRootUrl)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning(_options, "Test")) .And(x => _steps.GivenIHaveAddedATokenToMyRequest()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_call_withratelimiting() { int port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/api/ClientRateLimit", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, DownstreamScheme = "http", UpstreamPathTemplate = "/api/ClientRateLimit", UpstreamHttpMethod = new List <string> { "Get" }, RequestIdKey = _steps.RequestIdKey, RateLimitOptions = new FileRateLimitRule() { EnableRateLimiting = true, ClientWhitelist = new List <string>(), Limit = 3, Period = "1s", PeriodTimespan = 1000 } } }, GlobalConfiguration = new FileGlobalConfiguration() { RateLimitOptions = new FileRateLimitOptions() { ClientIdHeader = "ClientId", DisableRateLimitHeaders = false, QuotaExceededMessage = "", RateLimitCounterPrefix = "", HttpStatusCode = 428 }, RequestIdKey = "oceclientrequest" } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/api/ClientRateLimit")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 1)) .Then(x => _steps.ThenTheStatusCodeShouldBe(200)) .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 2)) .Then(x => _steps.ThenTheStatusCodeShouldBe(200)) .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 1)) .Then(x => _steps.ThenTheStatusCodeShouldBe(428)) .BDDfy(); }
public void should_return_200_and_change_downstream_path() { var user = new TestUser() { Username = "******", Password = "******", SubjectId = "registered|1231231", }; int port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/users/{userId}", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, }, }, DownstreamScheme = "http", UpstreamPathTemplate = "/users", UpstreamHttpMethod = new List <string> { "Get" }, AuthenticationOptions = new FileAuthenticationOptions { AuthenticationProviderKey = "Test", AllowedScopes = new List <string> { "openid", "offline_access", "api", }, }, ChangeDownstreamPathTemplate = { { "userId", "Claims[sub] > value[1] > |" }, }, }, }, }; this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt, user)) .And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200)) .And(x => _steps.GivenIHaveAToken(_identityServerRootUrl)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning(_options, "Test")) .And(x => _steps.GivenIHaveAddedATokenToMyRequest()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/users")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("UserId: 1231231")) .And(x => _downstreamFinalPath.ShouldBe("/users/1231231")) .BDDfy(); }
public void bug() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/api/v1/vacancy", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/vacancy/", UpstreamHttpMethod = new List <string> { "Options", "Put", "Get", "Post", "Delete" }, LoadBalancerOptions = new FileLoadBalancerOptions { Type = "LeastConnection" } }, new FileReRoute { DownstreamPathTemplate = "/api/v1/vacancy/{vacancyId}", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/vacancy/{vacancyId}", UpstreamHttpMethod = new List <string> { "Options", "Put", "Get", "Post", "Delete" }, LoadBalancerOptions = new FileLoadBalancerOptions { Type = "LeastConnection" } } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/api/v1/vacancy/1", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/vacancy/1")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_cache_two_http_client_different_re_route() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List<FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", DownstreamHostAndPorts = new List<FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/", UpstreamHttpMethod = new List<string> { "Get" }, }, new FileReRoute { DownstreamPathTemplate = "/two", DownstreamScheme = "http", DownstreamHostAndPorts = new List<FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/two", UpstreamHttpMethod = new List<string> { "Get" }, } } }; var cache = new FakeHttpClientCache(); this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningWithFakeHttpClientCache(cache)) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/two")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/two")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/two")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .And(x => cache.Count.ShouldBe(2)) .BDDfy(); }
public void should_use_priority() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/goods/{url}", DownstreamScheme = "http", UpstreamPathTemplate = "/goods/{url}", UpstreamHttpMethod = new List <string> { "Get" }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = 53879, } }, Priority = 0 }, new FileReRoute { DownstreamPathTemplate = "/goods/delete", DownstreamScheme = "http", UpstreamPathTemplate = "/goods/delete", UpstreamHttpMethod = new List <string> { "Get" }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/goods/delete", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/goods/delete")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_return_tracing_header() { int port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/api/values", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/api001/values", UpstreamHttpMethod = new List <string> { "Get" }, HttpHandlerOptions = new FileHttpHandlerOptions { UseTracing = true }, DownstreamHeaderTransform = new Dictionary <string, string>() { { "Trace-Id", "{TraceId}" }, { "Tom", "Laura" } } } } }; var butterflyPort = RandomPortFinder.GetRandomPort(); var butterflyUrl = $"http://localhost:{butterflyPort}"; var fakeTracer = new FakeTracer(); this.Given(x => GivenFakeOpenTracing(butterflyUrl)) .And(x => GivenServiceOneIsRunning($"http://localhost:{port}", "/api/values", 200, "Hello from Laura", butterflyUrl)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningUsingOpenTracing(fakeTracer)) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/api001/values")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .And(x => _steps.ThenTheTraceHeaderIsSet("Trace-Id")) .And(x => _steps.ThenTheResponseHeaderIs("Tom", "Laura")) .BDDfy(); }
public void should_call_global_di_handlers_multiple_times() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningWithGlobalHandlerRegisteredInDi <FakeHandlerAgain>()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_return_response_200_favouring_forward_slash_route_because_it_is_first() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, }, new FileRoute { DownstreamPathTemplate = "/{url}", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = 51879, } }, UpstreamPathTemplate = "/{url}", UpstreamHttpMethod = new List <string> { "Get" }, } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_fix_issue_271() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/api/v1/{everything}", DownstreamScheme = "http", UpstreamPathTemplate = "/api/v1/{everything}", UpstreamHttpMethod = new List <string> { "Get", "Put", "Post" }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, }, new FileReRoute { DownstreamPathTemplate = "/connect/token", DownstreamScheme = "http", UpstreamPathTemplate = "/connect/token", UpstreamHttpMethod = new List <string> { "Post" }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = 5001, } }, } } }; this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/api/v1/modules/Test", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/api/v1/modules/Test")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_load_balance_request_with_least_connection() { int portOne = RandomPortFinder.GetRandomPort(); int portTwo = RandomPortFinder.GetRandomPort(); var downstreamServiceOneUrl = $"http://localhost:{portOne}"; var downstreamServiceTwoUrl = $"http://localhost:{portTwo}"; var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, LoadBalancerOptions = new FileLoadBalancerOptions { Type = nameof(LeastConnection) }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = portOne }, new FileHostAndPort { Host = "localhost", Port = portTwo } } } }, GlobalConfiguration = new FileGlobalConfiguration() { } }; this.Given(x => x.GivenProductServiceOneIsRunning(downstreamServiceOneUrl, 200)) .And(x => x.GivenProductServiceTwoIsRunning(downstreamServiceTwoUrl, 200)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimes("/", 50)) .Then(x => x.ThenTheTwoServicesShouldHaveBeenCalledTimes(50)) .And(x => x.ThenBothServicesCalledRealisticAmountOfTimes(24, 26)) .BDDfy(); }
public void should_open_circuit_breaker_then_close() { var port = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { ReRoutes = new List <FileReRoute> { new FileReRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = port, } }, UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, QoSOptions = new FileQoSOptions { ExceptionsAllowedBeforeBreaking = 1, TimeoutValue = 500, DurationOfBreak = 1000 }, } } }; this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn($"http://localhost:{port}", "Hello from Laura")) .Given(x => _steps.GivenThereIsAConfiguration(configuration)) .Given(x => _steps.GivenOcelotIsRunningWithPolly()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .Given(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Given(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable)) .Given(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Given(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable)) .Given(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Given(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.ServiceUnavailable)) .Given(x => x.GivenIWaitMilliseconds(3000)) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_use_same_downstream_host() { var downstreamPortOne = RandomPortFinder.GetRandomPort(); var downstreamPortTwo = RandomPortFinder.GetRandomPort(); var downstreamServiceOneUrl = $"http://localhost:{downstreamPortOne}"; var downstreamServiceTwoUrl = $"http://localhost:{downstreamPortTwo}"; var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, LoadBalancerOptions = new FileLoadBalancerOptions { Type = "CookieStickySessions", Key = "sessionid", Expiry = 300000 }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = downstreamPortOne }, new FileHostAndPort { Host = "localhost", Port = downstreamPortTwo } } } } }; this.Given(x => x.GivenProductServiceOneIsRunning(downstreamServiceOneUrl, 200)) .And(x => x.GivenProductServiceTwoIsRunning(downstreamServiceTwoUrl, 200)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimes("/", 10, "sessionid", "123")) .Then(x => x.ThenTheFirstServiceIsCalled(10)) .Then(x => x.ThenTheSecondServiceIsCalled(0)) .BDDfy(); }
public void should_load_balance_request_with_custom_load_balancer() { var downstreamPortOne = RandomPortFinder.GetRandomPort(); var downstreamPortTwo = RandomPortFinder.GetRandomPort(); var downstreamServiceOneUrl = $"http://localhost:{downstreamPortOne}"; var downstreamServiceTwoUrl = $"http://localhost:{downstreamPortTwo}"; var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, LoadBalancerOptions = new FileLoadBalancerOptions { Type = nameof(CustomLoadBalancer) }, DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = downstreamPortOne, }, new FileHostAndPort { Host = "localhost", Port = downstreamPortTwo, }, }, }, }, GlobalConfiguration = new FileGlobalConfiguration(), }; Func <IServiceProvider, DownstreamRoute, IServiceDiscoveryProvider, CustomLoadBalancer> loadBalancerFactoryFunc = (serviceProvider, route, serviceDiscoveryProvider) => new CustomLoadBalancer(serviceDiscoveryProvider.Get); this.Given(x => x.GivenProductServiceOneIsRunning(downstreamServiceOneUrl, 200)) .And(x => x.GivenProductServiceTwoIsRunning(downstreamServiceTwoUrl, 200)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningWithCustomLoadBalancer(loadBalancerFactoryFunc)) .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimes("/", 50)) .Then(x => x.ThenTheTwoServicesShouldHaveBeenCalledTimes(50)) .And(x => x.ThenBothServicesCalledRealisticAmountOfTimes(24, 26)) .BDDfy(); }
public void should_handle_request_to_consul_for_downstream_service_and_make_request_no_re_routes() { int consulPort = RandomPortFinder.GetRandomPort(); const string serviceName = "web"; int downstreamServicePort = RandomPortFinder.GetRandomPort(); var downstreamServiceOneUrl = $"http://localhost:{downstreamServicePort}"; var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}"; var serviceEntryOne = new ServiceEntry() { Service = new AgentService() { Service = serviceName, Address = "localhost", Port = downstreamServicePort, ID = "web_90_0_2_224_8080", Tags = new[] { "version-v1" } }, }; var configuration = new FileConfiguration { GlobalConfiguration = new FileGlobalConfiguration { ServiceDiscoveryProvider = new FileServiceDiscoveryProvider { Scheme = "http", Host = "localhost", Port = consulPort }, DownstreamScheme = "http", HttpHandlerOptions = new FileHttpHandlerOptions { AllowAutoRedirect = true, UseCookieContainer = true, UseTracing = false } } }; this.Given(x => x.GivenThereIsAServiceRunningOn(downstreamServiceOneUrl, "/something", 200, "Hello from Laura")) .And(x => x.GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, serviceName)) .And(x => x.GivenTheServicesAreRegisteredWithConsul(serviceEntryOne)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningWithConsul()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/web/something")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public void should_return_response_200_with_simple_url() { int consulPort = RandomPortFinder.GetRandomPort(); int servicePort = RandomPortFinder.GetRandomPort(); var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", DownstreamHostAndPorts = new List <FileHostAndPort> { new FileHostAndPort { Host = "localhost", Port = servicePort, } }, UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, } }, GlobalConfiguration = new FileGlobalConfiguration() { ServiceDiscoveryProvider = new FileServiceDiscoveryProvider() { Scheme = "http", Host = "localhost", Port = consulPort } } }; var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}"; this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, "")) .And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{servicePort}", "", 200, "Hello from Laura")) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningUsingConsulToStoreConfig()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .BDDfy(); }
public ClaimsToQueryStringForwardingTests() { _steps = new Steps(); var identityServerPort = RandomPortFinder.GetRandomPort(); _identityServerRootUrl = $"http://localhost:{identityServerPort}"; _options = o => { o.Authority = _identityServerRootUrl; o.ApiName = "api"; o.RequireHttpsMetadata = false; o.SupportedTokens = SupportedTokens.Both; o.ApiSecret = "secret"; }; }
public void should_use_eureka_service_discovery_and_make_request() { var eurekaPort = 8761; var serviceName = "product"; var downstreamServicePort = RandomPortFinder.GetRandomPort(); var downstreamServiceOneUrl = $"http://localhost:{downstreamServicePort}"; var fakeEurekaServiceDiscoveryUrl = $"http://localhost:{eurekaPort}"; var instanceOne = new FakeEurekaService(serviceName, "localhost", downstreamServicePort, false, new Uri($"http://localhost:{downstreamServicePort}"), new Dictionary <string, string>()); var configuration = new FileConfiguration { Routes = new List <FileRoute> { new FileRoute { DownstreamPathTemplate = "/", DownstreamScheme = "http", UpstreamPathTemplate = "/", UpstreamHttpMethod = new List <string> { "Get" }, ServiceName = serviceName, LoadBalancerOptions = new FileLoadBalancerOptions { Type = "LeastConnection" }, }, }, GlobalConfiguration = new FileGlobalConfiguration() { ServiceDiscoveryProvider = new FileServiceDiscoveryProvider() { Type = "Eureka", }, }, }; this.Given(x => x.GivenEurekaProductServiceOneIsRunning(downstreamServiceOneUrl)) .And(x => x.GivenThereIsAFakeEurekaServiceDiscoveryProvider(fakeEurekaServiceDiscoveryUrl, serviceName)) .And(x => x.GivenTheServicesAreRegisteredWithEureka(instanceOne)) .And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunningWithEureka()) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(_ => _steps.ThenTheResponseBodyShouldBe(nameof(EurekaServiceDiscoveryTests))) .BDDfy(); }