diff --git a/src/Ocelot/Controllers/FileConfigurationController.cs b/src/Ocelot/Controllers/FileConfigurationController.cs new file mode 100644 index 00000000..cf0a792a --- /dev/null +++ b/src/Ocelot/Controllers/FileConfigurationController.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore.Mvc; +using Ocelot.Services; + +namespace Ocelot.Controllers +{ + [RouteAttribute("configuration")] + public class FileConfigurationController + { + private IGetFileConfiguration _getFileConfig; + + public FileConfigurationController(IGetFileConfiguration getFileConfig) + { + _getFileConfig = getFileConfig; + } + + public IActionResult Get() + { + return new OkObjectResult(_getFileConfig.Invoke().Data); + } + } +} \ No newline at end of file diff --git a/src/Ocelot/Controllers/ReRoutesController.cs b/src/Ocelot/Controllers/ReRoutesController.cs deleted file mode 100644 index 0b02c796..00000000 --- a/src/Ocelot/Controllers/ReRoutesController.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace Ocelot.Controllers -{ - [RouteAttribute("reroutes")] - public class ReRoutesController - { - public IActionResult Get() - { - return new OkObjectResult("hi from re routes controller"); - } - } -} \ No newline at end of file diff --git a/src/Ocelot/Services/GetFileConfiguration.cs b/src/Ocelot/Services/GetFileConfiguration.cs new file mode 100644 index 00000000..b97cac92 --- /dev/null +++ b/src/Ocelot/Services/GetFileConfiguration.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; +using Newtonsoft.Json; +using Ocelot.Configuration.File; +using Ocelot.Responses; + +namespace Ocelot.Services +{ + public class GetFileConfiguration : IGetFileConfiguration + { + public Response Invoke() + { + var configFilePath = "configuration.json"; + var json = File.ReadAllText(configFilePath); + var fileConfiguration = JsonConvert.DeserializeObject(json); + return new OkResponse(fileConfiguration); + } + } +} \ No newline at end of file diff --git a/src/Ocelot/Services/IGetFileConfiguration.cs b/src/Ocelot/Services/IGetFileConfiguration.cs new file mode 100644 index 00000000..08b950a8 --- /dev/null +++ b/src/Ocelot/Services/IGetFileConfiguration.cs @@ -0,0 +1,10 @@ +using Ocelot.Configuration.File; +using Ocelot.Responses; + +namespace Ocelot.Services +{ + public interface IGetFileConfiguration + { + Response Invoke(); + } +} \ No newline at end of file diff --git a/test/Ocelot.AcceptanceTests/AdministrationTests.cs b/test/Ocelot.AcceptanceTests/AdministrationTests.cs index 44c4447e..29ad10a8 100644 --- a/test/Ocelot.AcceptanceTests/AdministrationTests.cs +++ b/test/Ocelot.AcceptanceTests/AdministrationTests.cs @@ -34,12 +34,41 @@ namespace Ocelot.AcceptanceTests this.Given(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenOcelotIsRunning()) - .When(x => _steps.WhenIGetUrlOnTheApiGateway("/administration/reroutes")) + .When(x => _steps.WhenIGetUrlOnTheApiGateway("/administration/configuration")) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => _steps.ThenTheResponseBodyShouldBe("hi from re routes controller")) .BDDfy(); } + [Fact] + public void should_return_file_configuration() + { + var configuration = new FileConfiguration + { + GlobalConfiguration = new FileGlobalConfiguration + { + AdministrationPath = "/administration" + }, + ReRoutes = new List() + { + new FileReRoute() + { + DownstreamHost = "localhost", + DownstreamPort = 80, + DownstreamScheme = "https", + DownstreamPathTemplate = "/" + } + } + }; + + this.Given(x => _steps.GivenThereIsAConfiguration(configuration)) + .And(x => _steps.GivenOcelotIsRunning()) + .When(x => _steps.WhenIGetUrlOnTheApiGateway("/administration/configuration")) + .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) + .And(x => _steps.ThenTheResponseShouldBe(configuration)) + .BDDfy(); + } + private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody) { _builder = new WebHostBuilder() diff --git a/test/Ocelot.AcceptanceTests/Steps.cs b/test/Ocelot.AcceptanceTests/Steps.cs index 9b5faa04..73585017 100644 --- a/test/Ocelot.AcceptanceTests/Steps.cs +++ b/test/Ocelot.AcceptanceTests/Steps.cs @@ -75,6 +75,25 @@ namespace Ocelot.AcceptanceTests _ocelotClient = _ocelotServer.CreateClient(); } + internal void ThenTheResponseShouldBe(FileConfiguration expected) + { + var response = JsonConvert.DeserializeObject(_response.Content.ReadAsStringAsync().Result); + + response.GlobalConfiguration.AdministrationPath.ShouldBe(expected.GlobalConfiguration.AdministrationPath); + response.GlobalConfiguration.RequestIdKey.ShouldBe(expected.GlobalConfiguration.RequestIdKey); + response.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Host); + response.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Port); + response.GlobalConfiguration.ServiceDiscoveryProvider.Provider.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Provider); + + for(var i = 0; i < response.ReRoutes.Count; i++) + { + response.ReRoutes[i].DownstreamHost.ShouldBe(expected.ReRoutes[i].DownstreamHost); + response.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expected.ReRoutes[i].DownstreamPathTemplate); + response.ReRoutes[i].DownstreamPort.ShouldBe(expected.ReRoutes[i].DownstreamPort); + response.ReRoutes[i].DownstreamScheme.ShouldBe(expected.ReRoutes[i].DownstreamScheme); + } + } + /// /// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step. /// @@ -155,7 +174,6 @@ namespace Ocelot.AcceptanceTests } } - public void WhenIGetUrlOnTheApiGateway(string url) { _response = _ocelotClient.GetAsync(url).Result; diff --git a/test/Ocelot.AcceptanceTests/TestConfiguration.cs b/test/Ocelot.AcceptanceTests/TestConfiguration.cs index ce802efb..6784391c 100644 --- a/test/Ocelot.AcceptanceTests/TestConfiguration.cs +++ b/test/Ocelot.AcceptanceTests/TestConfiguration.cs @@ -28,7 +28,7 @@ { var runTime = $"{oSDescription}-{osArchitecture}".ToLower(); - var configPath = $"./bin/Debug/netcoreapp{Version}/{runTime}/configuration.json"; + var configPath = $"./test/Ocelot.AcceptanceTests/bin/Debug/netcoreapp{Version}/{runTime}/configuration.json"; return configPath; } diff --git a/test/Ocelot.UnitTests/Controllers/FileConfigurationControllerTests.cs b/test/Ocelot.UnitTests/Controllers/FileConfigurationControllerTests.cs new file mode 100644 index 00000000..cbd8aeac --- /dev/null +++ b/test/Ocelot.UnitTests/Controllers/FileConfigurationControllerTests.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Moq; +using Ocelot.Configuration; +using Ocelot.Configuration.File; +using Ocelot.Controllers; +using Ocelot.Responses; +using Ocelot.Services; +using TestStack.BDDfy; +using Xunit; + +namespace Ocelot.UnitTests.Controllers +{ + public class FileConfigurationControllerTests + { + private FileConfigurationController _controller; + private Mock _getFileConfig; + private IActionResult _result; + + public FileConfigurationControllerTests() + { + _getFileConfig = new Mock(); + _controller = new FileConfigurationController(_getFileConfig.Object); + } + + [Fact] + public void should_return_file_configuration() + { + var expected = new OkResponse(new FileConfiguration()); + + this.Given(x => x.GivenTheGetConfigurationReturns(expected)) + .When(x => x.WhenIGetTheFileConfiguration()) + .Then(x => x.ThenTheFileConfigurationIsReturned(expected.Data)) + .BDDfy(); + } + + private void GivenTheGetConfigurationReturns(Response fileConfiguration) + { + _getFileConfig + .Setup(x => x.Invoke()) + .Returns(fileConfiguration); + } + + private void WhenIGetTheFileConfiguration() + { + _result = _controller.Get(); + } + + private void ThenTheFileConfigurationIsReturned(FileConfiguration expected) + { + } + } +} \ No newline at end of file diff --git a/test/Ocelot.UnitTests/Services/GetFileConfigurationTests.cs b/test/Ocelot.UnitTests/Services/GetFileConfigurationTests.cs new file mode 100644 index 00000000..89ce22b1 --- /dev/null +++ b/test/Ocelot.UnitTests/Services/GetFileConfigurationTests.cs @@ -0,0 +1,96 @@ +using System.Collections.Generic; +using Moq; +using Ocelot.Configuration; +using Ocelot.Configuration.File; +using Ocelot.Responses; +using Shouldly; +using TestStack.BDDfy; +using Xunit; +using Ocelot.Services; +using Newtonsoft.Json; +using System.IO; + +namespace Ocelot.UnitTests.Services +{ + public class GetFileConfigurationTests + { + private IGetFileConfiguration _getReRoutes; + private FileConfiguration _result; + + public GetFileConfigurationTests() + { + _getReRoutes = new GetFileConfiguration(); + } + + [Fact] + public void should_return_file_configuration() + { + var reRoutes = new List + { + new FileReRoute + { + DownstreamHost = "localhost", + DownstreamPort = 80, + DownstreamScheme = "https", + DownstreamPathTemplate = "/test/test/{test}" + } + }; + + var globalConfiguration = new FileGlobalConfiguration + { + AdministrationPath = "testy", + ServiceDiscoveryProvider = new FileServiceDiscoveryProvider + { + Provider = "consul", + Port = 198, + Host = "blah" + } + }; + + var config = new FileConfiguration(); + config.GlobalConfiguration = globalConfiguration; + config.ReRoutes.AddRange(reRoutes); + + this.Given(x => x.GivenTheConfigurationIs(config)) + .When(x => x.WhenIGetTheReRoutes()) + .Then(x => x.ThenTheFollowingIsReturned(config)) + .BDDfy(); + } + + private void GivenTheConfigurationIs(FileConfiguration fileConfiguration) + { + var configurationPath = "configuration.json"; + var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration); + + if (File.Exists(configurationPath)) + { + File.Delete(configurationPath); + } + + File.WriteAllText(configurationPath, jsonConfiguration); + } + + private void WhenIGetTheReRoutes() + { + _result = _getReRoutes.Invoke().Data; + } + + private void ThenTheFollowingIsReturned(FileConfiguration expected) + { + _result.GlobalConfiguration.AdministrationPath.ShouldBe(expected.GlobalConfiguration.AdministrationPath); + _result.GlobalConfiguration.RequestIdKey.ShouldBe(expected.GlobalConfiguration.RequestIdKey); + _result.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Host); + _result.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Port); + _result.GlobalConfiguration.ServiceDiscoveryProvider.Provider.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Provider); + + for(var i = 0; i < _result.ReRoutes.Count; i++) + { + _result.ReRoutes[i].DownstreamHost.ShouldBe(expected.ReRoutes[i].DownstreamHost); + _result.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expected.ReRoutes[i].DownstreamPathTemplate); + _result.ReRoutes[i].DownstreamPort.ShouldBe(expected.ReRoutes[i].DownstreamPort); + _result.ReRoutes[i].DownstreamScheme.ShouldBe(expected.ReRoutes[i].DownstreamScheme); + //todo -- add more! + } + } + } +} \ No newline at end of file diff --git a/test/Ocelot.UnitTests/configuration.json b/test/Ocelot.UnitTests/configuration.json new file mode 100755 index 00000000..61548dab --- /dev/null +++ b/test/Ocelot.UnitTests/configuration.json @@ -0,0 +1 @@ +{"ReRoutes":[{"DownstreamPathTemplate":"/test/test/{test}","UpstreamPathTemplate":null,"UpstreamHttpMethod":null,"AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"https","DownstreamHost":"localhost","DownstreamPort":80,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":"consul","Host":"blah","Port":198},"AdministrationPath":"testy"}} \ No newline at end of file