Feature/fix #463 (#506)

* #463 save both files

* #463 made it so we dont save to disk on startup unless using admin api
This commit is contained in:
Tom Pallister 2018-07-27 23:13:22 +01:00 committed by GitHub
parent 9f4448378a
commit 1817564ea5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 484 additions and 274 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -98,11 +98,13 @@ 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}**

View File

@ -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());

View File

@ -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;
@ -27,18 +28,18 @@
await builder.UseOcelot(new OcelotPipelineConfiguration()); await builder.UseOcelot(new OcelotPipelineConfiguration());
return builder; return builder;
} }
public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, Action<OcelotPipelineConfiguration> pipelineConfiguration) public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, Action<OcelotPipelineConfiguration> pipelineConfiguration)
{ {
var config = new OcelotPipelineConfiguration(); var config = new OcelotPipelineConfiguration();
pipelineConfiguration?.Invoke(config); pipelineConfiguration?.Invoke(config);
return await builder.UseOcelot(config); return await builder.UseOcelot(config);
} }
public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, OcelotPipelineConfiguration pipelineConfiguration) public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, OcelotPipelineConfiguration pipelineConfiguration)
{ {
var configuration = await CreateConfiguration(builder); var configuration = await CreateConfiguration(builder);
CreateAdministrationArea(builder, configuration); CreateAdministrationArea(builder, configuration);
if (UsingRafty(builder)) if (UsingRafty(builder))
@ -105,9 +106,9 @@
{ {
// make configuration from file system? // make configuration from file system?
// earlier user needed to add ocelot files in startup configuration stuff, asp.net will map it to this // earlier user needed to add ocelot files in startup configuration stuff, asp.net will map it to this
var fileConfig = (IOptions<FileConfiguration>)builder.ApplicationServices.GetService(typeof(IOptions<FileConfiguration>)); var fileConfig = (IOptions<FileConfiguration>)builder.ApplicationServices.GetService(typeof(IOptions<FileConfiguration>));
// now create the config // now create the config
var internalConfigCreator = (IInternalConfigurationCreator)builder.ApplicationServices.GetService(typeof(IInternalConfigurationCreator)); var internalConfigCreator = (IInternalConfigurationCreator)builder.ApplicationServices.GetService(typeof(IInternalConfigurationCreator));
var internalConfig = await internalConfigCreator.Create(fileConfig.Value); var internalConfig = await internalConfigCreator.Create(fileConfig.Value);
@ -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))
{ {
@ -245,8 +255,8 @@
var listener = (OcelotDiagnosticListener)builder.ApplicationServices.GetService(typeof(OcelotDiagnosticListener)); var listener = (OcelotDiagnosticListener)builder.ApplicationServices.GetService(typeof(OcelotDiagnosticListener));
var diagnosticListener = (DiagnosticListener)builder.ApplicationServices.GetService(typeof(DiagnosticListener)); var diagnosticListener = (DiagnosticListener)builder.ApplicationServices.GetService(typeof(DiagnosticListener));
diagnosticListener.SubscribeWithAdapter(listener); diagnosticListener.SubscribeWithAdapter(listener);
} }
private static void OnShutdown(IApplicationBuilder app) private static void OnShutdown(IApplicationBuilder app)
{ {
var node = (INode)app.ApplicationServices.GetService(typeof(INode)); var node = (INode)app.ApplicationServices.GetService(typeof(INode));

View 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();
}
}
}
}

View File

@ -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();
}
} }
} }

View File

@ -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()
{ {

View File

@ -1,242 +1,287 @@
namespace Ocelot.UnitTests.Configuration namespace Ocelot.UnitTests.Configuration
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Moq; using Moq;
using Ocelot.Configuration.File; using Ocelot.Configuration.File;
using Shouldly; using Shouldly;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.IO; using System.IO;
using Microsoft.AspNetCore.Hosting; using System.Threading;
using Ocelot.Configuration.Repository; using Microsoft.AspNetCore.Hosting;
using Ocelot.Configuration.Repository;
public class DiskFileConfigurationRepositoryTests
{ public class DiskFileConfigurationRepositoryTests : IDisposable
private readonly Mock<IHostingEnvironment> _hostingEnvironment = new Mock<IHostingEnvironment>(); {
private IFileConfigurationRepository _repo; private readonly Mock<IHostingEnvironment> _hostingEnvironment;
private string _configurationPath; private IFileConfigurationRepository _repo;
private FileConfiguration _result; private string _environmentSpecificPath;
private FileConfiguration _fileConfiguration; private string _ocelotJsonPath;
private FileConfiguration _result;
// This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests private FileConfiguration _fileConfiguration;
// cant pick it up if they run in parralel..sigh these are not really unit
// tests but whatever... // This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
private string _environmentName = "DEV.DEV"; // cant pick it up if they run in parralel..and the semaphore stops them running at the same time...sigh
// these are not really unit tests but whatever...
public DiskFileConfigurationRepositoryTests() private string _environmentName = "DEV.DEV";
{ private static SemaphoreSlim _semaphore;
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object); public DiskFileConfigurationRepositoryTests()
} {
_semaphore = new SemaphoreSlim(1, 1);
[Fact] _semaphore.Wait();
public void should_return_file_configuration() _hostingEnvironment = new Mock<IHostingEnvironment>();
{ _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
var config = FakeFileConfigurationForGet(); _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
}
this.Given(_ => GivenTheConfigurationIs(config))
.When(_ => WhenIGetTheReRoutes()) [Fact]
.Then(_ => ThenTheFollowingIsReturned(config)) public void should_return_file_configuration()
.BDDfy(); {
} var config = FakeFileConfigurationForGet();
[Fact] this.Given(_ => GivenTheConfigurationIs(config))
public void should_return_file_configuration_if_environment_name_is_unavailable() .When(_ => WhenIGetTheReRoutes())
{ .Then(_ => ThenTheFollowingIsReturned(config))
var config = FakeFileConfigurationForGet(); .BDDfy();
}
this.Given(_ => GivenTheEnvironmentNameIsUnavailable())
.And(_ => GivenTheConfigurationIs(config)) [Fact]
.When(_ => WhenIGetTheReRoutes()) public void should_return_file_configuration_if_environment_name_is_unavailable()
.Then(_ => ThenTheFollowingIsReturned(config)) {
.BDDfy(); var config = FakeFileConfigurationForGet();
}
this.Given(_ => GivenTheEnvironmentNameIsUnavailable())
[Fact] .And(_ => GivenTheConfigurationIs(config))
public void should_set_file_configuration() .When(_ => WhenIGetTheReRoutes())
{ .Then(_ => ThenTheFollowingIsReturned(config))
var config = FakeFileConfigurationForSet(); .BDDfy();
}
this.Given(_ => GivenIHaveAConfiguration(config))
.When(_ => WhenISetTheConfiguration()) [Fact]
.Then(_ => ThenTheConfigurationIsStoredAs(config)) public void should_set_file_configuration()
.And(_ => ThenTheConfigurationJsonIsIndented(config)) {
.BDDfy(); var config = FakeFileConfigurationForSet();
}
this.Given(_ => GivenIHaveAConfiguration(config))
[Fact] .When(_ => WhenISetTheConfiguration())
public void should_set_file_configuration_if_environment_name_is_unavailable() .Then(_ => ThenTheConfigurationIsStoredAs(config))
{ .And(_ => ThenTheConfigurationJsonIsIndented(config))
var config = FakeFileConfigurationForSet(); .BDDfy();
}
this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenTheEnvironmentNameIsUnavailable()) [Fact]
.When(_ => WhenISetTheConfiguration()) public void should_set_file_configuration_if_environment_name_is_unavailable()
.Then(_ => ThenTheConfigurationIsStoredAs(config)) {
.And(_ => ThenTheConfigurationJsonIsIndented(config)) var config = FakeFileConfigurationForSet();
.BDDfy();
} this.Given(_ => GivenIHaveAConfiguration(config))
.And(_ => GivenTheEnvironmentNameIsUnavailable())
private void GivenTheEnvironmentNameIsUnavailable() .When(_ => WhenISetTheConfiguration())
{ .Then(_ => ThenTheConfigurationIsStoredAs(config))
_environmentName = null; .And(_ => ThenTheConfigurationJsonIsIndented(config))
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName); .BDDfy();
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object); }
}
[Fact]
private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration) public void should_set_environment_file_configuration_and_ocelot_file_configuration()
{ {
_fileConfiguration = fileConfiguration; var config = FakeFileConfigurationForSet();
}
this.Given(_ => GivenIHaveAConfiguration(config))
private void WhenISetTheConfiguration() .And(_ => GivenTheConfigurationIs(config))
{ .And(_ => GivenTheUserAddedOcelotJson())
_repo.Set(_fileConfiguration); .When(_ => WhenISetTheConfiguration())
_result = _repo.Get().Result.Data; .Then(_ => ThenTheConfigurationIsStoredAs(config))
} .And(_ => ThenTheConfigurationJsonIsIndented(config))
.Then(_ => ThenTheOcelotJsonIsStoredAs(config))
private void ThenTheConfigurationIsStoredAs(FileConfiguration expecteds) .BDDfy();
{ }
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host); private void GivenTheUserAddedOcelotJson()
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port); {
_ocelotJsonPath = $"{AppContext.BaseDirectory}/ocelot.json";
for(var i = 0; i < _result.ReRoutes.Count; i++)
{ if (File.Exists(_ocelotJsonPath))
for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++) {
{ File.Delete(_ocelotJsonPath);
var result = _result.ReRoutes[i].DownstreamHostAndPorts[j]; }
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
File.WriteAllText(_ocelotJsonPath, "Doesnt matter");
result.Host.ShouldBe(expected.Host); }
result.Port.ShouldBe(expected.Port);
} private void GivenTheEnvironmentNameIsUnavailable()
{
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate); _environmentName = null;
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme); _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
} _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
} }
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration) private void GivenIHaveAConfiguration(FileConfiguration fileConfiguration)
{ {
_configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json"; _fileConfiguration = fileConfiguration;
}
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
private void WhenISetTheConfiguration()
if (File.Exists(_configurationPath)) {
{ _repo.Set(_fileConfiguration);
File.Delete(_configurationPath); _result = _repo.Get().Result.Data;
} }
File.WriteAllText(_configurationPath, jsonConfiguration); private void ThenTheConfigurationIsStoredAs(FileConfiguration expecteds)
} {
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds) _result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
{ _result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
var path = !string.IsNullOrEmpty(_configurationPath) ? _configurationPath : _configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
for(var i = 0; i < _result.ReRoutes.Count; i++)
var resultText = File.ReadAllText(_configurationPath); {
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented); for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
resultText.ShouldBe(expectedText); {
} var result = _result.ReRoutes[i].DownstreamHostAndPorts[j];
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
private void WhenIGetTheReRoutes()
{ result.Host.ShouldBe(expected.Host);
_result = _repo.Get().Result.Data; result.Port.ShouldBe(expected.Port);
} }
private void ThenTheFollowingIsReturned(FileConfiguration expecteds) _result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
{ _result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
_result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey); }
_result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host); }
_result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
private void ThenTheOcelotJsonIsStoredAs(FileConfiguration expecteds)
for(var i = 0; i < _result.ReRoutes.Count; i++) {
{ var resultText = File.ReadAllText(_ocelotJsonPath);
for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++) var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
{ resultText.ShouldBe(expectedText);
var result = _result.ReRoutes[i].DownstreamHostAndPorts[j]; }
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
result.Host.ShouldBe(expected.Host); {
result.Port.ShouldBe(expected.Port); _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
}
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
_result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
_result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme); if (File.Exists(_environmentSpecificPath))
} {
} File.Delete(_environmentSpecificPath);
}
private FileConfiguration FakeFileConfigurationForSet()
{ File.WriteAllText(_environmentSpecificPath, jsonConfiguration);
var reRoutes = new List<FileReRoute> }
{
new FileReRoute private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
{ {
DownstreamHostAndPorts = new List<FileHostAndPort> var path = !string.IsNullOrEmpty(_environmentSpecificPath) ? _environmentSpecificPath : _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
{
new FileHostAndPort var resultText = File.ReadAllText(path);
{ var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
Host = "123.12.12.12", resultText.ShouldBe(expectedText);
Port = 80, }
}
}, private void WhenIGetTheReRoutes()
DownstreamScheme = "https", {
DownstreamPathTemplate = "/asdfs/test/{test}" _result = _repo.Get().Result.Data;
} }
};
private void ThenTheFollowingIsReturned(FileConfiguration expecteds)
var globalConfiguration = new FileGlobalConfiguration {
{ _result.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider _result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
{ _result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
Port = 198,
Host = "blah" for(var i = 0; i < _result.ReRoutes.Count; i++)
} {
}; for (int j = 0; j < _result.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
{
return new FileConfiguration var result = _result.ReRoutes[i].DownstreamHostAndPorts[j];
{ var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
GlobalConfiguration = globalConfiguration,
ReRoutes = reRoutes result.Host.ShouldBe(expected.Host);
}; result.Port.ShouldBe(expected.Port);
} }
private FileConfiguration FakeFileConfigurationForGet() _result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
{ _result.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
var reRoutes = new List<FileReRoute> }
{ }
new FileReRoute
{ private FileConfiguration FakeFileConfigurationForSet()
DownstreamHostAndPorts = new List<FileHostAndPort> {
{ var reRoutes = new List<FileReRoute>
new FileHostAndPort {
{ new FileReRoute
Host = "localhost", {
Port = 80, DownstreamHostAndPorts = new List<FileHostAndPort>
} {
}, new FileHostAndPort
DownstreamScheme = "https", {
DownstreamPathTemplate = "/test/test/{test}" Host = "123.12.12.12",
} Port = 80,
}; }
},
var globalConfiguration = new FileGlobalConfiguration DownstreamScheme = "https",
{ DownstreamPathTemplate = "/asdfs/test/{test}"
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider }
{ };
Port = 198,
Host = "blah" var globalConfiguration = new FileGlobalConfiguration
} {
}; ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
{
return new FileConfiguration Port = 198,
{ Host = "blah"
GlobalConfiguration = globalConfiguration, }
ReRoutes = reRoutes };
};
} return new FileConfiguration
} {
} GlobalConfiguration = globalConfiguration,
ReRoutes = reRoutes
};
}
private FileConfiguration FakeFileConfigurationForGet()
{
var reRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 80,
}
},
DownstreamScheme = "https",
DownstreamPathTemplate = "/test/test/{test}"
}
};
var globalConfiguration = new FileGlobalConfiguration
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
{
Port = 198,
Host = "blah"
}
};
return new FileConfiguration
{
GlobalConfiguration = globalConfiguration,
ReRoutes = reRoutes
};
}
public void Dispose()
{
_semaphore.Release();
}
}
}