From b28ced4ec5e519081b8824d0c0d39d3e071cb0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E4=BC=9F?= Date: Sun, 19 Jan 2020 18:42:11 +0800 Subject: [PATCH] Use registered scheme from Eureka (#1087) --- src/Ocelot.Provider.Eureka/Eureka.cs | 2 +- .../DownstreamUrlCreatorMiddleware.cs | 5 ++- .../Middleware/LoadBalancingMiddleware.cs | 5 +++ .../ServiceDiscoveryProviderFactory.cs | 2 +- src/Ocelot/Values/ServiceHostAndPort.cs | 7 +++- .../DownstreamUrlCreatorMiddlewareTests.cs | 30 ++++++++++++++++ .../LoadBalancerMiddlewareTests.cs | 36 +++++++++++++++++++ 7 files changed, 83 insertions(+), 4 deletions(-) diff --git a/src/Ocelot.Provider.Eureka/Eureka.cs b/src/Ocelot.Provider.Eureka/Eureka.cs index 8316beac..8a064549 100644 --- a/src/Ocelot.Provider.Eureka/Eureka.cs +++ b/src/Ocelot.Provider.Eureka/Eureka.cs @@ -26,7 +26,7 @@ if (instances != null && instances.Any()) { - services.AddRange(instances.Select(i => new Service(i.ServiceId, new ServiceHostAndPort(i.Host, i.Port), "", "", new List()))); + services.AddRange(instances.Select(i => new Service(i.ServiceId, new ServiceHostAndPort(i.Host, i.Port, i.Uri.Scheme), "", "", new List()))); } return Task.FromResult(services); diff --git a/src/Ocelot/DownstreamUrlCreator/Middleware/DownstreamUrlCreatorMiddleware.cs b/src/Ocelot/DownstreamUrlCreator/Middleware/DownstreamUrlCreatorMiddleware.cs index d2e53b95..7d19d523 100644 --- a/src/Ocelot/DownstreamUrlCreator/Middleware/DownstreamUrlCreatorMiddleware.cs +++ b/src/Ocelot/DownstreamUrlCreator/Middleware/DownstreamUrlCreatorMiddleware.cs @@ -37,7 +37,10 @@ namespace Ocelot.DownstreamUrlCreator.Middleware return; } - context.DownstreamRequest.Scheme = context.DownstreamReRoute.DownstreamScheme; + if (!string.IsNullOrEmpty(context.DownstreamReRoute.DownstreamScheme)) + { + context.DownstreamRequest.Scheme = context.DownstreamReRoute.DownstreamScheme; + } if (ServiceFabricRequest(context)) { diff --git a/src/Ocelot/LoadBalancer/Middleware/LoadBalancingMiddleware.cs b/src/Ocelot/LoadBalancer/Middleware/LoadBalancingMiddleware.cs index 22456430..646af5fe 100644 --- a/src/Ocelot/LoadBalancer/Middleware/LoadBalancingMiddleware.cs +++ b/src/Ocelot/LoadBalancer/Middleware/LoadBalancingMiddleware.cs @@ -45,6 +45,11 @@ namespace Ocelot.LoadBalancer.Middleware context.DownstreamRequest.Port = hostAndPort.Data.DownstreamPort; } + if (!string.IsNullOrEmpty(hostAndPort.Data.Scheme)) + { + context.DownstreamRequest.Scheme = hostAndPort.Data.Scheme; + } + try { await _next.Invoke(context); diff --git a/src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs b/src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs index 1863a206..7a580872 100644 --- a/src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs +++ b/src/Ocelot/ServiceDiscovery/ServiceDiscoveryProviderFactory.cs @@ -34,7 +34,7 @@ namespace Ocelot.ServiceDiscovery foreach (var downstreamAddress in reRoute.DownstreamAddresses) { - var service = new Service(reRoute.ServiceName, new ServiceHostAndPort(downstreamAddress.Host, downstreamAddress.Port), string.Empty, string.Empty, new string[0]); + var service = new Service(reRoute.ServiceName, new ServiceHostAndPort(downstreamAddress.Host, downstreamAddress.Port, reRoute.DownstreamScheme), string.Empty, string.Empty, new string[0]); services.Add(service); } diff --git a/src/Ocelot/Values/ServiceHostAndPort.cs b/src/Ocelot/Values/ServiceHostAndPort.cs index 4a8e3748..fff7edba 100644 --- a/src/Ocelot/Values/ServiceHostAndPort.cs +++ b/src/Ocelot/Values/ServiceHostAndPort.cs @@ -8,8 +8,13 @@ DownstreamPort = downstreamPort; } + public ServiceHostAndPort(string downstreamHost, int downstreamPort, string scheme) + : this(downstreamHost, downstreamPort) => Scheme = scheme; + public string DownstreamHost { get; } - public int DownstreamPort { get; } + public int DownstreamPort { get; } + + public string Scheme { get; } } } diff --git a/test/Ocelot.UnitTests/DownstreamUrlCreator/DownstreamUrlCreatorMiddlewareTests.cs b/test/Ocelot.UnitTests/DownstreamUrlCreator/DownstreamUrlCreatorMiddlewareTests.cs index ffd52b08..7ed6a02a 100644 --- a/test/Ocelot.UnitTests/DownstreamUrlCreator/DownstreamUrlCreatorMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/DownstreamUrlCreator/DownstreamUrlCreatorMiddlewareTests.cs @@ -350,6 +350,36 @@ .BDDfy(); } + [Fact] + public void should_not_replace_by_empty_scheme() + { + var downstreamReRoute = new DownstreamReRouteBuilder() + .WithDownstreamScheme("") + .WithServiceName("Ocelot/OcelotApp") + .WithUseServiceDiscovery(true) + .Build(); + + var downstreamRoute = new DownstreamRoute( + new List(), + new ReRouteBuilder() + .WithDownstreamReRoute(downstreamReRoute) + .Build()); + + var config = new ServiceProviderConfigurationBuilder() + .WithType("ServiceFabric") + .WithHost("localhost") + .WithPort(19081) + .Build(); + + this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) + .And(x => GivenTheServiceProviderConfigIs(config)) + .And(x => x.GivenTheDownstreamRequestUriIs("https://localhost:19081?PartitionKind=test&PartitionKey=1")) + .And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp")) + .When(x => x.WhenICallTheMiddleware()) + .Then(x => x.ThenTheDownstreamRequestUriIs("https://localhost:19081/Ocelot/OcelotApp/api/products/1?PartitionKind=test&PartitionKey=1")) + .BDDfy(); + } + private void GivenTheServiceProviderConfigIs(ServiceProviderConfiguration config) { var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null); diff --git a/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs b/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs index 8d31572a..2705b3b7 100644 --- a/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs @@ -1,3 +1,5 @@ +using System; +using System.Linq.Expressions; using Ocelot.Middleware; namespace Ocelot.UnitTests.LoadBalancer @@ -108,6 +110,26 @@ namespace Ocelot.UnitTests.LoadBalancer .BDDfy(); } + [Fact] + public void should_set_scheme() + { + var downstreamRoute = new DownstreamReRouteBuilder() + .WithUpstreamHttpMethod(new List { "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, new List())) + .And(x => x.GivenTheLoadBalancerHouseReturns()) + .And(x => x.GivenTheLoadBalancerReturnsOk()) + .When(x => x.WhenICallTheMiddleware()) + .Then(x => x.ThenAnHostAndPortIsSetOnPipeline()) + .BDDfy(); + } + private void WhenICallTheMiddleware() { _middleware = new LoadBalancingMiddleware(_next, _loggerFactory.Object, _loadBalancerHouse.Object); @@ -135,6 +157,13 @@ namespace Ocelot.UnitTests.LoadBalancer .ReturnsAsync(_getHostAndPortError); } + private void GivenTheLoadBalancerReturnsOk() + { + _loadBalancer + .Setup(x => x.Lease(It.IsAny())) + .ReturnsAsync(new OkResponse(new ServiceHostAndPort("abc", 123, "https"))); + } + private void GivenTheLoadBalancerReturns() { _hostAndPort = new ServiceHostAndPort("127.0.0.1", 80); @@ -186,6 +215,13 @@ namespace Ocelot.UnitTests.LoadBalancer _downstreamContext.Errors.ShouldBe(_getHostAndPortError.Errors); } + private void ThenAnHostAndPortIsSetOnPipeline() + { + _downstreamContext.DownstreamRequest.Host.ShouldBeEquivalentTo("abc"); + _downstreamContext.DownstreamRequest.Port.ShouldBeEquivalentTo(123); + _downstreamContext.DownstreamRequest.Scheme.ShouldBeEquivalentTo("https"); + } + private void ThenTheDownstreamUrlIsReplacedWith(string expectedUri) { _downstreamContext.DownstreamRequest.ToHttpRequestMessage().RequestUri.OriginalString.ShouldBe(expectedUri);