mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:42:50 +08:00
Feature/service discovery config key (#347)
* #346 make service discoery config key configurable * #346 missed this test * #346 updated docs
This commit is contained in:
parent
6793278597
commit
4e17190b3f
@ -146,6 +146,25 @@ I guess it means if you want to use Ocelot to its fullest you take on Consul as
|
|||||||
|
|
||||||
This feature has a 3 second ttl cache before making a new request to your local consul agent.
|
This feature has a 3 second ttl cache before making a new request to your local consul agent.
|
||||||
|
|
||||||
|
Configuration Key
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
If you are using Consul for configuration (or other providers in the future) you might want to key your configurations so you can have multiple configurations :) This feature was requested in `issue 346 <https://github.com/ThreeMammals/Ocelot/issues/346>`_! In order to specify the key you need to set the ConfigurationKey property in the ServiceDiscoveryProvider section of the configuration json file e.g.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
"GlobalConfiguration": {
|
||||||
|
"ServiceDiscoveryProvider": {
|
||||||
|
"Host": "localhost",
|
||||||
|
"Port": 9500,
|
||||||
|
"ConfigurationKey": "Oceolot_A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
In this example Ocelot will use Oceolot_A as the key for your configuration when looking it up in Consul.
|
||||||
|
|
||||||
|
If you do not set the ConfigurationKey Ocelot will use the string InternalConfiguration as the key.
|
||||||
|
|
||||||
Follow Redirects / Use CookieContainer
|
Follow Redirects / Use CookieContainer
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ namespace Ocelot.Configuration.Builder
|
|||||||
private int _serviceDiscoveryProviderPort;
|
private int _serviceDiscoveryProviderPort;
|
||||||
private string _type;
|
private string _type;
|
||||||
private string _token;
|
private string _token;
|
||||||
|
private string _configurationKey;
|
||||||
|
|
||||||
public ServiceProviderConfigurationBuilder WithHost(string serviceDiscoveryProviderHost)
|
public ServiceProviderConfigurationBuilder WithHost(string serviceDiscoveryProviderHost)
|
||||||
{
|
{
|
||||||
@ -31,9 +32,15 @@ namespace Ocelot.Configuration.Builder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServiceProviderConfigurationBuilder WithConfigurationKey(string configurationKey)
|
||||||
|
{
|
||||||
|
_configurationKey = configurationKey;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ServiceProviderConfiguration Build()
|
public ServiceProviderConfiguration Build()
|
||||||
{
|
{
|
||||||
return new ServiceProviderConfiguration(_type, _serviceDiscoveryProviderHost, _serviceDiscoveryProviderPort, _token);
|
return new ServiceProviderConfiguration(_type, _serviceDiscoveryProviderHost, _serviceDiscoveryProviderPort, _token, _configurationKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
.WithPort(serviceProviderPort)
|
.WithPort(serviceProviderPort)
|
||||||
.WithType(globalConfiguration?.ServiceDiscoveryProvider?.Type)
|
.WithType(globalConfiguration?.ServiceDiscoveryProvider?.Type)
|
||||||
.WithToken(globalConfiguration?.ServiceDiscoveryProvider?.Token)
|
.WithToken(globalConfiguration?.ServiceDiscoveryProvider?.Token)
|
||||||
|
.WithConfigurationKey(globalConfiguration?.ServiceDiscoveryProvider?.ConfigurationKey)
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,5 +6,6 @@ namespace Ocelot.Configuration.File
|
|||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public string Token { get; set; }
|
public string Token { get; set; }
|
||||||
|
public string ConfigurationKey { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
||||||
{
|
{
|
||||||
private readonly IConsulClient _consul;
|
private readonly IConsulClient _consul;
|
||||||
private const string OcelotConfiguration = "InternalConfiguration";
|
private readonly string _configurationKey;
|
||||||
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
|
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
var internalConfig = repo.Get();
|
var internalConfig = repo.Get();
|
||||||
|
|
||||||
|
_configurationKey = "InternalConfiguration";
|
||||||
var consulHost = "localhost";
|
var consulHost = "localhost";
|
||||||
var consulPort = 8500;
|
var consulPort = 8500;
|
||||||
string token = null;
|
string token = null;
|
||||||
@ -38,23 +39,25 @@ namespace Ocelot.Configuration.Repository
|
|||||||
consulHost = string.IsNullOrEmpty(internalConfig.Data.ServiceProviderConfiguration?.Host) ? consulHost : internalConfig.Data.ServiceProviderConfiguration?.Host;
|
consulHost = string.IsNullOrEmpty(internalConfig.Data.ServiceProviderConfiguration?.Host) ? consulHost : internalConfig.Data.ServiceProviderConfiguration?.Host;
|
||||||
consulPort = internalConfig.Data.ServiceProviderConfiguration?.Port ?? consulPort;
|
consulPort = internalConfig.Data.ServiceProviderConfiguration?.Port ?? consulPort;
|
||||||
token = internalConfig.Data.ServiceProviderConfiguration?.Token;
|
token = internalConfig.Data.ServiceProviderConfiguration?.Token;
|
||||||
|
_configurationKey = !string.IsNullOrEmpty(internalConfig.Data.ServiceProviderConfiguration?.ConfigurationKey) ?
|
||||||
|
internalConfig.Data.ServiceProviderConfiguration?.ConfigurationKey : _configurationKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = new ConsulRegistryConfiguration(consulHost, consulPort, OcelotConfiguration, token);
|
var config = new ConsulRegistryConfiguration(consulHost, consulPort, _configurationKey, token);
|
||||||
|
|
||||||
_consul = factory.Get(config);
|
_consul = factory.Get(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Response<FileConfiguration>> Get()
|
public async Task<Response<FileConfiguration>> Get()
|
||||||
{
|
{
|
||||||
var config = _cache.Get(OcelotConfiguration, OcelotConfiguration);
|
var config = _cache.Get(_configurationKey, _configurationKey);
|
||||||
|
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
return new OkResponse<FileConfiguration>(config);
|
return new OkResponse<FileConfiguration>(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryResult = await _consul.KV.Get(OcelotConfiguration);
|
var queryResult = await _consul.KV.Get(_configurationKey);
|
||||||
|
|
||||||
if (queryResult.Response == null)
|
if (queryResult.Response == null)
|
||||||
{
|
{
|
||||||
@ -76,7 +79,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
var bytes = Encoding.UTF8.GetBytes(json);
|
var bytes = Encoding.UTF8.GetBytes(json);
|
||||||
|
|
||||||
var kvPair = new KVPair(OcelotConfiguration)
|
var kvPair = new KVPair(_configurationKey)
|
||||||
{
|
{
|
||||||
Value = bytes
|
Value = bytes
|
||||||
};
|
};
|
||||||
@ -85,7 +88,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
if (result.Response)
|
if (result.Response)
|
||||||
{
|
{
|
||||||
_cache.AddAndDelete(OcelotConfiguration, ocelotConfiguration, TimeSpan.FromSeconds(3), OcelotConfiguration);
|
_cache.AddAndDelete(_configurationKey, ocelotConfiguration, TimeSpan.FromSeconds(3), _configurationKey);
|
||||||
|
|
||||||
return new OkResponse();
|
return new OkResponse();
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
{
|
{
|
||||||
public class ServiceProviderConfiguration
|
public class ServiceProviderConfiguration
|
||||||
{
|
{
|
||||||
public ServiceProviderConfiguration(string type, string host, int port, string token)
|
public ServiceProviderConfiguration(string type, string host, int port, string token, string configurationKey)
|
||||||
{
|
{
|
||||||
|
ConfigurationKey = configurationKey;
|
||||||
Host = host;
|
Host = host;
|
||||||
Port = port;
|
Port = port;
|
||||||
Token = token;
|
Token = token;
|
||||||
@ -14,5 +15,6 @@
|
|||||||
public int Port { get; }
|
public int Port { get; }
|
||||||
public string Type { get; }
|
public string Type { get; }
|
||||||
public string Token { get; }
|
public string Token { get; }
|
||||||
|
public string ConfigurationKey { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_client
|
_client
|
||||||
.Setup(x => x.KV)
|
.Setup(x => x.KV)
|
||||||
.Returns(_kvEndpoint.Object);
|
.Returns(_kvEndpoint.Object);
|
||||||
|
|
||||||
_factory
|
_factory
|
||||||
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
|
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
|
||||||
.Returns(_client.Object);
|
.Returns(_client.Object);
|
||||||
@ -104,6 +105,46 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_set_config_key()
|
||||||
|
{
|
||||||
|
var config = FakeFileConfiguration();
|
||||||
|
|
||||||
|
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||||
|
.And(_ => GivenTheConfigKeyComesFromFileConfig("Tom"))
|
||||||
|
.And(_ => GivenFetchFromConsulSucceeds())
|
||||||
|
.When(_ => WhenIGetTheConfiguration())
|
||||||
|
.And(_ => ThenTheConfigKeyIs("Tom"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_set_default_config_key()
|
||||||
|
{
|
||||||
|
var config = FakeFileConfiguration();
|
||||||
|
|
||||||
|
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||||
|
.And(_ => GivenFetchFromConsulSucceeds())
|
||||||
|
.When(_ => WhenIGetTheConfiguration())
|
||||||
|
.And(_ => ThenTheConfigKeyIs("InternalConfiguration"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheConfigKeyIs(string expected)
|
||||||
|
{
|
||||||
|
_kvEndpoint
|
||||||
|
.Verify(x => x.Get(expected, It.IsAny<CancellationToken>()), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheConfigKeyComesFromFileConfig(string key)
|
||||||
|
{
|
||||||
|
_internalRepo
|
||||||
|
.Setup(x => x.Get())
|
||||||
|
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().WithConfigurationKey(key).Build(), "")));
|
||||||
|
|
||||||
|
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
|
||||||
|
}
|
||||||
|
|
||||||
private void ThenTheConfigurationIsNull()
|
private void ThenTheConfigurationIsNull()
|
||||||
{
|
{
|
||||||
_getResult.Data.ShouldBeNull();
|
_getResult.Data.ShouldBeNull();
|
||||||
|
@ -29,7 +29,8 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
Host = "127.0.0.1",
|
Host = "127.0.0.1",
|
||||||
Port = 1234,
|
Port = 1234,
|
||||||
Type = "ServiceFabric",
|
Type = "ServiceFabric",
|
||||||
Token = "testtoken"
|
Token = "testtoken",
|
||||||
|
ConfigurationKey = "woo"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.WithPort(1234)
|
.WithPort(1234)
|
||||||
.WithType("ServiceFabric")
|
.WithType("ServiceFabric")
|
||||||
.WithToken("testtoken")
|
.WithToken("testtoken")
|
||||||
|
.WithConfigurationKey("woo")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
this.Given(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||||
@ -62,6 +64,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_result.Port.ShouldBe(expected.Port);
|
_result.Port.ShouldBe(expected.Port);
|
||||||
_result.Token.ShouldBe(expected.Token);
|
_result.Token.ShouldBe(expected.Token);
|
||||||
_result.Type.ShouldBe(expected.Type);
|
_result.Type.ShouldBe(expected.Type);
|
||||||
|
_result.ConfigurationKey.ShouldBe(expected.ConfigurationKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ namespace Ocelot.UnitTests.LoadBalancer
|
|||||||
{
|
{
|
||||||
_factory = new Mock<ILoadBalancerFactory>();
|
_factory = new Mock<ILoadBalancerFactory>();
|
||||||
_loadBalancerHouse = new LoadBalancerHouse(_factory.Object);
|
_loadBalancerHouse = new LoadBalancerHouse(_factory.Object);
|
||||||
_serviceProviderConfig = new ServiceProviderConfiguration("myType","myHost",123, string.Empty);
|
_serviceProviderConfig = new ServiceProviderConfiguration("myType","myHost",123, string.Empty, "configKey");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user