mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:55:28 +08:00 
			
		
		
		
	* #463 save both files * #463 made it so we dont save to disk on startup unless using admin api
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,7 @@
 | 
				
			|||||||
*.user
 | 
					*.user
 | 
				
			||||||
*.userosscache
 | 
					*.userosscache
 | 
				
			||||||
*.sln.docstates
 | 
					*.sln.docstates
 | 
				
			||||||
 | 
					.DS_Store
 | 
				
			||||||
# User-specific files (MonoDevelop/Xamarin Studio)
 | 
					# User-specific files (MonoDevelop/Xamarin Studio)
 | 
				
			||||||
*.userprefs
 | 
					*.userprefs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -98,12 +98,14 @@ This gets the current Ocelot configuration. It is exactly the same JSON we use t
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
**POST {adminPath}/configuration**
 | 
					**POST {adminPath}/configuration**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
This overrwrites the existing configuration (should probably be a put!). I reccomend getting your config from the GET endpoint, making any changes and posting it back...simples.
 | 
					This overrwrites the existing configuration (should probably be a put!). I reccomend getting your config from the GET endpoint, making any changes and posting it back...simples.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The body of the request is JSON and it is the same format as the FileConfiguration.cs that we use to set up 
 | 
					The body of the request is JSON and it is the same format as the FileConfiguration.cs that we use to set up 
 | 
				
			||||||
Ocelot on a file system. 
 | 
					Ocelot on a file system. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please note that if you want to use this API then the process running Ocelot must have permission to write to the disk
 | 
				
			||||||
 | 
					where your ocelot.json or ocelot.{environment}.json is located. This is because Ocelot will overwrite them on save. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**DELETE {adminPath}/outputcache/{region}**
 | 
					**DELETE {adminPath}/outputcache/{region}**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This clears a region of the cache. If you are using a backplane it will clear all instances of the cache! Giving your the ability to run a cluster of Ocelots and cache over all of them in memory and clear them all at the same time / just use a distributed cache.
 | 
					This clears a region of the cache. If you are using a backplane it will clear all instances of the cache! Giving your the ability to run a cluster of Ocelots and cache over all of them in memory and clear them all at the same time / just use a distributed cache.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,15 +9,16 @@ namespace Ocelot.Configuration.Repository
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class DiskFileConfigurationRepository : IFileConfigurationRepository
 | 
					    public class DiskFileConfigurationRepository : IFileConfigurationRepository
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private readonly string _configFilePath;
 | 
					        private readonly string _environmentFilePath;
 | 
				
			||||||
 | 
					        private readonly string _ocelotFilePath;
 | 
				
			||||||
        private static readonly object _lock = new object();
 | 
					        private static readonly object _lock = new object();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        private const string ConfigurationFileName = "ocelot";
 | 
					        private const string ConfigurationFileName = "ocelot";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public DiskFileConfigurationRepository(IHostingEnvironment hostingEnvironment)
 | 
					        public DiskFileConfigurationRepository(IHostingEnvironment hostingEnvironment)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _configFilePath = $"{AppContext.BaseDirectory}/{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
 | 
					            _environmentFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _ocelotFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}.json";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Task<Response<FileConfiguration>> Get()
 | 
					        public Task<Response<FileConfiguration>> Get()
 | 
				
			||||||
@@ -26,7 +27,7 @@ namespace Ocelot.Configuration.Repository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            lock(_lock)
 | 
					            lock(_lock)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                jsonConfiguration = System.IO.File.ReadAllText(_configFilePath);
 | 
					                jsonConfiguration = System.IO.File.ReadAllText(_environmentFilePath);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration);
 | 
					            var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration);
 | 
				
			||||||
@@ -40,12 +41,19 @@ namespace Ocelot.Configuration.Repository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            lock(_lock)
 | 
					            lock(_lock)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (System.IO.File.Exists(_configFilePath))
 | 
					                if (System.IO.File.Exists(_environmentFilePath))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    System.IO.File.Delete(_configFilePath);
 | 
					                    System.IO.File.Delete(_environmentFilePath);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                System.IO.File.WriteAllText(_configFilePath, jsonConfiguration);
 | 
					                System.IO.File.WriteAllText(_environmentFilePath, jsonConfiguration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (System.IO.File.Exists(_ocelotFilePath))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    System.IO.File.Delete(_ocelotFilePath);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                System.IO.File.WriteAllText(_ocelotFilePath, jsonConfiguration);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return Task.FromResult<Response>(new OkResponse());
 | 
					            return Task.FromResult<Response>(new OkResponse());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@
 | 
				
			|||||||
    using Microsoft.AspNetCore.Hosting;
 | 
					    using Microsoft.AspNetCore.Hosting;
 | 
				
			||||||
    using Microsoft.Extensions.Options;
 | 
					    using Microsoft.Extensions.Options;
 | 
				
			||||||
    using System.Diagnostics;
 | 
					    using System.Diagnostics;
 | 
				
			||||||
 | 
					    using DependencyInjection;
 | 
				
			||||||
    using Microsoft.AspNetCore.Builder;
 | 
					    using Microsoft.AspNetCore.Builder;
 | 
				
			||||||
    using Ocelot.Configuration;
 | 
					    using Ocelot.Configuration;
 | 
				
			||||||
    using Ocelot.Configuration.Creator;
 | 
					    using Ocelot.Configuration.Creator;
 | 
				
			||||||
@@ -115,22 +116,32 @@
 | 
				
			|||||||
            var internalConfigRepo = (IInternalConfigurationRepository)builder.ApplicationServices.GetService(typeof(IInternalConfigurationRepository));
 | 
					            var internalConfigRepo = (IInternalConfigurationRepository)builder.ApplicationServices.GetService(typeof(IInternalConfigurationRepository));
 | 
				
			||||||
            internalConfigRepo.AddOrReplace(internalConfig.Data);
 | 
					            internalConfigRepo.AddOrReplace(internalConfig.Data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var fileConfigSetter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var fileConfigRepo = (IFileConfigurationRepository)builder.ApplicationServices.GetService(typeof(IFileConfigurationRepository));
 | 
					            var fileConfigRepo = (IFileConfigurationRepository)builder.ApplicationServices.GetService(typeof(IFileConfigurationRepository));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var adminPath = (IAdministrationPath)builder.ApplicationServices.GetService(typeof(IAdministrationPath));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (UsingConsul(fileConfigRepo))
 | 
					            if (UsingConsul(fileConfigRepo))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                //Lots of jazz happens in here..check it out if you are using consul to store your config.
 | 
				
			||||||
                await SetFileConfigInConsul(builder, fileConfigRepo, fileConfig, internalConfigCreator, internalConfigRepo);
 | 
					                await SetFileConfigInConsul(builder, fileConfigRepo, fileConfig, internalConfigCreator, internalConfigRepo);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else if(AdministrationApiInUse(adminPath))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                //We have to make sure the file config is set for the ocelot.env.json and ocelot.json so that if we pull it from the 
 | 
				
			||||||
 | 
					                //admin api it works...boy this is getting a spit spags boll.
 | 
				
			||||||
 | 
					                var fileConfigSetter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                await SetFileConfig(fileConfigSetter, fileConfig);
 | 
					                await SetFileConfig(fileConfigSetter, fileConfig);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return GetOcelotConfigAndReturn(internalConfigRepo);
 | 
					            return GetOcelotConfigAndReturn(internalConfigRepo);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static bool AdministrationApiInUse(IAdministrationPath adminPath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return adminPath.GetType() != typeof(NullAdministrationPath);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static async Task SetFileConfigInConsul(IApplicationBuilder builder,
 | 
					        private static async Task SetFileConfigInConsul(IApplicationBuilder builder,
 | 
				
			||||||
            IFileConfigurationRepository fileConfigRepo, IOptions<FileConfiguration> fileConfig,
 | 
					            IFileConfigurationRepository fileConfigRepo, IOptions<FileConfiguration> fileConfig,
 | 
				
			||||||
            IInternalConfigurationCreator internalConfigCreator, IInternalConfigurationRepository internalConfigRepo)
 | 
					            IInternalConfigurationCreator internalConfigCreator, IInternalConfigurationRepository internalConfigRepo)
 | 
				
			||||||
@@ -179,8 +190,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private static async Task SetFileConfig(IFileConfigurationSetter fileConfigSetter, IOptions<FileConfiguration> fileConfig)
 | 
					        private static async Task SetFileConfig(IFileConfigurationSetter fileConfigSetter, IOptions<FileConfiguration> fileConfig)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Response response;
 | 
					            var response = await fileConfigSetter.Set(fileConfig.Value);
 | 
				
			||||||
            response = await fileConfigSetter.Set(fileConfig.Value);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (IsError(response))
 | 
					            if (IsError(response))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										100
									
								
								test/Ocelot.AcceptanceTests/StartupTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								test/Ocelot.AcceptanceTests/StartupTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					namespace Ocelot.AcceptanceTests
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    using System;
 | 
				
			||||||
 | 
					    using System.Collections.Generic;
 | 
				
			||||||
 | 
					    using System.IO;
 | 
				
			||||||
 | 
					    using System.Net;
 | 
				
			||||||
 | 
					    using System.Threading.Tasks;
 | 
				
			||||||
 | 
					    using Configuration.Repository;
 | 
				
			||||||
 | 
					    using Microsoft.AspNetCore.Http;
 | 
				
			||||||
 | 
					    using Ocelot.Configuration.File;
 | 
				
			||||||
 | 
					    using Responses;
 | 
				
			||||||
 | 
					    using TestStack.BDDfy;
 | 
				
			||||||
 | 
					    using Xunit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class StartupTests : IDisposable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly Steps _steps;
 | 
				
			||||||
 | 
					        private readonly ServiceHandler _serviceHandler;
 | 
				
			||||||
 | 
					        private string _downstreamPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public StartupTests()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _serviceHandler = new ServiceHandler();
 | 
				
			||||||
 | 
					            _steps = new Steps();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void should_not_try_and_write_to_disk_on_startup_when_not_using_admin_api()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var configuration = new FileConfiguration
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ReRoutes = new List<FileReRoute>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    new FileReRoute
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        DownstreamPathTemplate = "/",
 | 
				
			||||||
 | 
					                        DownstreamScheme = "http",
 | 
				
			||||||
 | 
					                        DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            new FileHostAndPort
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                Host = "localhost",
 | 
				
			||||||
 | 
					                                Port = 52179,
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        UpstreamPathTemplate = "/",
 | 
				
			||||||
 | 
					                        UpstreamHttpMethod = new List<string> { "Get" },
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var fakeRepo = new FakeFileConfigurationRepository();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:52179", "/", 200, "Hello from Laura"))
 | 
				
			||||||
 | 
					                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
				
			||||||
 | 
					                .And(x => _steps.GivenOcelotIsRunningWithBlowingUpDiskRepo(fakeRepo))
 | 
				
			||||||
 | 
					                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
				
			||||||
 | 
					                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
				
			||||||
 | 
					                .BDDfy();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (_downstreamPath != basePath)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    context.Response.StatusCode = statusCode;
 | 
				
			||||||
 | 
					                    await context.Response.WriteAsync("downstream path didnt match base path");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    context.Response.StatusCode = statusCode;
 | 
				
			||||||
 | 
					                    await context.Response.WriteAsync(responseBody);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Dispose()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _serviceHandler?.Dispose();
 | 
				
			||||||
 | 
					            _steps.Dispose();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class FakeFileConfigurationRepository : IFileConfigurationRepository
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public Task<Response<FileConfiguration>> Get()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new NotImplementedException();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public Task<Response> Set(FileConfiguration fileConfiguration)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new NotImplementedException();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -31,6 +31,7 @@ using static Ocelot.Infrastructure.Wait;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.AcceptanceTests
 | 
					namespace Ocelot.AcceptanceTests
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    using Configuration.Repository;
 | 
				
			||||||
    using Microsoft.Net.Http.Headers;
 | 
					    using Microsoft.Net.Http.Headers;
 | 
				
			||||||
    using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
 | 
					    using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -928,5 +929,35 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
            var content = await response.Content.ReadAsStringAsync();
 | 
					            var content = await response.Content.ReadAsStringAsync();
 | 
				
			||||||
            content.ShouldBe(expectedBody);
 | 
					            content.ShouldBe(expectedBody);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void GivenOcelotIsRunningWithBlowingUpDiskRepo(IFileConfigurationRepository fake)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _webHostBuilder = new WebHostBuilder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _webHostBuilder
 | 
				
			||||||
 | 
					                .ConfigureAppConfiguration((hostingContext, config) =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
 | 
				
			||||||
 | 
					                    var env = hostingContext.HostingEnvironment;
 | 
				
			||||||
 | 
					                    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
 | 
				
			||||||
 | 
					                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
 | 
				
			||||||
 | 
					                    config.AddJsonFile("ocelot.json", false, false);
 | 
				
			||||||
 | 
					                    config.AddEnvironmentVariables();
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .ConfigureServices(s =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    s.AddSingleton<IFileConfigurationRepository>(fake);
 | 
				
			||||||
 | 
					                    s.AddOcelot();
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .Configure(app =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    app.UseOcelot().Wait();
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _ocelotServer = new TestServer(_webHostBuilder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _ocelotClient = _ocelotServer.CreateClient();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -276,9 +276,23 @@ namespace Ocelot.IntegrationTests
 | 
				
			|||||||
                .And(x => ThenTheResponseShouldBe(updatedConfiguration))
 | 
					                .And(x => ThenTheResponseShouldBe(updatedConfiguration))
 | 
				
			||||||
                .When(x => WhenIGetUrlOnTheApiGateway("/administration/configuration"))
 | 
					                .When(x => WhenIGetUrlOnTheApiGateway("/administration/configuration"))
 | 
				
			||||||
                .And(x => ThenTheResponseShouldBe(updatedConfiguration))
 | 
					                .And(x => ThenTheResponseShouldBe(updatedConfiguration))
 | 
				
			||||||
 | 
					                .And(_ => ThenTheConfigurationIsSavedCorrectly(updatedConfiguration))
 | 
				
			||||||
                .BDDfy();
 | 
					                .BDDfy();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void ThenTheConfigurationIsSavedCorrectly(FileConfiguration expected)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var ocelotJsonPath = $"{AppContext.BaseDirectory}ocelot.json";
 | 
				
			||||||
 | 
					            var resultText = File.ReadAllText(ocelotJsonPath);
 | 
				
			||||||
 | 
					            var expectedText = JsonConvert.SerializeObject(expected, Formatting.Indented);
 | 
				
			||||||
 | 
					            resultText.ShouldBe(expectedText);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot.Production.json";
 | 
				
			||||||
 | 
					            resultText = File.ReadAllText(environmentSpecificPath);
 | 
				
			||||||
 | 
					            expectedText = JsonConvert.SerializeObject(expected, Formatting.Indented);
 | 
				
			||||||
 | 
					            resultText.ShouldBe(expectedText);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void should_get_file_configuration_edit_and_post_updated_version_redirecting_reroute()
 | 
					        public void should_get_file_configuration_edit_and_post_updated_version_redirecting_reroute()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,24 +9,30 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
    using Xunit;
 | 
					    using Xunit;
 | 
				
			||||||
    using Newtonsoft.Json;
 | 
					    using Newtonsoft.Json;
 | 
				
			||||||
    using System.IO;
 | 
					    using System.IO;
 | 
				
			||||||
 | 
					    using System.Threading;
 | 
				
			||||||
    using Microsoft.AspNetCore.Hosting;
 | 
					    using Microsoft.AspNetCore.Hosting;
 | 
				
			||||||
    using Ocelot.Configuration.Repository;
 | 
					    using Ocelot.Configuration.Repository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public class DiskFileConfigurationRepositoryTests
 | 
					    public class DiskFileConfigurationRepositoryTests : IDisposable
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private readonly Mock<IHostingEnvironment> _hostingEnvironment = new Mock<IHostingEnvironment>();
 | 
					        private readonly Mock<IHostingEnvironment> _hostingEnvironment;
 | 
				
			||||||
        private IFileConfigurationRepository _repo;
 | 
					        private IFileConfigurationRepository _repo;
 | 
				
			||||||
        private string _configurationPath;
 | 
					        private string _environmentSpecificPath;
 | 
				
			||||||
 | 
					        private string _ocelotJsonPath;
 | 
				
			||||||
        private FileConfiguration _result;
 | 
					        private FileConfiguration _result;
 | 
				
			||||||
        private FileConfiguration _fileConfiguration;
 | 
					        private FileConfiguration _fileConfiguration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
 | 
					        // This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
 | 
				
			||||||
        // cant pick it up if they run in parralel..sigh these are not really unit 
 | 
					        // cant pick it up if they run in parralel..and the semaphore stops them running at the same time...sigh
 | 
				
			||||||
        // tests but whatever...
 | 
					        // these are not really unit tests but whatever...
 | 
				
			||||||
        private string _environmentName = "DEV.DEV";
 | 
					        private string _environmentName = "DEV.DEV";
 | 
				
			||||||
 | 
					        private static SemaphoreSlim _semaphore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public DiskFileConfigurationRepositoryTests()
 | 
					        public DiskFileConfigurationRepositoryTests()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            _semaphore = new SemaphoreSlim(1, 1);
 | 
				
			||||||
 | 
					            _semaphore.Wait();
 | 
				
			||||||
 | 
					            _hostingEnvironment = new Mock<IHostingEnvironment>();
 | 
				
			||||||
            _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
 | 
					            _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
 | 
				
			||||||
            _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
 | 
					            _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -79,6 +85,33 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
                .BDDfy();
 | 
					                .BDDfy();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void should_set_environment_file_configuration_and_ocelot_file_configuration()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var config = FakeFileConfigurationForSet();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.Given(_ => GivenIHaveAConfiguration(config))
 | 
				
			||||||
 | 
					                .And(_ => GivenTheConfigurationIs(config))
 | 
				
			||||||
 | 
					                .And(_ => GivenTheUserAddedOcelotJson())
 | 
				
			||||||
 | 
					                .When(_ => WhenISetTheConfiguration())
 | 
				
			||||||
 | 
					                .Then(_ => ThenTheConfigurationIsStoredAs(config))
 | 
				
			||||||
 | 
					                .And(_ => ThenTheConfigurationJsonIsIndented(config))
 | 
				
			||||||
 | 
					                .Then(_ => ThenTheOcelotJsonIsStoredAs(config))
 | 
				
			||||||
 | 
					                .BDDfy();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void GivenTheUserAddedOcelotJson()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					             _ocelotJsonPath = $"{AppContext.BaseDirectory}/ocelot.json";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (File.Exists(_ocelotJsonPath))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                File.Delete(_ocelotJsonPath);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            File.WriteAllText(_ocelotJsonPath, "Doesnt matter");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void GivenTheEnvironmentNameIsUnavailable()
 | 
					        private void GivenTheEnvironmentNameIsUnavailable()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _environmentName = null;
 | 
					            _environmentName = null;
 | 
				
			||||||
@@ -119,25 +152,32 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void ThenTheOcelotJsonIsStoredAs(FileConfiguration expecteds)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var resultText = File.ReadAllText(_ocelotJsonPath);
 | 
				
			||||||
 | 
					            var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
 | 
				
			||||||
 | 
					            resultText.ShouldBe(expectedText);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
 | 
					        private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
 | 
					            _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
 | 
					            var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (File.Exists(_configurationPath))
 | 
					            if (File.Exists(_environmentSpecificPath))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                File.Delete(_configurationPath);
 | 
					                File.Delete(_environmentSpecificPath);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            File.WriteAllText(_configurationPath, jsonConfiguration);
 | 
					            File.WriteAllText(_environmentSpecificPath, jsonConfiguration);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
 | 
					        private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var path = !string.IsNullOrEmpty(_configurationPath) ? _configurationPath : _configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
 | 
					            var path = !string.IsNullOrEmpty(_environmentSpecificPath) ? _environmentSpecificPath : _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            var resultText = File.ReadAllText(_configurationPath);
 | 
					            var resultText = File.ReadAllText(path);
 | 
				
			||||||
            var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
 | 
					            var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
 | 
				
			||||||
            resultText.ShouldBe(expectedText);
 | 
					            resultText.ShouldBe(expectedText);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -238,5 +278,10 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
                ReRoutes = reRoutes
 | 
					                ReRoutes = reRoutes
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Dispose()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _semaphore.Release();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user