mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
refactoring configuration code so its not so crazy, still need to work on the creator class
This commit is contained in:
parent
707f1d6908
commit
2e6640c6ef
@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Ocelot.Library.Configuration;
|
|
||||||
|
|
||||||
namespace Ocelot.Library.Builder
|
namespace Ocelot.Library.Configuration.Builder
|
||||||
{
|
{
|
||||||
public class ReRouteBuilder
|
public class ReRouteBuilder
|
||||||
{
|
{
|
@ -0,0 +1,9 @@
|
|||||||
|
using Ocelot.Library.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Library.Configuration.Creator
|
||||||
|
{
|
||||||
|
public interface IOcelotConfigurationCreator
|
||||||
|
{
|
||||||
|
Response<IOcelotConfiguration> Create();
|
||||||
|
}
|
||||||
|
}
|
@ -1,127 +1,14 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Ocelot.Library.RequestBuilder;
|
|
||||||
|
|
||||||
namespace Ocelot.Library.Configuration
|
namespace Ocelot.Library.Configuration
|
||||||
{
|
{
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Yaml;
|
|
||||||
|
|
||||||
public class OcelotConfiguration : IOcelotConfiguration
|
public class OcelotConfiguration : IOcelotConfiguration
|
||||||
{
|
{
|
||||||
private readonly IOptions<YamlConfiguration> _options;
|
public OcelotConfiguration(List<ReRoute> reRoutes)
|
||||||
private readonly IConfigurationValidator _configurationValidator;
|
|
||||||
private readonly List<ReRoute> _reRoutes;
|
|
||||||
private const string RegExMatchEverything = ".*";
|
|
||||||
private const string RegExMatchEndString = "$";
|
|
||||||
private readonly IClaimToHeaderConfigurationParser _claimToHeaderConfigurationParser;
|
|
||||||
private readonly ILogger<OcelotConfiguration> _logger;
|
|
||||||
|
|
||||||
public OcelotConfiguration(IOptions<YamlConfiguration> options,
|
|
||||||
IConfigurationValidator configurationValidator,
|
|
||||||
IClaimToHeaderConfigurationParser claimToHeaderConfigurationParser,
|
|
||||||
ILogger<OcelotConfiguration> logger)
|
|
||||||
{
|
{
|
||||||
_options = options;
|
ReRoutes = reRoutes;
|
||||||
_configurationValidator = configurationValidator;
|
|
||||||
_claimToHeaderConfigurationParser = claimToHeaderConfigurationParser;
|
|
||||||
_logger = logger;
|
|
||||||
_reRoutes = new List<ReRoute>();
|
|
||||||
SetUpConfiguration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public List<ReRoute> ReRoutes { get; }
|
||||||
/// This method is meant to be tempoary to convert a yaml config to an ocelot config...probably wont keep this but we will see
|
|
||||||
/// will need a refactor at some point as its crap
|
|
||||||
/// </summary>
|
|
||||||
private void SetUpConfiguration()
|
|
||||||
{
|
|
||||||
var response = _configurationValidator.IsValid(_options.Value);
|
|
||||||
|
|
||||||
if (!response.IsError && !response.Data.IsError)
|
|
||||||
{
|
|
||||||
foreach (var reRoute in _options.Value.ReRoutes)
|
|
||||||
{
|
|
||||||
SetUpReRoute(reRoute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetUpReRoute(YamlReRoute reRoute)
|
|
||||||
{
|
|
||||||
var upstreamTemplate = reRoute.UpstreamTemplate;
|
|
||||||
|
|
||||||
var placeholders = new List<string>();
|
|
||||||
|
|
||||||
for (var i = 0; i < upstreamTemplate.Length; i++)
|
|
||||||
{
|
|
||||||
if (IsPlaceHolder(upstreamTemplate, i))
|
|
||||||
{
|
|
||||||
var postitionOfPlaceHolderClosingBracket = upstreamTemplate.IndexOf('}', i);
|
|
||||||
var difference = postitionOfPlaceHolderClosingBracket - i + 1;
|
|
||||||
var variableName = upstreamTemplate.Substring(i, difference);
|
|
||||||
placeholders.Add(variableName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var placeholder in placeholders)
|
|
||||||
{
|
|
||||||
upstreamTemplate = upstreamTemplate.Replace(placeholder, RegExMatchEverything);
|
|
||||||
}
|
|
||||||
|
|
||||||
upstreamTemplate = $"{upstreamTemplate}{RegExMatchEndString}";
|
|
||||||
|
|
||||||
var isAuthenticated = !string.IsNullOrEmpty(reRoute.AuthenticationOptions?.Provider);
|
|
||||||
|
|
||||||
if (isAuthenticated)
|
|
||||||
{
|
|
||||||
var authOptionsForRoute = new AuthenticationOptions(reRoute.AuthenticationOptions.Provider,
|
|
||||||
reRoute.AuthenticationOptions.ProviderRootUrl, reRoute.AuthenticationOptions.ScopeName,
|
|
||||||
reRoute.AuthenticationOptions.RequireHttps, reRoute.AuthenticationOptions.AdditionalScopes,
|
|
||||||
reRoute.AuthenticationOptions.ScopeSecret);
|
|
||||||
|
|
||||||
var configHeaders = GetHeadersToAddToRequest(reRoute);
|
|
||||||
|
|
||||||
_reRoutes.Add(new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate,
|
|
||||||
reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
|
|
||||||
authOptionsForRoute, configHeaders
|
|
||||||
));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_reRoutes.Add(new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate, reRoute.UpstreamHttpMethod,
|
|
||||||
upstreamTemplate, isAuthenticated, null, new List<ClaimToHeader>()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ClaimToHeader> GetHeadersToAddToRequest(YamlReRoute reRoute)
|
|
||||||
{
|
|
||||||
var configHeaders = new List<ClaimToHeader>();
|
|
||||||
|
|
||||||
foreach (var add in reRoute.AddHeadersToRequest)
|
|
||||||
{
|
|
||||||
var configurationHeader = _claimToHeaderConfigurationParser.Extract(add.Key, add.Value);
|
|
||||||
|
|
||||||
if (configurationHeader.IsError)
|
|
||||||
{
|
|
||||||
_logger.LogCritical(new EventId(1, "Application Failed to start"),
|
|
||||||
$"Unable to extract configuration for key: {add.Key} and value: {add.Value} your configuration file is incorrect");
|
|
||||||
|
|
||||||
throw new Exception(configurationHeader.Errors[0].Message);
|
|
||||||
}
|
|
||||||
configHeaders.Add(configurationHeader.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return configHeaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsPlaceHolder(string upstreamTemplate, int i)
|
|
||||||
{
|
|
||||||
return upstreamTemplate[i] == '{';
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ReRoute> ReRoutes => _reRoutes;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ using Ocelot.Library.Errors;
|
|||||||
using Ocelot.Library.RequestBuilder;
|
using Ocelot.Library.RequestBuilder;
|
||||||
using Ocelot.Library.Responses;
|
using Ocelot.Library.Responses;
|
||||||
|
|
||||||
namespace Ocelot.Library.Configuration
|
namespace Ocelot.Library.Configuration.Parser
|
||||||
{
|
{
|
||||||
public class ClaimToHeaderConfigurationParser : IClaimToHeaderConfigurationParser
|
public class ClaimToHeaderConfigurationParser : IClaimToHeaderConfigurationParser
|
||||||
{
|
{
|
@ -1,6 +1,6 @@
|
|||||||
using Ocelot.Library.Responses;
|
using Ocelot.Library.Responses;
|
||||||
|
|
||||||
namespace Ocelot.Library.Configuration
|
namespace Ocelot.Library.Configuration.Parser
|
||||||
{
|
{
|
||||||
public interface IClaimToHeaderConfigurationParser
|
public interface IClaimToHeaderConfigurationParser
|
||||||
{
|
{
|
@ -0,0 +1,9 @@
|
|||||||
|
using Ocelot.Library.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Library.Configuration.Provider
|
||||||
|
{
|
||||||
|
public interface IOcelotConfigurationProvider
|
||||||
|
{
|
||||||
|
Response<IOcelotConfiguration> Get();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
using Ocelot.Library.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Library.Configuration.Repository
|
||||||
|
{
|
||||||
|
public interface IOcelotConfigurationRepository
|
||||||
|
{
|
||||||
|
Response<IOcelotConfiguration> Get();
|
||||||
|
Response AddOrReplace(IOcelotConfiguration ocelotConfiguration);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
using Ocelot.Library.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Library.Configuration.Repository
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Register as singleton
|
||||||
|
/// </summary>
|
||||||
|
public class InMemoryOcelotConfigurationRepository : IOcelotConfigurationRepository
|
||||||
|
{
|
||||||
|
private static readonly object LockObject = new object();
|
||||||
|
|
||||||
|
private IOcelotConfiguration _ocelotConfiguration;
|
||||||
|
|
||||||
|
public Response<IOcelotConfiguration> Get()
|
||||||
|
{
|
||||||
|
return new OkResponse<IOcelotConfiguration>(_ocelotConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response AddOrReplace(IOcelotConfiguration ocelotConfiguration)
|
||||||
|
{
|
||||||
|
lock (LockObject)
|
||||||
|
{
|
||||||
|
_ocelotConfiguration = ocelotConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OkResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Ocelot.Library.Configuration.Creator;
|
||||||
|
using Ocelot.Library.Configuration.Parser;
|
||||||
|
using Ocelot.Library.Configuration.Repository;
|
||||||
|
using Ocelot.Library.Errors;
|
||||||
|
using Ocelot.Library.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Library.Configuration.Yaml
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Register as singleton
|
||||||
|
/// </summary>
|
||||||
|
public class YamlOcelotConfigurationCreator : IOcelotConfigurationCreator
|
||||||
|
{
|
||||||
|
private readonly IOptions<YamlConfiguration> _options;
|
||||||
|
private readonly IConfigurationValidator _configurationValidator;
|
||||||
|
private const string RegExMatchEverything = ".*";
|
||||||
|
private const string RegExMatchEndString = "$";
|
||||||
|
private readonly IClaimToHeaderConfigurationParser _claimToHeaderConfigurationParser;
|
||||||
|
private readonly ILogger<YamlOcelotConfigurationCreator> _logger;
|
||||||
|
|
||||||
|
public YamlOcelotConfigurationCreator(
|
||||||
|
IOptions<YamlConfiguration> options,
|
||||||
|
IConfigurationValidator configurationValidator,
|
||||||
|
IClaimToHeaderConfigurationParser claimToHeaderConfigurationParser,
|
||||||
|
ILogger<YamlOcelotConfigurationCreator> logger)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
_configurationValidator = configurationValidator;
|
||||||
|
_claimToHeaderConfigurationParser = claimToHeaderConfigurationParser;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response<IOcelotConfiguration> Create()
|
||||||
|
{
|
||||||
|
var config = SetUpConfiguration();
|
||||||
|
|
||||||
|
return new OkResponse<IOcelotConfiguration>(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method is meant to be tempoary to convert a yaml config to an ocelot config...probably wont keep this but we will see
|
||||||
|
/// will need a refactor at some point as its crap
|
||||||
|
/// </summary>
|
||||||
|
private IOcelotConfiguration SetUpConfiguration()
|
||||||
|
{
|
||||||
|
var response = _configurationValidator.IsValid(_options.Value);
|
||||||
|
|
||||||
|
var reRoutes = new List<ReRoute>();
|
||||||
|
|
||||||
|
if (!response.IsError && !response.Data.IsError)
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach (var yamlReRoute in _options.Value.ReRoutes)
|
||||||
|
{
|
||||||
|
var ocelotReRoute = SetUpReRoute(yamlReRoute);
|
||||||
|
reRoutes.Add(ocelotReRoute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OcelotConfiguration(reRoutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReRoute SetUpReRoute(YamlReRoute reRoute)
|
||||||
|
{
|
||||||
|
var upstreamTemplate = reRoute.UpstreamTemplate;
|
||||||
|
|
||||||
|
var placeholders = new List<string>();
|
||||||
|
|
||||||
|
for (var i = 0; i < upstreamTemplate.Length; i++)
|
||||||
|
{
|
||||||
|
if (IsPlaceHolder(upstreamTemplate, i))
|
||||||
|
{
|
||||||
|
var postitionOfPlaceHolderClosingBracket = upstreamTemplate.IndexOf('}', i);
|
||||||
|
var difference = postitionOfPlaceHolderClosingBracket - i + 1;
|
||||||
|
var variableName = upstreamTemplate.Substring(i, difference);
|
||||||
|
placeholders.Add(variableName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var placeholder in placeholders)
|
||||||
|
{
|
||||||
|
upstreamTemplate = upstreamTemplate.Replace(placeholder, RegExMatchEverything);
|
||||||
|
}
|
||||||
|
|
||||||
|
upstreamTemplate = $"{upstreamTemplate}{RegExMatchEndString}";
|
||||||
|
|
||||||
|
var isAuthenticated = !string.IsNullOrEmpty(reRoute.AuthenticationOptions?.Provider);
|
||||||
|
|
||||||
|
if (isAuthenticated)
|
||||||
|
{
|
||||||
|
var authOptionsForRoute = new AuthenticationOptions(reRoute.AuthenticationOptions.Provider,
|
||||||
|
reRoute.AuthenticationOptions.ProviderRootUrl, reRoute.AuthenticationOptions.ScopeName,
|
||||||
|
reRoute.AuthenticationOptions.RequireHttps, reRoute.AuthenticationOptions.AdditionalScopes,
|
||||||
|
reRoute.AuthenticationOptions.ScopeSecret);
|
||||||
|
|
||||||
|
var configHeaders = GetHeadersToAddToRequest(reRoute);
|
||||||
|
|
||||||
|
return new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate,
|
||||||
|
reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
|
||||||
|
authOptionsForRoute, configHeaders
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate, reRoute.UpstreamHttpMethod,
|
||||||
|
upstreamTemplate, isAuthenticated, null, new List<ClaimToHeader>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ClaimToHeader> GetHeadersToAddToRequest(YamlReRoute reRoute)
|
||||||
|
{
|
||||||
|
var configHeaders = new List<ClaimToHeader>();
|
||||||
|
|
||||||
|
foreach (var add in reRoute.AddHeadersToRequest)
|
||||||
|
{
|
||||||
|
var configurationHeader = _claimToHeaderConfigurationParser.Extract(add.Key, add.Value);
|
||||||
|
|
||||||
|
if (configurationHeader.IsError)
|
||||||
|
{
|
||||||
|
_logger.LogCritical(new EventId(1, "Application Failed to start"),
|
||||||
|
$"Unable to extract configuration for key: {add.Key} and value: {add.Value} your configuration file is incorrect");
|
||||||
|
|
||||||
|
throw new Exception(configurationHeader.Errors[0].Message);
|
||||||
|
}
|
||||||
|
configHeaders.Add(configurationHeader.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return configHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsPlaceHolder(string upstreamTemplate, int i)
|
||||||
|
{
|
||||||
|
return upstreamTemplate[i] == '{';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
using Ocelot.Library.Configuration.Creator;
|
||||||
|
using Ocelot.Library.Configuration.Provider;
|
||||||
|
using Ocelot.Library.Configuration.Repository;
|
||||||
|
using Ocelot.Library.Responses;
|
||||||
|
|
||||||
|
namespace Ocelot.Library.Configuration.Yaml
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Register as singleton
|
||||||
|
/// </summary>
|
||||||
|
public class YamlOcelotConfigurationProvider : IOcelotConfigurationProvider
|
||||||
|
{
|
||||||
|
private readonly IOcelotConfigurationRepository _repo;
|
||||||
|
private readonly IOcelotConfigurationCreator _creator;
|
||||||
|
|
||||||
|
public YamlOcelotConfigurationProvider(IOcelotConfigurationRepository repo,
|
||||||
|
IOcelotConfigurationCreator creator)
|
||||||
|
{
|
||||||
|
_repo = repo;
|
||||||
|
_creator = creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response<IOcelotConfiguration> Get()
|
||||||
|
{
|
||||||
|
var config = _repo.Get();
|
||||||
|
|
||||||
|
if (config.IsError)
|
||||||
|
{
|
||||||
|
return new ErrorResponse<IOcelotConfiguration>(config.Errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.Data == null)
|
||||||
|
{
|
||||||
|
var configuration = _creator.Create();
|
||||||
|
|
||||||
|
if (configuration.IsError)
|
||||||
|
{
|
||||||
|
return new ErrorResponse<IOcelotConfiguration>(configuration.Errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
_repo.AddOrReplace(configuration.Data);
|
||||||
|
|
||||||
|
return new OkResponse<IOcelotConfiguration>(configuration.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OkResponse<IOcelotConfiguration>(config.Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,9 @@
|
|||||||
namespace Ocelot.Library.DependencyInjection
|
using Ocelot.Library.Configuration.Creator;
|
||||||
|
using Ocelot.Library.Configuration.Parser;
|
||||||
|
using Ocelot.Library.Configuration.Provider;
|
||||||
|
using Ocelot.Library.Configuration.Repository;
|
||||||
|
|
||||||
|
namespace Ocelot.Library.DependencyInjection
|
||||||
{
|
{
|
||||||
using Authentication;
|
using Authentication;
|
||||||
using Configuration;
|
using Configuration;
|
||||||
@ -16,22 +21,30 @@
|
|||||||
|
|
||||||
public static class ServiceCollectionExtensions
|
public static class ServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddOcelot(this IServiceCollection services, IConfigurationRoot configurationRoot)
|
public static IServiceCollection AddOcelotYamlConfiguration(this IServiceCollection services, IConfigurationRoot configurationRoot)
|
||||||
{
|
{
|
||||||
// framework services
|
|
||||||
services.AddOptions();
|
|
||||||
services.AddMvcCore().AddJsonFormatters();
|
|
||||||
services.AddLogging();
|
|
||||||
|
|
||||||
// initial configuration from yaml
|
// initial configuration from yaml
|
||||||
services.Configure<YamlConfiguration>(configurationRoot);
|
services.Configure<YamlConfiguration>(configurationRoot);
|
||||||
|
|
||||||
// ocelot services.
|
// ocelot services.
|
||||||
services.AddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();
|
services.AddSingleton<IOcelotConfigurationCreator, YamlOcelotConfigurationCreator>();
|
||||||
services.AddSingleton<IClaimsParser, ClaimsParser>();
|
services.AddSingleton<IOcelotConfigurationProvider, YamlOcelotConfigurationProvider>();
|
||||||
|
services.AddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
|
||||||
services.AddSingleton<IClaimToHeaderConfigurationParser, ClaimToHeaderConfigurationParser>();
|
services.AddSingleton<IClaimToHeaderConfigurationParser, ClaimToHeaderConfigurationParser>();
|
||||||
services.AddSingleton<IConfigurationValidator, ConfigurationValidator>();
|
services.AddSingleton<IConfigurationValidator, ConfigurationValidator>();
|
||||||
services.AddSingleton<IOcelotConfiguration, OcelotConfiguration>();
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddOcelot(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
// framework services
|
||||||
|
services.AddMvcCore().AddJsonFormatters();
|
||||||
|
services.AddLogging();
|
||||||
|
|
||||||
|
// ocelot services.
|
||||||
|
services.AddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();
|
||||||
|
services.AddSingleton<IClaimsParser, ClaimsParser>();
|
||||||
services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
||||||
services.AddSingleton<ITemplateVariableNameAndValueFinder, TemplateVariableNameAndValueFinder>();
|
services.AddSingleton<ITemplateVariableNameAndValueFinder, TemplateVariableNameAndValueFinder>();
|
||||||
services.AddSingleton<IDownstreamUrlTemplateVariableReplacer, DownstreamUrlTemplateVariableReplacer>();
|
services.AddSingleton<IDownstreamUrlTemplateVariableReplacer, DownstreamUrlTemplateVariableReplacer>();
|
||||||
|
@ -1,29 +1,31 @@
|
|||||||
namespace Ocelot.Library.DownstreamRouteFinder
|
using System;
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Configuration;
|
using Ocelot.Library.Configuration.Provider;
|
||||||
using Errors;
|
using Ocelot.Library.Errors;
|
||||||
using Responses;
|
using Ocelot.Library.Responses;
|
||||||
using UrlMatcher;
|
using Ocelot.Library.UrlMatcher;
|
||||||
|
|
||||||
|
namespace Ocelot.Library.DownstreamRouteFinder
|
||||||
|
{
|
||||||
public class DownstreamRouteFinder : IDownstreamRouteFinder
|
public class DownstreamRouteFinder : IDownstreamRouteFinder
|
||||||
{
|
{
|
||||||
private readonly IOcelotConfiguration _configuration;
|
private readonly IOcelotConfigurationProvider _configProvider;
|
||||||
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
|
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
|
||||||
private readonly ITemplateVariableNameAndValueFinder _templateVariableNameAndValueFinder;
|
private readonly ITemplateVariableNameAndValueFinder _templateVariableNameAndValueFinder;
|
||||||
|
|
||||||
public DownstreamRouteFinder(IOcelotConfiguration configuration, IUrlPathToUrlTemplateMatcher urlMatcher, ITemplateVariableNameAndValueFinder templateVariableNameAndValueFinder)
|
public DownstreamRouteFinder(IOcelotConfigurationProvider configProvider, IUrlPathToUrlTemplateMatcher urlMatcher, ITemplateVariableNameAndValueFinder templateVariableNameAndValueFinder)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configProvider = configProvider;
|
||||||
_urlMatcher = urlMatcher;
|
_urlMatcher = urlMatcher;
|
||||||
_templateVariableNameAndValueFinder = templateVariableNameAndValueFinder;
|
_templateVariableNameAndValueFinder = templateVariableNameAndValueFinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
|
public Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
|
||||||
{
|
{
|
||||||
foreach (var template in _configuration.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod, upstreamHttpMethod, StringComparison.CurrentCultureIgnoreCase)))
|
var configuration = _configProvider.Get();
|
||||||
|
|
||||||
|
foreach (var template in configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod, upstreamHttpMethod, StringComparison.CurrentCultureIgnoreCase)))
|
||||||
{
|
{
|
||||||
var urlMatch = _urlMatcher.Match(upstreamUrlPath, template.UpstreamTemplatePattern);
|
var urlMatch = _urlMatcher.Match(upstreamUrlPath, template.UpstreamTemplatePattern);
|
||||||
|
|
||||||
|
@ -28,7 +28,8 @@ namespace Ocelot
|
|||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddOcelot(Configuration);
|
services.AddOcelotYamlConfiguration(Configuration);
|
||||||
|
services.AddOcelot();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Library.Configuration;
|
||||||
|
using Ocelot.Library.Configuration.Builder;
|
||||||
|
using Ocelot.Library.Configuration.Repository;
|
||||||
|
using Ocelot.Library.Responses;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Configuration
|
||||||
|
{
|
||||||
|
public class InMemoryConfigurationRepositoryTests
|
||||||
|
{
|
||||||
|
private readonly InMemoryOcelotConfigurationRepository _repo;
|
||||||
|
private IOcelotConfiguration _config;
|
||||||
|
private Response _result;
|
||||||
|
private Response<IOcelotConfiguration> _getResult;
|
||||||
|
|
||||||
|
public InMemoryConfigurationRepositoryTests()
|
||||||
|
{
|
||||||
|
_repo = new InMemoryOcelotConfigurationRepository();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void can_add_config()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenTheConfigurationIs(new FakeConfig("initial")))
|
||||||
|
.When(x => x.WhenIAddOrReplaceTheConfig())
|
||||||
|
.Then(x => x.ThenNoErrorsAreReturned())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void can_get_config()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenThereIsASavedConfiguration())
|
||||||
|
.When(x => x.WhenIGetTheConfiguration())
|
||||||
|
.Then(x => x.ThenTheConfigurationIsReturned())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// long runnnig unit test to make sure repo thread safeok on
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public void repo_is_thread_safe()
|
||||||
|
{
|
||||||
|
var tasks = new Task[100000];
|
||||||
|
for (int i = 0; i < tasks.Length; i++)
|
||||||
|
{
|
||||||
|
tasks[i] = Fire();
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.WaitAll(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Fire()
|
||||||
|
{
|
||||||
|
var taskGuid = Guid.NewGuid().ToString();
|
||||||
|
_repo.AddOrReplace(new FakeConfig(taskGuid));
|
||||||
|
var configuration = _repo.Get();
|
||||||
|
configuration.Data.ReRoutes[0].DownstreamTemplate.ShouldBe(taskGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheConfigurationIsReturned()
|
||||||
|
{
|
||||||
|
_getResult.Data.ReRoutes[0].DownstreamTemplate.ShouldBe("initial");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIGetTheConfiguration()
|
||||||
|
{
|
||||||
|
_getResult = _repo.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsASavedConfiguration()
|
||||||
|
{
|
||||||
|
GivenTheConfigurationIs(new FakeConfig("initial"));
|
||||||
|
WhenIAddOrReplaceTheConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheConfigurationIs(IOcelotConfiguration config)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIAddOrReplaceTheConfig()
|
||||||
|
{
|
||||||
|
_result = _repo.AddOrReplace(_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenNoErrorsAreReturned()
|
||||||
|
{
|
||||||
|
_result.IsError.ShouldBeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeConfig : IOcelotConfiguration
|
||||||
|
{
|
||||||
|
private readonly string _downstreamTemplate;
|
||||||
|
|
||||||
|
public FakeConfig(string downstreamTemplate)
|
||||||
|
{
|
||||||
|
_downstreamTemplate = downstreamTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ReRoute> ReRoutes => new List<ReRoute>
|
||||||
|
{
|
||||||
|
new ReRouteBuilder().WithDownstreamTemplate(_downstreamTemplate).Build()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,9 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using Ocelot.Library.Configuration.Builder;
|
||||||
|
using Ocelot.Library.Configuration.Parser;
|
||||||
|
using Ocelot.Library.Configuration.Repository;
|
||||||
using Ocelot.Library.RequestBuilder;
|
using Ocelot.Library.RequestBuilder;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
@ -9,26 +12,28 @@ using Xunit;
|
|||||||
|
|
||||||
namespace Ocelot.UnitTests.Configuration
|
namespace Ocelot.UnitTests.Configuration
|
||||||
{
|
{
|
||||||
using Library.Builder;
|
|
||||||
using Library.Configuration;
|
using Library.Configuration;
|
||||||
using Library.Configuration.Yaml;
|
using Library.Configuration.Yaml;
|
||||||
using Library.Responses;
|
using Library.Responses;
|
||||||
|
|
||||||
public class OcelotConfigurationTests
|
public class YamlConfigurationCreatorTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IOptions<YamlConfiguration>> _yamlConfig;
|
private readonly Mock<IOptions<YamlConfiguration>> _yamlConfig;
|
||||||
private readonly Mock<IConfigurationValidator> _validator;
|
private readonly Mock<IConfigurationValidator> _validator;
|
||||||
private OcelotConfiguration _config;
|
private Response<IOcelotConfiguration> _config;
|
||||||
private YamlConfiguration _yamlConfiguration;
|
private YamlConfiguration _yamlConfiguration;
|
||||||
private readonly Mock<IClaimToHeaderConfigurationParser> _configExtractor;
|
private readonly Mock<IClaimToHeaderConfigurationParser> _configParser;
|
||||||
private readonly Mock<ILogger<OcelotConfiguration>> _logger;
|
private readonly Mock<ILogger<YamlOcelotConfigurationCreator>> _logger;
|
||||||
|
private readonly YamlOcelotConfigurationCreator _ocelotConfigurationCreator;
|
||||||
|
|
||||||
public OcelotConfigurationTests()
|
public YamlConfigurationCreatorTests()
|
||||||
{
|
{
|
||||||
_logger = new Mock<ILogger<OcelotConfiguration>>();
|
_logger = new Mock<ILogger<YamlOcelotConfigurationCreator>>();
|
||||||
_configExtractor = new Mock<IClaimToHeaderConfigurationParser>();
|
_configParser = new Mock<IClaimToHeaderConfigurationParser>();
|
||||||
_validator = new Mock<IConfigurationValidator>();
|
_validator = new Mock<IConfigurationValidator>();
|
||||||
_yamlConfig = new Mock<IOptions<YamlConfiguration>>();
|
_yamlConfig = new Mock<IOptions<YamlConfiguration>>();
|
||||||
|
_ocelotConfigurationCreator = new YamlOcelotConfigurationCreator(
|
||||||
|
_yamlConfig.Object, _validator.Object, _configParser.Object, _logger.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -47,7 +52,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.And(x => x.GivenTheYamlConfigIsValid())
|
.And(x => x.GivenTheYamlConfigIsValid())
|
||||||
.When(x => x.WhenIInstanciateTheOcelotConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||||
{
|
{
|
||||||
new ReRouteBuilder()
|
new ReRouteBuilder()
|
||||||
@ -109,7 +114,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}))
|
}))
|
||||||
.And(x => x.GivenTheYamlConfigIsValid())
|
.And(x => x.GivenTheYamlConfigIsValid())
|
||||||
.And(x => x.GivenTheConfigHeaderExtractorReturns(new ClaimToHeader("CustomerId", "CustomerId", "", 0)))
|
.And(x => x.GivenTheConfigHeaderExtractorReturns(new ClaimToHeader("CustomerId", "CustomerId", "", 0)))
|
||||||
.When(x => x.WhenIInstanciateTheOcelotConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(expected))
|
.Then(x => x.ThenTheReRoutesAre(expected))
|
||||||
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -117,7 +122,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void GivenTheConfigHeaderExtractorReturns(ClaimToHeader expected)
|
private void GivenTheConfigHeaderExtractorReturns(ClaimToHeader expected)
|
||||||
{
|
{
|
||||||
_configExtractor
|
_configParser
|
||||||
.Setup(x => x.Extract(It.IsAny<string>(), It.IsAny<string>()))
|
.Setup(x => x.Extract(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns(new OkResponse<ClaimToHeader>(expected));
|
.Returns(new OkResponse<ClaimToHeader>(expected));
|
||||||
}
|
}
|
||||||
@ -162,7 +167,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.And(x => x.GivenTheYamlConfigIsValid())
|
.And(x => x.GivenTheYamlConfigIsValid())
|
||||||
.When(x => x.WhenIInstanciateTheOcelotConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(expected))
|
.Then(x => x.ThenTheReRoutesAre(expected))
|
||||||
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
.And(x => x.ThenTheAuthenticationOptionsAre(expected))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
@ -184,7 +189,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.And(x => x.GivenTheYamlConfigIsValid())
|
.And(x => x.GivenTheYamlConfigIsValid())
|
||||||
.When(x => x.WhenIInstanciateTheOcelotConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||||
{
|
{
|
||||||
new ReRouteBuilder()
|
new ReRouteBuilder()
|
||||||
@ -213,7 +218,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.And(x => x.GivenTheYamlConfigIsValid())
|
.And(x => x.GivenTheYamlConfigIsValid())
|
||||||
.When(x => x.WhenIInstanciateTheOcelotConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||||
{
|
{
|
||||||
new ReRouteBuilder()
|
new ReRouteBuilder()
|
||||||
@ -242,7 +247,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.And(x => x.GivenTheYamlConfigIsValid())
|
.And(x => x.GivenTheYamlConfigIsValid())
|
||||||
.When(x => x.WhenIInstanciateTheOcelotConfig())
|
.When(x => x.WhenICreateTheConfig())
|
||||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||||
{
|
{
|
||||||
new ReRouteBuilder()
|
new ReRouteBuilder()
|
||||||
@ -270,17 +275,16 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.Returns(_yamlConfiguration);
|
.Returns(_yamlConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WhenIInstanciateTheOcelotConfig()
|
private void WhenICreateTheConfig()
|
||||||
{
|
{
|
||||||
_config = new OcelotConfiguration(_yamlConfig.Object, _validator.Object,
|
_config = _ocelotConfigurationCreator.Create();
|
||||||
_configExtractor.Object, _logger.Object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
|
private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _config.ReRoutes.Count; i++)
|
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
||||||
{
|
{
|
||||||
var result = _config.ReRoutes[i];
|
var result = _config.Data.ReRoutes[i];
|
||||||
var expected = expectedReRoutes[i];
|
var expected = expectedReRoutes[i];
|
||||||
|
|
||||||
result.DownstreamTemplate.ShouldBe(expected.DownstreamTemplate);
|
result.DownstreamTemplate.ShouldBe(expected.DownstreamTemplate);
|
||||||
@ -292,9 +296,9 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void ThenTheAuthenticationOptionsAre(List<ReRoute> expectedReRoutes)
|
private void ThenTheAuthenticationOptionsAre(List<ReRoute> expectedReRoutes)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _config.ReRoutes.Count; i++)
|
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
||||||
{
|
{
|
||||||
var result = _config.ReRoutes[i].AuthenticationOptions;
|
var result = _config.Data.ReRoutes[i].AuthenticationOptions;
|
||||||
var expected = expectedReRoutes[i].AuthenticationOptions;
|
var expected = expectedReRoutes[i].AuthenticationOptions;
|
||||||
|
|
||||||
result.AdditionalScopes.ShouldBe(expected.AdditionalScopes);
|
result.AdditionalScopes.ShouldBe(expected.AdditionalScopes);
|
@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Library.Configuration;
|
||||||
|
using Ocelot.Library.Configuration.Creator;
|
||||||
|
using Ocelot.Library.Configuration.Provider;
|
||||||
|
using Ocelot.Library.Configuration.Repository;
|
||||||
|
using Ocelot.Library.Configuration.Yaml;
|
||||||
|
using Ocelot.Library.Errors;
|
||||||
|
using Ocelot.Library.Responses;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Configuration
|
||||||
|
{
|
||||||
|
public class YamlConfigurationProviderTests
|
||||||
|
{
|
||||||
|
private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider;
|
||||||
|
private readonly Mock<IOcelotConfigurationRepository> _configurationRepository;
|
||||||
|
private readonly Mock<IOcelotConfigurationCreator> _creator;
|
||||||
|
private Response<IOcelotConfiguration> _result;
|
||||||
|
|
||||||
|
public YamlConfigurationProviderTests()
|
||||||
|
{
|
||||||
|
_creator = new Mock<IOcelotConfigurationCreator>();
|
||||||
|
_configurationRepository = new Mock<IOcelotConfigurationRepository>();
|
||||||
|
_ocelotConfigurationProvider = new YamlOcelotConfigurationProvider(_configurationRepository.Object, _creator.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_get_config()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>()))))
|
||||||
|
.When(x => x.WhenIGetTheConfig())
|
||||||
|
.Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>()))))
|
||||||
|
.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>()))))
|
||||||
|
.When(x => x.WhenIGetTheConfig())
|
||||||
|
.Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>()))))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_error()
|
||||||
|
{
|
||||||
|
this.Given(x => x.GivenTheRepoReturns(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
[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())
|
||||||
|
.Returns(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheRepoReturns(Response<IOcelotConfiguration> config)
|
||||||
|
{
|
||||||
|
_configurationRepository
|
||||||
|
.Setup(x => x.Get())
|
||||||
|
.Returns(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenIGetTheConfig()
|
||||||
|
{
|
||||||
|
_result = _ocelotConfigurationProvider.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)
|
||||||
|
{
|
||||||
|
_result.IsError.ShouldBe(expected.IsError);
|
||||||
|
}
|
||||||
|
|
||||||
|
class AnyError : Error
|
||||||
|
{
|
||||||
|
public AnyError()
|
||||||
|
: base("blamo", OcelotErrorCode.UnknownError)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using Ocelot.Library.Configuration.Builder;
|
||||||
|
using Ocelot.Library.Configuration.Provider;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||||
{
|
{
|
||||||
using Library.Builder;
|
|
||||||
using Library.Configuration;
|
using Library.Configuration;
|
||||||
using Library.DownstreamRouteFinder;
|
using Library.DownstreamRouteFinder;
|
||||||
using Library.Responses;
|
using Library.Responses;
|
||||||
@ -15,7 +16,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
public class DownstreamRouteFinderTests
|
public class DownstreamRouteFinderTests
|
||||||
{
|
{
|
||||||
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
|
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
|
||||||
private readonly Mock<IOcelotConfiguration> _mockConfig;
|
private readonly Mock<IOcelotConfigurationProvider> _mockConfig;
|
||||||
private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher;
|
private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher;
|
||||||
private readonly Mock<ITemplateVariableNameAndValueFinder> _finder;
|
private readonly Mock<ITemplateVariableNameAndValueFinder> _finder;
|
||||||
private string _upstreamUrlPath;
|
private string _upstreamUrlPath;
|
||||||
@ -26,7 +27,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
|
|
||||||
public DownstreamRouteFinderTests()
|
public DownstreamRouteFinderTests()
|
||||||
{
|
{
|
||||||
_mockConfig = new Mock<IOcelotConfiguration>();
|
_mockConfig = new Mock<IOcelotConfigurationProvider>();
|
||||||
_mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>();
|
_mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>();
|
||||||
_finder = new Mock<ITemplateVariableNameAndValueFinder>();
|
_finder = new Mock<ITemplateVariableNameAndValueFinder>();
|
||||||
_downstreamRouteFinder = new DownstreamRouteFinder(_mockConfig.Object, _mockMatcher.Object, _finder.Object);
|
_downstreamRouteFinder = new DownstreamRouteFinder(_mockConfig.Object, _mockMatcher.Object, _finder.Object);
|
||||||
@ -157,8 +158,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
{
|
{
|
||||||
_reRoutesConfig = reRoutesConfig;
|
_reRoutesConfig = reRoutesConfig;
|
||||||
_mockConfig
|
_mockConfig
|
||||||
.Setup(x => x.ReRoutes)
|
.Setup(x => x.Get())
|
||||||
.Returns(_reRoutesConfig);
|
.Returns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
|
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
|
||||||
|
@ -6,13 +6,13 @@ using Microsoft.AspNetCore.Hosting;
|
|||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using Ocelot.Library.Configuration.Builder;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Middleware
|
namespace Ocelot.UnitTests.Middleware
|
||||||
{
|
{
|
||||||
using Library.Authentication;
|
using Library.Authentication;
|
||||||
using Library.Builder;
|
|
||||||
using Library.DownstreamRouteFinder;
|
using Library.DownstreamRouteFinder;
|
||||||
using Library.Middleware;
|
using Library.Middleware;
|
||||||
using Library.Repository;
|
using Library.Repository;
|
||||||
|
@ -6,12 +6,12 @@ using Microsoft.AspNetCore.Hosting;
|
|||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using Ocelot.Library.Configuration.Builder;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Middleware
|
namespace Ocelot.UnitTests.Middleware
|
||||||
{
|
{
|
||||||
using Library.Builder;
|
|
||||||
using Library.DownstreamRouteFinder;
|
using Library.DownstreamRouteFinder;
|
||||||
using Library.Middleware;
|
using Library.Middleware;
|
||||||
using Library.Repository;
|
using Library.Repository;
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
namespace Ocelot.UnitTests.Middleware
|
using Ocelot.Library.Configuration.Builder;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Middleware
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using Library.Builder;
|
|
||||||
using Library.DownstreamRouteFinder;
|
using Library.DownstreamRouteFinder;
|
||||||
using Library.Middleware;
|
using Library.Middleware;
|
||||||
using Library.Repository;
|
using Library.Repository;
|
||||||
|
@ -7,8 +7,8 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Library.Builder;
|
|
||||||
using Ocelot.Library.Configuration;
|
using Ocelot.Library.Configuration;
|
||||||
|
using Ocelot.Library.Configuration.Builder;
|
||||||
using Ocelot.Library.DownstreamRouteFinder;
|
using Ocelot.Library.DownstreamRouteFinder;
|
||||||
using Ocelot.Library.Middleware;
|
using Ocelot.Library.Middleware;
|
||||||
using Ocelot.Library.Repository;
|
using Ocelot.Library.Repository;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Ocelot.Library.Configuration;
|
using Ocelot.Library.Configuration;
|
||||||
|
using Ocelot.Library.Configuration.Parser;
|
||||||
using Ocelot.Library.Errors;
|
using Ocelot.Library.Errors;
|
||||||
using Ocelot.Library.RequestBuilder;
|
using Ocelot.Library.RequestBuilder;
|
||||||
using Ocelot.Library.Responses;
|
using Ocelot.Library.Responses;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Ocelot.Library.Configuration.Builder;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.UrlTemplateReplacer
|
namespace Ocelot.UnitTests.UrlTemplateReplacer
|
||||||
{
|
{
|
||||||
using Library.Builder;
|
|
||||||
using Library.DownstreamRouteFinder;
|
using Library.DownstreamRouteFinder;
|
||||||
using Library.Responses;
|
using Library.Responses;
|
||||||
using Library.UrlMatcher;
|
using Library.UrlMatcher;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user