after much hacking unit tests passing

This commit is contained in:
Tom Gardham-Pallister 2017-02-21 07:34:47 +00:00
parent d548a86327
commit 2dfdf0bb86
44 changed files with 313 additions and 194 deletions

View File

@ -1,48 +0,0 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>Ocelot</id>
<version>1.0.0</version>
<authors>Tom Pallister</authors>
<owners>Tom Pallister</owners>
<licenseUrl>https://github.com/TomPallister/Ocelot/blob/develop/LICENSE.md</licenseUrl>
<projectUrl>https://github.com/TomPallister/Ocelot</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Ocelot Api Gateway</description>
<releaseNotes>Latest Ocelot</releaseNotes>
<copyright></copyright>
<tags></tags>
<dependencies>
<dependency id="Microsoft.AspNetCore.Server.IISIntegration" version="1.1.0" />
<dependency id="Microsoft.Extensions.Configuration.EnvironmentVariables" version= "1.1.0" />
<dependency id="Microsoft.Extensions.Configuration.FileExtensions" version= "1.1.0" />
<dependency id="Microsoft.Extensions.Configuration.Json" version="1.1.0" />
<dependency id="Microsoft.Extensions.Logging" version="1.1.0" />
<dependency id="Microsoft.Extensions.Logging.Console" version="1.1.0" />
<dependency id="Microsoft.Extensions.Logging.Debug" version="1.1.0" />
<dependency id="Microsoft.Extensions.Options.ConfigurationExtensions" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Http" version="1.1.0" />
<dependency id="System.Text.RegularExpressions" version="4.3.0" />
<dependency id="Microsoft.AspNetCore.Authentication.OAuth" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Authentication.JwtBearer" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Authentication.OpenIdConnect" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Authentication.Cookies" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Authentication.Google" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Authentication.Facebook" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Authentication.Twitter" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Authentication.MicrosoftAccount" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Authentication" version="1.1.0" />
<dependency id="IdentityServer4.AccessTokenValidation" version="1.0.2" />
<dependency id="Microsoft.AspNetCore.Mvc" version="1.1.0" />
<dependency id="Microsoft.AspNetCore.Server.Kestrel" version="1.1.0" />
<dependency id="Microsoft.NETCore.App" version="1.1.0" />
<dependency id="CacheManager.Core" version="0.9.2" />
<dependency id="CacheManager.Microsoft.Extensions.Configuration" version="0.9.2" />
<dependency id="CacheManager.Microsoft.Extensions.Logging" version="0.9.2" />
</dependencies>
</metadata>
<files>
<file src="src\Ocelot\bin\Release\netcoreapp1.4\Ocelot.dll" target="lib\netstandard1.4" />
<file src="src\Ocelot\bin\Release\netcoreapp1.4\Ocelot.pdb" target="lib\netstandard1.4" />
</files>
</package>

View File

@ -1,8 +0,0 @@
version: 1.0.{build}
configuration:
- Release
platform: Any CPU
build_script:
- build.ps1
cache:
- '%USERPROFILE%\.nuget\packages'

View File

@ -2,7 +2,6 @@
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;
using Ocelot.Middleware; using Ocelot.Middleware;

View File

@ -1,7 +1,6 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;
using Ocelot.Middleware; using Ocelot.Middleware;

View File

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using Ocelot.Values; using Ocelot.Values;

View File

@ -56,14 +56,21 @@ namespace Ocelot.Configuration.Creator
public async Task<Response<IOcelotConfiguration>> Create() public async Task<Response<IOcelotConfiguration>> Create()
{ {
var config = await SetUpConfiguration(); var config = await SetUpConfiguration(_options.Value);
return new OkResponse<IOcelotConfiguration>(config); return new OkResponse<IOcelotConfiguration>(config);
} }
private async Task<IOcelotConfiguration> SetUpConfiguration() public async Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration)
{ {
var response = _configurationValidator.IsValid(_options.Value); var config = await SetUpConfiguration(fileConfiguration);
return new OkResponse<IOcelotConfiguration>(config);
}
private async Task<IOcelotConfiguration> SetUpConfiguration(FileConfiguration fileConfiguration)
{
var response = _configurationValidator.IsValid(fileConfiguration);
if (response.Data.IsError) if (response.Data.IsError)
{ {

View File

@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses; using Ocelot.Responses;
namespace Ocelot.Configuration.Creator namespace Ocelot.Configuration.Creator
@ -6,5 +7,6 @@ namespace Ocelot.Configuration.Creator
public interface IOcelotConfigurationCreator public interface IOcelotConfigurationCreator
{ {
Task<Response<IOcelotConfiguration>> Create(); Task<Response<IOcelotConfiguration>> Create();
Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration);
} }
} }

View File

@ -1,9 +1,4 @@
using System; namespace Ocelot.Configuration.File
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Ocelot.Configuration.File
{ {
public class FileQoSOptions public class FileQoSOptions
{ {

View File

@ -1,10 +1,9 @@
using System.Threading.Tasks; using Ocelot.Responses;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider namespace Ocelot.Configuration.Provider
{ {
public interface IOcelotConfigurationProvider public interface IOcelotConfigurationProvider
{ {
Task<Response<IOcelotConfiguration>> Get(); Response<IOcelotConfiguration> Get();
} }
} }

View File

@ -1,6 +1,4 @@
using System.Threading.Tasks; using Ocelot.Configuration.Repository;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.Repository;
using Ocelot.Responses; using Ocelot.Responses;
namespace Ocelot.Configuration.Provider namespace Ocelot.Configuration.Provider
@ -11,16 +9,13 @@ namespace Ocelot.Configuration.Provider
public class OcelotConfigurationProvider : IOcelotConfigurationProvider public class OcelotConfigurationProvider : IOcelotConfigurationProvider
{ {
private readonly IOcelotConfigurationRepository _repo; private readonly IOcelotConfigurationRepository _repo;
private readonly IOcelotConfigurationCreator _creator;
public OcelotConfigurationProvider(IOcelotConfigurationRepository repo, public OcelotConfigurationProvider(IOcelotConfigurationRepository repo)
IOcelotConfigurationCreator creator)
{ {
_repo = repo; _repo = repo;
_creator = creator;
} }
public async Task<Response<IOcelotConfiguration>> Get() public Response<IOcelotConfiguration> Get()
{ {
var repoConfig = _repo.Get(); var repoConfig = _repo.Get();
@ -29,20 +24,6 @@ namespace Ocelot.Configuration.Provider
return new ErrorResponse<IOcelotConfiguration>(repoConfig.Errors); return new ErrorResponse<IOcelotConfiguration>(repoConfig.Errors);
} }
if (repoConfig.Data == null)
{
var creatorConfig = await _creator.Create();
if (creatorConfig.IsError)
{
return new ErrorResponse<IOcelotConfiguration>(creatorConfig.Errors);
}
_repo.AddOrReplace(creatorConfig.Data);
return new OkResponse<IOcelotConfiguration>(creatorConfig.Data);
}
return new OkResponse<IOcelotConfiguration>(repoConfig.Data); return new OkResponse<IOcelotConfiguration>(repoConfig.Data);
} }
} }

View File

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using Ocelot.Values; using Ocelot.Values;

View File

@ -0,0 +1,32 @@
using System.Threading.Tasks;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Responses;
namespace Ocelot.Configuration.Setter
{
public class FileConfigurationSetter : IFileConfigurationSetter
{
private readonly IOcelotConfigurationRepository _configRepo;
private readonly IOcelotConfigurationCreator _configCreator;
public FileConfigurationSetter(IOcelotConfigurationRepository configRepo, IOcelotConfigurationCreator configCreator)
{
_configRepo = configRepo;
_configCreator = configCreator;
}
public async Task<Response> Set(FileConfiguration fileConfig)
{
var config = await _configCreator.Create(fileConfig);
if(!config.IsError)
{
_configRepo.AddOrReplace(config.Data);
}
return new ErrorResponse(config.Errors);
}
}
}

View File

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Setter
{
public interface IFileConfigurationSetter
{
Task<Response> Set(FileConfiguration config);
}
}

View File

@ -1,5 +1,8 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Setter;
using Ocelot.Services; using Ocelot.Services;
namespace Ocelot.Controllers namespace Ocelot.Controllers
@ -8,17 +11,39 @@ namespace Ocelot.Controllers
[Route("configuration")] [Route("configuration")]
public class FileConfigurationController : Controller public class FileConfigurationController : Controller
{ {
private readonly IGetFileConfiguration _getFileConfig; private readonly IFileConfigurationProvider _configGetter;
private readonly IFileConfigurationSetter _configSetter;
public FileConfigurationController(IGetFileConfiguration getFileConfig) public FileConfigurationController(IFileConfigurationProvider getFileConfig, IFileConfigurationSetter configSetter)
{ {
_getFileConfig = getFileConfig; _configGetter = getFileConfig;
_configSetter = configSetter;
} }
[HttpGet] [HttpGet]
public IActionResult Get() public IActionResult Get()
{ {
return new OkObjectResult(_getFileConfig.Invoke().Data); var response = _configGetter.Get();
if(response.IsError)
{
return new BadRequestObjectResult(response.Errors);
}
return new OkObjectResult(response.Data);
}
[HttpPost]
public async Task<IActionResult> Post(FileConfiguration fileConfiguration)
{
var response = await _configSetter.Set(fileConfiguration);
if(response.IsError)
{
return new BadRequestObjectResult(response.Errors);
}
return new OkObjectResult(fileConfiguration);
} }
} }
} }

View File

@ -1,14 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Security.Claims;
using CacheManager.Core; using CacheManager.Core;
using IdentityServer4.Models; using IdentityServer4.Models;
using IdentityServer4.Test; using IdentityServer4.Test;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Ocelot.Authentication.Handler.Creator; using Ocelot.Authentication.Handler.Creator;
using Ocelot.Authentication.Handler.Factory; using Ocelot.Authentication.Handler.Factory;
using Ocelot.Authorisation; using Ocelot.Authorisation;
@ -46,7 +44,6 @@ namespace Ocelot.DependencyInjection
{ {
var cacheManagerOutputCache = CacheFactory.Build<HttpResponseMessage>("OcelotOutputCache", settings); var cacheManagerOutputCache = CacheFactory.Build<HttpResponseMessage>("OcelotOutputCache", settings);
var ocelotCacheManager = new OcelotCacheManagerCache<HttpResponseMessage>(cacheManagerOutputCache); var ocelotCacheManager = new OcelotCacheManagerCache<HttpResponseMessage>(cacheManagerOutputCache);
services.AddSingleton<ICacheManager<HttpResponseMessage>>(cacheManagerOutputCache); services.AddSingleton<ICacheManager<HttpResponseMessage>>(cacheManagerOutputCache);
services.AddSingleton<IOcelotCache<HttpResponseMessage>>(ocelotCacheManager); services.AddSingleton<IOcelotCache<HttpResponseMessage>>(ocelotCacheManager);
@ -55,11 +52,9 @@ namespace Ocelot.DependencyInjection
public static IServiceCollection AddOcelotFileConfiguration(this IServiceCollection services, IConfigurationRoot configurationRoot) public static IServiceCollection AddOcelotFileConfiguration(this IServiceCollection services, IConfigurationRoot configurationRoot)
{ {
services.Configure<FileConfiguration>(configurationRoot); services.Configure<FileConfiguration>(configurationRoot);
services.AddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>(); services.AddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
services.AddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>(); services.AddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
services.AddSingleton<IConfigurationValidator, FileConfigurationValidator>(); services.AddSingleton<IConfigurationValidator, FileConfigurationValidator>();
return services; return services;
} }
@ -116,7 +111,7 @@ namespace Ocelot.DependencyInjection
.AddAuthorization() .AddAuthorization()
.AddJsonFormatters(); .AddJsonFormatters();
services.AddLogging(); services.AddLogging();
services.AddSingleton<IGetFileConfiguration, GetFileConfiguration>(); services.AddSingleton<IFileConfigurationProvider, Services.FileConfigurationProvider>();
services.AddSingleton<IQosProviderHouse, QosProviderHouse>(); services.AddSingleton<IQosProviderHouse, QosProviderHouse>();
services.AddSingleton<IQoSProviderFactory, QoSProviderFactory>(); services.AddSingleton<IQoSProviderFactory, QoSProviderFactory>();
services.AddSingleton<IServiceDiscoveryProviderFactory, ServiceDiscoveryProviderFactory>(); services.AddSingleton<IServiceDiscoveryProviderFactory, ServiceDiscoveryProviderFactory>();

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Ocelot.Configuration.Provider; using Ocelot.Configuration.Provider;
using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Errors; using Ocelot.Errors;
@ -22,9 +21,9 @@ namespace Ocelot.DownstreamRouteFinder.Finder
_urlPathPlaceholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder; _urlPathPlaceholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
} }
public async Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod) public Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
{ {
var configuration = await _configProvider.Get(); var configuration = _configProvider.Get();
var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod.Method, upstreamHttpMethod, StringComparison.CurrentCultureIgnoreCase)); var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod.Method, upstreamHttpMethod, StringComparison.CurrentCultureIgnoreCase));

View File

@ -1,10 +1,9 @@
using System.Threading.Tasks; using Ocelot.Responses;
using Ocelot.Responses;
namespace Ocelot.DownstreamRouteFinder.Finder namespace Ocelot.DownstreamRouteFinder.Finder
{ {
public interface IDownstreamRouteFinder public interface IDownstreamRouteFinder
{ {
Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod); Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod);
} }
} }

View File

@ -1,6 +1,5 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Ocelot.DownstreamRouteFinder.Finder; using Ocelot.DownstreamRouteFinder.Finder;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;
@ -34,7 +33,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
_logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath); _logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);
var downstreamRoute = await _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method); var downstreamRoute = _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method);
if (downstreamRoute.IsError) if (downstreamRoute.IsError)
{ {

View File

@ -1,6 +1,4 @@
using Ocelot.Configuration; using Ocelot.Responses;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Responses;
using Ocelot.Values; using Ocelot.Values;
namespace Ocelot.DownstreamUrlCreator namespace Ocelot.DownstreamUrlCreator

View File

@ -1,12 +1,9 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Ocelot.Configuration;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer; using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;
using Ocelot.Middleware; using Ocelot.Middleware;
using Ocelot.Values;
namespace Ocelot.DownstreamUrlCreator.Middleware namespace Ocelot.DownstreamUrlCreator.Middleware
{ {

View File

@ -1,7 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Ocelot.Configuration;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Errors; using Ocelot.Errors;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Values; using Ocelot.Values;

View File

@ -1,8 +1,6 @@
using System; using System;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;

View File

@ -1,7 +1,6 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;
using Ocelot.Middleware; using Ocelot.Middleware;

View File

@ -3,8 +3,6 @@ using Ocelot.Responses;
namespace Ocelot.Headers namespace Ocelot.Headers
{ {
using System;
public class RemoveOutputHeaders : IRemoveOutputHeaders public class RemoveOutputHeaders : IRemoveOutputHeaders
{ {
/// <summary> /// <summary>

View File

@ -1,4 +1,3 @@
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Values; using Ocelot.Values;

View File

@ -1,7 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ocelot.Responses; using Ocelot.Responses;
namespace Ocelot.LoadBalancer.LoadBalancers namespace Ocelot.LoadBalancer.LoadBalancers

View File

@ -20,8 +20,11 @@ namespace Ocelot.Middleware
using System.Threading.Tasks; using System.Threading.Tasks;
using Authorisation.Middleware; using Authorisation.Middleware;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Ocelot.Configuration; using Ocelot.Configuration;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Provider; using Ocelot.Configuration.Provider;
using Ocelot.Configuration.Setter;
using Ocelot.LoadBalancer.Middleware; using Ocelot.LoadBalancer.Middleware;
public static class OcelotMiddlewareExtensions public static class OcelotMiddlewareExtensions
@ -127,17 +130,27 @@ namespace Ocelot.Middleware
private static async Task<IOcelotConfiguration> CreateConfiguration(IApplicationBuilder builder) private static async Task<IOcelotConfiguration> CreateConfiguration(IApplicationBuilder builder)
{ {
var fileConfig = (IOptions<FileConfiguration>)builder.ApplicationServices.GetService(typeof(IOptions<FileConfiguration>));
var configSetter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
var configProvider = (IOcelotConfigurationProvider)builder.ApplicationServices.GetService(typeof(IOcelotConfigurationProvider)); var configProvider = (IOcelotConfigurationProvider)builder.ApplicationServices.GetService(typeof(IOcelotConfigurationProvider));
var config = await configProvider.Get(); var config = await configSetter.Set(fileConfig.Value);
//todo move this to config validators if(config == null || config.IsError)
if(config == null || config.Data == null || config.IsError)
{ {
throw new Exception("Unable to start Ocelot: configuration was invalid"); throw new Exception("Unable to start Ocelot: configuration was not set up correctly.");
} }
return config.Data; var ocelotConfiguration = configProvider.Get();
if(ocelotConfiguration == null || ocelotConfiguration.Data == null || ocelotConfiguration.IsError)
{
throw new Exception("Unable to start Ocelot: ocelot configuration was not returned by provider.");
}
return ocelotConfiguration.Data;
} }
private static async Task CreateAdministrationArea(IApplicationBuilder builder) private static async Task CreateAdministrationArea(IApplicationBuilder builder)

View File

@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following

View File

@ -1,7 +1,6 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;
using Ocelot.Middleware; using Ocelot.Middleware;

View File

@ -5,6 +5,9 @@ namespace Ocelot.Responses
{ {
public class ErrorResponse : Response public class ErrorResponse : Response
{ {
public ErrorResponse(Error error) : base(new List<Error>{error})
{
}
public ErrorResponse(List<Error> errors) : base(errors) public ErrorResponse(List<Error> errors) : base(errors)
{ {
} }

View File

@ -6,9 +6,9 @@ using Ocelot.Responses;
namespace Ocelot.Services namespace Ocelot.Services
{ {
public class GetFileConfiguration : IGetFileConfiguration public class FileConfigurationProvider : IFileConfigurationProvider
{ {
public Response<FileConfiguration> Invoke() public Response<FileConfiguration> Get()
{ {
var configFilePath = $"{AppContext.BaseDirectory}/configuration.json"; var configFilePath = $"{AppContext.BaseDirectory}/configuration.json";
var json = File.ReadAllText(configFilePath); var json = File.ReadAllText(configFilePath);

View File

@ -3,8 +3,8 @@ using Ocelot.Responses;
namespace Ocelot.Services namespace Ocelot.Services
{ {
public interface IGetFileConfiguration public interface IFileConfigurationProvider
{ {
Response<FileConfiguration> Invoke(); Response<FileConfiguration> Get();
} }
} }

View File

@ -34,6 +34,7 @@
"runtimes": { "runtimes": {
"win10-x64": {}, "win10-x64": {},
"osx.10.11-x64": {}, "osx.10.11-x64": {},
"osx.10.12-x64": {},
"win7-x64": {} "win7-x64": {}
}, },
"frameworks": { "frameworks": {

View File

@ -38,6 +38,7 @@
"runtimes": { "runtimes": {
"win10-x64": {}, "win10-x64": {},
"osx.10.11-x64": {}, "osx.10.11-x64": {},
"osx.10.12-x64": {},
"win7-x64": {} "win7-x64": {}
}, },
"frameworks": { "frameworks": {

View File

@ -11,6 +11,7 @@
"runtimes": { "runtimes": {
"win10-x64": {}, "win10-x64": {},
"osx.10.11-x64":{}, "osx.10.11-x64":{},
"osx.10.12-x64": {},
"win7-x64": {} "win7-x64": {}
}, },
"frameworks": { "frameworks": {

View File

@ -39,6 +39,7 @@
"runtimes": { "runtimes": {
"win10-x64": {}, "win10-x64": {},
"osx.10.11-x64": {}, "osx.10.11-x64": {},
"osx.10.12-x64": {},
"win7-x64": {} "win7-x64": {}
}, },
"frameworks": { "frameworks": {

View File

@ -23,6 +23,7 @@
"runtimes": { "runtimes": {
"win10-x64": {}, "win10-x64": {},
"osx.10.11-x64":{}, "osx.10.11-x64":{},
"osx.10.12-x64": {},
"win7-x64": {} "win7-x64": {}
}, },
"frameworks": { "frameworks": {

View File

@ -16,14 +16,12 @@ namespace Ocelot.UnitTests.Configuration
{ {
private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider; private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider;
private readonly Mock<IOcelotConfigurationRepository> _configurationRepository; private readonly Mock<IOcelotConfigurationRepository> _configurationRepository;
private readonly Mock<IOcelotConfigurationCreator> _creator;
private Response<IOcelotConfiguration> _result; private Response<IOcelotConfiguration> _result;
public FileConfigurationProviderTests() public FileConfigurationProviderTests()
{ {
_creator = new Mock<IOcelotConfigurationCreator>();
_configurationRepository = new Mock<IOcelotConfigurationRepository>(); _configurationRepository = new Mock<IOcelotConfigurationRepository>();
_ocelotConfigurationProvider = new OcelotConfigurationProvider(_configurationRepository.Object, _creator.Object); _ocelotConfigurationProvider = new OcelotConfigurationProvider(_configurationRepository.Object);
} }
[Fact] [Fact]
@ -35,16 +33,6 @@ namespace Ocelot.UnitTests.Configuration
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_create_config_if_it_doesnt_exist()
{
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(null)))
.And(x => x.GivenTheCreatorReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty))))
.When(x => x.WhenIGetTheConfig())
.Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty))))
.BDDfy();
}
[Fact] [Fact]
public void should_return_error() public void should_return_error()
{ {
@ -61,29 +49,6 @@ namespace Ocelot.UnitTests.Configuration
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_return_error_if_creator_errors()
{
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(null)))
.And(x => x.GivenTheCreatorReturns(new ErrorResponse<IOcelotConfiguration>(new List<Error>
{
new AnyError()
})))
.When(x => x.WhenIGetTheConfig())
.Then(x => x.TheFollowingIsReturned(new ErrorResponse<IOcelotConfiguration>(new List<Error>
{
new AnyError()
})))
.BDDfy();
}
private void GivenTheCreatorReturns(Response<IOcelotConfiguration> config)
{
_creator
.Setup(x => x.Create())
.ReturnsAsync(config);
}
private void GivenTheRepoReturns(Response<IOcelotConfiguration> config) private void GivenTheRepoReturns(Response<IOcelotConfiguration> config)
{ {
_configurationRepository _configurationRepository
@ -93,7 +58,7 @@ namespace Ocelot.UnitTests.Configuration
private void WhenIGetTheConfig() private void WhenIGetTheConfig()
{ {
_result = _ocelotConfigurationProvider.Get().Result; _result = _ocelotConfigurationProvider.Get();
} }
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected) private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)

View File

@ -0,0 +1,86 @@
using System.Collections.Generic;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Configuration.Setter;
using Ocelot.Errors;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Configuration
{
public class FileConfigurationSetterTests
{
private FileConfiguration _fileConfiguration;
private FileConfigurationSetter _configSetter;
private Mock<IOcelotConfigurationRepository> _configRepo;
private Mock<IOcelotConfigurationCreator> _configCreator;
private Response<IOcelotConfiguration> _configuration;
private object _result;
public FileConfigurationSetterTests()
{
_configRepo = new Mock<IOcelotConfigurationRepository>();
_configCreator = new Mock<IOcelotConfigurationCreator>();
_configSetter = new FileConfigurationSetter(_configRepo.Object, _configCreator.Object);
}
[Fact]
public void should_set_configuration()
{
var fileConfig = new FileConfiguration();
var config = new OcelotConfiguration(new List<ReRoute>(), string.Empty);
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
.And(x => GivenTheCreatorReturns(new OkResponse<IOcelotConfiguration>(config)))
.When(x => WhenISetTheConfiguration())
.Then(x => ThenTheConfigurationRepositoryIsCalledCorrectly())
.BDDfy();
}
[Fact]
public void should_return_error_if_unable_to_set_configuration()
{
var fileConfig = new FileConfiguration();
this.Given(x => GivenTheFollowingConfiguration(fileConfig))
.And(x => GivenTheCreatorReturns(new ErrorResponse<IOcelotConfiguration>(It.IsAny<Error>())))
.When(x => WhenISetTheConfiguration())
.And(x => ThenAnErrorResponseIsReturned())
.BDDfy();
}
private void ThenAnErrorResponseIsReturned()
{
_result.ShouldBeOfType<ErrorResponse>();
}
private void GivenTheCreatorReturns(Response<IOcelotConfiguration> configuration)
{
_configuration = configuration;
_configCreator
.Setup(x => x.Create(_fileConfiguration))
.ReturnsAsync(_configuration);
}
private void GivenTheFollowingConfiguration(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;
}
private void WhenISetTheConfiguration()
{
_result = _configSetter.Set(_fileConfiguration).Result;
}
private void ThenTheConfigurationRepositoryIsCalledCorrectly()
{
_configRepo
.Verify(x => x.AddOrReplace(_configuration.Data), Times.Once);
}
}
}

View File

@ -1,28 +1,36 @@
using System;
using System.Net;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Moq; using Moq;
using Ocelot.Configuration.File; using Ocelot.Configuration.File;
using Ocelot.Configuration.Setter;
using Ocelot.Controllers; using Ocelot.Controllers;
using Ocelot.Errors;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Services; using Ocelot.Services;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
using Shouldly;
namespace Ocelot.UnitTests.Controllers namespace Ocelot.UnitTests.Controllers
{ {
public class FileConfigurationControllerTests public class FileConfigurationControllerTests
{ {
private FileConfigurationController _controller; private FileConfigurationController _controller;
private Mock<IGetFileConfiguration> _getFileConfig; private Mock<IFileConfigurationProvider> _configGetter;
private Mock<IFileConfigurationSetter> _configSetter;
private IActionResult _result; private IActionResult _result;
private FileConfiguration _fileConfiguration;
public FileConfigurationControllerTests() public FileConfigurationControllerTests()
{ {
_getFileConfig = new Mock<IGetFileConfiguration>(); _configGetter = new Mock<IFileConfigurationProvider>();
_controller = new FileConfigurationController(_getFileConfig.Object); _configSetter = new Mock<IFileConfigurationSetter>();
_controller = new FileConfigurationController(_configGetter.Object, _configSetter.Object);
} }
[Fact] [Fact]
public void should_return_file_configuration() public void should_get_file_configuration()
{ {
var expected = new OkResponse<FileConfiguration>(new FileConfiguration()); var expected = new OkResponse<FileConfiguration>(new FileConfiguration());
@ -32,10 +40,75 @@ namespace Ocelot.UnitTests.Controllers
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_return_error_when_cannot_get_config()
{
var expected = new ErrorResponse<FileConfiguration>(It.IsAny<Error>());
this.Given(x => x.GivenTheGetConfigurationReturns(expected))
.When(x => x.WhenIGetTheFileConfiguration())
.Then(x => x.TheTheGetFileConfigurationIsCalledCorrectly())
.And(x => x.ThenTheResponseIs<BadRequestObjectResult>())
.BDDfy();
}
[Fact]
public void should_post_file_configuration()
{
var expected = new FileConfiguration();
this.Given(x => GivenTheFileConfiguration(expected))
.And(x => GivenTheConfigSetterReturnsAnError(new OkResponse()))
.When(x => WhenIPostTheFileConfiguration())
.Then(x => x.ThenTheConfigrationSetterIsCalledCorrectly())
.BDDfy();
}
[Fact]
public void should_return_error_when_cannot_set_config()
{
var expected = new FileConfiguration();
this.Given(x => GivenTheFileConfiguration(expected))
.And(x => GivenTheConfigSetterReturnsAnError(new ErrorResponse(new FakeError())))
.When(x => WhenIPostTheFileConfiguration())
.Then(x => x.ThenTheConfigrationSetterIsCalledCorrectly())
.And(x => ThenTheResponseIs<BadRequestObjectResult>())
.BDDfy();
}
private void GivenTheConfigSetterReturnsAnError(Response response)
{
_configSetter
.Setup(x => x.Set(It.IsAny<FileConfiguration>()))
.ReturnsAsync(response);
}
private void ThenTheConfigrationSetterIsCalledCorrectly()
{
_configSetter
.Verify(x => x.Set(_fileConfiguration), Times.Once);
}
private void WhenIPostTheFileConfiguration()
{
_result = _controller.Post(_fileConfiguration).Result;
}
private void GivenTheFileConfiguration(FileConfiguration fileConfiguration)
{
_fileConfiguration = fileConfiguration;
}
private void ThenTheResponseIs<T>()
{
_result.ShouldBeOfType<T>();
}
private void GivenTheGetConfigurationReturns(Response<FileConfiguration> fileConfiguration) private void GivenTheGetConfigurationReturns(Response<FileConfiguration> fileConfiguration)
{ {
_getFileConfig _configGetter
.Setup(x => x.Invoke()) .Setup(x => x.Get())
.Returns(fileConfiguration); .Returns(fileConfiguration);
} }
@ -46,8 +119,15 @@ namespace Ocelot.UnitTests.Controllers
private void TheTheGetFileConfigurationIsCalledCorrectly() private void TheTheGetFileConfigurationIsCalledCorrectly()
{ {
_getFileConfig _configGetter
.Verify(x => x.Invoke(), Times.Once); .Verify(x => x.Get(), Times.Once);
}
class FakeError : Error
{
public FakeError() : base(string.Empty, OcelotErrorCode.CannotAddDataError)
{
}
} }
} }
} }

View File

@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute); _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
_downstreamRouteFinder _downstreamRouteFinder
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>())) .Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync(_downstreamRoute); .Returns(_downstreamRoute);
} }
public void Dispose() public void Dispose()

View File

@ -199,7 +199,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
_reRoutesConfig = reRoutesConfig; _reRoutesConfig = reRoutesConfig;
_mockConfig _mockConfig
.Setup(x => x.Get()) .Setup(x => x.Get())
.ReturnsAsync(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig, adminPath))); .Returns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig, adminPath)));
} }
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath) private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
@ -209,7 +209,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void WhenICallTheFinder() private void WhenICallTheFinder()
{ {
_result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod).Result; _result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod);
} }
private void ThenTheFollowingIsReturned(DownstreamRoute expected) private void ThenTheFollowingIsReturned(DownstreamRoute expected)

View File

@ -15,12 +15,12 @@ namespace Ocelot.UnitTests.Services
{ {
public class GetFileConfigurationTests public class GetFileConfigurationTests
{ {
private readonly IGetFileConfiguration _getReRoutes; private readonly IFileConfigurationProvider _getReRoutes;
private FileConfiguration _result; private FileConfiguration _result;
public GetFileConfigurationTests() public GetFileConfigurationTests()
{ {
_getReRoutes = new GetFileConfiguration(); _getReRoutes = new FileConfigurationProvider();
} }
[Fact] [Fact]
@ -74,7 +74,7 @@ namespace Ocelot.UnitTests.Services
private void WhenIGetTheReRoutes() private void WhenIGetTheReRoutes()
{ {
_result = _getReRoutes.Invoke().Data; _result = _getReRoutes.Get().Data;
} }
private void ThenTheFollowingIsReturned(FileConfiguration expected) private void ThenTheFollowingIsReturned(FileConfiguration expected)

View File

@ -29,6 +29,7 @@
"runtimes": { "runtimes": {
"win10-x64": {}, "win10-x64": {},
"osx.10.11-x64":{}, "osx.10.11-x64":{},
"osx.10.12-x64": {},
"win7-x64": {} "win7-x64": {}
}, },
"frameworks": { "frameworks": {