Feature/automatic routes with sd (#351)

* #340 started looking at supporting automatic routing when using service discovery

* #340 getting old routing tests to pass

* #340 renamed stuff to provider rather than finder, as its not longer finding anything

* #340 working towards supporting dynamic routing

* #340 loads of refactoring to make configuration work with dynamic routing

* #340 refactor consul config code so the registry class owns it

* #340 default to consul to maintain backwards compat

* #340 added docs, finished this branches todos
This commit is contained in:
Tom Pallister
2018-05-14 21:26:10 +01:00
committed by GitHub
parent dadb43ef6f
commit 1e2e953b2c
64 changed files with 2082 additions and 1221 deletions

View File

@ -55,7 +55,7 @@ namespace Ocelot.UnitTests.Configuration
_internalRepo
.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().Build(), "")));
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().Build(), "", It.IsAny<LoadBalancerOptions>(), It.IsAny<string>(), It.IsAny<QoSOptions>(), It.IsAny<HttpHandlerOptions>())));
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
}
@ -140,7 +140,10 @@ namespace Ocelot.UnitTests.Configuration
{
_internalRepo
.Setup(x => x.Get())
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().WithConfigurationKey(key).Build(), "")));
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "",
new ServiceProviderConfigurationBuilder().WithConfigurationKey(key).Build(), "",
new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(),
new HttpHandlerOptionsBuilder().Build())));
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
}

View File

@ -38,7 +38,7 @@ namespace Ocelot.UnitTests.Configuration
{
var fileConfig = new FileConfiguration();
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf");
var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf", new LoadBalancerOptionsBuilder().Build(), "", new QoSOptionsBuilder().Build(), new HttpHandlerOptionsBuilder().Build());
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
.And(x => GivenTheRepoReturns(new OkResponse()))

View File

@ -86,7 +86,7 @@
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" })
.WithReRouteKey("CookieStickySessions:sessionid")
.WithLoadBalancerKey("CookieStickySessions:sessionid")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
@ -199,7 +199,7 @@
.WithDownstreamScheme("http")
.WithUpstreamHttpMethod(new List<string>() {"Get"})
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("localhost", 51878)})
.WithReRouteKey("/laura|Get")
.WithLoadBalancerKey("/laura|Get")
.Build();
var lauraReRoute = new ReRouteBuilder()
@ -218,7 +218,7 @@
.WithDownstreamScheme("http")
.WithUpstreamHttpMethod(new List<string>() { "Get" })
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() { new DownstreamHostAndPort("localhost", 51878) })
.WithReRouteKey("/tom|Get")
.WithLoadBalancerKey("/tom|Get")
.Build();
var tomReRoute = new ReRouteBuilder()
@ -361,7 +361,6 @@
.Build();
var serviceOptions = new ReRouteOptionsBuilder()
.WithIsQos(true)
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
@ -410,7 +409,7 @@
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithReRouteKey("/api/products/{productId}|Get")
.WithLoadBalancerKey("/api/products/{productId}|Get")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
@ -462,7 +461,7 @@
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithDelegatingHandlers(handlers)
.WithReRouteKey("/api/products/{productId}|Get")
.WithLoadBalancerKey("/api/products/{productId}|Get")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
@ -507,7 +506,7 @@
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUseServiceDiscovery(true)
.WithServiceName("ProductService")
.WithReRouteKey("/api/products/{productId}|Get")
.WithLoadBalancerKey("/api/products/{productId}|Get")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
@ -558,7 +557,7 @@
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUseServiceDiscovery(false)
.WithReRouteKey("/api/products/{productId}|Get")
.WithLoadBalancerKey("/api/products/{productId}|Get")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
@ -601,7 +600,7 @@
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
.WithReRouteKey("/api/products/{productId}|Get")
.WithLoadBalancerKey("/api/products/{productId}|Get")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
@ -646,7 +645,7 @@
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithRequestIdKey("blahhhh")
.WithReRouteKey("/api/products/{productId}|Get")
.WithLoadBalancerKey("/api/products/{productId}|Get")
.Build();
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
@ -741,7 +740,7 @@
{
new ClaimToThing("CustomerId", "CustomerId", "", 0),
})
.WithReRouteKey("/api/products/{productId}|Get")
.WithLoadBalancerKey("/api/products/{productId}|Get")
.Build();
var expected = new List<ReRoute>
@ -784,7 +783,7 @@
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"})
.WithAuthenticationOptions(authenticationOptions)
.WithReRouteKey("/api/products/{productId}|Get")
.WithLoadBalancerKey("/api/products/{productId}|Get")
.Build();
var expected = new List<ReRoute>
@ -942,16 +941,15 @@
private void GivenTheQosOptionsCreatorReturns(QoSOptions qosOptions)
{
_qosOptionsCreator
.Setup(x => x.Create(_fileConfiguration.ReRoutes[0]))
.Setup(x => x.Create(_fileConfiguration.ReRoutes[0].QoSOptions, It.IsAny<string>(), It.IsAny<string[]>()))
.Returns(qosOptions);
}
private void ThenTheQosOptionsAre(QoSOptions qosOptions)
{
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
}
private void ThenTheServiceProviderCreatorIsCalledCorrectly()
@ -992,13 +990,13 @@
private void GivenTheFollowingHttpHandlerOptionsAreReturned(HttpHandlerOptions httpHandlerOptions)
{
_httpHandlerOptionsCreator.Setup(x => x.Create(It.IsAny<FileReRoute>()))
_httpHandlerOptionsCreator.Setup(x => x.Create(It.IsAny<FileHttpHandlerOptions>()))
.Returns(httpHandlerOptions);
}
private void ThenTheHttpHandlerOptionsCreatorIsCalledCorrectly()
{
_httpHandlerOptionsCreator.Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once());
_httpHandlerOptionsCreator.Verify(x => x.Create(_fileConfiguration.ReRoutes[0].HttpHandlerOptions), Times.Once());
}
private void GivenTheDownstreamAddresses()

View File

@ -103,7 +103,7 @@ namespace Ocelot.UnitTests.Configuration
private void WhenICreateHttpHandlerOptions()
{
_httpHandlerOptions = _httpHandlerOptionsCreator.Create(_fileReRoute);
_httpHandlerOptions = _httpHandlerOptionsCreator.Create(_fileReRoute.HttpHandlerOptions);
}
private void ThenTheFollowingOptionsReturned(HttpHandlerOptions expected)

View File

@ -105,6 +105,10 @@ namespace Ocelot.UnitTests.Configuration
public ServiceProviderConfiguration ServiceProviderConfiguration => throw new NotImplementedException();
public string RequestId {get;}
public LoadBalancerOptions LoadBalancerOptions { get; }
public string DownstreamScheme { get; }
public QoSOptions QoSOptions { get; }
public HttpHandlerOptions HttpHandlerOptions { get; }
}
}
}

View File

@ -50,7 +50,7 @@ namespace Ocelot.UnitTests.Configuration
private void WhenICreate()
{
_result = _creator.Create(_fileReRoute);
_result = _creator.Create(_fileReRoute.QoSOptions);
}
private void ThenTheFollowingIsReturned(QoSOptions expected)
@ -60,4 +60,4 @@ namespace Ocelot.UnitTests.Configuration
_result.TimeoutValue.ShouldBe(expected.TimeoutValue);
}
}
}
}

View File

@ -29,11 +29,6 @@ namespace Ocelot.UnitTests.Configuration
{
EnableRateLimiting = true
},
QoSOptions = new FileQoSOptions
{
ExceptionsAllowedBeforeBreaking = 1,
TimeoutValue = 1
},
AuthenticationOptions = new FileAuthenticationOptions()
{
AuthenticationProviderKey = "Test"
@ -52,7 +47,6 @@ namespace Ocelot.UnitTests.Configuration
.WithIsAuthenticated(true)
.WithIsAuthorised(true)
.WithIsCached(true)
.WithIsQos(true)
.WithRateLimiting(true)
.Build();
@ -76,9 +70,8 @@ namespace Ocelot.UnitTests.Configuration
{
_result.IsAuthenticated.ShouldBe(expected.IsAuthenticated);
_result.IsAuthorised.ShouldBe(expected.IsAuthorised);
_result.IsQos.ShouldBe(expected.IsQos);
_result.IsCached.ShouldBe(expected.IsCached);
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
}
}
}
}