mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
Feature/#295 consul acl (#307)
* removed file * updated package * updated package * updated package * updated package * updated package * updated package * updated package * all packages updated * #295 can add token to service provider config and this will be used by consul clients to get services and configuration * #295 wait longer for this test
This commit is contained in:
parent
d7ef956935
commit
982eebfc74
@ -38,3 +38,18 @@ and LeastConnection algorithm you can use. If no load balancer is specified Ocel
|
|||||||
}
|
}
|
||||||
|
|
||||||
When this is set up Ocelot will lookup the downstream host and port from the service discover provider and load balance requests across any available services.
|
When this is set up Ocelot will lookup the downstream host and port from the service discover provider and load balance requests across any available services.
|
||||||
|
|
||||||
|
ACL Token
|
||||||
|
---------
|
||||||
|
|
||||||
|
If you are using ACL with Consul Ocelot supports adding the X-Consul-Token header. In order so this to work you must add the additional property below.
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
"ServiceDiscoveryProvider": {
|
||||||
|
"Host": "localhost",
|
||||||
|
"Port": 9500,
|
||||||
|
"Token": "footoken"
|
||||||
|
}
|
||||||
|
|
||||||
|
Ocelot will add this token to the consul client that it uses to make requests and that is then used for every request.
|
@ -5,28 +5,35 @@ namespace Ocelot.Configuration.Builder
|
|||||||
private string _serviceDiscoveryProviderHost;
|
private string _serviceDiscoveryProviderHost;
|
||||||
private int _serviceDiscoveryProviderPort;
|
private int _serviceDiscoveryProviderPort;
|
||||||
private string _type;
|
private string _type;
|
||||||
|
private string _token;
|
||||||
|
|
||||||
public ServiceProviderConfigurationBuilder WithServiceDiscoveryProviderHost(string serviceDiscoveryProviderHost)
|
public ServiceProviderConfigurationBuilder WithHost(string serviceDiscoveryProviderHost)
|
||||||
{
|
{
|
||||||
_serviceDiscoveryProviderHost = serviceDiscoveryProviderHost;
|
_serviceDiscoveryProviderHost = serviceDiscoveryProviderHost;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceProviderConfigurationBuilder WithServiceDiscoveryProviderPort(int serviceDiscoveryProviderPort)
|
public ServiceProviderConfigurationBuilder WithPort(int serviceDiscoveryProviderPort)
|
||||||
{
|
{
|
||||||
_serviceDiscoveryProviderPort = serviceDiscoveryProviderPort;
|
_serviceDiscoveryProviderPort = serviceDiscoveryProviderPort;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceProviderConfigurationBuilder WithServiceDiscoveryProviderType(string type)
|
public ServiceProviderConfigurationBuilder WithType(string type)
|
||||||
{
|
{
|
||||||
_type = type;
|
_type = type;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServiceProviderConfigurationBuilder WithToken(string token)
|
||||||
|
{
|
||||||
|
_token = token;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ServiceProviderConfiguration Build()
|
public ServiceProviderConfiguration Build()
|
||||||
{
|
{
|
||||||
return new ServiceProviderConfiguration(_type, _serviceDiscoveryProviderHost, _serviceDiscoveryProviderPort);
|
return new ServiceProviderConfiguration(_type, _serviceDiscoveryProviderHost, _serviceDiscoveryProviderPort, _token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,10 @@ namespace Ocelot.Configuration.Creator
|
|||||||
var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0;
|
var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0;
|
||||||
|
|
||||||
return new ServiceProviderConfigurationBuilder()
|
return new ServiceProviderConfigurationBuilder()
|
||||||
.WithServiceDiscoveryProviderHost(globalConfiguration?.ServiceDiscoveryProvider?.Host)
|
.WithHost(globalConfiguration?.ServiceDiscoveryProvider?.Host)
|
||||||
.WithServiceDiscoveryProviderPort(serviceProviderPort)
|
.WithPort(serviceProviderPort)
|
||||||
.WithServiceDiscoveryProviderType(globalConfiguration?.ServiceDiscoveryProvider?.Type)
|
.WithType(globalConfiguration?.ServiceDiscoveryProvider?.Type)
|
||||||
|
.WithToken(globalConfiguration?.ServiceDiscoveryProvider?.Token)
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,6 @@ namespace Ocelot.Configuration.File
|
|||||||
public string Host {get;set;}
|
public string Host {get;set;}
|
||||||
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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ using System.Threading.Tasks;
|
|||||||
using Consul;
|
using Consul;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.Infrastructure.Consul;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
using Ocelot.ServiceDiscovery;
|
|
||||||
using Ocelot.ServiceDiscovery.Configuration;
|
using Ocelot.ServiceDiscovery.Configuration;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Repository
|
namespace Ocelot.Configuration.Repository
|
||||||
@ -13,31 +13,31 @@ namespace Ocelot.Configuration.Repository
|
|||||||
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
||||||
{
|
{
|
||||||
private readonly ConsulClient _consul;
|
private readonly ConsulClient _consul;
|
||||||
private string _ocelotConfiguration = "OcelotConfiguration";
|
private const string OcelotConfiguration = "OcelotConfiguration";
|
||||||
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
|
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
|
||||||
|
|
||||||
public ConsulFileConfigurationRepository(Cache.IOcelotCache<FileConfiguration> cache, ServiceProviderConfiguration serviceProviderConfig)
|
public ConsulFileConfigurationRepository(
|
||||||
|
Cache.IOcelotCache<FileConfiguration> cache,
|
||||||
|
ServiceProviderConfiguration serviceProviderConfig,
|
||||||
|
IConsulClientFactory factory)
|
||||||
{
|
{
|
||||||
var consulHost = string.IsNullOrEmpty(serviceProviderConfig?.Host) ? "localhost" : serviceProviderConfig?.Host;
|
var consulHost = string.IsNullOrEmpty(serviceProviderConfig?.Host) ? "localhost" : serviceProviderConfig?.Host;
|
||||||
var consulPort = serviceProviderConfig?.Port ?? 8500;
|
var consulPort = serviceProviderConfig?.Port ?? 8500;
|
||||||
var configuration = new ConsulRegistryConfiguration(consulHost, consulPort, _ocelotConfiguration);
|
var config = new ConsulRegistryConfiguration(consulHost, consulPort, OcelotConfiguration, serviceProviderConfig?.Token);
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
_consul = new ConsulClient(c =>
|
_consul = factory.Get(config);
|
||||||
{
|
|
||||||
c.Address = new Uri($"http://{configuration.HostName}:{configuration.Port}");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Response<FileConfiguration>> Get()
|
public async Task<Response<FileConfiguration>> Get()
|
||||||
{
|
{
|
||||||
var config = _cache.Get(_ocelotConfiguration, _ocelotConfiguration);
|
var config = _cache.Get(OcelotConfiguration, OcelotConfiguration);
|
||||||
|
|
||||||
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(OcelotConfiguration);
|
||||||
|
|
||||||
if (queryResult.Response == null)
|
if (queryResult.Response == null)
|
||||||
{
|
{
|
||||||
@ -59,7 +59,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(OcelotConfiguration)
|
||||||
{
|
{
|
||||||
Value = bytes
|
Value = bytes
|
||||||
};
|
};
|
||||||
@ -68,7 +68,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
if (result.Response)
|
if (result.Response)
|
||||||
{
|
{
|
||||||
_cache.AddAndDelete(_ocelotConfiguration, ocelotConfiguration, TimeSpan.FromSeconds(3), _ocelotConfiguration);
|
_cache.AddAndDelete(OcelotConfiguration, ocelotConfiguration, TimeSpan.FromSeconds(3), OcelotConfiguration);
|
||||||
|
|
||||||
return new OkResponse();
|
return new OkResponse();
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,17 @@
|
|||||||
{
|
{
|
||||||
public class ServiceProviderConfiguration
|
public class ServiceProviderConfiguration
|
||||||
{
|
{
|
||||||
public ServiceProviderConfiguration(string type, string host, int port)
|
public ServiceProviderConfiguration(string type, string host, int port, string token)
|
||||||
{
|
{
|
||||||
Host = host;
|
Host = host;
|
||||||
Port = port;
|
Port = port;
|
||||||
|
Token = token;
|
||||||
Type = type;
|
Type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Host { get; private set; }
|
public string Host { get; }
|
||||||
public int Port { get; private set; }
|
public int Port { get; }
|
||||||
public string Type { get; private set; }
|
public string Type { get; }
|
||||||
|
public string Token { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -53,6 +53,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using Butterfly.Client.AspNetCore;
|
using Butterfly.Client.AspNetCore;
|
||||||
using Ocelot.Infrastructure;
|
using Ocelot.Infrastructure;
|
||||||
|
using Ocelot.Infrastructure.Consul;
|
||||||
|
|
||||||
public class OcelotBuilder : IOcelotBuilder
|
public class OcelotBuilder : IOcelotBuilder
|
||||||
{
|
{
|
||||||
@ -152,6 +153,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
_services.TryAddSingleton<IConsulPollerConfiguration, InMemoryConsulPollerConfiguration>();
|
_services.TryAddSingleton<IConsulPollerConfiguration, InMemoryConsulPollerConfiguration>();
|
||||||
_services.TryAddSingleton<IAddHeadersToResponse, AddHeadersToResponse>();
|
_services.TryAddSingleton<IAddHeadersToResponse, AddHeadersToResponse>();
|
||||||
_services.TryAddSingleton<IPlaceholders, Placeholders>();
|
_services.TryAddSingleton<IPlaceholders, Placeholders>();
|
||||||
|
_services.TryAddSingleton<IConsulClientFactory, ConsulClientFactory>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOcelotAdministrationBuilder AddAdministration(string path, string secret)
|
public IOcelotAdministrationBuilder AddAdministration(string path, string secret)
|
||||||
@ -236,10 +238,12 @@ namespace Ocelot.DependencyInjection
|
|||||||
{
|
{
|
||||||
var serviceDiscoveryPort = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Port", 0);
|
var serviceDiscoveryPort = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Port", 0);
|
||||||
var serviceDiscoveryHost = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Host", string.Empty);
|
var serviceDiscoveryHost = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Host", string.Empty);
|
||||||
|
var serviceDiscoveryToken = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Token", string.Empty);
|
||||||
|
|
||||||
var config = new ServiceProviderConfigurationBuilder()
|
var config = new ServiceProviderConfigurationBuilder()
|
||||||
.WithServiceDiscoveryProviderPort(serviceDiscoveryPort)
|
.WithPort(serviceDiscoveryPort)
|
||||||
.WithServiceDiscoveryProviderHost(serviceDiscoveryHost)
|
.WithHost(serviceDiscoveryHost)
|
||||||
|
.WithToken(serviceDiscoveryToken)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_services.AddSingleton<ServiceProviderConfiguration>(config);
|
_services.AddSingleton<ServiceProviderConfiguration>(config);
|
||||||
|
22
src/Ocelot/Infrastructure/Consul/ConsulClientFactory.cs
Normal file
22
src/Ocelot/Infrastructure/Consul/ConsulClientFactory.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using Consul;
|
||||||
|
using Ocelot.ServiceDiscovery.Configuration;
|
||||||
|
|
||||||
|
namespace Ocelot.Infrastructure.Consul
|
||||||
|
{
|
||||||
|
public class ConsulClientFactory : IConsulClientFactory
|
||||||
|
{
|
||||||
|
public ConsulClient Get(ConsulRegistryConfiguration config)
|
||||||
|
{
|
||||||
|
return new ConsulClient(c =>
|
||||||
|
{
|
||||||
|
c.Address = new Uri($"http://{config.Host}:{config.Port}");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(config?.Token))
|
||||||
|
{
|
||||||
|
c.Token = config.Token;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/Ocelot/Infrastructure/Consul/IConsulClientFactory.cs
Normal file
10
src/Ocelot/Infrastructure/Consul/IConsulClientFactory.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Consul;
|
||||||
|
using Ocelot.ServiceDiscovery.Configuration;
|
||||||
|
|
||||||
|
namespace Ocelot.Infrastructure.Consul
|
||||||
|
{
|
||||||
|
public interface IConsulClientFactory
|
||||||
|
{
|
||||||
|
ConsulClient Get(ConsulRegistryConfiguration config);
|
||||||
|
}
|
||||||
|
}
|
@ -26,27 +26,27 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
||||||
<PackageReference Include="FluentValidation" Version="7.2.1" />
|
<PackageReference Include="FluentValidation" Version="7.5.2" />
|
||||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.1.0" />
|
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.4.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DiagnosticAdapter" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
|
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
|
||||||
<PackageReference Include="CacheManager.Core" Version="1.1.1" />
|
<PackageReference Include="CacheManager.Core" Version="1.1.2" />
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.1.1" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.1.2" />
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.1" />
|
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.2" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.3" />
|
<PackageReference Include="Consul" Version="0.7.2.4" />
|
||||||
<PackageReference Include="Polly" Version="5.3.1" />
|
<PackageReference Include="Polly" Version="5.8.0" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.0.2" />
|
<PackageReference Include="IdentityServer4" Version="2.1.3" />
|
||||||
<PackageReference Include="Rafty" Version="0.4.2" />
|
<PackageReference Include="Rafty" Version="0.4.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,15 +2,17 @@ namespace Ocelot.ServiceDiscovery.Configuration
|
|||||||
{
|
{
|
||||||
public class ConsulRegistryConfiguration
|
public class ConsulRegistryConfiguration
|
||||||
{
|
{
|
||||||
public ConsulRegistryConfiguration(string hostName, int port, string keyOfServiceInConsul)
|
public ConsulRegistryConfiguration(string host, int port, string keyOfServiceInConsul, string token)
|
||||||
{
|
{
|
||||||
HostName = hostName;
|
Host = host;
|
||||||
Port = port;
|
Port = port;
|
||||||
KeyOfServiceInConsul = keyOfServiceInConsul;
|
KeyOfServiceInConsul = keyOfServiceInConsul;
|
||||||
|
Token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string KeyOfServiceInConsul { get; private set; }
|
public string KeyOfServiceInConsul { get; }
|
||||||
public string HostName { get; private set; }
|
public string Host { get; }
|
||||||
public int Port { get; private set; }
|
public int Port { get; }
|
||||||
|
public string Token { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Consul;
|
using Consul;
|
||||||
|
using Ocelot.Infrastructure.Consul;
|
||||||
using Ocelot.Infrastructure.Extensions;
|
using Ocelot.Infrastructure.Extensions;
|
||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
using Ocelot.ServiceDiscovery.Configuration;
|
using Ocelot.ServiceDiscovery.Configuration;
|
||||||
@ -12,30 +13,27 @@ namespace Ocelot.ServiceDiscovery.Providers
|
|||||||
{
|
{
|
||||||
public class ConsulServiceDiscoveryProvider : IServiceDiscoveryProvider
|
public class ConsulServiceDiscoveryProvider : IServiceDiscoveryProvider
|
||||||
{
|
{
|
||||||
private readonly ConsulRegistryConfiguration _consulConfig;
|
private readonly ConsulRegistryConfiguration _config;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
private readonly ConsulClient _consul;
|
private readonly ConsulClient _consul;
|
||||||
private const string VersionPrefix = "version-";
|
private const string VersionPrefix = "version-";
|
||||||
|
|
||||||
public ConsulServiceDiscoveryProvider(ConsulRegistryConfiguration consulRegistryConfiguration, IOcelotLoggerFactory factory)
|
public ConsulServiceDiscoveryProvider(ConsulRegistryConfiguration config, IOcelotLoggerFactory factory, IConsulClientFactory clientFactory)
|
||||||
{;
|
{;
|
||||||
_logger = factory.CreateLogger<ConsulServiceDiscoveryProvider>();
|
_logger = factory.CreateLogger<ConsulServiceDiscoveryProvider>();
|
||||||
|
|
||||||
var consulHost = string.IsNullOrEmpty(consulRegistryConfiguration?.HostName) ? "localhost" : consulRegistryConfiguration.HostName;
|
var consulHost = string.IsNullOrEmpty(config?.Host) ? "localhost" : config.Host;
|
||||||
|
|
||||||
var consulPort = consulRegistryConfiguration?.Port ?? 8500;
|
var consulPort = config?.Port ?? 8500;
|
||||||
|
|
||||||
_consulConfig = new ConsulRegistryConfiguration(consulHost, consulPort, consulRegistryConfiguration?.KeyOfServiceInConsul);
|
_config = new ConsulRegistryConfiguration(consulHost, consulPort, config?.KeyOfServiceInConsul, config?.Token);
|
||||||
|
|
||||||
_consul = new ConsulClient(config =>
|
_consul = clientFactory.Get(_config);
|
||||||
{
|
|
||||||
config.Address = new Uri($"http://{_consulConfig.HostName}:{_consulConfig.Port}");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Service>> Get()
|
public async Task<List<Service>> Get()
|
||||||
{
|
{
|
||||||
var queryResult = await _consul.Health.Service(_consulConfig.KeyOfServiceInConsul, string.Empty, true);
|
var queryResult = await _consul.Health.Service(_config.KeyOfServiceInConsul, string.Empty, true);
|
||||||
|
|
||||||
var services = new List<Service>();
|
var services = new List<Service>();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Infrastructure.Consul;
|
||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
using Ocelot.ServiceDiscovery.Configuration;
|
using Ocelot.ServiceDiscovery.Configuration;
|
||||||
using Ocelot.ServiceDiscovery.Providers;
|
using Ocelot.ServiceDiscovery.Providers;
|
||||||
@ -10,10 +11,12 @@ namespace Ocelot.ServiceDiscovery
|
|||||||
public class ServiceDiscoveryProviderFactory : IServiceDiscoveryProviderFactory
|
public class ServiceDiscoveryProviderFactory : IServiceDiscoveryProviderFactory
|
||||||
{
|
{
|
||||||
private readonly IOcelotLoggerFactory _factory;
|
private readonly IOcelotLoggerFactory _factory;
|
||||||
|
private readonly IConsulClientFactory _clientFactory;
|
||||||
|
|
||||||
public ServiceDiscoveryProviderFactory(IOcelotLoggerFactory factory)
|
public ServiceDiscoveryProviderFactory(IOcelotLoggerFactory factory, IConsulClientFactory clientFactory)
|
||||||
{
|
{
|
||||||
_factory = factory;
|
_factory = factory;
|
||||||
|
_clientFactory = clientFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig, DownstreamReRoute reRoute)
|
public IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig, DownstreamReRoute reRoute)
|
||||||
@ -43,8 +46,8 @@ namespace Ocelot.ServiceDiscovery
|
|||||||
return new ServiceFabricServiceDiscoveryProvider(config);
|
return new ServiceFabricServiceDiscoveryProvider(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
var consulRegistryConfiguration = new ConsulRegistryConfiguration(serviceConfig.Host, serviceConfig.Port, serviceName);
|
var consulRegistryConfiguration = new ConsulRegistryConfiguration(serviceConfig.Host, serviceConfig.Port, serviceName, serviceConfig.Token);
|
||||||
return new ConsulServiceDiscoveryProvider(consulRegistryConfiguration, _factory);
|
return new ConsulServiceDiscoveryProvider(consulRegistryConfiguration, _factory, _clientFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Tom"))
|
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Tom"))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
|
|
||||||
var commandOnAllStateMachines = WaitFor(5000).Until(() => _butterflyCalled == 4);
|
var commandOnAllStateMachines = WaitFor(10000).Until(() => _butterflyCalled == 4);
|
||||||
|
|
||||||
commandOnAllStateMachines.ShouldBeTrue();
|
commandOnAllStateMachines.ShouldBeTrue();
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
public class HeaderTests : IDisposable
|
public class HeaderTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
private IWebHost _builder;
|
||||||
private string _cookieValue;
|
|
||||||
private int _count;
|
private int _count;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
|
||||||
@ -278,14 +277,14 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
{
|
{
|
||||||
app.UsePathBase(basePath);
|
app.UsePathBase(basePath);
|
||||||
app.Run(async context =>
|
app.Run(context =>
|
||||||
{
|
{
|
||||||
if (_count == 0)
|
if (_count == 0)
|
||||||
{
|
{
|
||||||
context.Response.Cookies.Append("test", "0");
|
context.Response.Cookies.Append("test", "0");
|
||||||
_count++;
|
_count++;
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
return;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.Request.Cookies.TryGetValue("test", out var cookieValue) || context.Request.Headers.TryGetValue("Set-Cookie", out var headerValue))
|
if (context.Request.Cookies.TryGetValue("test", out var cookieValue) || context.Request.Headers.TryGetValue("Set-Cookie", out var headerValue))
|
||||||
@ -293,11 +292,12 @@ namespace Ocelot.AcceptanceTests
|
|||||||
if (cookieValue == "0" || headerValue == "test=1; path=/")
|
if (cookieValue == "0" || headerValue == "test=1; path=/")
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
return;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Response.StatusCode = 500;
|
context.Response.StatusCode = 500;
|
||||||
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.Build();
|
.Build();
|
||||||
|
@ -27,26 +27,26 @@
|
|||||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CacheManager.Serialization.Json" Version="1.1.1" />
|
<PackageReference Include="CacheManager.Serialization.Json" Version="1.1.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.2" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
<PackageReference Include="Shouldly" Version="3.0.0" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.3" />
|
<PackageReference Include="Consul" Version="0.7.2.4" />
|
||||||
<PackageReference Include="xunit" Version="2.3.1" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Consul;
|
using Consul;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
@ -22,9 +23,10 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private readonly List<ServiceEntry> _serviceEntries;
|
private readonly List<ServiceEntry> _serviceEntries;
|
||||||
private int _counterOne;
|
private int _counterOne;
|
||||||
private int _counterTwo;
|
private int _counterTwo;
|
||||||
private static readonly object _syncLock = new object();
|
private static readonly object SyncLock = new object();
|
||||||
private IWebHost _builder;
|
private IWebHost _builder;
|
||||||
private string _downstreamPath;
|
private string _downstreamPath;
|
||||||
|
private string _receivedToken;
|
||||||
|
|
||||||
public ServiceDiscoveryTests()
|
public ServiceDiscoveryTests()
|
||||||
{
|
{
|
||||||
@ -100,13 +102,13 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
//test from issue 213
|
//test from issue #213
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_handle_request_to_consul_for_downstream_service_and_make_request()
|
public void should_handle_request_to_consul_for_downstream_service_and_make_request()
|
||||||
{
|
{
|
||||||
var consulPort = 8505;
|
const int consulPort = 8505;
|
||||||
var serviceName = "web";
|
const string serviceName = "web";
|
||||||
var downstreamServiceOneUrl = "http://localhost:8080";
|
const string downstreamServiceOneUrl = "http://localhost:8080";
|
||||||
var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}";
|
var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}";
|
||||||
var serviceEntryOne = new ServiceEntry()
|
var serviceEntryOne = new ServiceEntry()
|
||||||
{
|
{
|
||||||
@ -116,7 +118,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
Address = "localhost",
|
Address = "localhost",
|
||||||
Port = 8080,
|
Port = 8080,
|
||||||
ID = "web_90_0_2_224_8080",
|
ID = "web_90_0_2_224_8080",
|
||||||
Tags = new string[1]{"version-v1"}
|
Tags = new[] {"version-v1"}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -156,6 +158,65 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//test from issue #295
|
||||||
|
[Fact]
|
||||||
|
public void should_use_token_to_make_request_to_consul()
|
||||||
|
{
|
||||||
|
var token = "abctoken";
|
||||||
|
var consulPort = 8515;
|
||||||
|
var serviceName = "web";
|
||||||
|
var downstreamServiceOneUrl = "http://localhost:8081";
|
||||||
|
var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}";
|
||||||
|
var serviceEntryOne = new ServiceEntry()
|
||||||
|
{
|
||||||
|
Service = new AgentService()
|
||||||
|
{
|
||||||
|
Service = serviceName,
|
||||||
|
Address = "localhost",
|
||||||
|
Port = 8081,
|
||||||
|
ID = "web_90_0_2_224_8080",
|
||||||
|
Tags = new[] { "version-v1" }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/api/home",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
UpstreamPathTemplate = "/home",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get", "Options" },
|
||||||
|
ServiceName = serviceName,
|
||||||
|
LoadBalancer = "LeastConnection",
|
||||||
|
UseServiceDiscovery = true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GlobalConfiguration = new FileGlobalConfiguration()
|
||||||
|
{
|
||||||
|
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider()
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = consulPort,
|
||||||
|
Token = token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(_ => GivenThereIsAServiceRunningOn(downstreamServiceOneUrl, "/api/home", 200, "Hello from Laura"))
|
||||||
|
.And(_ => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, serviceName))
|
||||||
|
.And(_ => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne))
|
||||||
|
.And(_ => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(_ => _steps.GivenOcelotIsRunning())
|
||||||
|
.When(_ => _steps.WhenIGetUrlOnTheApiGateway("/home"))
|
||||||
|
.Then(_ => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.And(_ => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||||
|
.And(_ => _receivedToken.ShouldBe(token))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_send_request_to_service_after_it_becomes_available()
|
public void should_send_request_to_service_after_it_becomes_available()
|
||||||
{
|
{
|
||||||
@ -289,6 +350,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
if(context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
if(context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
||||||
{
|
{
|
||||||
|
if (context.Request.Headers.TryGetValue("X-Consul-Token", out var values))
|
||||||
|
{
|
||||||
|
_receivedToken = values.First();
|
||||||
|
}
|
||||||
|
|
||||||
await context.Response.WriteJsonAsync(_serviceEntries);
|
await context.Response.WriteJsonAsync(_serviceEntries);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -312,8 +378,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = string.Empty;
|
string response;
|
||||||
lock (_syncLock)
|
lock (SyncLock)
|
||||||
{
|
{
|
||||||
_counterOne++;
|
_counterOne++;
|
||||||
response = _counterOne.ToString();
|
response = _counterOne.ToString();
|
||||||
@ -321,7 +387,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(response);
|
await context.Response.WriteAsync(response);
|
||||||
}
|
}
|
||||||
catch (System.Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
@ -346,8 +412,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = string.Empty;
|
string response;
|
||||||
lock (_syncLock)
|
lock (SyncLock)
|
||||||
{
|
{
|
||||||
_counterTwo++;
|
_counterTwo++;
|
||||||
response = _counterTwo.ToString();
|
response = _counterTwo.ToString();
|
||||||
@ -356,7 +422,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(response);
|
await context.Response.WriteAsync(response);
|
||||||
}
|
}
|
||||||
catch (System.Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
|
@ -1,722 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using CacheManager.Core;
|
|
||||||
using IdentityServer4.AccessTokenValidation;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.TestHost;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.DependencyInjection;
|
|
||||||
using Ocelot.Middleware;
|
|
||||||
using Shouldly;
|
|
||||||
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
|
|
||||||
using Ocelot.AcceptanceTests.Caching;
|
|
||||||
<<<<<<< HEAD
|
|
||||||
using static Ocelot.AcceptanceTests.HttpDelegatingHandlersTests;
|
|
||||||
||||||| merged common ancestors
|
|
||||||
=======
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Text;
|
|
||||||
>>>>>>> develop
|
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class Steps : IDisposable
|
|
||||||
{
|
|
||||||
private TestServer _ocelotServer;
|
|
||||||
private HttpClient _ocelotClient;
|
|
||||||
private HttpResponseMessage _response;
|
|
||||||
private HttpContent _postContent;
|
|
||||||
private BearerToken _token;
|
|
||||||
public HttpClient OcelotClient => _ocelotClient;
|
|
||||||
public string RequestIdKey = "OcRequestId";
|
|
||||||
private readonly Random _random;
|
|
||||||
private IWebHostBuilder _webHostBuilder;
|
|
||||||
|
|
||||||
public Steps()
|
|
||||||
{
|
|
||||||
_random = new Random();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
|
|
||||||
{
|
|
||||||
var configurationPath = TestConfiguration.ConfigurationPath;
|
|
||||||
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
|
||||||
|
|
||||||
if (File.Exists(configurationPath))
|
|
||||||
{
|
|
||||||
File.Delete(configurationPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
File.WriteAllText(configurationPath, jsonConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenThereIsAConfiguration(FileConfiguration fileConfiguration, string configurationPath)
|
|
||||||
{
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
|
||||||
|
|
||||||
if (File.Exists(configurationPath))
|
|
||||||
{
|
|
||||||
File.Delete(configurationPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
File.WriteAllText(configurationPath, jsonConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
|
|
||||||
/// </summary>
|
|
||||||
public void GivenOcelotIsRunning()
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot();
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void GivenOcelotIsRunningUsingButterfly(string butterflyUrl)
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot()
|
|
||||||
.AddOpenTracing(option =>
|
|
||||||
{
|
|
||||||
//this is the url that the butterfly collector server is running on...
|
|
||||||
option.CollectorUrl = butterflyUrl;
|
|
||||||
option.Service = "Ocelot";
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Use(async (context, next) =>
|
|
||||||
{
|
|
||||||
await next.Invoke();
|
|
||||||
});
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
public void GivenIHaveAddedXForwardedForHeader(string value)
|
|
||||||
{
|
|
||||||
_ocelotClient.DefaultRequestHeaders.TryAddWithoutValidation("X-Forwarded-For", value);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public void GivenOcelotIsRunningWithMiddleareBeforePipeline<T>(Func<object, Task> callback)
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot();
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseMiddleware<T>(callback);
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenOcelotIsRunningWithHandlersRegisteredInDi<TOne, TWo>()
|
|
||||||
where TOne : DelegatingHandler
|
|
||||||
where TWo : DelegatingHandler
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddSingleton(_webHostBuilder);
|
|
||||||
s.AddOcelot()
|
|
||||||
.AddDelegatingHandler<TOne>()
|
|
||||||
.AddDelegatingHandler<TWo>();
|
|
||||||
})
|
|
||||||
.Configure(a =>
|
|
||||||
{
|
|
||||||
a.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenOcelotIsRunningWithHandlersRegisteredInDi<TOne>(FakeDependency dependency)
|
|
||||||
where TOne : DelegatingHandler
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddSingleton(_webHostBuilder);
|
|
||||||
s.AddSingleton<FakeDependency>(dependency);
|
|
||||||
s.AddOcelot()
|
|
||||||
.AddDelegatingHandler<TOne>();
|
|
||||||
})
|
|
||||||
.Configure(a =>
|
|
||||||
{
|
|
||||||
a.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
|
|
||||||
/// </summary>
|
|
||||||
public void GivenOcelotIsRunning(Action<IdentityServerAuthenticationOptions> options, string authenticationProviderKey)
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot();
|
|
||||||
s.AddAuthentication()
|
|
||||||
.AddIdentityServerAuthentication(authenticationProviderKey, options);
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ThenTheResponseHeaderIs(string key, string value)
|
|
||||||
{
|
|
||||||
var header = _response.Headers.GetValues(key);
|
|
||||||
header.First().ShouldBe(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenOcelotIsRunningUsingJsonSerializedCache()
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot()
|
|
||||||
.AddCacheManager((x) =>
|
|
||||||
{
|
|
||||||
x.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithJsonSerializer()
|
|
||||||
.WithHandle(typeof(InMemoryJsonHandle<>));
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenOcelotIsRunningUsingConsulToStoreConfig()
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot().AddStoreOcelotConfigurationInConsul();
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache()
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddJsonFile("configuration.json");
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot()
|
|
||||||
.AddCacheManager((x) =>
|
|
||||||
{
|
|
||||||
x.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithJsonSerializer()
|
|
||||||
.WithHandle(typeof(InMemoryJsonHandle<>));
|
|
||||||
})
|
|
||||||
.AddStoreOcelotConfigurationInConsul();
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ThenTheResponseShouldBe(FileConfiguration expecteds)
|
|
||||||
{
|
|
||||||
var response = JsonConvert.DeserializeObject<FileConfiguration>(_response.Content.ReadAsStringAsync().Result);
|
|
||||||
|
|
||||||
response.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
|
|
||||||
response.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
|
||||||
response.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
|
||||||
|
|
||||||
for (var i = 0; i < response.ReRoutes.Count; i++)
|
|
||||||
{
|
|
||||||
for (var j = 0; j < response.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
|
|
||||||
{
|
|
||||||
var result = response.ReRoutes[i].DownstreamHostAndPorts[j];
|
|
||||||
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
|
|
||||||
result.Host.ShouldBe(expected.Host);
|
|
||||||
result.Port.ShouldBe(expected.Port);
|
|
||||||
}
|
|
||||||
|
|
||||||
response.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
|
|
||||||
response.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
|
|
||||||
response.ReRoutes[i].UpstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].UpstreamPathTemplate);
|
|
||||||
response.ReRoutes[i].UpstreamHttpMethod.ShouldBe(expecteds.ReRoutes[i].UpstreamHttpMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
|
|
||||||
/// </summary>
|
|
||||||
public void GivenOcelotIsRunning(OcelotPipelineConfiguration ocelotPipelineConfig)
|
|
||||||
{
|
|
||||||
var builder = new ConfigurationBuilder()
|
|
||||||
.SetBasePath(Directory.GetCurrentDirectory())
|
|
||||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile("configuration.json")
|
|
||||||
.AddEnvironmentVariables();
|
|
||||||
|
|
||||||
var configuration = builder.Build();
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
_webHostBuilder.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddSingleton(_webHostBuilder);
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder
|
|
||||||
.UseConfiguration(configuration)
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
Action<ConfigurationBuilderCachePart> settings = (x) =>
|
|
||||||
{
|
|
||||||
x.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithDictionaryHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
s.AddOcelot(configuration);
|
|
||||||
})
|
|
||||||
.ConfigureLogging(l =>
|
|
||||||
{
|
|
||||||
l.AddConsole();
|
|
||||||
l.AddDebug();
|
|
||||||
})
|
|
||||||
.Configure(a =>
|
|
||||||
{
|
|
||||||
a.UseOcelot(ocelotPipelineConfig).Wait();
|
|
||||||
}));
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenIHaveAddedATokenToMyRequest()
|
|
||||||
{
|
|
||||||
_ocelotClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token.AccessToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenIHaveAToken(string url)
|
|
||||||
{
|
|
||||||
var tokenUrl = $"{url}/connect/token";
|
|
||||||
var formData = new List<KeyValuePair<string, string>>
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string>("client_id", "client"),
|
|
||||||
new KeyValuePair<string, string>("client_secret", "secret"),
|
|
||||||
new KeyValuePair<string, string>("scope", "api"),
|
|
||||||
new KeyValuePair<string, string>("username", "test"),
|
|
||||||
new KeyValuePair<string, string>("password", "test"),
|
|
||||||
new KeyValuePair<string, string>("grant_type", "password")
|
|
||||||
};
|
|
||||||
var content = new FormUrlEncodedContent(formData);
|
|
||||||
|
|
||||||
using (var httpClient = new HttpClient())
|
|
||||||
{
|
|
||||||
var response = httpClient.PostAsync(tokenUrl, content).Result;
|
|
||||||
var responseContent = response.Content.ReadAsStringAsync().Result;
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
_token = JsonConvert.DeserializeObject<BearerToken>(responseContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenIHaveATokenForApiReadOnlyScope(string url)
|
|
||||||
{
|
|
||||||
var tokenUrl = $"{url}/connect/token";
|
|
||||||
var formData = new List<KeyValuePair<string, string>>
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string>("client_id", "client"),
|
|
||||||
new KeyValuePair<string, string>("client_secret", "secret"),
|
|
||||||
new KeyValuePair<string, string>("scope", "api.readOnly"),
|
|
||||||
new KeyValuePair<string, string>("username", "test"),
|
|
||||||
new KeyValuePair<string, string>("password", "test"),
|
|
||||||
new KeyValuePair<string, string>("grant_type", "password")
|
|
||||||
};
|
|
||||||
var content = new FormUrlEncodedContent(formData);
|
|
||||||
|
|
||||||
using (var httpClient = new HttpClient())
|
|
||||||
{
|
|
||||||
var response = httpClient.PostAsync(tokenUrl, content).Result;
|
|
||||||
var responseContent = response.Content.ReadAsStringAsync().Result;
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
_token = JsonConvert.DeserializeObject<BearerToken>(responseContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenIHaveATokenForApi2(string url)
|
|
||||||
{
|
|
||||||
var tokenUrl = $"{url}/connect/token";
|
|
||||||
var formData = new List<KeyValuePair<string, string>>
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string>("client_id", "client"),
|
|
||||||
new KeyValuePair<string, string>("client_secret", "secret"),
|
|
||||||
new KeyValuePair<string, string>("scope", "api2"),
|
|
||||||
new KeyValuePair<string, string>("username", "test"),
|
|
||||||
new KeyValuePair<string, string>("password", "test"),
|
|
||||||
new KeyValuePair<string, string>("grant_type", "password")
|
|
||||||
};
|
|
||||||
var content = new FormUrlEncodedContent(formData);
|
|
||||||
|
|
||||||
using (var httpClient = new HttpClient())
|
|
||||||
{
|
|
||||||
var response = httpClient.PostAsync(tokenUrl, content).Result;
|
|
||||||
var responseContent = response.Content.ReadAsStringAsync().Result;
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
_token = JsonConvert.DeserializeObject<BearerToken>(responseContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenIHaveAnOcelotToken(string adminPath)
|
|
||||||
{
|
|
||||||
var tokenUrl = $"{adminPath}/connect/token";
|
|
||||||
var formData = new List<KeyValuePair<string, string>>
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string>("client_id", "admin"),
|
|
||||||
new KeyValuePair<string, string>("client_secret", "secret"),
|
|
||||||
new KeyValuePair<string, string>("scope", "admin"),
|
|
||||||
new KeyValuePair<string, string>("username", "admin"),
|
|
||||||
new KeyValuePair<string, string>("password", "admin"),
|
|
||||||
new KeyValuePair<string, string>("grant_type", "password")
|
|
||||||
};
|
|
||||||
var content = new FormUrlEncodedContent(formData);
|
|
||||||
|
|
||||||
var response = _ocelotClient.PostAsync(tokenUrl, content).Result;
|
|
||||||
var responseContent = response.Content.ReadAsStringAsync().Result;
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
_token = JsonConvert.DeserializeObject<BearerToken>(responseContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VerifyIdentiryServerStarted(string url)
|
|
||||||
{
|
|
||||||
using (var httpClient = new HttpClient())
|
|
||||||
{
|
|
||||||
var response = httpClient.GetAsync($"{url}/.well-known/openid-configuration").Result;
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WhenIGetUrlOnTheApiGateway(string url)
|
|
||||||
{
|
|
||||||
_response = _ocelotClient.GetAsync(url).Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenIAddAHeader(string key, string value)
|
|
||||||
{
|
|
||||||
_ocelotClient.DefaultRequestHeaders.Add(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WhenIGetUrlOnTheApiGatewayMultipleTimes(string url, int times)
|
|
||||||
{
|
|
||||||
var tasks = new Task[times];
|
|
||||||
|
|
||||||
for (int i = 0; i < times; i++)
|
|
||||||
{
|
|
||||||
var urlCopy = url;
|
|
||||||
tasks[i] = GetForServiceDiscoveryTest(urlCopy);
|
|
||||||
Thread.Sleep(_random.Next(40, 60));
|
|
||||||
}
|
|
||||||
|
|
||||||
Task.WaitAll(tasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task GetForServiceDiscoveryTest(string url)
|
|
||||||
{
|
|
||||||
var response = await _ocelotClient.GetAsync(url);
|
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
|
||||||
int count = int.Parse(content);
|
|
||||||
count.ShouldBeGreaterThan(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit(string url, int times)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < times; i++)
|
|
||||||
{
|
|
||||||
var clientId = "ocelotclient1";
|
|
||||||
var request = new HttpRequestMessage(new HttpMethod("GET"), url);
|
|
||||||
request.Headers.Add("ClientId", clientId);
|
|
||||||
_response = _ocelotClient.SendAsync(request).Result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WhenIGetUrlOnTheApiGateway(string url, string requestId)
|
|
||||||
{
|
|
||||||
_ocelotClient.DefaultRequestHeaders.TryAddWithoutValidation(RequestIdKey, requestId);
|
|
||||||
|
|
||||||
_response = _ocelotClient.GetAsync(url).Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WhenIPostUrlOnTheApiGateway(string url)
|
|
||||||
{
|
|
||||||
_response = _ocelotClient.PostAsync(url, _postContent).Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenThePostHasContent(string postcontent)
|
|
||||||
{
|
|
||||||
_postContent = new StringContent(postcontent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenThePostHasGzipContent(object input)
|
|
||||||
{
|
|
||||||
string json = JsonConvert.SerializeObject(input);
|
|
||||||
byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
|
|
||||||
MemoryStream ms = new MemoryStream();
|
|
||||||
using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress, true))
|
|
||||||
{
|
|
||||||
gzip.Write(jsonBytes, 0, jsonBytes.Length);
|
|
||||||
}
|
|
||||||
ms.Position = 0;
|
|
||||||
StreamContent content = new StreamContent(ms);
|
|
||||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
|
||||||
content.Headers.ContentEncoding.Add("gzip");
|
|
||||||
_postContent = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ThenTheResponseBodyShouldBe(string expectedBody)
|
|
||||||
{
|
|
||||||
_response.Content.ReadAsStringAsync().Result.ShouldBe(expectedBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ThenTheStatusCodeShouldBe(HttpStatusCode expectedHttpStatusCode)
|
|
||||||
{
|
|
||||||
_response.StatusCode.ShouldBe(expectedHttpStatusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ThenTheStatusCodeShouldBe(int expectedHttpStatusCode)
|
|
||||||
{
|
|
||||||
var responseStatusCode = (int)_response.StatusCode;
|
|
||||||
responseStatusCode.ShouldBe(expectedHttpStatusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_ocelotClient?.Dispose();
|
|
||||||
_ocelotServer?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ThenTheRequestIdIsReturned()
|
|
||||||
{
|
|
||||||
_response.Headers.GetValues(RequestIdKey).First().ShouldNotBeNullOrEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ThenTheRequestIdIsReturned(string expected)
|
|
||||||
{
|
|
||||||
_response.Headers.GetValues(RequestIdKey).First().ShouldBe(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ThenTheContentLengthIs(int expected)
|
|
||||||
{
|
|
||||||
_response.Content.Headers.ContentLength.ShouldBe(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WhenIMakeLotsOfDifferentRequestsToTheApiGateway()
|
|
||||||
{
|
|
||||||
int numberOfRequests = 100;
|
|
||||||
var aggregateUrl = "/";
|
|
||||||
var aggregateExpected = "{\"Laura\":{Hello from Laura},\"Tom\":{Hello from Tom}}";
|
|
||||||
var tomUrl = "/tom";
|
|
||||||
var tomExpected = "{Hello from Tom}";
|
|
||||||
var lauraUrl = "/laura";
|
|
||||||
var lauraExpected = "{Hello from Laura}";
|
|
||||||
var random = new Random();
|
|
||||||
|
|
||||||
var aggregateTasks = new Task[numberOfRequests];
|
|
||||||
|
|
||||||
for (int i = 0; i < numberOfRequests; i++)
|
|
||||||
{
|
|
||||||
aggregateTasks[i] = Fire(aggregateUrl, aggregateExpected, random);
|
|
||||||
}
|
|
||||||
|
|
||||||
var tomTasks = new Task[numberOfRequests];
|
|
||||||
|
|
||||||
for (int i = 0; i < numberOfRequests; i++)
|
|
||||||
{
|
|
||||||
tomTasks[i] = Fire(tomUrl, tomExpected, random);
|
|
||||||
}
|
|
||||||
|
|
||||||
var lauraTasks = new Task[numberOfRequests];
|
|
||||||
|
|
||||||
for (int i = 0; i < numberOfRequests; i++)
|
|
||||||
{
|
|
||||||
lauraTasks[i] = Fire(lauraUrl, lauraExpected, random);
|
|
||||||
}
|
|
||||||
|
|
||||||
Task.WaitAll(lauraTasks);
|
|
||||||
Task.WaitAll(tomTasks);
|
|
||||||
Task.WaitAll(aggregateTasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Fire(string url, string expectedBody, Random random)
|
|
||||||
{
|
|
||||||
var request = new HttpRequestMessage(new HttpMethod("GET"), url);
|
|
||||||
await Task.Delay(random.Next(0, 2));
|
|
||||||
var response = await _ocelotClient.SendAsync(request);
|
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
|
||||||
content.ShouldBe(expectedBody);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -37,7 +37,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task should_proxy_websocket_input_to_downstream_service()
|
public void should_proxy_websocket_input_to_downstream_service()
|
||||||
{
|
{
|
||||||
var downstreamPort = 5001;
|
var downstreamPort = 5001;
|
||||||
var downstreamHost = "localhost";
|
var downstreamHost = "localhost";
|
||||||
@ -72,7 +72,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task should_proxy_websocket_input_to_downstream_service_and_use_load_balancer()
|
public void should_proxy_websocket_input_to_downstream_service_and_use_load_balancer()
|
||||||
{
|
{
|
||||||
var downstreamPort = 5005;
|
var downstreamPort = 5005;
|
||||||
var downstreamHost = "localhost";
|
var downstreamHost = "localhost";
|
||||||
@ -116,7 +116,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task should_proxy_websocket_input_to_downstream_service_and_use_service_discovery_and_load_balancer()
|
public void should_proxy_websocket_input_to_downstream_service_and_use_service_discovery_and_load_balancer()
|
||||||
{
|
{
|
||||||
var downstreamPort = 5007;
|
var downstreamPort = 5007;
|
||||||
var downstreamHost = "localhost";
|
var downstreamHost = "localhost";
|
||||||
@ -274,7 +274,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
_firstRecieved.Add(Encoding.UTF8.GetString(buffer, 0, result.Count));
|
_firstRecieved.Add(Encoding.UTF8.GetString(buffer, 0, result.Count));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (result.MessageType == WebSocketMessageType.Close)
|
else if (result.MessageType == WebSocketMessageType.Close)
|
||||||
{
|
{
|
||||||
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
||||||
@ -321,7 +320,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
_secondRecieved.Add(Encoding.UTF8.GetString(buffer, 0, result.Count));
|
_secondRecieved.Add(Encoding.UTF8.GetString(buffer, 0, result.Count));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (result.MessageType == WebSocketMessageType.Close)
|
else if (result.MessageType == WebSocketMessageType.Close)
|
||||||
{
|
{
|
||||||
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
||||||
@ -333,7 +331,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await Task.WhenAll(sending, receiving);
|
await Task.WhenAll(sending, receiving);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task StartFakeDownstreamService(string url, string path)
|
private async Task StartFakeDownstreamService(string url, string path)
|
||||||
{
|
{
|
||||||
_firstDownstreamHost = new WebHostBuilder()
|
_firstDownstreamHost = new WebHostBuilder()
|
||||||
@ -380,7 +377,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await _firstDownstreamHost.StartAsync();
|
await _firstDownstreamHost.StartAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task StartSecondFakeDownstreamService(string url, string path)
|
private async Task StartSecondFakeDownstreamService(string url, string path)
|
||||||
{
|
{
|
||||||
_secondDownstreamHost = new WebHostBuilder()
|
_secondDownstreamHost = new WebHostBuilder()
|
||||||
@ -427,7 +423,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await _secondDownstreamHost.StartAsync();
|
await _secondDownstreamHost.StartAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task Echo(WebSocket webSocket)
|
private async Task Echo(WebSocket webSocket)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BenchmarkDotNet" Version="0.10.12" />
|
<PackageReference Include="BenchmarkDotNet" Version="0.10.13" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@ -25,26 +25,26 @@
|
|||||||
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="xunit" Version="2.3.1" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.0.2" />
|
<PackageReference Include="IdentityServer4" Version="2.1.3" />
|
||||||
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
<PackageReference Include="Shouldly" Version="3.0.0" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.3" />
|
<PackageReference Include="Consul" Version="0.7.2.4" />
|
||||||
<PackageReference Include="Rafty" Version="0.4.2" />
|
<PackageReference Include="Rafty" Version="0.4.2" />
|
||||||
<PackageReference Include="Microsoft.Data.SQLite" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Data.SQLite" Version="2.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -24,16 +24,16 @@
|
|||||||
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0"/>
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0"/>
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0"/>
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0"/>
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0"/>
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0"/>
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0"/>
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0"/>
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Consul" Version="0.7.2.3"/>
|
<PackageReference Include="Consul" Version="0.7.2.4" />
|
||||||
<PackageReference Include="Polly" Version="5.3.1"/>
|
<PackageReference Include="Polly" Version="5.8.0" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@ -10,8 +10,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
public class ServiceProviderCreatorTests
|
public class ServiceProviderCreatorTests
|
||||||
{
|
{
|
||||||
private ServiceProviderConfigurationCreator _creator;
|
private readonly ServiceProviderConfigurationCreator _creator;
|
||||||
private FileReRoute _reRoute;
|
|
||||||
private FileGlobalConfiguration _globalConfig;
|
private FileGlobalConfiguration _globalConfig;
|
||||||
private ServiceProviderConfiguration _result;
|
private ServiceProviderConfiguration _result;
|
||||||
|
|
||||||
@ -23,36 +22,30 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_create_service_provider_config()
|
public void should_create_service_provider_config()
|
||||||
{
|
{
|
||||||
var reRoute = new FileReRoute();
|
|
||||||
|
|
||||||
var globalConfig = new FileGlobalConfiguration
|
var globalConfig = new FileGlobalConfiguration
|
||||||
{
|
{
|
||||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||||
{
|
{
|
||||||
Host = "127.0.0.1",
|
Host = "127.0.0.1",
|
||||||
Port = 1234,
|
Port = 1234,
|
||||||
Type = "ServiceFabric"
|
Type = "ServiceFabric",
|
||||||
|
Token = "testtoken"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var expected = new ServiceProviderConfigurationBuilder()
|
var expected = new ServiceProviderConfigurationBuilder()
|
||||||
.WithServiceDiscoveryProviderHost("127.0.0.1")
|
.WithHost("127.0.0.1")
|
||||||
.WithServiceDiscoveryProviderPort(1234)
|
.WithPort(1234)
|
||||||
.WithServiceDiscoveryProviderType("ServiceFabric")
|
.WithType("ServiceFabric")
|
||||||
|
.WithToken("testtoken")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheFollowingReRoute(reRoute))
|
this.Given(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
||||||
.And(x => x.GivenTheFollowingGlobalConfig(globalConfig))
|
|
||||||
.When(x => x.WhenICreate())
|
.When(x => x.WhenICreate())
|
||||||
.Then(x => x.ThenTheConfigIs(expected))
|
.Then(x => x.ThenTheConfigIs(expected))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheFollowingReRoute(FileReRoute fileReRoute)
|
|
||||||
{
|
|
||||||
_reRoute = fileReRoute;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
||||||
{
|
{
|
||||||
_globalConfig = fileGlobalConfig;
|
_globalConfig = fileGlobalConfig;
|
||||||
@ -67,6 +60,8 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_result.Host.ShouldBe(expected.Host);
|
_result.Host.ShouldBe(expected.Host);
|
||||||
_result.Port.ShouldBe(expected.Port);
|
_result.Port.ShouldBe(expected.Port);
|
||||||
|
_result.Token.ShouldBe(expected.Token);
|
||||||
|
_result.Type.ShouldBe(expected.Type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,9 +82,9 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
|||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var config = new ServiceProviderConfigurationBuilder()
|
var config = new ServiceProviderConfigurationBuilder()
|
||||||
.WithServiceDiscoveryProviderType("ServiceFabric")
|
.WithType("ServiceFabric")
|
||||||
.WithServiceDiscoveryProviderHost("localhost")
|
.WithHost("localhost")
|
||||||
.WithServiceDiscoveryProviderPort(19081)
|
.WithPort(19081)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheDownStreamRouteIs(
|
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||||
@ -118,9 +118,9 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
|||||||
.Build());
|
.Build());
|
||||||
|
|
||||||
var config = new ServiceProviderConfigurationBuilder()
|
var config = new ServiceProviderConfigurationBuilder()
|
||||||
.WithServiceDiscoveryProviderType("ServiceFabric")
|
.WithType("ServiceFabric")
|
||||||
.WithServiceDiscoveryProviderHost("localhost")
|
.WithHost("localhost")
|
||||||
.WithServiceDiscoveryProviderPort(19081)
|
.WithPort(19081)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||||
@ -148,9 +148,9 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
|||||||
.Build());
|
.Build());
|
||||||
|
|
||||||
var config = new ServiceProviderConfigurationBuilder()
|
var config = new ServiceProviderConfigurationBuilder()
|
||||||
.WithServiceDiscoveryProviderType("ServiceFabric")
|
.WithType("ServiceFabric")
|
||||||
.WithServiceDiscoveryProviderHost("localhost")
|
.WithHost("localhost")
|
||||||
.WithServiceDiscoveryProviderPort(19081)
|
.WithPort(19081)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||||
@ -178,9 +178,9 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
|||||||
.Build());
|
.Build());
|
||||||
|
|
||||||
var config = new ServiceProviderConfigurationBuilder()
|
var config = new ServiceProviderConfigurationBuilder()
|
||||||
.WithServiceDiscoveryProviderType("ServiceFabric")
|
.WithType("ServiceFabric")
|
||||||
.WithServiceDiscoveryProviderHost("localhost")
|
.WithHost("localhost")
|
||||||
.WithServiceDiscoveryProviderPort(19081)
|
.WithPort(19081)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||||
|
@ -25,7 +25,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);
|
_serviceProviderConfig = new ServiceProviderConfiguration("myType","myHost",123, string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -35,23 +35,23 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.2" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
<PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.1" />
|
||||||
<PackageReference Include="Moq" Version="4.7.142" />
|
<PackageReference Include="Moq" Version="4.8.2" />
|
||||||
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
|
<PackageReference Include="Shouldly" Version="3.0.0" />
|
||||||
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
|
||||||
<PackageReference Include="xunit" Version="2.3.1" />
|
<PackageReference Include="xunit" Version="2.3.1" />
|
||||||
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Linq;
|
||||||
using Consul;
|
using Consul;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using Ocelot.Infrastructure.Consul;
|
||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
using Ocelot.ServiceDiscovery;
|
|
||||||
using Ocelot.ServiceDiscovery.Configuration;
|
using Ocelot.ServiceDiscovery.Configuration;
|
||||||
using Ocelot.ServiceDiscovery.Providers;
|
using Ocelot.ServiceDiscovery.Providers;
|
||||||
using Ocelot.Values;
|
using Ocelot.Values;
|
||||||
@ -22,14 +22,16 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
|||||||
{
|
{
|
||||||
private IWebHost _fakeConsulBuilder;
|
private IWebHost _fakeConsulBuilder;
|
||||||
private readonly List<ServiceEntry> _serviceEntries;
|
private readonly List<ServiceEntry> _serviceEntries;
|
||||||
private readonly ConsulServiceDiscoveryProvider _provider;
|
private ConsulServiceDiscoveryProvider _provider;
|
||||||
private readonly string _serviceName;
|
private readonly string _serviceName;
|
||||||
private readonly int _port;
|
private readonly int _port;
|
||||||
private readonly string _consulHost;
|
private readonly string _consulHost;
|
||||||
private readonly string _fakeConsulServiceDiscoveryUrl;
|
private readonly string _fakeConsulServiceDiscoveryUrl;
|
||||||
private List<Service> _services;
|
private List<Service> _services;
|
||||||
private Mock<IOcelotLoggerFactory> _factory;
|
private readonly Mock<IOcelotLoggerFactory> _factory;
|
||||||
private readonly Mock<IOcelotLogger> _logger;
|
private readonly Mock<IOcelotLogger> _logger;
|
||||||
|
private string _receivedToken;
|
||||||
|
private IConsulClientFactory _clientFactory;
|
||||||
|
|
||||||
public ConsulServiceDiscoveryProviderTests()
|
public ConsulServiceDiscoveryProviderTests()
|
||||||
{
|
{
|
||||||
@ -40,11 +42,12 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
|||||||
_serviceEntries = new List<ServiceEntry>();
|
_serviceEntries = new List<ServiceEntry>();
|
||||||
|
|
||||||
_factory = new Mock<IOcelotLoggerFactory>();
|
_factory = new Mock<IOcelotLoggerFactory>();
|
||||||
|
_clientFactory = new ConsulClientFactory();
|
||||||
_logger = new Mock<IOcelotLogger>();
|
_logger = new Mock<IOcelotLogger>();
|
||||||
_factory.Setup(x => x.CreateLogger<ConsulServiceDiscoveryProvider>()).Returns(_logger.Object);
|
_factory.Setup(x => x.CreateLogger<ConsulServiceDiscoveryProvider>()).Returns(_logger.Object);
|
||||||
|
|
||||||
var config = new ConsulRegistryConfiguration(_consulHost, _port, _serviceName);
|
var config = new ConsulRegistryConfiguration(_consulHost, _port, _serviceName, null);
|
||||||
_provider = new ConsulServiceDiscoveryProvider(config, _factory.Object);
|
_provider = new ConsulServiceDiscoveryProvider(config, _factory.Object, _clientFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -69,6 +72,33 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_use_token()
|
||||||
|
{
|
||||||
|
var token = "test token";
|
||||||
|
var config = new ConsulRegistryConfiguration(_consulHost, _port, _serviceName, token);
|
||||||
|
_provider = new ConsulServiceDiscoveryProvider(config, _factory.Object, _clientFactory);
|
||||||
|
|
||||||
|
var serviceEntryOne = new ServiceEntry()
|
||||||
|
{
|
||||||
|
Service = new AgentService()
|
||||||
|
{
|
||||||
|
Service = _serviceName,
|
||||||
|
Address = "localhost",
|
||||||
|
Port = 50881,
|
||||||
|
ID = Guid.NewGuid().ToString(),
|
||||||
|
Tags = new string[0]
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(_ => GivenThereIsAFakeConsulServiceDiscoveryProvider(_fakeConsulServiceDiscoveryUrl, _serviceName))
|
||||||
|
.And(_ => GivenTheServicesAreRegisteredWithConsul(serviceEntryOne))
|
||||||
|
.When(_ => WhenIGetTheServices())
|
||||||
|
.Then(_ => ThenTheCountIs(1))
|
||||||
|
.And(_ => _receivedToken.ShouldBe(token))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_not_return_services_with_invalid_address()
|
public void should_not_return_services_with_invalid_address()
|
||||||
{
|
{
|
||||||
@ -197,6 +227,11 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
|||||||
{
|
{
|
||||||
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
||||||
{
|
{
|
||||||
|
if (context.Request.Headers.TryGetValue("X-Consul-Token", out var values))
|
||||||
|
{
|
||||||
|
_receivedToken = values.First();
|
||||||
|
}
|
||||||
|
|
||||||
await context.Response.WriteJsonAsync(_serviceEntries);
|
await context.Response.WriteJsonAsync(_serviceEntries);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Builder;
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Ocelot.Infrastructure.Consul;
|
||||||
using Ocelot.Logging;
|
using Ocelot.Logging;
|
||||||
using Ocelot.ServiceDiscovery;
|
using Ocelot.ServiceDiscovery;
|
||||||
using Ocelot.ServiceDiscovery.Providers;
|
using Ocelot.ServiceDiscovery.Providers;
|
||||||
@ -19,11 +20,13 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
|||||||
private readonly ServiceDiscoveryProviderFactory _factory;
|
private readonly ServiceDiscoveryProviderFactory _factory;
|
||||||
private DownstreamReRoute _reRoute;
|
private DownstreamReRoute _reRoute;
|
||||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
|
private IConsulClientFactory _clientFactory;
|
||||||
|
|
||||||
public ServiceProviderFactoryTests()
|
public ServiceProviderFactoryTests()
|
||||||
{
|
{
|
||||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||||
_factory = new ServiceDiscoveryProviderFactory(_loggerFactory.Object);
|
_clientFactory = new ConsulClientFactory();
|
||||||
|
_factory = new ServiceDiscoveryProviderFactory(_loggerFactory.Object, _clientFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -87,7 +90,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
|
|||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
var serviceConfig = new ServiceProviderConfigurationBuilder()
|
||||||
.WithServiceDiscoveryProviderType("ServiceFabric")
|
.WithType("ServiceFabric")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user