mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 14:02:49 +08:00
plugged load balancer middleware into Ocelot pipeline, load balanced downstream host and port now used by url creator middleware
This commit is contained in:
parent
aef6507da3
commit
f285b0e0ad
@ -6,6 +6,7 @@ namespace Ocelot.Configuration.Builder
|
||||
{
|
||||
public class ReRouteBuilder
|
||||
{
|
||||
private string _loadBalancerKey;
|
||||
private string _downstreamPathTemplate;
|
||||
private string _upstreamTemplate;
|
||||
private string _upstreamTemplatePattern;
|
||||
@ -199,6 +200,12 @@ namespace Ocelot.Configuration.Builder
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReRouteBuilder WithLoadBalancerKey(string loadBalancerKey)
|
||||
{
|
||||
_loadBalancerKey = loadBalancerKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReRoute Build()
|
||||
{
|
||||
return new ReRoute(new DownstreamPathTemplate(_downstreamPathTemplate), _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern,
|
||||
@ -206,7 +213,7 @@ namespace Ocelot.Configuration.Builder
|
||||
_requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement,
|
||||
_isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _serviceName,
|
||||
_useServiceDiscovery, _serviceDiscoveryAddress, _serviceDiscoveryProvider, _downstreamScheme, _loadBalancer,
|
||||
_downstreamHost, _dsPort);
|
||||
_downstreamHost, _dsPort, _loadBalancerKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +104,9 @@ namespace Ocelot.Configuration.Creator
|
||||
&& !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Address)
|
||||
&& !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
|
||||
|
||||
//note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain
|
||||
var loadBalancerKey = $"{fileReRoute.UpstreamTemplate}{fileReRoute.UpstreamHttpMethod}";
|
||||
|
||||
ReRoute reRoute;
|
||||
|
||||
if (isAuthenticated)
|
||||
@ -124,7 +127,7 @@ namespace Ocelot.Configuration.Creator
|
||||
requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
|
||||
fileReRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
|
||||
globalConfiguration?.ServiceDiscoveryProvider?.Address, fileReRoute.DownstreamScheme,
|
||||
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort);
|
||||
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort,loadBalancerKey);
|
||||
}
|
||||
|
||||
reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate), fileReRoute.UpstreamTemplate,
|
||||
@ -134,11 +137,10 @@ namespace Ocelot.Configuration.Creator
|
||||
requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
|
||||
fileReRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
|
||||
globalConfiguration?.ServiceDiscoveryProvider?.Address, fileReRoute.DownstreamScheme,
|
||||
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort);
|
||||
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort,loadBalancerKey);
|
||||
|
||||
var loadBalancer = _loadBalanceFactory.Get(reRoute);
|
||||
//todo - not sure if this is the correct key, but this is probably the only unique key i can think of
|
||||
_loadBalancerHouse.Add($"{fileReRoute.UpstreamTemplate}{fileReRoute.UpstreamHttpMethod}", loadBalancer);
|
||||
_loadBalancerHouse.Add(reRoute.LoadBalancerKey, loadBalancer);
|
||||
return reRoute;
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,9 @@ namespace Ocelot.Configuration
|
||||
List<ClaimToThing> claimsToClaims, Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, List<ClaimToThing> claimsToQueries,
|
||||
string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string serviceName, bool useServiceDiscovery,
|
||||
string serviceDiscoveryProvider, string serviceDiscoveryAddress,
|
||||
string downstreamScheme, string loadBalancer, string downstreamHost, int downstreamPort)
|
||||
string downstreamScheme, string loadBalancer, string downstreamHost, int downstreamPort, string loadBalancerKey)
|
||||
{
|
||||
LoadBalancerKey = loadBalancerKey;
|
||||
LoadBalancer = loadBalancer;
|
||||
DownstreamHost = downstreamHost;
|
||||
DownstreamPort = downstreamPort;
|
||||
@ -39,6 +40,7 @@ namespace Ocelot.Configuration
|
||||
ServiceDiscoveryAddress = serviceDiscoveryAddress;
|
||||
DownstreamScheme = downstreamScheme;
|
||||
}
|
||||
public string LoadBalancerKey {get;private set;}
|
||||
public DownstreamPathTemplate DownstreamPathTemplate { get; private set; }
|
||||
public string UpstreamTemplate { get; private set; }
|
||||
public string UpstreamTemplatePattern { get; private set; }
|
||||
|
@ -47,15 +47,12 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
|
||||
|
||||
var dsScheme = DownstreamRoute.ReRoute.DownstreamScheme;
|
||||
|
||||
//todo - get this out of scoped data repo?
|
||||
var dsHostAndPort = new HostAndPort(DownstreamRoute.ReRoute.DownstreamHost,
|
||||
DownstreamRoute.ReRoute.DownstreamPort);
|
||||
var dsHostAndPort = HostAndPort;
|
||||
|
||||
var dsUrl = _urlBuilder.Build(dsPath.Data.Value, dsScheme, dsHostAndPort);
|
||||
|
||||
if (dsUrl.IsError)
|
||||
{
|
||||
//todo - release the lb connection?
|
||||
_logger.LogDebug("IUrlBuilder returned an error, setting pipeline error");
|
||||
|
||||
SetPipelineError(dsUrl.Errors);
|
||||
@ -70,8 +67,6 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
|
||||
|
||||
await _next.Invoke(context);
|
||||
|
||||
//todo - release the lb connection?
|
||||
|
||||
_logger.LogDebug("succesfully called next middleware");
|
||||
}
|
||||
}
|
||||
|
@ -31,26 +31,32 @@ namespace Ocelot.LoadBalancer.Middleware
|
||||
{
|
||||
_logger.LogDebug("started calling load balancing middleware");
|
||||
|
||||
var loadBalancer = _loadBalancerHouse.Get($"{DownstreamRoute.ReRoute.UpstreamTemplate}{DownstreamRoute.ReRoute.UpstreamHttpMethod}");
|
||||
//todo check reponse and return error
|
||||
var loadBalancer = _loadBalancerHouse.Get(DownstreamRoute.ReRoute.LoadBalancerKey);
|
||||
if(loadBalancer.IsError)
|
||||
{
|
||||
//set errors and return
|
||||
}
|
||||
|
||||
var response = loadBalancer.Data.Lease();
|
||||
//todo check reponse and return error
|
||||
var hostAndPort = loadBalancer.Data.Lease();
|
||||
if(hostAndPort.IsError)
|
||||
{
|
||||
//set errors and return
|
||||
}
|
||||
|
||||
SetHostAndPortForThisRequest(hostAndPort.Data);
|
||||
|
||||
SetHostAndPortForThisRequest(response.Data);
|
||||
_logger.LogDebug("calling next middleware");
|
||||
|
||||
//todo - try next middleware if we get an exception make sure we release
|
||||
//the host and port? Not sure if this is the way to go but we shall see!
|
||||
try
|
||||
{
|
||||
await _next.Invoke(context);
|
||||
|
||||
loadBalancer.Data.Release(response.Data);
|
||||
loadBalancer.Data.Release(hostAndPort.Data);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
loadBalancer.Data.Release(response.Data);
|
||||
loadBalancer.Data.Release(hostAndPort.Data);
|
||||
_logger.LogDebug("error calling next middleware, exception will be thrown to global handler");
|
||||
throw;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ namespace Ocelot.LoadBalancer.Middleware
|
||||
{
|
||||
public static class LoadBalancingMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseLoadBalancingMiddlewareExtensions(this IApplicationBuilder builder)
|
||||
public static IApplicationBuilder UseLoadBalancingMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<LoadBalancingMiddleware>();
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ namespace Ocelot.Middleware
|
||||
using System.Threading.Tasks;
|
||||
using Authorisation.Middleware;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.LoadBalancer.Middleware;
|
||||
|
||||
public static class OcelotMiddlewareExtensions
|
||||
{
|
||||
@ -98,6 +99,9 @@ namespace Ocelot.Middleware
|
||||
// Now we can run any query string transformation logic
|
||||
builder.UseQueryStringBuilderMiddleware();
|
||||
|
||||
// Get the load balancer for this request
|
||||
builder.UseLoadBalancingMiddleware();
|
||||
|
||||
// This takes the downstream route we retrieved earlier and replaces any placeholders with the variables that should be used
|
||||
builder.UseDownstreamUrlCreatorMiddleware();
|
||||
|
||||
|
@ -36,6 +36,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
private HttpResponseMessage _result;
|
||||
private OkResponse<DownstreamPath> _downstreamPath;
|
||||
private OkResponse<DownstreamUrl> _downstreamUrl;
|
||||
private HostAndPort _hostAndPort;
|
||||
|
||||
public DownstreamUrlCreatorMiddlewareTests()
|
||||
{
|
||||
@ -69,14 +70,25 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
[Fact]
|
||||
public void should_call_dependencies_correctly()
|
||||
{
|
||||
var hostAndPort = new HostAndPort("127.0.0.1", 80);
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("any old string").Build())))
|
||||
.And(x => x.GivenTheHostAndPortIs(hostAndPort))
|
||||
.And(x => x.TheUrlReplacerReturns("/api/products/1"))
|
||||
.And(x => x.TheUrlBuilderReturns("http://www.bbc.co.uk/api/products/1"))
|
||||
.And(x => x.TheUrlBuilderReturns("http://127.0.0.1:80/api/products/1"))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheHostAndPortIs(HostAndPort hostAndPort)
|
||||
{
|
||||
_hostAndPort = hostAndPort;
|
||||
_scopedRepository
|
||||
.Setup(x => x.Get<HostAndPort>("HostAndPort"))
|
||||
.Returns(new OkResponse<HostAndPort>(_hostAndPort));
|
||||
}
|
||||
|
||||
private void TheUrlBuilderReturns(string dsUrl)
|
||||
{
|
||||
_downstreamUrl = new OkResponse<DownstreamUrl>(new DownstreamUrl(dsUrl));
|
||||
|
@ -54,7 +54,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
||||
.UseUrls(_url)
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseLoadBalancingMiddlewareExtensions();
|
||||
app.UseLoadBalancingMiddleware();
|
||||
});
|
||||
|
||||
_server = new TestServer(builder);
|
||||
|
Loading…
x
Reference in New Issue
Block a user