mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
Feature/store configuraton json idented (#328)
* messing around with benchmark.net.seems Ocelot adds about 2ms to a request..lets make this less? :) * #326 store json indented so it looks nice :P
This commit is contained in:
parent
636d116491
commit
77211e9f16
@ -163,7 +163,7 @@ requests. This would also mean that subsequent requests dont use the cookies fro
|
|||||||
UseCookieContainer to true unless you have a really really good reason. Just look at your response headers and forward the cookies back with your next request!
|
UseCookieContainer to true unless you have a really really good reason. Just look at your response headers and forward the cookies back with your next request!
|
||||||
|
|
||||||
SSL Errors
|
SSL Errors
|
||||||
----------
|
^^^^^^^^^^
|
||||||
|
|
||||||
Id you want to ignore SSL warnings / errors set the following in your ReRoute config.
|
Id you want to ignore SSL warnings / errors set the following in your ReRoute config.
|
||||||
|
|
||||||
|
@ -69,18 +69,20 @@ In order to get this working add the following to ocelot.json..
|
|||||||
"Type": "Eureka"
|
"Type": "Eureka"
|
||||||
}
|
}
|
||||||
|
|
||||||
And following the guide `Here <https://steeltoe.io/docs/steeltoe-discovery/>`_ you may also need to add some stuff to appsettings.json. For example the json below
|
And following the guide `Here <https://steeltoe.io/docs/steeltoe-discovery/>`_ you may also need to add some stuff to appsettings.json. For example the json below tells the steeltoe / pivotal services where to look for the service discovery server and if the service should register with it.
|
||||||
tells the steeltoe / pivotal services where to look for the service discovery server and if the service should register with it.
|
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
"eureka": {
|
"eureka": {
|
||||||
"client": {
|
"client": {
|
||||||
"serviceUrl": "http://localhost:8761/eureka/",
|
"serviceUrl": "http://localhost:8761/eureka/",
|
||||||
"shouldRegisterWithEureka": true
|
"shouldRegisterWithEureka": false,
|
||||||
|
"shouldFetchRegistry": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
I am told that if shouldRegisterWithEureka is false then shouldFetchRegistry will defaut to true so you don't need it explicitly but left it in there.
|
||||||
|
|
||||||
Ocelot will now register all the necessary services when it starts up and if you have the json above will register itself with
|
Ocelot will now register all the necessary services when it starts up and if you have the json above will register itself with
|
||||||
Eureka. One of the services polls Eureka every 30 seconds (default) and gets the latest service state and persists this in memory.
|
Eureka. One of the services polls Eureka every 30 seconds (default) and gets the latest service state and persists this in memory.
|
||||||
When Ocelot asks for a given service it is retrieved from memory so performance is not a big problem. Please note that this code
|
When Ocelot asks for a given service it is retrieved from memory so performance is not a big problem. Please note that this code
|
||||||
|
@ -13,7 +13,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
|
||||||
{
|
{
|
||||||
private readonly ConsulClient _consul;
|
private readonly IConsulClient _consul;
|
||||||
private const string OcelotConfiguration = "InternalConfiguration";
|
private const string OcelotConfiguration = "InternalConfiguration";
|
||||||
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
|
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
@ -72,7 +72,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
public async Task<Response> Set(FileConfiguration ocelotConfiguration)
|
public async Task<Response> Set(FileConfiguration ocelotConfiguration)
|
||||||
{
|
{
|
||||||
var json = JsonConvert.SerializeObject(ocelotConfiguration);
|
var json = JsonConvert.SerializeObject(ocelotConfiguration, Formatting.Indented);
|
||||||
|
|
||||||
var bytes = Encoding.UTF8.GetBytes(json);
|
var bytes = Encoding.UTF8.GetBytes(json);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
public Task<Response> Set(FileConfiguration fileConfiguration)
|
public Task<Response> Set(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
string jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
string jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
|
||||||
|
|
||||||
lock(_lock)
|
lock(_lock)
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,7 @@ namespace Ocelot.Infrastructure.Consul
|
|||||||
{
|
{
|
||||||
public class ConsulClientFactory : IConsulClientFactory
|
public class ConsulClientFactory : IConsulClientFactory
|
||||||
{
|
{
|
||||||
public ConsulClient Get(ConsulRegistryConfiguration config)
|
public IConsulClient Get(ConsulRegistryConfiguration config)
|
||||||
{
|
{
|
||||||
return new ConsulClient(c =>
|
return new ConsulClient(c =>
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,6 @@ namespace Ocelot.Infrastructure.Consul
|
|||||||
{
|
{
|
||||||
public interface IConsulClientFactory
|
public interface IConsulClientFactory
|
||||||
{
|
{
|
||||||
ConsulClient Get(ConsulRegistryConfiguration config);
|
IConsulClient Get(ConsulRegistryConfiguration config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ namespace Ocelot.ServiceDiscovery.Providers
|
|||||||
{
|
{
|
||||||
private readonly ConsulRegistryConfiguration _config;
|
private readonly ConsulRegistryConfiguration _config;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
private readonly ConsulClient _consul;
|
private readonly IConsulClient _consul;
|
||||||
private const string VersionPrefix = "version-";
|
private const string VersionPrefix = "version-";
|
||||||
|
|
||||||
public ConsulServiceDiscoveryProvider(ConsulRegistryConfiguration config, IOcelotLoggerFactory factory, IConsulClientFactory clientFactory)
|
public ConsulServiceDiscoveryProvider(ConsulRegistryConfiguration config, IOcelotLoggerFactory factory, IConsulClientFactory clientFactory)
|
||||||
|
@ -88,7 +88,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
var configurationPath = TestConfiguration.ConfigurationPath;
|
var configurationPath = TestConfiguration.ConfigurationPath;
|
||||||
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
|
||||||
|
|
||||||
if (File.Exists(configurationPath))
|
if (File.Exists(configurationPath))
|
||||||
{
|
{
|
||||||
@ -100,7 +100,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public void GivenThereIsAConfiguration(FileConfiguration fileConfiguration, string configurationPath)
|
public void GivenThereIsAConfiguration(FileConfiguration fileConfiguration, string configurationPath)
|
||||||
{
|
{
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
|
||||||
|
|
||||||
if (File.Exists(configurationPath))
|
if (File.Exists(configurationPath))
|
||||||
{
|
{
|
||||||
|
157
test/Ocelot.Benchmarks/AllTheThingsBenchmarks.cs
Normal file
157
test/Ocelot.Benchmarks/AllTheThingsBenchmarks.cs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using BenchmarkDotNet.Columns;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
using Ocelot.DependencyInjection;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BenchmarkDotNet.Attributes.Jobs;
|
||||||
|
using BenchmarkDotNet.Diagnosers;
|
||||||
|
using BenchmarkDotNet.Validators;
|
||||||
|
|
||||||
|
namespace Ocelot.Benchmarks
|
||||||
|
{
|
||||||
|
[Config(typeof(AllTheThingsBenchmarks))]
|
||||||
|
public class AllTheThingsBenchmarks : ManualConfig
|
||||||
|
{
|
||||||
|
private IWebHost _service;
|
||||||
|
private IWebHost _ocelot;
|
||||||
|
private HttpClient _httpClient;
|
||||||
|
|
||||||
|
public AllTheThingsBenchmarks()
|
||||||
|
{
|
||||||
|
Add(StatisticColumn.AllStatistics);
|
||||||
|
Add(MemoryDiagnoser.Default);
|
||||||
|
Add(BaselineValidator.FailOnError);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 51879,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 201, string.Empty);
|
||||||
|
GivenThereIsAConfiguration(configuration);
|
||||||
|
GivenOcelotIsRunning("http://localhost:5000");
|
||||||
|
|
||||||
|
_httpClient = new HttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark(Baseline = true)]
|
||||||
|
public async Task Baseline()
|
||||||
|
{
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5000/");
|
||||||
|
var response = await _httpClient.SendAsync(request);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// * Summary *
|
||||||
|
// BenchmarkDotNet=v0.10.13, OS=macOS 10.12.6 (16G1212) [Darwin 16.7.0]
|
||||||
|
// Intel Core i5-4278U CPU 2.60GHz (Haswell), 1 CPU, 4 logical cores and 2 physical cores
|
||||||
|
// .NET Core SDK=2.1.4
|
||||||
|
// [Host] : .NET Core 2.0.6 (CoreCLR 4.6.0.0, CoreFX 4.6.26212.01), 64bit RyuJIT
|
||||||
|
// DefaultJob : .NET Core 2.0.6 (CoreCLR 4.6.0.0, CoreFX 4.6.26212.01), 64bit RyuJIT
|
||||||
|
|
||||||
|
// Method | Mean | Error | StdDev | StdErr | Min | Q1 | Median | Q3 | Max | Op/s | Scaled | Gen 0 | Gen 1 | Allocated |
|
||||||
|
// --------- |---------:|----------:|----------:|----------:|---------:|---------:|---------:|---------:|---------:|------:|-------:|--------:|-------:|----------:|
|
||||||
|
// Baseline | 2.102 ms | 0.0292 ms | 0.0273 ms | 0.0070 ms | 2.063 ms | 2.080 ms | 2.093 ms | 2.122 ms | 2.152 ms | 475.8 | 1.00 | 31.2500 | 3.9063 | 1.63 KB |
|
||||||
|
|
||||||
|
private void GivenOcelotIsRunning(string url)
|
||||||
|
{
|
||||||
|
_ocelot = new WebHostBuilder()
|
||||||
|
.UseKestrel()
|
||||||
|
.UseUrls(url)
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
|
{
|
||||||
|
config
|
||||||
|
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
|
||||||
|
.AddJsonFile("appsettings.json", true, true)
|
||||||
|
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
|
||||||
|
.AddJsonFile("ocelot.json")
|
||||||
|
.AddEnvironmentVariables();
|
||||||
|
})
|
||||||
|
.ConfigureServices(s => {
|
||||||
|
s.AddOcelot();
|
||||||
|
})
|
||||||
|
.ConfigureLogging((hostingContext, logging) =>
|
||||||
|
{
|
||||||
|
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
||||||
|
})
|
||||||
|
.UseIISIntegration()
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UseOcelot().Wait();
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_ocelot.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GivenThereIsAConfiguration(FileConfiguration fileConfiguration)
|
||||||
|
{
|
||||||
|
var configurationPath = Path.Combine(AppContext.BaseDirectory, "ocelot.json");;
|
||||||
|
|
||||||
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
||||||
|
|
||||||
|
if (File.Exists(configurationPath))
|
||||||
|
{
|
||||||
|
File.Delete(configurationPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(configurationPath, jsonConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
|
{
|
||||||
|
_service = new WebHostBuilder()
|
||||||
|
.UseUrls(baseUrl)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UsePathBase(basePath);
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = statusCode;
|
||||||
|
await context.Response.WriteAsync(responseBody);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_service.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using BenchmarkDotNet.Columns;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
using Ocelot.DependencyInjection;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BenchmarkDotNet.Attributes.Jobs;
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
|
using Ocelot.Infrastructure.RequestData;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.Errors.Middleware;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using BenchmarkDotNet.Diagnosers;
|
||||||
|
using BenchmarkDotNet.Validators;
|
||||||
|
|
||||||
|
namespace Ocelot.Benchmarks
|
||||||
|
{
|
||||||
|
[SimpleJob(launchCount: 1, warmupCount: 2, targetCount: 5)]
|
||||||
|
[Config(typeof(ExceptionHandlerMiddlewareBenchmarks))]
|
||||||
|
public class ExceptionHandlerMiddlewareBenchmarks : ManualConfig
|
||||||
|
{
|
||||||
|
private ExceptionHandlerMiddleware _middleware;
|
||||||
|
private DownstreamContext _downstreamContext;
|
||||||
|
private OcelotRequestDelegate _next;
|
||||||
|
|
||||||
|
public ExceptionHandlerMiddlewareBenchmarks()
|
||||||
|
{
|
||||||
|
Add(StatisticColumn.AllStatistics);
|
||||||
|
Add(MemoryDiagnoser.Default);
|
||||||
|
Add(BaselineValidator.FailOnError);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
var serviceCollection = new ServiceCollection();
|
||||||
|
var config = new ConfigurationRoot(new List<IConfigurationProvider>());
|
||||||
|
var builder = new OcelotBuilder(serviceCollection, config);
|
||||||
|
var services = serviceCollection.BuildServiceProvider();
|
||||||
|
var loggerFactory = services.GetService<IOcelotLoggerFactory>();
|
||||||
|
var configRepo = services.GetService<IInternalConfigurationRepository>();
|
||||||
|
var repo = services.GetService<IRequestScopedDataRepository>();
|
||||||
|
_next = async context => {
|
||||||
|
await Task.CompletedTask;
|
||||||
|
throw new Exception("BOOM");
|
||||||
|
};
|
||||||
|
_middleware = new ExceptionHandlerMiddleware(_next, loggerFactory, configRepo, repo);
|
||||||
|
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark(Baseline = true)]
|
||||||
|
public async Task Baseline()
|
||||||
|
{
|
||||||
|
await _middleware.Invoke(_downstreamContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,9 @@ namespace Ocelot.Benchmarks
|
|||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var switcher = new BenchmarkSwitcher(new[] {
|
var switcher = new BenchmarkSwitcher(new[] {
|
||||||
typeof(UrlPathToUrlPathTemplateMatcherBenchmarks),
|
typeof(UrlPathToUrlPathTemplateMatcherBenchmarks),
|
||||||
|
typeof(AllTheThingsBenchmarks),
|
||||||
|
typeof(ExceptionHandlerMiddlewareBenchmarks)
|
||||||
});
|
});
|
||||||
|
|
||||||
switcher.Run(args);
|
switcher.Run(args);
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
using System;
|
||||||
using BenchmarkDotNet.Attributes;
|
using BenchmarkDotNet.Attributes;
|
||||||
using BenchmarkDotNet.Columns;
|
using BenchmarkDotNet.Columns;
|
||||||
using BenchmarkDotNet.Configs;
|
using BenchmarkDotNet.Configs;
|
||||||
|
using BenchmarkDotNet.Diagnosers;
|
||||||
|
using BenchmarkDotNet.Validators;
|
||||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
|
|
||||||
namespace Ocelot.Benchmarks
|
namespace Ocelot.Benchmarks
|
||||||
@ -15,6 +18,8 @@ namespace Ocelot.Benchmarks
|
|||||||
public UrlPathToUrlPathTemplateMatcherBenchmarks()
|
public UrlPathToUrlPathTemplateMatcherBenchmarks()
|
||||||
{
|
{
|
||||||
Add(StatisticColumn.AllStatistics);
|
Add(StatisticColumn.AllStatistics);
|
||||||
|
Add(MemoryDiagnoser.Default);
|
||||||
|
Add(BaselineValidator.FailOnError);
|
||||||
}
|
}
|
||||||
|
|
||||||
[GlobalSetup]
|
[GlobalSetup]
|
||||||
@ -25,16 +30,23 @@ namespace Ocelot.Benchmarks
|
|||||||
_downstreamUrlPathTemplate = "api/product/products/{productId}/variants/";
|
_downstreamUrlPathTemplate = "api/product/products/{productId}/variants/";
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
[Benchmark(Baseline = true)]
|
||||||
public void Benchmark1()
|
public void Baseline()
|
||||||
{
|
{
|
||||||
_urlPathMatcher.Match(_downstreamUrlPath, _downstreamUrlPathTemplate);
|
_urlPathMatcher.Match(_downstreamUrlPath, _downstreamUrlPathTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
// * Summary *
|
||||||
public void Benchmark2()
|
|
||||||
{
|
// BenchmarkDotNet=v0.10.13, OS=macOS 10.12.6 (16G1212) [Darwin 16.7.0]
|
||||||
_urlPathMatcher.Match(_downstreamUrlPath, _downstreamUrlPathTemplate);
|
// Intel Core i5-4278U CPU 2.60GHz (Haswell), 1 CPU, 4 logical cores and 2 physical cores
|
||||||
}
|
// .NET Core SDK=2.1.4
|
||||||
|
// [Host] : .NET Core 2.0.6 (CoreCLR 4.6.0.0, CoreFX 4.6.26212.01), 64bit RyuJIT
|
||||||
|
// DefaultJob : .NET Core 2.0.6 (CoreCLR 4.6.0.0, CoreFX 4.6.26212.01), 64bit RyuJIT
|
||||||
|
|
||||||
|
|
||||||
|
// Method | Mean | Error | StdDev | StdErr | Min | Q1 | Median | Q3 | Max | Op/s |
|
||||||
|
// ----------- |---------:|----------:|----------:|----------:|---------:|---------:|---------:|---------:|---------:|----------:|
|
||||||
|
// Benchmark1 | 3.133 us | 0.0492 us | 0.0460 us | 0.0119 us | 3.082 us | 3.100 us | 3.122 us | 3.168 us | 3.233 us | 319,161.9 |
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,137 @@
|
|||||||
|
namespace Ocelot.UnitTests.Configuration
|
||||||
|
{
|
||||||
|
using Xunit;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Shouldly;
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Infrastructure.Consul;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.Cache;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Ocelot.ServiceDiscovery.Configuration;
|
||||||
|
using Consul;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
public class ConsulFileConfigurationRepositoryTests
|
||||||
|
{
|
||||||
|
private ConsulFileConfigurationRepository _repo;
|
||||||
|
private Mock<IOcelotCache<FileConfiguration>> _cache;
|
||||||
|
private Mock<IInternalConfigurationRepository> _internalRepo;
|
||||||
|
private Mock<IConsulClientFactory> _factory;
|
||||||
|
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
|
private Mock<IConsulClient> _client;
|
||||||
|
private Mock<IKVEndpoint> _kvEndpoint;
|
||||||
|
private FileConfiguration _fileConfiguration;
|
||||||
|
private Response _result;
|
||||||
|
|
||||||
|
public ConsulFileConfigurationRepositoryTests()
|
||||||
|
{
|
||||||
|
_cache = new Mock<IOcelotCache<FileConfiguration>>();
|
||||||
|
_internalRepo = new Mock<IInternalConfigurationRepository>();
|
||||||
|
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||||
|
|
||||||
|
_factory = new Mock<IConsulClientFactory>();
|
||||||
|
_client = new Mock<IConsulClient>();
|
||||||
|
_kvEndpoint = new Mock<IKVEndpoint>();
|
||||||
|
|
||||||
|
_client
|
||||||
|
.Setup(x => x.KV)
|
||||||
|
.Returns(_kvEndpoint.Object);
|
||||||
|
_factory
|
||||||
|
.Setup(x => x.Get(It.IsAny<ConsulRegistryConfiguration>()))
|
||||||
|
.Returns(_client.Object);
|
||||||
|
|
||||||
|
_internalRepo
|
||||||
|
.Setup(x => x.Get())
|
||||||
|
.Returns(new OkResponse<IInternalConfiguration>(new InternalConfiguration(new List<ReRoute>(), "", new ServiceProviderConfigurationBuilder().Build(), "")));
|
||||||
|
|
||||||
|
_repo = new ConsulFileConfigurationRepository(_cache.Object, _internalRepo.Object, _factory.Object, _loggerFactory.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_set_config()
|
||||||
|
{
|
||||||
|
var config = FakeFileConfiguration();
|
||||||
|
|
||||||
|
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||||
|
.And(_ => GivenWritingToConsulSucceeds())
|
||||||
|
.When(_ => WhenISetTheConfiguration())
|
||||||
|
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenWritingToConsulSucceeds()
|
||||||
|
{
|
||||||
|
var response = new WriteResult<bool>();
|
||||||
|
response.Response = true;
|
||||||
|
|
||||||
|
_kvEndpoint
|
||||||
|
.Setup(x => x.Put(It.IsAny<KVPair>(), It.IsAny<CancellationToken>())).ReturnsAsync(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheConfigurationIsStoredAs(FileConfiguration config)
|
||||||
|
{
|
||||||
|
var json = JsonConvert.SerializeObject(config, Formatting.Indented);
|
||||||
|
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(json);
|
||||||
|
|
||||||
|
_kvEndpoint
|
||||||
|
.Verify(x => x.Put(It.Is<KVPair>(k => k.Value.SequenceEqual(bytes)), It.IsAny<CancellationToken>()), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task WhenISetTheConfiguration()
|
||||||
|
{
|
||||||
|
_result = await _repo.Set(_fileConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenIHaveAConfiguration(FileConfiguration config)
|
||||||
|
{
|
||||||
|
_fileConfiguration = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileConfiguration FakeFileConfiguration()
|
||||||
|
{
|
||||||
|
var reRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "123.12.12.12",
|
||||||
|
Port = 80,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DownstreamScheme = "https",
|
||||||
|
DownstreamPathTemplate = "/asdfs/test/{test}"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var globalConfiguration = new FileGlobalConfiguration
|
||||||
|
{
|
||||||
|
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
|
||||||
|
{
|
||||||
|
Port = 198,
|
||||||
|
Host = "blah"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return new FileConfiguration
|
||||||
|
{
|
||||||
|
GlobalConfiguration = globalConfiguration,
|
||||||
|
ReRoutes = reRoutes
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,22 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.IO;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Ocelot.Configuration.Repository;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
namespace Ocelot.UnitTests.Configuration
|
||||||
{
|
{
|
||||||
public class FileConfigurationRepositoryTests
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
|
|
||||||
|
public class DiskFileConfigurationRepositoryTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IHostingEnvironment> _hostingEnvironment = new Mock<IHostingEnvironment>();
|
private readonly Mock<IHostingEnvironment> _hostingEnvironment = new Mock<IHostingEnvironment>();
|
||||||
private IFileConfigurationRepository _repo;
|
private IFileConfigurationRepository _repo;
|
||||||
|
private string _configurationPath;
|
||||||
private FileConfiguration _result;
|
private FileConfiguration _result;
|
||||||
private FileConfiguration _fileConfiguration;
|
private FileConfiguration _fileConfiguration;
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
// tests but whatever...
|
// tests but whatever...
|
||||||
private string _environmentName = "DEV.DEV";
|
private string _environmentName = "DEV.DEV";
|
||||||
|
|
||||||
public FileConfigurationRepositoryTests()
|
public DiskFileConfigurationRepositoryTests()
|
||||||
{
|
{
|
||||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
|
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
|
||||||
@ -35,9 +36,9 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
var config = FakeFileConfigurationForGet();
|
var config = FakeFileConfigurationForGet();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheConfigurationIs(config))
|
this.Given(_ => GivenTheConfigurationIs(config))
|
||||||
.When(x => x.WhenIGetTheReRoutes())
|
.When(_ => WhenIGetTheReRoutes())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned(config))
|
.Then(_ => ThenTheFollowingIsReturned(config))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,10 +47,10 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
var config = FakeFileConfigurationForGet();
|
var config = FakeFileConfigurationForGet();
|
||||||
|
|
||||||
this.Given(x => x.GivenTheEnvironmentNameIsUnavailable())
|
this.Given(_ => GivenTheEnvironmentNameIsUnavailable())
|
||||||
.And(x => x.GivenTheConfigurationIs(config))
|
.And(_ => GivenTheConfigurationIs(config))
|
||||||
.When(x => x.WhenIGetTheReRoutes())
|
.When(_ => WhenIGetTheReRoutes())
|
||||||
.Then(x => x.ThenTheFollowingIsReturned(config))
|
.Then(_ => ThenTheFollowingIsReturned(config))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,9 +59,10 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
var config = FakeFileConfigurationForSet();
|
var config = FakeFileConfigurationForSet();
|
||||||
|
|
||||||
this.Given(x => GivenIHaveAConfiguration(config))
|
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||||
.When(x => WhenISetTheConfiguration())
|
.When(_ => WhenISetTheConfiguration())
|
||||||
.Then(x => ThenTheConfigurationIsStoredAs(config))
|
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||||
|
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,10 +70,12 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
public void should_set_file_configuration_if_environment_name_is_unavailable()
|
public void should_set_file_configuration_if_environment_name_is_unavailable()
|
||||||
{
|
{
|
||||||
var config = FakeFileConfigurationForSet();
|
var config = FakeFileConfigurationForSet();
|
||||||
this.Given(x => GivenIHaveAConfiguration(config))
|
|
||||||
.And(x => GivenTheEnvironmentNameIsUnavailable())
|
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||||
.When(x => WhenISetTheConfiguration())
|
.And(_ => GivenTheEnvironmentNameIsUnavailable())
|
||||||
.Then(x => ThenTheConfigurationIsStoredAs(config))
|
.When(_ => WhenISetTheConfiguration())
|
||||||
|
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||||
|
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,16 +121,25 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
var configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
_configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||||
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
|
||||||
|
|
||||||
if (File.Exists(configurationPath))
|
if (File.Exists(_configurationPath))
|
||||||
{
|
{
|
||||||
File.Delete(configurationPath);
|
File.Delete(_configurationPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
File.WriteAllText(configurationPath, jsonConfiguration);
|
File.WriteAllText(_configurationPath, jsonConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
|
||||||
|
{
|
||||||
|
var path = !string.IsNullOrEmpty(_configurationPath) ? _configurationPath : _configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||||
|
|
||||||
|
var resultText = File.ReadAllText(_configurationPath);
|
||||||
|
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
|
||||||
|
resultText.ShouldBe(expectedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WhenIGetTheReRoutes()
|
private void WhenIGetTheReRoutes()
|
Loading…
x
Reference in New Issue
Block a user