Extend OcelotBuilder with overloads of the AddCustomLoadBalancer registration helper method

This commit is contained in:
David Lievrouw 2019-07-10 19:36:01 +02:00
parent de012a0794
commit 80ab5f6a91
4 changed files with 103 additions and 10 deletions

View File

@ -3,6 +3,9 @@ using Microsoft.Extensions.DependencyInjection;
using Ocelot.Middleware.Multiplexer; using Ocelot.Middleware.Multiplexer;
using System; using System;
using System.Net.Http; using System.Net.Http;
using Ocelot.Configuration;
using Ocelot.LoadBalancer.LoadBalancers;
using Ocelot.ServiceDiscovery.Providers;
namespace Ocelot.DependencyInjection namespace Ocelot.DependencyInjection
{ {
@ -25,6 +28,23 @@ namespace Ocelot.DependencyInjection
IOcelotBuilder AddTransientDefinedAggregator<T>() IOcelotBuilder AddTransientDefinedAggregator<T>()
where T : class, IDefinedAggregator; where T : class, IDefinedAggregator;
IOcelotBuilder AddCustomLoadBalancer<T>()
where T : ILoadBalancer, new();
IOcelotBuilder AddCustomLoadBalancer<T>(Func<T> loadBalancerFactoryFunc)
where T : ILoadBalancer;
IOcelotBuilder AddCustomLoadBalancer<T>(Func<IServiceProvider, T> loadBalancerFactoryFunc)
where T : ILoadBalancer;
IOcelotBuilder AddCustomLoadBalancer<T>(
Func<DownstreamReRoute, IServiceDiscoveryProvider, T> loadBalancerFactoryFunc)
where T : ILoadBalancer;
IOcelotBuilder AddCustomLoadBalancer<T>(
Func<IServiceProvider, DownstreamReRoute, IServiceDiscoveryProvider, T> loadBalancerFactoryFunc)
where T : ILoadBalancer;
IOcelotBuilder AddConfigPlaceholders(); IOcelotBuilder AddConfigPlaceholders();
} }
} }

View File

@ -1,3 +1,5 @@
using Ocelot.ServiceDiscovery.Providers;
using Ocelot.Configuration.ChangeTracking; using Ocelot.Configuration.ChangeTracking;
namespace Ocelot.DependencyInjection namespace Ocelot.DependencyInjection
@ -173,6 +175,47 @@ namespace Ocelot.DependencyInjection
return this; return this;
} }
public IOcelotBuilder AddCustomLoadBalancer<T>()
where T : ILoadBalancer, new()
{
AddCustomLoadBalancer((provider, reRoute, serviceDiscoveryProvider) => new T());
return this;
}
public IOcelotBuilder AddCustomLoadBalancer<T>(Func<T> loadBalancerFactoryFunc)
where T : ILoadBalancer
{
AddCustomLoadBalancer((provider, reRoute, serviceDiscoveryProvider) =>
loadBalancerFactoryFunc());
return this;
}
public IOcelotBuilder AddCustomLoadBalancer<T>(Func<IServiceProvider, T> loadBalancerFactoryFunc)
where T : ILoadBalancer
{
AddCustomLoadBalancer((provider, reRoute, serviceDiscoveryProvider) =>
loadBalancerFactoryFunc(provider));
return this;
}
public IOcelotBuilder AddCustomLoadBalancer<T>(Func<DownstreamReRoute, IServiceDiscoveryProvider, T> loadBalancerFactoryFunc)
where T : ILoadBalancer
{
AddCustomLoadBalancer((provider, reRoute, serviceDiscoveryProvider) =>
loadBalancerFactoryFunc(reRoute, serviceDiscoveryProvider));
return this;
}
public IOcelotBuilder AddCustomLoadBalancer<T>(Func<IServiceProvider, DownstreamReRoute, IServiceDiscoveryProvider, T> loadBalancerFactoryFunc)
where T : ILoadBalancer
{
Services.AddSingleton<ILoadBalancerCreator>(provider =>
new DelegateInvokingLoadBalancerCreator<T>(
(reRoute, serviceDiscoveryProvider) =>
loadBalancerFactoryFunc(provider, reRoute, serviceDiscoveryProvider)));
return this;
}
private void AddSecurity() private void AddSecurity()
{ {
Services.TryAddSingleton<ISecurityOptionsCreator, SecurityOptionsCreator>(); Services.TryAddSingleton<ISecurityOptionsCreator, SecurityOptionsCreator>();

View File

@ -0,0 +1,25 @@
namespace Ocelot.LoadBalancer.LoadBalancers
{
using System;
using Ocelot.Configuration;
using Ocelot.ServiceDiscovery.Providers;
public class DelegateInvokingLoadBalancerCreator<T> : ILoadBalancerCreator
where T : ILoadBalancer
{
private readonly Func<DownstreamReRoute, IServiceDiscoveryProvider, ILoadBalancer> _creatorFunc;
public DelegateInvokingLoadBalancerCreator(
Func<DownstreamReRoute, IServiceDiscoveryProvider, ILoadBalancer> creatorFunc)
{
_creatorFunc = creatorFunc;
}
public ILoadBalancer Create(DownstreamReRoute reRoute, IServiceDiscoveryProvider serviceProvider)
{
return _creatorFunc(reRoute, serviceProvider);
}
public string Type => typeof(T).Name;
}
}

View File

@ -1,6 +1,8 @@
using Ocelot.Configuration; using System.Threading.Tasks;
using Ocelot.LoadBalancer.LoadBalancers; using Ocelot.LoadBalancer.LoadBalancers;
using Ocelot.ServiceDiscovery.Providers; using Ocelot.Middleware;
using Ocelot.Responses;
using Ocelot.Values;
namespace Ocelot.UnitTests.DependencyInjection namespace Ocelot.UnitTests.DependencyInjection
{ {
@ -166,7 +168,7 @@ namespace Ocelot.UnitTests.DependencyInjection
public void should_add_custom_load_balancer_creators() public void should_add_custom_load_balancer_creators()
{ {
this.Given(x => WhenISetUpOcelotServices()) this.Given(x => WhenISetUpOcelotServices())
.When(x => AddSingletonLoadBalancerCreator<FakeCustomLoadBalancerCreator>()) .When(x => AddCustomLoadBalancer<FakeCustomLoadBalancer>())
.Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators()) .Then(x => ThenTheProviderIsRegisteredAndReturnsBothBuiltInAndCustomLoadBalancerCreators())
.BDDfy(); .BDDfy();
} }
@ -177,10 +179,10 @@ namespace Ocelot.UnitTests.DependencyInjection
_ocelotBuilder.AddSingletonDefinedAggregator<T>(); _ocelotBuilder.AddSingletonDefinedAggregator<T>();
} }
private void AddSingletonLoadBalancerCreator<T>() private void AddCustomLoadBalancer<T>()
where T : class, ILoadBalancerCreator where T : ILoadBalancer, new()
{ {
_ocelotBuilder.Services.AddSingleton<ILoadBalancerCreator, T>(); _ocelotBuilder.AddCustomLoadBalancer<T>();
} }
private void AddTransientDefinedAggregator<T>() private void AddTransientDefinedAggregator<T>()
@ -266,7 +268,7 @@ namespace Ocelot.UnitTests.DependencyInjection
creators.Count(c => c.GetType() == typeof(RoundRobinCreator)).ShouldBe(1); creators.Count(c => c.GetType() == typeof(RoundRobinCreator)).ShouldBe(1);
creators.Count(c => c.GetType() == typeof(CookieStickySessionsCreator)).ShouldBe(1); creators.Count(c => c.GetType() == typeof(CookieStickySessionsCreator)).ShouldBe(1);
creators.Count(c => c.GetType() == typeof(LeastConnectionCreator)).ShouldBe(1); creators.Count(c => c.GetType() == typeof(LeastConnectionCreator)).ShouldBe(1);
creators.Count(c => c.GetType() == typeof(FakeCustomLoadBalancerCreator)).ShouldBe(1); creators.Count(c => c.GetType() == typeof(DelegateInvokingLoadBalancerCreator<FakeCustomLoadBalancer>)).ShouldBe(1);
} }
private void ThenTheAggregatorsAreTransient<TOne, TWo>() private void ThenTheAggregatorsAreTransient<TOne, TWo>()
@ -354,14 +356,17 @@ namespace Ocelot.UnitTests.DependencyInjection
_ex.ShouldBeNull(); _ex.ShouldBeNull();
} }
private class FakeCustomLoadBalancerCreator : ILoadBalancerCreator private class FakeCustomLoadBalancer : ILoadBalancer
{ {
public ILoadBalancer Create(DownstreamReRoute reRoute, IServiceDiscoveryProvider serviceProvider) public Task<Response<ServiceHostAndPort>> Lease(DownstreamContext context)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public string Type { get; } public void Release(ServiceHostAndPort hostAndPort)
{
throw new NotImplementedException();
}
} }
} }
} }