mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-10-31 10:19:26 +08:00 
			
		
		
		
	after much hacking unit tests passing
This commit is contained in:
		| @@ -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> | ||||
| @@ -1,8 +0,0 @@ | ||||
| version: 1.0.{build} | ||||
| configuration: | ||||
| - Release | ||||
| platform: Any CPU | ||||
| build_script: | ||||
| - build.ps1 | ||||
| cache: | ||||
| - '%USERPROFILE%\.nuget\packages' | ||||
| @@ -2,7 +2,6 @@ | ||||
| using System.Net.Http; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Ocelot.Infrastructure.RequestData; | ||||
| using Ocelot.Logging; | ||||
| using Ocelot.Middleware; | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Ocelot.Infrastructure.RequestData; | ||||
| using Ocelot.Logging; | ||||
| using Ocelot.Middleware; | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.Generic; | ||||
| using System.Net.Http; | ||||
| using Ocelot.Values; | ||||
|  | ||||
|   | ||||
| @@ -56,14 +56,21 @@ namespace Ocelot.Configuration.Creator | ||||
|  | ||||
|         public async Task<Response<IOcelotConfiguration>> Create() | ||||
|         {      | ||||
|             var config = await SetUpConfiguration(); | ||||
|             var config = await SetUpConfiguration(_options.Value); | ||||
|  | ||||
|             return new OkResponse<IOcelotConfiguration>(config); | ||||
|         } | ||||
|  | ||||
|         private async Task<IOcelotConfiguration> SetUpConfiguration() | ||||
|         public async Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration) | ||||
|         {      | ||||
|             var config = await SetUpConfiguration(fileConfiguration); | ||||
|  | ||||
|             return new OkResponse<IOcelotConfiguration>(config); | ||||
|         } | ||||
|  | ||||
|         private async Task<IOcelotConfiguration> SetUpConfiguration(FileConfiguration fileConfiguration) | ||||
|         { | ||||
|             var response = _configurationValidator.IsValid(_options.Value); | ||||
|             var response = _configurationValidator.IsValid(fileConfiguration); | ||||
|  | ||||
|             if (response.Data.IsError) | ||||
|             { | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Configuration.File; | ||||
| using Ocelot.Responses; | ||||
|  | ||||
| namespace Ocelot.Configuration.Creator | ||||
| @@ -6,5 +7,6 @@ namespace Ocelot.Configuration.Creator | ||||
|     public interface IOcelotConfigurationCreator | ||||
|     { | ||||
|         Task<Response<IOcelotConfiguration>> Create(); | ||||
|         Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration); | ||||
|     } | ||||
| } | ||||
| @@ -1,9 +1,4 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace Ocelot.Configuration.File | ||||
| namespace Ocelot.Configuration.File | ||||
| { | ||||
|     public class FileQoSOptions | ||||
|     { | ||||
|   | ||||
| @@ -1,10 +1,9 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Responses; | ||||
| using Ocelot.Responses; | ||||
|  | ||||
| namespace Ocelot.Configuration.Provider | ||||
| { | ||||
|     public interface IOcelotConfigurationProvider | ||||
|     { | ||||
|         Task<Response<IOcelotConfiguration>> Get(); | ||||
|         Response<IOcelotConfiguration> Get(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Configuration.Creator; | ||||
| using Ocelot.Configuration.Repository; | ||||
| using Ocelot.Configuration.Repository; | ||||
| using Ocelot.Responses; | ||||
|  | ||||
| namespace Ocelot.Configuration.Provider | ||||
| @@ -11,16 +9,13 @@ namespace Ocelot.Configuration.Provider | ||||
|     public class OcelotConfigurationProvider : IOcelotConfigurationProvider | ||||
|     { | ||||
|         private readonly IOcelotConfigurationRepository _repo; | ||||
|         private readonly IOcelotConfigurationCreator _creator; | ||||
|  | ||||
|         public OcelotConfigurationProvider(IOcelotConfigurationRepository repo,  | ||||
|             IOcelotConfigurationCreator creator) | ||||
|         public OcelotConfigurationProvider(IOcelotConfigurationRepository repo) | ||||
|         { | ||||
|             _repo = repo; | ||||
|             _creator = creator; | ||||
|         } | ||||
|  | ||||
|         public async Task<Response<IOcelotConfiguration>> Get() | ||||
|         public Response<IOcelotConfiguration> Get() | ||||
|         { | ||||
|             var repoConfig = _repo.Get(); | ||||
|  | ||||
| @@ -29,20 +24,6 @@ namespace Ocelot.Configuration.Provider | ||||
|                 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); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.Generic; | ||||
| using System.Net.Http; | ||||
| using Ocelot.Values; | ||||
|  | ||||
|   | ||||
							
								
								
									
										32
									
								
								src/Ocelot/Configuration/Setter/FileConfigurationSetter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/Ocelot/Configuration/Setter/FileConfigurationSetter.cs
									
									
									
									
									
										Normal 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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								src/Ocelot/Configuration/Setter/IFileConfigurationSetter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/Ocelot/Configuration/Setter/IFileConfigurationSetter.cs
									
									
									
									
									
										Normal 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); | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,8 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Authorization; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Ocelot.Configuration.File; | ||||
| using Ocelot.Configuration.Setter; | ||||
| using Ocelot.Services; | ||||
|  | ||||
| namespace Ocelot.Controllers | ||||
| @@ -8,17 +11,39 @@ namespace Ocelot.Controllers | ||||
|     [Route("configuration")] | ||||
|     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] | ||||
|         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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,14 +1,12 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Net.Http; | ||||
| using System.Security.Claims; | ||||
| using CacheManager.Core; | ||||
| using IdentityServer4.Models; | ||||
| using IdentityServer4.Test; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Ocelot.Authentication.Handler.Creator; | ||||
| using Ocelot.Authentication.Handler.Factory; | ||||
| using Ocelot.Authorisation; | ||||
| @@ -46,7 +44,6 @@ namespace Ocelot.DependencyInjection | ||||
|         { | ||||
|             var cacheManagerOutputCache = CacheFactory.Build<HttpResponseMessage>("OcelotOutputCache", settings); | ||||
|             var ocelotCacheManager = new OcelotCacheManagerCache<HttpResponseMessage>(cacheManagerOutputCache); | ||||
|  | ||||
|             services.AddSingleton<ICacheManager<HttpResponseMessage>>(cacheManagerOutputCache); | ||||
|             services.AddSingleton<IOcelotCache<HttpResponseMessage>>(ocelotCacheManager); | ||||
|  | ||||
| @@ -55,11 +52,9 @@ namespace Ocelot.DependencyInjection | ||||
|         public static IServiceCollection AddOcelotFileConfiguration(this IServiceCollection services, IConfigurationRoot configurationRoot) | ||||
|         { | ||||
|             services.Configure<FileConfiguration>(configurationRoot); | ||||
|  | ||||
|             services.AddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>(); | ||||
|             services.AddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>(); | ||||
|             services.AddSingleton<IConfigurationValidator, FileConfigurationValidator>(); | ||||
|  | ||||
|             return services; | ||||
|         } | ||||
|  | ||||
| @@ -116,7 +111,7 @@ namespace Ocelot.DependencyInjection | ||||
|                 .AddAuthorization() | ||||
|                 .AddJsonFormatters(); | ||||
|             services.AddLogging(); | ||||
|             services.AddSingleton<IGetFileConfiguration, GetFileConfiguration>(); | ||||
|             services.AddSingleton<IFileConfigurationProvider, Services.FileConfigurationProvider>(); | ||||
|             services.AddSingleton<IQosProviderHouse, QosProviderHouse>(); | ||||
|             services.AddSingleton<IQoSProviderFactory, QoSProviderFactory>(); | ||||
|             services.AddSingleton<IServiceDiscoveryProviderFactory, ServiceDiscoveryProviderFactory>(); | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Configuration.Provider; | ||||
| using Ocelot.DownstreamRouteFinder.UrlMatcher; | ||||
| using Ocelot.Errors; | ||||
| @@ -22,9 +21,9 @@ namespace Ocelot.DownstreamRouteFinder.Finder | ||||
|             _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)); | ||||
|  | ||||
|   | ||||
| @@ -1,10 +1,9 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Responses; | ||||
| using Ocelot.Responses; | ||||
|  | ||||
| namespace Ocelot.DownstreamRouteFinder.Finder | ||||
| { | ||||
|     public interface IDownstreamRouteFinder | ||||
|     { | ||||
|         Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod); | ||||
|         Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Ocelot.DownstreamRouteFinder.Finder; | ||||
| using Ocelot.Infrastructure.RequestData; | ||||
| using Ocelot.Logging; | ||||
| @@ -34,7 +33,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware | ||||
|  | ||||
|             _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) | ||||
|             { | ||||
|   | ||||
| @@ -1,6 +1,4 @@ | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer; | ||||
| using Ocelot.Responses; | ||||
| using Ocelot.Responses; | ||||
| using Ocelot.Values; | ||||
|  | ||||
| namespace Ocelot.DownstreamUrlCreator | ||||
|   | ||||
| @@ -1,12 +1,9 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer; | ||||
| using Ocelot.Infrastructure.RequestData; | ||||
| using Ocelot.Logging; | ||||
| using Ocelot.Middleware; | ||||
| using Ocelot.Values; | ||||
|  | ||||
| namespace Ocelot.DownstreamUrlCreator.Middleware | ||||
| { | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer; | ||||
| using Ocelot.Errors; | ||||
| using Ocelot.Responses; | ||||
| using Ocelot.Values; | ||||
|   | ||||
| @@ -1,8 +1,6 @@ | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Ocelot.Infrastructure.RequestData; | ||||
| using Ocelot.Logging; | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Ocelot.Infrastructure.RequestData; | ||||
| using Ocelot.Logging; | ||||
| using Ocelot.Middleware; | ||||
|   | ||||
| @@ -3,8 +3,6 @@ using Ocelot.Responses; | ||||
|  | ||||
| namespace Ocelot.Headers | ||||
| { | ||||
|     using System; | ||||
|  | ||||
|     public class RemoveOutputHeaders : IRemoveOutputHeaders | ||||
|     { | ||||
|         /// <summary> | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| using System; | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Responses; | ||||
| using Ocelot.Values; | ||||
|   | ||||
| @@ -1,7 +1,4 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using System.Collections.Generic; | ||||
| using Ocelot.Responses; | ||||
|  | ||||
| namespace Ocelot.LoadBalancer.LoadBalancers | ||||
|   | ||||
| @@ -20,8 +20,11 @@ namespace Ocelot.Middleware | ||||
|     using System.Threading.Tasks; | ||||
|     using Authorisation.Middleware; | ||||
|     using Microsoft.AspNetCore.Http; | ||||
|     using Microsoft.Extensions.Options; | ||||
|     using Ocelot.Configuration; | ||||
|     using Ocelot.Configuration.File; | ||||
|     using Ocelot.Configuration.Provider; | ||||
|     using Ocelot.Configuration.Setter; | ||||
|     using Ocelot.LoadBalancer.Middleware; | ||||
|  | ||||
|     public static class OcelotMiddlewareExtensions | ||||
| @@ -127,17 +130,27 @@ namespace Ocelot.Middleware | ||||
|  | ||||
|         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 config = await configProvider.Get(); | ||||
|             var config = await configSetter.Set(fileConfig.Value); | ||||
|              | ||||
|             //todo move this to config validators | ||||
|             if(config == null || config.Data == null || config.IsError) | ||||
|             if(config == 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) | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| using System.Reflection; | ||||
| using System.Runtime.CompilerServices; | ||||
| using System.Runtime.InteropServices; | ||||
|  | ||||
| // General Information about an assembly is controlled through the following | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Ocelot.Infrastructure.RequestData; | ||||
| using Ocelot.Logging; | ||||
| using Ocelot.Middleware; | ||||
|   | ||||
| @@ -5,6 +5,9 @@ namespace Ocelot.Responses | ||||
| { | ||||
|     public class ErrorResponse : Response | ||||
|     { | ||||
|         public ErrorResponse(Error error) : base(new List<Error>{error}) | ||||
|         { | ||||
|         } | ||||
|         public ErrorResponse(List<Error> errors) : base(errors) | ||||
|         { | ||||
|         } | ||||
|   | ||||
| @@ -6,9 +6,9 @@ using Ocelot.Responses; | ||||
| 
 | ||||
| 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 json = File.ReadAllText(configFilePath); | ||||
| @@ -3,8 +3,8 @@ using Ocelot.Responses; | ||||
| 
 | ||||
| namespace Ocelot.Services | ||||
| { | ||||
|     public interface IGetFileConfiguration | ||||
|     public interface IFileConfigurationProvider | ||||
|     { | ||||
|         Response<FileConfiguration> Invoke(); | ||||
|         Response<FileConfiguration> Get(); | ||||
|     } | ||||
| } | ||||
| @@ -34,6 +34,7 @@ | ||||
|   "runtimes": { | ||||
|     "win10-x64": {}, | ||||
|     "osx.10.11-x64": {}, | ||||
|     "osx.10.12-x64": {}, | ||||
|     "win7-x64": {} | ||||
|   }, | ||||
|   "frameworks": { | ||||
|   | ||||
| @@ -38,6 +38,7 @@ | ||||
|   "runtimes": { | ||||
|     "win10-x64": {}, | ||||
|     "osx.10.11-x64": {}, | ||||
|     "osx.10.12-x64": {}, | ||||
|     "win7-x64": {} | ||||
|   }, | ||||
|   "frameworks": { | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
|   "runtimes": { | ||||
|     "win10-x64": {}, | ||||
|     "osx.10.11-x64":{}, | ||||
|     "osx.10.12-x64": {}, | ||||
|     "win7-x64": {} | ||||
|   }, | ||||
|   "frameworks": { | ||||
|   | ||||
| @@ -39,6 +39,7 @@ | ||||
|     "runtimes": { | ||||
|         "win10-x64": {}, | ||||
|         "osx.10.11-x64": {}, | ||||
|         "osx.10.12-x64": {}, | ||||
|         "win7-x64": {} | ||||
|     }, | ||||
|     "frameworks": { | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
|   "runtimes": { | ||||
|     "win10-x64": {}, | ||||
|     "osx.10.11-x64":{}, | ||||
|     "osx.10.12-x64": {}, | ||||
|     "win7-x64": {} | ||||
|   }, | ||||
|   "frameworks": { | ||||
|   | ||||
| @@ -16,14 +16,12 @@ namespace Ocelot.UnitTests.Configuration | ||||
|     { | ||||
|         private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider; | ||||
|         private readonly Mock<IOcelotConfigurationRepository> _configurationRepository; | ||||
|         private readonly Mock<IOcelotConfigurationCreator> _creator; | ||||
|         private Response<IOcelotConfiguration> _result; | ||||
|  | ||||
|         public FileConfigurationProviderTests() | ||||
|         { | ||||
|             _creator = new Mock<IOcelotConfigurationCreator>(); | ||||
|             _configurationRepository = new Mock<IOcelotConfigurationRepository>(); | ||||
|             _ocelotConfigurationProvider = new OcelotConfigurationProvider(_configurationRepository.Object, _creator.Object); | ||||
|             _ocelotConfigurationProvider = new OcelotConfigurationProvider(_configurationRepository.Object); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
| @@ -35,16 +33,6 @@ namespace Ocelot.UnitTests.Configuration | ||||
|                 .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] | ||||
|         public void should_return_error() | ||||
|         { | ||||
| @@ -61,29 +49,6 @@ namespace Ocelot.UnitTests.Configuration | ||||
|               .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) | ||||
|         { | ||||
|             _configurationRepository | ||||
| @@ -93,7 +58,7 @@ namespace Ocelot.UnitTests.Configuration | ||||
|  | ||||
|         private void WhenIGetTheConfig() | ||||
|         { | ||||
|             _result = _ocelotConfigurationProvider.Get().Result; | ||||
|             _result = _ocelotConfigurationProvider.Get(); | ||||
|         } | ||||
|  | ||||
|         private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected) | ||||
|   | ||||
| @@ -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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,28 +1,36 @@ | ||||
| using System; | ||||
| using System.Net; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Moq; | ||||
| using Ocelot.Configuration.File; | ||||
| using Ocelot.Configuration.Setter; | ||||
| using Ocelot.Controllers; | ||||
| using Ocelot.Errors; | ||||
| using Ocelot.Responses; | ||||
| using Ocelot.Services; | ||||
| using TestStack.BDDfy; | ||||
| using Xunit; | ||||
| using Shouldly; | ||||
|  | ||||
| namespace Ocelot.UnitTests.Controllers | ||||
| { | ||||
|     public class FileConfigurationControllerTests | ||||
|     { | ||||
|         private FileConfigurationController _controller; | ||||
|         private Mock<IGetFileConfiguration> _getFileConfig; | ||||
|         private Mock<IFileConfigurationProvider> _configGetter; | ||||
|         private Mock<IFileConfigurationSetter> _configSetter; | ||||
|         private IActionResult _result; | ||||
|         private FileConfiguration _fileConfiguration; | ||||
|  | ||||
|         public FileConfigurationControllerTests() | ||||
|         { | ||||
|             _getFileConfig = new Mock<IGetFileConfiguration>(); | ||||
|             _controller = new FileConfigurationController(_getFileConfig.Object); | ||||
|             _configGetter = new Mock<IFileConfigurationProvider>(); | ||||
|             _configSetter = new Mock<IFileConfigurationSetter>(); | ||||
|             _controller = new FileConfigurationController(_configGetter.Object, _configSetter.Object); | ||||
|         } | ||||
|          | ||||
|         [Fact] | ||||
|         public void should_return_file_configuration() | ||||
|         public void should_get_file_configuration() | ||||
|         { | ||||
|             var expected = new OkResponse<FileConfiguration>(new FileConfiguration()); | ||||
|  | ||||
| @@ -32,10 +40,75 @@ namespace Ocelot.UnitTests.Controllers | ||||
|                 .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) | ||||
|         { | ||||
|             _getFileConfig | ||||
|                 .Setup(x => x.Invoke()) | ||||
|             _configGetter | ||||
|                 .Setup(x => x.Get()) | ||||
|                 .Returns(fileConfiguration); | ||||
|         } | ||||
|  | ||||
| @@ -46,8 +119,15 @@ namespace Ocelot.UnitTests.Controllers | ||||
|  | ||||
|         private void TheTheGetFileConfigurationIsCalledCorrectly() | ||||
|         { | ||||
|                _getFileConfig | ||||
|                 .Verify(x => x.Invoke(), Times.Once); | ||||
|                _configGetter | ||||
|                 .Verify(x => x.Get(), Times.Once); | ||||
|         } | ||||
|  | ||||
|         class FakeError : Error | ||||
|         { | ||||
|             public FakeError() : base(string.Empty, OcelotErrorCode.CannotAddDataError) | ||||
|             { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|             _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute); | ||||
|             _downstreamRouteFinder | ||||
|                 .Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>())) | ||||
|                 .ReturnsAsync(_downstreamRoute); | ||||
|                 .Returns(_downstreamRoute); | ||||
|         } | ||||
|  | ||||
|         public void Dispose() | ||||
|   | ||||
| @@ -199,7 +199,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|             _reRoutesConfig = reRoutesConfig; | ||||
|             _mockConfig | ||||
|                 .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) | ||||
| @@ -209,7 +209,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|  | ||||
|         private void WhenICallTheFinder() | ||||
|         { | ||||
|             _result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod).Result; | ||||
|             _result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheFollowingIsReturned(DownstreamRoute expected) | ||||
|   | ||||
| @@ -15,12 +15,12 @@ namespace Ocelot.UnitTests.Services | ||||
| { | ||||
|     public class GetFileConfigurationTests | ||||
|     { | ||||
|         private readonly IGetFileConfiguration _getReRoutes; | ||||
|         private readonly IFileConfigurationProvider _getReRoutes; | ||||
|         private FileConfiguration _result; | ||||
| 
 | ||||
|         public GetFileConfigurationTests() | ||||
|         { | ||||
|             _getReRoutes = new GetFileConfiguration(); | ||||
|             _getReRoutes = new FileConfigurationProvider(); | ||||
|         } | ||||
| 
 | ||||
|         [Fact] | ||||
| @@ -74,7 +74,7 @@ namespace Ocelot.UnitTests.Services | ||||
| 
 | ||||
|         private void WhenIGetTheReRoutes() | ||||
|         { | ||||
|             _result = _getReRoutes.Invoke().Data; | ||||
|             _result = _getReRoutes.Get().Data; | ||||
|         } | ||||
| 
 | ||||
|         private void ThenTheFollowingIsReturned(FileConfiguration expected) | ||||
| @@ -29,6 +29,7 @@ | ||||
|   "runtimes": { | ||||
|     "win10-x64": {}, | ||||
|     "osx.10.11-x64":{}, | ||||
|     "osx.10.12-x64": {}, | ||||
|     "win7-x64": {} | ||||
|   }, | ||||
|   "frameworks": { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tom Gardham-Pallister
					Tom Gardham-Pallister