mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +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:
		@@ -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()
 | 
				
			||||||
		Reference in New Issue
	
	Block a user