mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 15:10:50 +08:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/develop' into feature/AddStyleCopAnalyzers
# Conflicts: # test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj # test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj
This commit is contained in:
		@@ -1,6 +1,11 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Authentication
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Authentication
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.IO;
 | 
			
		||||
    using System.Text;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
@@ -8,6 +13,7 @@
 | 
			
		||||
    using Ocelot.Authentication.Middleware;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
@@ -15,56 +21,75 @@
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class AuthenticationMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class AuthenticationMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private OkResponse<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private AuthenticationMiddleware _middleware;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _factory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
 | 
			
		||||
        public AuthenticationMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _factory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _factory.Setup(x => x.CreateLogger<AuthenticationMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_next_middleware_if_route_is_not_authenticated()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamRouteIs(
 | 
			
		||||
                    new DownstreamRoute(
 | 
			
		||||
                    new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                    new ReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build())))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheUserIsAuthenticated())
 | 
			
		||||
            this.Given(x => GivenTheDownStreamRouteIs(
 | 
			
		||||
                    new DownstreamReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build()))
 | 
			
		||||
                .And(x => GivenTheTestServerPipelineIsConfigured())
 | 
			
		||||
                .When(x => WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => ThenTheUserIsAuthenticated())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private  void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            _next = async (context) => {
 | 
			
		||||
                byte[] byteArray = Encoding.ASCII.GetBytes("The user is authenticated");
 | 
			
		||||
                MemoryStream stream = new MemoryStream(byteArray);
 | 
			
		||||
                context.HttpContext.Response.Body = stream;
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new AuthenticationMiddleware(_next, _factory.Object);
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        private void GivenTheTestServerPipelineIsConfigured()
 | 
			
		||||
        {
 | 
			
		||||
            app.UseAuthenticationMiddleware();
 | 
			
		||||
 | 
			
		||||
            app.Run(async x =>
 | 
			
		||||
            {
 | 
			
		||||
                await x.Response.WriteAsync("The user is authenticated");
 | 
			
		||||
            });
 | 
			
		||||
            _next = async (context) => {
 | 
			
		||||
                byte[] byteArray = Encoding.ASCII.GetBytes("The user is authenticated");
 | 
			
		||||
                MemoryStream stream = new MemoryStream(byteArray);
 | 
			
		||||
                context.HttpContext.Response.Body = stream;
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheUserIsAuthenticated()
 | 
			
		||||
        {
 | 
			
		||||
            var content = ResponseMessage.Content.ReadAsStringAsync().Result;
 | 
			
		||||
            var content = _downstreamContext.HttpContext.Response.Body.AsString(); 
 | 
			
		||||
            content.ShouldBe("The user is authenticated");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamReRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class StreamExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static string AsString(this Stream stream)
 | 
			
		||||
        {
 | 
			
		||||
            using(var reader = new StreamReader(stream))
 | 
			
		||||
            {
 | 
			
		||||
                string text = reader.ReadToEnd();
 | 
			
		||||
                return text;
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Authorization
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Authorization
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Security.Claims;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Authorisation;
 | 
			
		||||
    using Ocelot.Authorisation.Middleware;
 | 
			
		||||
@@ -14,55 +14,57 @@
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
 | 
			
		||||
    public class AuthorisationMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class AuthorisationMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IClaimsAuthoriser> _authService;
 | 
			
		||||
        private readonly Mock<IScopesAuthoriser> _authScopesService;
 | 
			
		||||
        private OkResponse<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private readonly AuthorisationMiddleware _middleware;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public AuthorisationMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _authService = new Mock<IClaimsAuthoriser>();
 | 
			
		||||
            _authScopesService = new Mock<IScopesAuthoriser>();
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<AuthorisationMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new AuthorisationMiddleware(_next, _authService.Object, _authScopesService.Object, _loggerFactory.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_authorisation_service()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamRouteIs(new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                new DownstreamReRouteBuilder()
 | 
			
		||||
                    .WithIsAuthorised(true)
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())))
 | 
			
		||||
                    .Build()))
 | 
			
		||||
                .And(x => x.GivenTheAuthServiceReturns(new OkResponse<bool>(true)))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheAuthServiceIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_authService.Object);
 | 
			
		||||
            services.AddSingleton(_authScopesService.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(List<PlaceholderNameAndValue> templatePlaceholderNameAndValues, DownstreamReRoute downstreamReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseAuthorisationMiddleware();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = templatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamReRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheAuthServiceReturns(Response<bool> expected)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Cache
 | 
			
		||||
{
 | 
			
		||||
@@ -22,20 +24,37 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
 | 
			
		||||
    public class OutputCacheMiddlewareRealCacheTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class OutputCacheMiddlewareRealCacheTests
 | 
			
		||||
    {
 | 
			
		||||
        private IOcelotCache<CachedResponse> _cacheManager;
 | 
			
		||||
        private CachedResponse _response;
 | 
			
		||||
        private IRequestScopedDataRepository _repo;
 | 
			
		||||
        private OutputCacheMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private IRegionCreator _regionCreator;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
 | 
			
		||||
        public OutputCacheMiddlewareRealCacheTests()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
 | 
			
		||||
                .Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _regionCreator = new RegionCreator();
 | 
			
		||||
            var cacheManagerOutputCache = CacheFactory.Build<CachedResponse>("OcelotOutputCache", x =>
 | 
			
		||||
            {
 | 
			
		||||
                x.WithDictionaryHandle();
 | 
			
		||||
            });
 | 
			
		||||
            _cacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _downstreamContext.DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123");
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing..
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager, _regionCreator);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -54,12 +73,16 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
            this.Given(x => x.GivenResponseIsNotCached(response))
 | 
			
		||||
                .And(x => x.GivenTheDownstreamRouteIs())
 | 
			
		||||
                .And(x => x.GivenThereAreNoErrors())
 | 
			
		||||
                .And(x => x.GivenThereIsADownstreamUrl())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheContentTypeHeaderIsCached())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheContentTypeHeaderIsCached()
 | 
			
		||||
        {
 | 
			
		||||
            var result = _cacheManager.Get("GET-https://some.url/blah?abcd=123", "kanken");
 | 
			
		||||
@@ -67,65 +90,25 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
            header.First().ShouldBe("application/json");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            var cacheManagerOutputCache = CacheFactory.Build<CachedResponse>("OcelotOutputCache", x =>
 | 
			
		||||
            {
 | 
			
		||||
                x.WithDictionaryHandle();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            _cacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
 | 
			
		||||
 | 
			
		||||
            services.AddSingleton<ICacheManager<CachedResponse>>(cacheManagerOutputCache);
 | 
			
		||||
            services.AddSingleton<IOcelotCache<CachedResponse>>(_cacheManager);
 | 
			
		||||
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_cacheManager);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            services.AddSingleton<IRegionCreator, RegionCreator>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseOutputCacheMiddleware();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenResponseIsNotCached(HttpResponseMessage message)
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
 | 
			
		||||
                .Returns(new OkResponse<HttpResponseMessage>(message));
 | 
			
		||||
            _downstreamContext.DownstreamResponse = message;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamRouteIs()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithIsCached(true)
 | 
			
		||||
                .WithCacheOptions(new CacheOptions(100, "kanken"))
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereAreNoErrors()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<bool>("OcelotMiddlewareError"))
 | 
			
		||||
                .Returns(new OkResponse<bool>(false));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsADownstreamUrl()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<string>("DownstreamUrl"))
 | 
			
		||||
                .Returns(new OkResponse<string>("anything"));
 | 
			
		||||
            _downstreamContext.Errors = new List<Error>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
using System.Net;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Cache
 | 
			
		||||
{
 | 
			
		||||
@@ -6,6 +8,7 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Cache;
 | 
			
		||||
@@ -13,26 +16,37 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class OutputCacheMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class OutputCacheMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
 | 
			
		||||
        private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;    
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private OutputCacheMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private CachedResponse _response;
 | 
			
		||||
        private IRegionCreator _regionCreator;
 | 
			
		||||
 | 
			
		||||
        public OutputCacheMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _cacheManager = new Mock<IOcelotCache<CachedResponse>>();
 | 
			
		||||
            _regionCreator = new RegionCreator();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
 | 
			
		||||
                .Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext.DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -41,7 +55,6 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
            var cachedResponse = new CachedResponse(HttpStatusCode.OK, new Dictionary<string, IEnumerable<string>>(), "", new Dictionary<string, IEnumerable<string>>());
 | 
			
		||||
            this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
 | 
			
		||||
                .And(x => x.GivenTheDownstreamRouteIs())
 | 
			
		||||
                .And(x => x.GivenThereIsADownstreamUrl())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheCacheGetIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
@@ -53,24 +66,15 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
            this.Given(x => x.GivenResponseIsNotCached())
 | 
			
		||||
                .And(x => x.GivenTheDownstreamRouteIs())
 | 
			
		||||
                .And(x => x.GivenThereAreNoErrors())
 | 
			
		||||
                .And(x => x.GivenThereIsADownstreamUrl())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheCacheAddIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_cacheManager.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            services.AddSingleton<IRegionCreator, RegionCreator>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseOutputCacheMiddleware();
 | 
			
		||||
            _middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager.Object, _regionCreator);
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsACachedResponse(CachedResponse response)
 | 
			
		||||
@@ -83,38 +87,30 @@ namespace Ocelot.UnitTests.Cache
 | 
			
		||||
 | 
			
		||||
        private void GivenResponseIsNotCached()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
 | 
			
		||||
                .Returns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage()));
 | 
			
		||||
            _downstreamContext.DownstreamResponse = new HttpResponseMessage();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamRouteIs()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithIsCached(true)
 | 
			
		||||
                .WithCacheOptions(new CacheOptions(100, "kanken"))
 | 
			
		||||
                .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                    .WithIsCached(true)
 | 
			
		||||
                    .WithCacheOptions(new CacheOptions(100, "kanken"))
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build();
 | 
			
		||||
                
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereAreNoErrors()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<bool>("OcelotMiddlewareError"))
 | 
			
		||||
                .Returns(new OkResponse<bool>(false));
 | 
			
		||||
        }
 | 
			
		||||
            _downstreamContext.Errors = new List<Error>();
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsADownstreamUrl()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<string>("DownstreamUrl"))
 | 
			
		||||
                .Returns(new OkResponse<string>("anything"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheCacheGetIsCalledCorrectly()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Claims
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Claims
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Claims;
 | 
			
		||||
    using Ocelot.Claims.Middleware;
 | 
			
		||||
@@ -15,17 +15,29 @@
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
 | 
			
		||||
    public class ClaimsBuilderMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class ClaimsBuilderMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IAddClaimsToRequest> _addHeaders;
 | 
			
		||||
        private Response<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private readonly ClaimsBuilderMiddleware _middleware;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public ClaimsBuilderMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _addHeaders = new Mock<IAddClaimsToRequest>();
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<ClaimsBuilderMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new ClaimsBuilderMiddleware(_next, _loggerFactory.Object, _addHeaders.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -33,11 +45,14 @@
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                    .WithClaimsToClaims(new List<ClaimToThing>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ClaimToThing("sub", "UserType", "|", 0)
 | 
			
		||||
                    })
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                        .WithClaimsToClaims(new List<ClaimToThing>
 | 
			
		||||
                        {
 | 
			
		||||
                            new ClaimToThing("sub", "UserType", "|", 0)
 | 
			
		||||
                        })
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build());
 | 
			
		||||
 | 
			
		||||
@@ -48,25 +63,16 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_addHeaders.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseClaimsBuilderMiddleware();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheAddClaimsToRequestReturns()
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        private readonly IConfigurationValidator _configurationValidator;
 | 
			
		||||
        private FileConfiguration _fileConfiguration;
 | 
			
		||||
        private Response<ConfigurationValidationResult> _result;
 | 
			
		||||
        private Mock<IAuthenticationSchemeProvider> _provider;
 | 
			
		||||
        private readonly Mock<IAuthenticationSchemeProvider> _provider;
 | 
			
		||||
 | 
			
		||||
        public ConfigurationFluentValidationTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -28,6 +28,373 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            _configurationValidator = new FileConfigurationFluentValidator(_provider.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void configuration_is_valid_if_aggregates_are_valid()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51878,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51880,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Tom"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAConfiguration(configuration))
 | 
			
		||||
                .When(x => x.WhenIValidateTheConfiguration())
 | 
			
		||||
                .Then(x => x.ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void configuration_is_invalid_if_aggregates_are_duplicate_of_re_routes()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51878,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51880,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Tom",
 | 
			
		||||
                            UpstreamHost = "localhost"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            },
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAConfiguration(configuration))
 | 
			
		||||
                .When(x => x.WhenIValidateTheConfiguration())
 | 
			
		||||
                .Then(x => x.ThenTheResultIsNotValid())
 | 
			
		||||
                .And(x => x.ThenTheErrorMessageAtPositionIs(0, "reRoute /tom has duplicate aggregate"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void configuration_is_valid_if_aggregates_are_not_duplicate_of_re_routes()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51878,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51880,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Post" },
 | 
			
		||||
                            Key = "Tom",
 | 
			
		||||
                            UpstreamHost = "localhost"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            },
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAConfiguration(configuration))
 | 
			
		||||
                .When(x => x.WhenIValidateTheConfiguration())
 | 
			
		||||
                .Then(x => x.ThenTheResultIsValid())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void configuration_is_invalid_if_aggregates_are_duplicate_of_aggregates()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51878,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51880,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/lol",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Tom"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAConfiguration(configuration))
 | 
			
		||||
                .When(x => x.WhenIValidateTheConfiguration())
 | 
			
		||||
                .Then(x => x.ThenTheResultIsNotValid())
 | 
			
		||||
                .And(x => x.ThenTheErrorMessageAtPositionIs(0, "aggregate /tom has duplicate aggregate"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void configuration_is_invalid_if_re_routes_dont_exist_for_aggregate()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51878,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAConfiguration(configuration))
 | 
			
		||||
                .When(x => x.WhenIValidateTheConfiguration())
 | 
			
		||||
                .Then(x => x.ThenTheResultIsNotValid())
 | 
			
		||||
                .And(x => x.ThenTheErrorMessageAtPositionIs(0, "ReRoutes for aggregateReRoute / either do not exist or do not have correct Key property"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void configuration_is_invalid_if_aggregate_has_re_routes_with_specific_request_id_keys()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51878,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51880,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            RequestIdKey = "should_fail",
 | 
			
		||||
                            Key = "Tom"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAConfiguration(configuration))
 | 
			
		||||
                .When(x => x.WhenIValidateTheConfiguration())
 | 
			
		||||
                .Then(x => x.ThenTheResultIsNotValid())
 | 
			
		||||
                .And(x => x.ThenTheErrorMessageAtPositionIs(0, "aggregateReRoute / contains ReRoute with specific RequestIdKey, this is not possible with Aggregates"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void configuration_is_invalid_if_scheme_in_downstream_or_upstream_template()
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Castle.Components.DictionaryAdapter;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Cache;
 | 
			
		||||
@@ -81,6 +82,125 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                _downstreamAddressesCreator.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_set_up_aggregate_re_route()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51878,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura",
 | 
			
		||||
                            UpstreamHost = "localhost"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51880,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Tom",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
 | 
			
		||||
 | 
			
		||||
            var expected = new List<ReRoute>();
 | 
			
		||||
 | 
			
		||||
            var lauraDownstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithUpstreamHost("localhost")
 | 
			
		||||
                .WithKey("Laura")
 | 
			
		||||
                .WithDownstreamPathTemplate("/")
 | 
			
		||||
                .WithDownstreamScheme("http")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string>() {"Get"})
 | 
			
		||||
                .WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("localhost", 51878)})
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var lauraReRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string>() { "Get" })
 | 
			
		||||
                .WithUpstreamHost("localhost")
 | 
			
		||||
                .WithUpstreamPathTemplate("/laura")
 | 
			
		||||
                .WithDownstreamReRoute(lauraDownstreamReRoute)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            expected.Add(lauraReRoute);
 | 
			
		||||
 | 
			
		||||
            var tomDownstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithUpstreamHost("localhost")
 | 
			
		||||
                .WithKey("Tom")
 | 
			
		||||
                .WithDownstreamPathTemplate("/")
 | 
			
		||||
                .WithDownstreamScheme("http")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string>() { "Get" })
 | 
			
		||||
                .WithDownstreamAddresses(new List<DownstreamHostAndPort>() { new DownstreamHostAndPort("localhost", 51878) })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var tomReRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string>() { "Get" })
 | 
			
		||||
                .WithUpstreamHost("localhost")
 | 
			
		||||
                .WithUpstreamPathTemplate("/tom")
 | 
			
		||||
                .WithDownstreamReRoute(tomDownstreamReRoute)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            expected.Add(tomReRoute);
 | 
			
		||||
 | 
			
		||||
            var aggregateReReRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithUpstreamPathTemplate("/")
 | 
			
		||||
                .WithUpstreamHost("localhost")
 | 
			
		||||
                .WithDownstreamReRoute(lauraDownstreamReRoute)
 | 
			
		||||
                .WithDownstreamReRoute(tomDownstreamReRoute)
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string>() { "Get" })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            expected.Add(aggregateReReRoute);
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheConfigIs(configuration))
 | 
			
		||||
                .And(x => x.GivenTheFollowingOptionsAreReturned(new ReRouteOptionsBuilder().Build()))
 | 
			
		||||
                .And(x => x.GivenTheFollowingIsReturned(serviceProviderConfig))
 | 
			
		||||
                .And(x => GivenTheDownstreamAddresses())
 | 
			
		||||
                .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
 | 
			
		||||
                .And(x => x.GivenTheConfigIsValid())
 | 
			
		||||
                .When(x => x.WhenICreateTheConfig())
 | 
			
		||||
                .Then(x => x.ThenTheServiceProviderCreatorIsCalledCorrectly())
 | 
			
		||||
                .Then(x => x.ThenTheReRoutesAre(expected))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_service_provider_config_creator()
 | 
			
		||||
        {
 | 
			
		||||
@@ -234,6 +354,13 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            var reRouteOptions = new ReRouteOptionsBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("127.0.0.1", 80)})
 | 
			
		||||
                .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheConfigIs(new FileConfiguration
 | 
			
		||||
                        {
 | 
			
		||||
                            ReRoutes = new List<FileReRoute>
 | 
			
		||||
@@ -261,8 +388,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                            .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
 | 
			
		||||
                            {
 | 
			
		||||
                                new ReRouteBuilder()
 | 
			
		||||
                                    .WithDownstreamAddresses(new List<DownstreamHostAndPort>(){new DownstreamHostAndPort("127.0.0.1", 80) })
 | 
			
		||||
                                    .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                                    .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                                    .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                    .Build()
 | 
			
		||||
@@ -276,6 +402,13 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            var reRouteOptions = new ReRouteOptionsBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamScheme("https")
 | 
			
		||||
                .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheConfigIs(new FileConfiguration
 | 
			
		||||
                                        {
 | 
			
		||||
                                            ReRoutes = new List<FileReRoute>
 | 
			
		||||
@@ -297,8 +430,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                                            .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
 | 
			
		||||
                                            {
 | 
			
		||||
                                                new ReRouteBuilder()
 | 
			
		||||
                                                    .WithDownstreamScheme("https")
 | 
			
		||||
                                                    .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                                                    .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                                                    .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                                                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                                    .Build()
 | 
			
		||||
@@ -312,6 +444,14 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            var reRouteOptions = new ReRouteOptionsBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .WithUseServiceDiscovery(true)
 | 
			
		||||
                .WithServiceName("ProductService")
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheConfigIs(new FileConfiguration
 | 
			
		||||
                        {
 | 
			
		||||
                            ReRoutes = new List<FileReRoute>
 | 
			
		||||
@@ -341,11 +481,9 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                            .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
 | 
			
		||||
                            {
 | 
			
		||||
                                new ReRouteBuilder()
 | 
			
		||||
                                    .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                                    .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                                    .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                    .WithUseServiceDiscovery(true)
 | 
			
		||||
                                    .WithServiceName("ProductService")
 | 
			
		||||
                                    .Build()
 | 
			
		||||
                            }))
 | 
			
		||||
                            .BDDfy();
 | 
			
		||||
@@ -356,7 +494,15 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        {
 | 
			
		||||
            var reRouteOptions = new ReRouteOptionsBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .WithUseServiceDiscovery(false)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheConfigIs(new FileConfiguration
 | 
			
		||||
                        {
 | 
			
		||||
                            ReRoutes = new List<FileReRoute>
 | 
			
		||||
@@ -378,10 +524,9 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                            .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
 | 
			
		||||
                            {
 | 
			
		||||
                                new ReRouteBuilder()
 | 
			
		||||
                                    .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                                    .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                                    .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                    .WithUseServiceDiscovery(false)
 | 
			
		||||
                                    .Build()
 | 
			
		||||
                            }))
 | 
			
		||||
                            .BDDfy();
 | 
			
		||||
@@ -392,7 +537,15 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        {
 | 
			
		||||
             var reRouteOptions = new ReRouteOptionsBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheConfigIs(new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
@@ -415,7 +568,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                        .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                        .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
 | 
			
		||||
@@ -430,6 +583,13 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            var reRouteOptions = new ReRouteOptionsBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .WithRequestIdKey("blahhhh")
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheConfigIs(new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
@@ -456,10 +616,9 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                        .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                        .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .WithRequestIdKey("blahhhh")
 | 
			
		||||
                        .Build()
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.ThenTheRequestIdKeyCreatorIsCalledCorrectly())
 | 
			
		||||
@@ -514,17 +673,23 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                    .WithAllowedScopes(new List<string>())
 | 
			
		||||
                    .Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .WithAuthenticationOptions(authenticationOptions)
 | 
			
		||||
                .WithClaimsToHeaders(new List<ClaimToThing>
 | 
			
		||||
                {
 | 
			
		||||
                    new ClaimToThing("CustomerId", "CustomerId", "", 0),
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var expected = new List<ReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                    .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                    .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .WithAuthenticationOptions(authenticationOptions)
 | 
			
		||||
                    .WithClaimsToHeaders(new List<ClaimToThing>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ClaimToThing("CustomerId", "CustomerId", "", 0),
 | 
			
		||||
                    })
 | 
			
		||||
                    .Build()
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
@@ -554,13 +719,19 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                   .WithAllowedScopes(new List<string>())
 | 
			
		||||
                   .Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .WithAuthenticationOptions(authenticationOptions)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var expected = new List<ReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("/products/{productId}")
 | 
			
		||||
                    .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                    .WithUpstreamPathTemplate("/api/products/{productId}")
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .WithAuthenticationOptions(authenticationOptions)
 | 
			
		||||
                    .Build()
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
@@ -643,14 +814,16 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                var result = _config.Data.ReRoutes[i];
 | 
			
		||||
                var expected = expectedReRoutes[i];
 | 
			
		||||
 | 
			
		||||
                result.DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate.Value);
 | 
			
		||||
                result.DownstreamReRoute.Count.ShouldBe(expected.DownstreamReRoute.Count);
 | 
			
		||||
 | 
			
		||||
                result.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamReRoute[0].DownstreamPathTemplate.Value);
 | 
			
		||||
                result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
 | 
			
		||||
                result.UpstreamPathTemplate.Value.ShouldBe(expected.UpstreamPathTemplate.Value);
 | 
			
		||||
                result.UpstreamTemplatePattern?.Template.ShouldBe(expected.UpstreamTemplatePattern?.Template);
 | 
			
		||||
                result.ClaimsToClaims.Count.ShouldBe(expected.ClaimsToClaims.Count);
 | 
			
		||||
                result.ClaimsToHeaders.Count.ShouldBe(expected.ClaimsToHeaders.Count);
 | 
			
		||||
                result.ClaimsToQueries.Count.ShouldBe(expected.ClaimsToQueries.Count);
 | 
			
		||||
                result.RequestIdKey.ShouldBe(expected.RequestIdKey);
 | 
			
		||||
                result.DownstreamReRoute[0].ClaimsToClaims.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToClaims.Count);
 | 
			
		||||
                result.DownstreamReRoute[0].ClaimsToHeaders.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToHeaders.Count);
 | 
			
		||||
                result.DownstreamReRoute[0].ClaimsToQueries.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToQueries.Count);
 | 
			
		||||
                result.DownstreamReRoute[0].RequestIdKey.ShouldBe(expected.DownstreamReRoute[0].RequestIdKey);
 | 
			
		||||
            
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -659,8 +832,8 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                var result = _config.Data.ReRoutes[i].AuthenticationOptions;
 | 
			
		||||
                var expected = expectedReRoutes[i].AuthenticationOptions;
 | 
			
		||||
                var result = _config.Data.ReRoutes[i].DownstreamReRoute[0].AuthenticationOptions;
 | 
			
		||||
                var expected = expectedReRoutes[i].DownstreamReRoute[0].AuthenticationOptions;
 | 
			
		||||
                result.AllowedScopes.ShouldBe(expected.AllowedScopes);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -714,10 +887,10 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
 | 
			
		||||
        private void ThenTheQosOptionsAre(QoSOptions qosOptions)
 | 
			
		||||
        {
 | 
			
		||||
            _config.Data.ReRoutes[0].QosOptionsOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
 | 
			
		||||
            _config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
 | 
			
		||||
 | 
			
		||||
            _config.Data.ReRoutes[0].QosOptionsOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
 | 
			
		||||
            _config.Data.ReRoutes[0].QosOptionsOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
 | 
			
		||||
            _config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
 | 
			
		||||
            _config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheServiceProviderCreatorIsCalledCorrectly()
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
 | 
			
		||||
        private void ThenTheConfigurationIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _getResult.Data.ReRoutes[0].DownstreamPathTemplate.Value.ShouldBe("initial");
 | 
			
		||||
            _getResult.Data.ReRoutes[0].DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("initial");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIGetTheConfiguration()
 | 
			
		||||
@@ -83,13 +83,24 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                AdministrationPath = administrationPath;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public List<ReRoute> ReRoutes => new List<ReRoute>
 | 
			
		||||
            public List<ReRoute> ReRoutes
 | 
			
		||||
            {
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate(_downstreamTemplatePath)
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build()
 | 
			
		||||
            };
 | 
			
		||||
                get
 | 
			
		||||
                {
 | 
			
		||||
                    var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate(_downstreamTemplatePath)
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build();
 | 
			
		||||
 | 
			
		||||
                    return new List<ReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                            .Build()
 | 
			
		||||
                    };
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public string AdministrationPath {get;}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,11 @@
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
@@ -13,22 +17,36 @@
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class DownstreamRouteFinderMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class DownstreamRouteFinderMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IDownstreamRouteFinder> _downstreamRouteFinder;
 | 
			
		||||
        private readonly Mock<IDownstreamRouteFinder> _finder;
 | 
			
		||||
        private readonly Mock<IOcelotConfigurationProvider> _provider;
 | 
			
		||||
        private Response<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private IOcelotConfiguration _config;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private DownstreamRouteFinderMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private readonly Mock<IMultiplexer> _multiplexer;
 | 
			
		||||
 | 
			
		||||
        public DownstreamRouteFinderMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _provider = new Mock<IOcelotConfigurationProvider>();
 | 
			
		||||
            _downstreamRouteFinder = new Mock<IDownstreamRouteFinder>();
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _finder = new Mock<IDownstreamRouteFinder>();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<DownstreamRouteFinderMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _multiplexer = new Mock<IMultiplexer>();
 | 
			
		||||
            _middleware = new DownstreamRouteFinderMiddleware(_next, _loggerFactory.Object, _finder.Object, _provider.Object, _multiplexer.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -36,11 +54,16 @@
 | 
			
		||||
        {
 | 
			
		||||
            var config = new OcelotConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "");
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamRouteFinderReturns(
 | 
			
		||||
                new DownstreamRoute(
 | 
			
		||||
                    new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                        .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())))
 | 
			
		||||
                .And(x => GivenTheFollowingConfig(config))
 | 
			
		||||
@@ -49,6 +72,11 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetType();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFollowingConfig(IOcelotConfiguration config)
 | 
			
		||||
        {
 | 
			
		||||
            _config = config;
 | 
			
		||||
@@ -57,35 +85,18 @@
 | 
			
		||||
                .ReturnsAsync(new OkResponse<IOcelotConfiguration>(_config));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_downstreamRouteFinder.Object);
 | 
			
		||||
            services.AddSingleton(_provider.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseDownstreamRouteFinderMiddleware();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            _downstreamRouteFinder
 | 
			
		||||
            _finder
 | 
			
		||||
                .Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IOcelotConfiguration>(), It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheScopedDataRepositoryIsCalledCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("DownstreamRoute", _downstreamRoute.Data), Times.Once());
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("ServiceProviderConfiguration", _config.ServiceProviderConfiguration), Times.Once());
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues.ShouldBe(_downstreamRoute.Data.TemplatePlaceholderNameAndValues);
 | 
			
		||||
            _downstreamContext.ServiceProviderConfiguration.ShouldBe(_config.ServiceProviderConfiguration);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -47,13 +47,23 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
                        .Build(),
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
 | 
			
		||||
@@ -64,7 +74,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .When(x => x.WhenICallTheFinder())
 | 
			
		||||
                .Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
@@ -84,13 +99,23 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
 | 
			
		||||
                        .Build(),
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
@@ -101,7 +126,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .When(x => x.WhenICallTheFinder())
 | 
			
		||||
                .Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .Build()
 | 
			
		||||
@@ -121,7 +150,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
@@ -135,7 +169,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
 | 
			
		||||
                            new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                            new ReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                    .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                    .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                    .Build())
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .Build()
 | 
			
		||||
@@ -157,7 +195,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
@@ -171,7 +214,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
 | 
			
		||||
                            new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                            new ReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                    .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                    .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                    .Build())
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .Build()
 | 
			
		||||
@@ -193,7 +240,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
@@ -206,7 +258,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .Then(
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .Build()
 | 
			
		||||
@@ -227,13 +283,23 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                        .Build(),
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPathForAPost")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPathForAPost")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
@@ -246,7 +312,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .Then(
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPathForAPost")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPathForAPost")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                            .Build()
 | 
			
		||||
@@ -263,7 +333,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                 .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                     {
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("somPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("somPath")
 | 
			
		||||
                                .WithUpstreamPathTemplate("somePath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("somePath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
 | 
			
		||||
@@ -292,7 +367,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
@@ -305,7 +385,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .Then(
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                            .Build()
 | 
			
		||||
@@ -326,7 +410,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string>())
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string>())
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
@@ -339,7 +428,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .Then(
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Post" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                            .Build()
 | 
			
		||||
@@ -360,7 +453,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                {
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
 | 
			
		||||
                        .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
 | 
			
		||||
@@ -388,7 +486,13 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .WithUpstreamHost("MATCH")
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
@@ -403,7 +507,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
 | 
			
		||||
                        new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .Build()
 | 
			
		||||
@@ -425,7 +533,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
@@ -439,7 +552,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
 | 
			
		||||
                        new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .Build()
 | 
			
		||||
@@ -459,12 +576,17 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .WithUpstreamHost("MATCH")
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .WithUpstreamHost("MATCH")
 | 
			
		||||
 | 
			
		||||
                            .Build()
 | 
			
		||||
                    }, string.Empty, serviceProviderConfig
 | 
			
		||||
                ))
 | 
			
		||||
@@ -490,13 +612,24 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("THENULLPATH")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("THENULLPATH")
 | 
			
		||||
                                .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .Build(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .WithUpstreamHost("MATCH")
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamPathTemplate("someUpstreamPath")
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
@@ -511,7 +644,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
                    x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
 | 
			
		||||
                        new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                        new ReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                            .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                                .WithDownstreamPathTemplate("someDownstreamPath")
 | 
			
		||||
                                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                                .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                                .Build())
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
 | 
			
		||||
                            .Build()
 | 
			
		||||
@@ -592,7 +729,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
 | 
			
		||||
        private void ThenTheFollowingIsReturned(DownstreamRoute expected)
 | 
			
		||||
        {
 | 
			
		||||
            _result.Data.ReRoute.DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamPathTemplate.Value);
 | 
			
		||||
            _result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value);
 | 
			
		||||
            _result.Data.ReRoute.UpstreamTemplatePattern.Priority.ShouldBe(expected.ReRoute.UpstreamTemplatePattern.Priority);
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < _result.Data.TemplatePlaceholderNameAndValues.Count; i++)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamUrlCreator
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
@@ -19,39 +21,49 @@
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
 | 
			
		||||
    public class DownstreamUrlCreatorMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class DownstreamUrlCreatorMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IDownstreamPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer;
 | 
			
		||||
        private readonly Mock<IUrlBuilder> _urlBuilder;
 | 
			
		||||
        private Response<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private OkResponse<DownstreamPath> _downstreamPath;
 | 
			
		||||
        private HttpRequestMessage _downstreamRequest;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private DownstreamUrlCreatorMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public DownstreamUrlCreatorMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<DownstreamUrlCreatorMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamPathPlaceholderReplacer>();
 | 
			
		||||
            _urlBuilder = new Mock<IUrlBuilder>();
 | 
			
		||||
 | 
			
		||||
            _downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://my.url/abc/?q=123");
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
 | 
			
		||||
                .Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext.DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://my.url/abc/?q=123");
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_replace_scheme_and_path()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .WithDownstreamScheme("https")
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamRouteIs(
 | 
			
		||||
                    new DownstreamRoute(
 | 
			
		||||
                    new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                        .WithDownstreamReRoute(downstreamReRoute)
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .WithDownstreamScheme("https")
 | 
			
		||||
                        .Build())))
 | 
			
		||||
                .And(x => x.GivenTheDownstreamRequestUriIs("http://my.url/abc?q=123"))
 | 
			
		||||
                .And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1"))
 | 
			
		||||
@@ -60,31 +72,21 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_downstreamUrlTemplateVariableReplacer.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            services.AddSingleton(_urlBuilder.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseDownstreamUrlCreatorMiddleware();
 | 
			
		||||
            _middleware = new DownstreamUrlCreatorMiddleware(_next, _loggerFactory.Object, _downstreamUrlTemplateVariableReplacer.Object, _urlBuilder.Object);
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamRequestUriIs(string uri)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRequest.RequestUri = new Uri(uri);
 | 
			
		||||
            _downstreamContext.DownstreamRequest.RequestUri = new Uri(uri);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheUrlReplacerWillReturn(string path)
 | 
			
		||||
@@ -97,7 +99,7 @@
 | 
			
		||||
 | 
			
		||||
        private void ThenTheDownstreamRequestUriIs(string expectedUri)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
 | 
			
		||||
            _downstreamContext.DownstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,9 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
                new DownstreamRoute(
 | 
			
		||||
                    new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                    new ReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .Build())
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())))
 | 
			
		||||
                .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
@@ -43,7 +46,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
                new DownstreamRoute(
 | 
			
		||||
                new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("/")
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("/")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())))
 | 
			
		||||
                .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
@@ -56,7 +62,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("api")
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("api")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())))
 | 
			
		||||
                .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
@@ -69,7 +78,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("api/")
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("api/")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())))
 | 
			
		||||
                .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
@@ -82,7 +94,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(), 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("api/product/products/")
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("api/product/products/")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())))
 | 
			
		||||
                .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
@@ -100,7 +115,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("productservice/products/{productId}/")
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("productservice/products/{productId}/")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())))
 | 
			
		||||
             .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
@@ -118,7 +136,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("productservice/products/{productId}/variants")
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("productservice/products/{productId}/variants")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())))
 | 
			
		||||
             .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
@@ -137,7 +158,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build())))
 | 
			
		||||
             .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
@@ -157,8 +181,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, 
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build())))
 | 
			
		||||
             .When(x => x.WhenIReplaceTheTemplateVariables())
 | 
			
		||||
             .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
 | 
			
		||||
@@ -172,7 +199,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
 | 
			
		||||
 | 
			
		||||
        private void WhenIReplaceTheTemplateVariables()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues);
 | 
			
		||||
            _result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheDownstreamUrlPathIsReturned(string expected)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Errors
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Net;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Ocelot.Errors.Middleware;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
@@ -14,18 +14,41 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
    using Ocelot.Configuration.Provider;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Rafty.Concensus;
 | 
			
		||||
    using Ocelot.Errors;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
 | 
			
		||||
    public class ExceptionHandlerMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class ExceptionHandlerMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        bool _shouldThrowAnException = false;
 | 
			
		||||
        private Mock<IOcelotConfigurationProvider> _provider;
 | 
			
		||||
        private Mock<IRequestScopedDataRepository> _repo;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private ExceptionHandlerMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public ExceptionHandlerMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _provider = new Mock<IOcelotConfigurationProvider>();
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _repo = new Mock<IRequestScopedDataRepository>();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<ExceptionHandlerMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                await Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
                if (_shouldThrowAnException)
 | 
			
		||||
                {
 | 
			
		||||
                    throw new Exception("BOOM");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new ExceptionHandlerMiddleware(_next, _loggerFactory.Object, _provider.Object, _repo.Object);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -99,6 +122,17 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddlewareWithTheRequestIdKey(string key, string value)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.HttpContext.Request.Headers.Add(key, value);
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheConfigThrows()
 | 
			
		||||
        {
 | 
			
		||||
            var ex = new Exception("outer", new  Exception("inner"));
 | 
			
		||||
@@ -108,7 +142,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
 | 
			
		||||
        private void ThenAnExceptionIsThrown()
 | 
			
		||||
        {
 | 
			
		||||
            ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
 | 
			
		||||
            _downstreamContext.HttpContext.Response.StatusCode.ShouldBe(500);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheConfigReturnsError()
 | 
			
		||||
@@ -130,7 +164,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
 | 
			
		||||
        private void TheRequestIdIsSet(string key, string value)
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository.Verify(x => x.Add<string>(key, value), Times.Once);
 | 
			
		||||
            _repo.Verify(x => x.Add<string>(key, value), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheConfigurationIs(IOcelotConfiguration config)
 | 
			
		||||
@@ -140,31 +174,6 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
                .Setup(x => x.Get()).ReturnsAsync(response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            services.AddSingleton<IOcelotConfigurationProvider>(_provider.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseExceptionHandlerMiddleware();
 | 
			
		||||
            app.Run(DownstreamExceptionSimulator);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task DownstreamExceptionSimulator(HttpContext context)
 | 
			
		||||
        {
 | 
			
		||||
            await Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
            if (_shouldThrowAnException)
 | 
			
		||||
            {
 | 
			
		||||
                throw new Exception("BOOM");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            context.Response.StatusCode = (int)HttpStatusCode.OK;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenAnExceptionWillNotBeThrownDownstream()
 | 
			
		||||
        {
 | 
			
		||||
@@ -178,17 +187,18 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResponseIsOk()
 | 
			
		||||
        {
 | 
			
		||||
            ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.OK);
 | 
			
		||||
            _downstreamContext.HttpContext.Response.StatusCode.ShouldBe(200);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResponseIsError()
 | 
			
		||||
        {
 | 
			
		||||
            ResponseMessage.StatusCode.ShouldBe(HttpStatusCode.InternalServerError);
 | 
			
		||||
 | 
			
		||||
            _downstreamContext.HttpContext.Response.StatusCode.ShouldBe(500);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void TheRequestIdIsNotSet()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository.Verify(x => x.Add<string>(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
 | 
			
		||||
            _repo.Verify(x => x.Add<string>(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +1,43 @@
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Ocelot.Headers.Middleware;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Headers;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Ocelot.Authorisation.Middleware;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Headers
 | 
			
		||||
{
 | 
			
		||||
    public class HttpHeadersTransformationMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class HttpHeadersTransformationMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private Mock<IHttpContextRequestHeaderReplacer> _preReplacer;
 | 
			
		||||
        private Mock<IHttpResponseHeaderReplacer> _postReplacer;
 | 
			
		||||
        
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private HttpHeadersTransformationMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public HttpHeadersTransformationMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _preReplacer = new Mock<IHttpContextRequestHeaderReplacer>();
 | 
			
		||||
            _postReplacer = new Mock<IHttpResponseHeaderReplacer>();
 | 
			
		||||
            
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<AuthorisationMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new HttpHeadersTransformationMiddleware(_next, _loggerFactory.Object, _preReplacer.Object, _postReplacer.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -46,27 +53,34 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamRequestIs()
 | 
			
		||||
        {
 | 
			
		||||
            var request = new HttpRequestMessage();
 | 
			
		||||
            var response = new OkResponse<HttpRequestMessage>(request);
 | 
			
		||||
            ScopedRepository.Setup(x => x.Get<HttpRequestMessage>("DownstreamRequest")).Returns(response);
 | 
			
		||||
            _downstreamContext.DownstreamRequest = new HttpRequestMessage();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheHttpResponseMessageIs()
 | 
			
		||||
        {
 | 
			
		||||
            var httpResponseMessage = new HttpResponseMessage();
 | 
			
		||||
            var response = new OkResponse<HttpResponseMessage>(httpResponseMessage);
 | 
			
		||||
            ScopedRepository.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage")).Returns(response);
 | 
			
		||||
            _downstreamContext.DownstreamResponse = new HttpResponseMessage();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheReRouteHasPreFindAndReplaceSetUp()
 | 
			
		||||
        {
 | 
			
		||||
            var fAndRs = new List<HeaderFindAndReplace>();
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithUpstreamHeaderFindAndReplace(fAndRs).WithDownstreamHeaderFindAndReplace(fAndRs).Build();
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoute(new DownstreamReRouteBuilder().WithUpstreamHeaderFindAndReplace(fAndRs)
 | 
			
		||||
                    .WithDownstreamHeaderFindAndReplace(fAndRs).Build())
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var dR = new DownstreamRoute(null, reRoute);
 | 
			
		||||
            var response = new OkResponse<DownstreamRoute>(dR);
 | 
			
		||||
            ScopedRepository.Setup(x => x.Get<DownstreamRoute>("DownstreamRoute")).Returns(response);
 | 
			
		||||
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = dR.TemplatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = dR.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheIHttpContextRequestHeaderReplacerIsCalledCorrectly()
 | 
			
		||||
@@ -81,21 +95,7 @@ namespace Ocelot.UnitTests.Headers
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFollowingRequest()
 | 
			
		||||
        {
 | 
			
		||||
            Client.DefaultRequestHeaders.Add("test", "test");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            services.AddSingleton(_preReplacer.Object);
 | 
			
		||||
            services.AddSingleton(_postReplacer.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseHttpHeadersTransformationMiddleware();
 | 
			
		||||
            _downstreamContext.HttpContext.Request.Headers.Add("test", "test");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,17 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Headers
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Headers
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
    using Ocelot.Headers;
 | 
			
		||||
    using Ocelot.Headers.Middleware;
 | 
			
		||||
@@ -16,22 +20,28 @@
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class HttpRequestHeadersBuilderMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class HttpRequestHeadersBuilderMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IAddHeadersToRequest> _addHeaders;
 | 
			
		||||
        private readonly HttpRequestMessage _downstreamRequest;
 | 
			
		||||
        private Response<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private HttpRequestHeadersBuilderMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public HttpRequestHeadersBuilderMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _addHeaders = new Mock<IAddHeadersToRequest>();
 | 
			
		||||
 | 
			
		||||
            _downstreamRequest = new HttpRequestMessage();
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
 | 
			
		||||
                .Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<HttpRequestHeadersBuilderMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new HttpRequestHeadersBuilderMiddleware(_next, _loggerFactory.Object, _addHeaders.Object);
 | 
			
		||||
            _downstreamContext.DownstreamRequest = new HttpRequestMessage();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -39,11 +49,14 @@
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                    .WithClaimsToHeaders(new List<ClaimToThing>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ClaimToThing("UserId", "Subject", "", 0)
 | 
			
		||||
                    })
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                            .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                            .WithClaimsToHeaders(new List<ClaimToThing>
 | 
			
		||||
                            {
 | 
			
		||||
                                new ClaimToThing("UserId", "Subject", "", 0)
 | 
			
		||||
                            })
 | 
			
		||||
                            .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                            .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build());
 | 
			
		||||
 | 
			
		||||
@@ -54,25 +67,16 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_addHeaders.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseHttpRequestHeadersBuilderMiddleware();
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheAddHeadersToDownstreamRequestReturnsOk()
 | 
			
		||||
@@ -91,7 +95,7 @@
 | 
			
		||||
                .Verify(x => x.SetHeadersOnDownstreamRequest(
 | 
			
		||||
                    It.IsAny<List<ClaimToThing>>(),
 | 
			
		||||
                    It.IsAny<IEnumerable<System.Security.Claims.Claim>>(), 
 | 
			
		||||
                    _downstreamRequest), Times.Once);
 | 
			
		||||
                    _downstreamContext.DownstreamRequest), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
{
 | 
			
		||||
    public class LoadBalancerFactoryTests
 | 
			
		||||
    {
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private DownstreamReRoute _reRoute;
 | 
			
		||||
        private LoadBalancerFactory _factory;
 | 
			
		||||
        private ILoadBalancer _result;
 | 
			
		||||
        private Mock<IServiceDiscoveryProviderFactory> _serviceProviderFactory;
 | 
			
		||||
@@ -29,7 +29,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_no_load_balancer()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
@@ -44,9 +44,9 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_round_robin_load_balancer()
 | 
			
		||||
        {
 | 
			
		||||
             var reRoute = new ReRouteBuilder()
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithLoadBalancer("RoundRobin")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAReRoute(reRoute))
 | 
			
		||||
@@ -60,9 +60,9 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_round_least_connection_balancer()
 | 
			
		||||
        {
 | 
			
		||||
             var reRoute = new ReRouteBuilder()
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithLoadBalancer("LeastConnection")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAReRoute(reRoute))
 | 
			
		||||
@@ -76,9 +76,9 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_service_provider()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithLoadBalancer("RoundRobin")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenAReRoute(reRoute))
 | 
			
		||||
@@ -97,17 +97,17 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        private void GivenTheServiceProviderFactoryReturns()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceProviderFactory
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()))
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamReRoute>()))
 | 
			
		||||
                .Returns(_serviceProvider.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheServiceProviderIsCalledCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceProviderFactory
 | 
			
		||||
                .Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()), Times.Once);
 | 
			
		||||
                .Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<DownstreamReRoute>()), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenAReRoute(ReRoute reRoute)
 | 
			
		||||
        private void GivenAReRoute(DownstreamReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
@@ -122,4 +122,4 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
            _result.ShouldBeOfType<T>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,13 +14,13 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
{
 | 
			
		||||
    public class LoadBalancerHouseTests
 | 
			
		||||
    {
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private DownstreamReRoute _reRoute;
 | 
			
		||||
        private ILoadBalancer _loadBalancer;
 | 
			
		||||
        private readonly LoadBalancerHouse _loadBalancerHouse;
 | 
			
		||||
        private Response _addResult;
 | 
			
		||||
        private Response<ILoadBalancer> _getResult;
 | 
			
		||||
        private string _key;
 | 
			
		||||
        private Mock<ILoadBalancerFactory> _factory;
 | 
			
		||||
        private readonly Mock<ILoadBalancerFactory> _factory;
 | 
			
		||||
        private ServiceProviderConfiguration _serviceProviderConfig;
 | 
			
		||||
 | 
			
		||||
        public LoadBalancerHouseTests()
 | 
			
		||||
@@ -32,7 +32,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_store_load_balancer_on_first_request()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
 | 
			
		||||
                .Then(x => x.ThenItIsAdded())
 | 
			
		||||
@@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_store_load_balancer_on_second_request()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
 | 
			
		||||
                .When(x => x.WhenWeGetTheLoadBalancer(reRoute))
 | 
			
		||||
@@ -53,8 +53,8 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_store_load_balancers_by_key()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
            var reRouteTwo = new ReRouteBuilder().WithReRouteKey("testtwo").Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
 | 
			
		||||
            var reRouteTwo = new DownstreamReRouteBuilder().WithLoadBalancer("FakeRoundRobinLoadBalancer").WithReRouteKey("testtwo").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
 | 
			
		||||
                .And(x => x.GivenThereIsALoadBalancer(reRouteTwo, new FakeRoundRobinLoadBalancer()))
 | 
			
		||||
@@ -68,7 +68,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error_if_exception()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().Build();
 | 
			
		||||
 | 
			
		||||
            this.When(x => x.WhenWeGetTheLoadBalancer(reRoute))
 | 
			
		||||
            .Then(x => x.ThenAnErrorIsReturned())
 | 
			
		||||
@@ -78,9 +78,9 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_get_new_load_balancer_if_reroute_load_balancer_has_changed()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithLoadBalancer("FakeLoadBalancer").WithReRouteKey("test").Build();
 | 
			
		||||
 | 
			
		||||
            var reRouteTwo = new ReRouteBuilder().WithLoadBalancer("LeastConnection").WithReRouteKey("test").Build();
 | 
			
		||||
            var reRouteTwo = new DownstreamReRouteBuilder().WithLoadBalancer("LeastConnection").WithReRouteKey("test").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer()))
 | 
			
		||||
                .When(x => x.WhenWeGetTheLoadBalancer(reRoute))
 | 
			
		||||
@@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(ReRoute reRoute)
 | 
			
		||||
        private void WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(DownstreamReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
            _factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(new LeastConnection(null, null));
 | 
			
		||||
@@ -117,7 +117,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsALoadBalancer(ReRoute reRoute, ILoadBalancer loadBalancer)
 | 
			
		||||
        private void GivenThereIsALoadBalancer(DownstreamReRoute reRoute, ILoadBalancer loadBalancer)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
            _loadBalancer = loadBalancer;
 | 
			
		||||
@@ -125,7 +125,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
            _getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenWeGetTheLoadBalancer(ReRoute reRoute)
 | 
			
		||||
        private void WhenWeGetTheLoadBalancer(DownstreamReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,18 @@
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Configuration.Provider;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Ocelot.Errors;
 | 
			
		||||
    using Ocelot.LoadBalancer.LoadBalancers;
 | 
			
		||||
    using Ocelot.LoadBalancer.Middleware;
 | 
			
		||||
@@ -19,7 +23,7 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class LoadBalancerMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class LoadBalancerMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<ILoadBalancerHouse> _loadBalancerHouse;
 | 
			
		||||
        private readonly Mock<ILoadBalancer> _loadBalancer;
 | 
			
		||||
@@ -29,6 +33,11 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        private ErrorResponse<ServiceHostAndPort> _getHostAndPortError;
 | 
			
		||||
        private HttpRequestMessage _downstreamRequest;
 | 
			
		||||
        private ServiceProviderConfiguration _config;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private LoadBalancingMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public LoadBalancerMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -36,28 +45,29 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
            _loadBalancer = new Mock<ILoadBalancer>();
 | 
			
		||||
            _loadBalancerHouse = new Mock<ILoadBalancerHouse>();
 | 
			
		||||
            _downstreamRequest = new HttpRequestMessage(HttpMethod.Get, "");
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
 | 
			
		||||
                .Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<LoadBalancingMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _downstreamContext.DownstreamRequest = _downstreamRequest;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_scoped_data_repository_correctly()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
            var downstreamRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build());
 | 
			
		||||
                    .Build();
 | 
			
		||||
 | 
			
		||||
            var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
 | 
			
		||||
                .And(x => GivenTheConfigurationIs(serviceProviderConfig))
 | 
			
		||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
 | 
			
		||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute, new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>()))
 | 
			
		||||
                .And(x => x.GivenTheLoadBalancerHouseReturns())
 | 
			
		||||
                .And(x => x.GivenTheLoadBalancerReturns())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
@@ -68,17 +78,16 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_set_pipeline_error_if_cannot_get_load_balancer()
 | 
			
		||||
        {         
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
            var downstreamRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build());
 | 
			
		||||
                    .Build();
 | 
			
		||||
 | 
			
		||||
            var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
 | 
			
		||||
                .And(x => GivenTheConfigurationIs(serviceProviderConfig))
 | 
			
		||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
 | 
			
		||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute, new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>()))
 | 
			
		||||
                .And(x => x.GivenTheLoadBalancerHouseReturnsAnError())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline())
 | 
			
		||||
@@ -88,17 +97,16 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_set_pipeline_error_if_cannot_get_least()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
            var downstreamRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build());
 | 
			
		||||
                    .Build();
 | 
			
		||||
                
 | 
			
		||||
             var serviceProviderConfig = new ServiceProviderConfigurationBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamUrlIs("http://my.url/abc?q=123"))
 | 
			
		||||
                .And(x => GivenTheConfigurationIs(serviceProviderConfig))
 | 
			
		||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
 | 
			
		||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute, new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>()))
 | 
			
		||||
                .And(x => x.GivenTheLoadBalancerHouseReturns())
 | 
			
		||||
                .And(x => x.GivenTheLoadBalancerReturnsAnError())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
@@ -106,24 +114,16 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            _middleware = new LoadBalancingMiddleware(_next, _loggerFactory.Object, _loadBalancerHouse.Object);
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheConfigurationIs(ServiceProviderConfiguration config)
 | 
			
		||||
        {
 | 
			
		||||
            _config = config;
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<ServiceProviderConfiguration>("ServiceProviderConfiguration")).Returns(new OkResponse<ServiceProviderConfiguration>(config));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_loadBalancerHouse.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseLoadBalancingMiddleware();
 | 
			
		||||
            _downstreamContext.ServiceProviderConfiguration = config;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamUrlIs(string downstreamUrl)
 | 
			
		||||
@@ -147,18 +147,16 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
                .ReturnsAsync(new OkResponse<ServiceHostAndPort>(_hostAndPort));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamReRoute downstreamRoute, List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue> placeholder)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = placeholder;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheLoadBalancerHouseReturns()
 | 
			
		||||
        {
 | 
			
		||||
            _loadBalancerHouse
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<DownstreamReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
 | 
			
		||||
                .ReturnsAsync(new OkResponse<ILoadBalancer>(_loadBalancer.Object));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -170,40 +168,32 @@ namespace Ocelot.UnitTests.LoadBalancer
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            _loadBalancerHouse
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<DownstreamReRoute>(), It.IsAny<ServiceProviderConfiguration>()))
 | 
			
		||||
                .ReturnsAsync(_getLoadBalancerHouseError);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("OcelotMiddlewareErrors", _getLoadBalancerHouseError.Errors), Times.Once);
 | 
			
		||||
            _downstreamContext.IsError.ShouldBeTrue();
 | 
			
		||||
            _downstreamContext.Errors.ShouldBe(_getLoadBalancerHouseError.Errors);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenAnErrorSayingReleaseFailedIsSetOnThePipeline()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("OcelotMiddlewareErrors", It.IsAny<List<Error>>()), Times.Once);
 | 
			
		||||
            _downstreamContext.IsError.ShouldBeTrue();
 | 
			
		||||
            _downstreamContext.Errors.ShouldBe(It.IsAny<List<Error>>());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenAnErrorStatingHostAndPortCouldNotBeFoundIsSetOnPipeline()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once);
 | 
			
		||||
            _downstreamContext.IsError.ShouldBeTrue();
 | 
			
		||||
            _downstreamContext.Errors.ShouldBe(_getHostAndPortError.Errors);
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("OcelotMiddlewareErrors", _getHostAndPortError.Errors), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheDownstreamUrlIsReplacedWith(string expectedUri)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
 | 
			
		||||
            _downstreamContext.DownstreamRequest.RequestUri.OriginalString.ShouldBe(expectedUri);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										69
									
								
								test/Ocelot.UnitTests/Middleware/MultiplexerTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								test/Ocelot.UnitTests/Middleware/MultiplexerTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
{
 | 
			
		||||
    public class MultiplexerTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Multiplexer _multiplexer;
 | 
			
		||||
        private readonly DownstreamContext _context;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private readonly OcelotRequestDelegate _pipeline;
 | 
			
		||||
        private int _count;
 | 
			
		||||
        private Mock<IResponseAggregator> _aggregator;
 | 
			
		||||
 | 
			
		||||
        public MultiplexerTests()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator = new Mock<IResponseAggregator>();
 | 
			
		||||
            _context = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _pipeline = async context => { _count++; }; 
 | 
			
		||||
            _multiplexer = new Multiplexer(_aggregator.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_multiplex()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowing(reRoute))
 | 
			
		||||
                .When(x => WhenIMultiplex())
 | 
			
		||||
                .Then(x => ThePipelineIsCalled(2))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_multiplex()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithDownstreamReRoute(new DownstreamReRouteBuilder().Build()).Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowing(reRoute))
 | 
			
		||||
                .When(x => WhenIMultiplex())
 | 
			
		||||
                .Then(x => ThePipelineIsCalled(1))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFollowing(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIMultiplex()
 | 
			
		||||
        {
 | 
			
		||||
            _multiplexer.Multiplex(_context, _reRoute, _pipeline).GetAwaiter().GetResult();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThePipelineIsCalled(int expected)
 | 
			
		||||
        {
 | 
			
		||||
            _count.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,87 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
    using Microsoft.AspNetCore.Hosting.Internal;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.Configuration;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Ocelot.DependencyInjection;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Middleware.Pipeline;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class OcelotPiplineBuilderTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IServiceCollection _services;
 | 
			
		||||
        private IServiceProvider _serviceProvider;
 | 
			
		||||
        private readonly IConfiguration _configRoot;
 | 
			
		||||
        private IOcelotBuilder _ocelotBuilder;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private int _counter;
 | 
			
		||||
 | 
			
		||||
        public OcelotPiplineBuilderTests()
 | 
			
		||||
        {
 | 
			
		||||
            _configRoot = new ConfigurationRoot(new List<IConfigurationProvider>());
 | 
			
		||||
            _services = new ServiceCollection();
 | 
			
		||||
            _services.AddSingleton<IHostingEnvironment, HostingEnvironment>();
 | 
			
		||||
            _services.AddSingleton<IConfiguration>(_configRoot);
 | 
			
		||||
            _services.AddOcelot();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_build_generic()
 | 
			
		||||
        {
 | 
			
		||||
            this.When(x => WhenIUseAGeneric())
 | 
			
		||||
                .Then(x => ThenTheGenericIsInThePipeline())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_build_func()
 | 
			
		||||
        {
 | 
			
		||||
            this.When(x => WhenIUseAFunc())
 | 
			
		||||
                .Then(x => ThenTheFuncIsInThePipeline())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIUseAGeneric()
 | 
			
		||||
        {
 | 
			
		||||
            var provider = _services.BuildServiceProvider();
 | 
			
		||||
            IOcelotPipelineBuilder builder = new OcelotPipelineBuilder(provider);
 | 
			
		||||
            builder = builder.UseMiddleware<Ocelot.Errors.Middleware.ExceptionHandlerMiddleware>();
 | 
			
		||||
            var del = builder.Build();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            del.Invoke(_downstreamContext);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheGenericIsInThePipeline()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext.HttpContext.Response.StatusCode.ShouldBe(500);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIUseAFunc()
 | 
			
		||||
        {
 | 
			
		||||
            _counter = 0;
 | 
			
		||||
            var provider = _services.BuildServiceProvider();
 | 
			
		||||
            IOcelotPipelineBuilder builder = new OcelotPipelineBuilder(provider);
 | 
			
		||||
            builder = builder.Use(async (ctx, next) =>
 | 
			
		||||
            {
 | 
			
		||||
                _counter++;
 | 
			
		||||
                await next.Invoke();
 | 
			
		||||
            });
 | 
			
		||||
            var del = builder.Build();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            del.Invoke(_downstreamContext);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheFuncIsInThePipeline()
 | 
			
		||||
        {
 | 
			
		||||
            _counter.ShouldBe(1);
 | 
			
		||||
            _downstreamContext.HttpContext.Response.StatusCode.ShouldBe(404);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,202 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
using Ocelot.UnitTests.Responder;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Middleware
 | 
			
		||||
{
 | 
			
		||||
    public class SimpleJsonResponseAggregatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly SimpleJsonResponseAggregator _aggregator;
 | 
			
		||||
        private List<DownstreamContext> _downstreamContexts;
 | 
			
		||||
        private DownstreamContext _upstreamContext;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
 | 
			
		||||
        public SimpleJsonResponseAggregatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator = new SimpleJsonResponseAggregator();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_map_all_downstream_to_upstream_when_not_aggregate()
 | 
			
		||||
        {
 | 
			
		||||
            var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoutes = new List<DownstreamReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                billDownstreamReRoute,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoutes(downstreamReRoutes)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Bill says hi") },
 | 
			
		||||
                DownstreamReRoute = billDownstreamReRoute,
 | 
			
		||||
                Errors = new List<Error> { new AnyError() },
 | 
			
		||||
                DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, new Uri("http://www.bbc.co.uk")),
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var downstreamContexts = new List<DownstreamContext> { billDownstreamContext };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
 | 
			
		||||
                .And(x => GivenTheReRoute(reRoute))
 | 
			
		||||
                .And(x => GivenTheDownstreamContext(downstreamContexts))
 | 
			
		||||
                .When(x => WhenIAggregate())
 | 
			
		||||
                .Then(x => ThenTheContentIs("Bill says hi"))
 | 
			
		||||
                .And(x => ThenTheUpstreamContextIsMappedForNonAggregate())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_aggregate_n_responses_and_set_response_content_on_upstream_context()
 | 
			
		||||
        {
 | 
			
		||||
            var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoutes = new List<DownstreamReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                billDownstreamReRoute,
 | 
			
		||||
                georgeDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoutes(downstreamReRoutes)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("Bill says hi")},
 | 
			
		||||
                DownstreamReRoute = billDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("George says hi")},
 | 
			
		||||
                DownstreamReRoute = georgeDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var downstreamContexts = new List<DownstreamContext> { billDownstreamContext, georgeDownstreamContext };
 | 
			
		||||
 | 
			
		||||
            var expected = "{\"Bill\":Bill says hi,\"George\":George says hi}";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
 | 
			
		||||
                .And(x => GivenTheReRoute(reRoute))
 | 
			
		||||
                .And(x => GivenTheDownstreamContext(downstreamContexts))
 | 
			
		||||
                .When(x => WhenIAggregate())
 | 
			
		||||
                .Then(x => ThenTheContentIs(expected))
 | 
			
		||||
                .And(x => ThenTheContentTypeIs("application/json"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error_if_any_downstreams_have_errored()
 | 
			
		||||
        {
 | 
			
		||||
            var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoutes = new List<DownstreamReRoute>
 | 
			
		||||
            {
 | 
			
		||||
                billDownstreamReRoute,
 | 
			
		||||
                georgeDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamReRoutes(downstreamReRoutes)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Bill says hi") },
 | 
			
		||||
                DownstreamReRoute = billDownstreamReRoute
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var georgeDownstreamContext = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamResponse =
 | 
			
		||||
                    new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Error") },
 | 
			
		||||
                DownstreamReRoute = georgeDownstreamReRoute,
 | 
			
		||||
                Errors = new List<Error>() { new AnyError() }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var downstreamContexts = new List<DownstreamContext> { billDownstreamContext, georgeDownstreamContext };
 | 
			
		||||
 | 
			
		||||
            var expected = "Error";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
 | 
			
		||||
                .And(x => GivenTheReRoute(reRoute))
 | 
			
		||||
                .And(x => GivenTheDownstreamContext(downstreamContexts))
 | 
			
		||||
                .When(x => WhenIAggregate())
 | 
			
		||||
                .Then(x => ThenTheContentIs(expected))
 | 
			
		||||
                .And(x => ThenTheErrorIsMapped())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheErrorIsMapped()
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext.Errors.ShouldBe(_downstreamContexts[1].Errors);
 | 
			
		||||
            _upstreamContext.DownstreamResponse.ShouldBe(_downstreamContexts[1].DownstreamResponse);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheReRoute(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheUpstreamContext(DownstreamContext upstreamContext)
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext = upstreamContext;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownstreamContext(List<DownstreamContext> downstreamContexts)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContexts = downstreamContexts;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIAggregate()
 | 
			
		||||
        {
 | 
			
		||||
            _aggregator.Aggregate(_reRoute, _upstreamContext, _downstreamContexts).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheContentIs(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            var content = _upstreamContext.DownstreamResponse.Content.ReadAsStringAsync()
 | 
			
		||||
                .GetAwaiter()
 | 
			
		||||
                .GetResult();
 | 
			
		||||
 | 
			
		||||
            content.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheContentTypeIs(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext.DownstreamResponse.Content.Headers.ContentType.MediaType.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheUpstreamContextIsMappedForNonAggregate()
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamContext.DownstreamRequest.ShouldBe(_downstreamContexts[0].DownstreamRequest);
 | 
			
		||||
            _upstreamContext.DownstreamResponse.ShouldBe(_downstreamContexts[0].DownstreamResponse);
 | 
			
		||||
            _upstreamContext.Errors.ShouldBe(_downstreamContexts[0].Errors);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -54,6 +54,7 @@
 | 
			
		||||
    <PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
 | 
			
		||||
    <PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
 | 
			
		||||
    <PackageReference Include="xunit" Version="2.3.1" />
 | 
			
		||||
    <PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
namespace Ocelot.UnitTests.QueryStrings
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.QueryStrings
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
@@ -16,22 +18,30 @@
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using System.Security.Claims;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
 | 
			
		||||
    public class QueryStringBuilderMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class QueryStringBuilderMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IAddQueriesToRequest> _addQueries;
 | 
			
		||||
        private readonly HttpRequestMessage _downstreamRequest;
 | 
			
		||||
        private Response<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private QueryStringBuilderMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public QueryStringBuilderMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<QueryStringBuilderMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _addQueries = new Mock<IAddQueriesToRequest>();
 | 
			
		||||
 | 
			
		||||
            _downstreamRequest = new HttpRequestMessage();
 | 
			
		||||
            ScopedRepository.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
 | 
			
		||||
                .Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext.DownstreamRequest = new HttpRequestMessage();
 | 
			
		||||
            _middleware = new QueryStringBuilderMiddleware(_next, _loggerFactory.Object, _addQueries.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -39,11 +49,14 @@
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                    .WithClaimsToQueries(new List<ClaimToThing>
 | 
			
		||||
                    {
 | 
			
		||||
                        new ClaimToThing("UserId", "Subject", "", 0)
 | 
			
		||||
                    })
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                        .WithClaimsToQueries(new List<ClaimToThing>
 | 
			
		||||
                        {
 | 
			
		||||
                            new ClaimToThing("UserId", "Subject", "", 0)
 | 
			
		||||
                        })
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .Build());
 | 
			
		||||
 | 
			
		||||
@@ -54,17 +67,9 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_addQueries.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseQueryStringBuilderMiddleware();
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheAddHeadersToRequestReturnsOk()
 | 
			
		||||
@@ -83,15 +88,13 @@
 | 
			
		||||
                .Verify(x => x.SetQueriesOnDownstreamRequest(
 | 
			
		||||
                    It.IsAny<List<ClaimToThing>>(),
 | 
			
		||||
                    It.IsAny<IEnumerable<Claim>>(),
 | 
			
		||||
                    _downstreamRequest), Times.Once);
 | 
			
		||||
                    _downstreamContext.DownstreamRequest), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,10 @@
 | 
			
		||||
namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.RateLimit
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
@@ -13,27 +12,51 @@
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.RateLimit;
 | 
			
		||||
    using Ocelot.RateLimit.Middleware;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Microsoft.Extensions.Caching.Memory;
 | 
			
		||||
    using System.IO;
 | 
			
		||||
 | 
			
		||||
    public class ClientRateLimitMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
 | 
			
		||||
    public class ClientRateLimitMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private OkResponse<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private int responseStatusCode;
 | 
			
		||||
        private int _responseStatusCode;
 | 
			
		||||
        private IRateLimitCounterHandler _rateLimitCounterHandler;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private readonly ClientRateLimitMiddleware _middleware;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private readonly string _url;
 | 
			
		||||
 | 
			
		||||
        public ClientRateLimitMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _url = "http://localhost:51879";
 | 
			
		||||
            var cacheEntryOptions = new MemoryCacheOptions();
 | 
			
		||||
            _rateLimitCounterHandler = new MemoryCacheRateLimitCounterHandler(new MemoryCache(cacheEntryOptions));
 | 
			
		||||
            var httpContext = new DefaultHttpContext();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(httpContext);
 | 
			
		||||
            _downstreamContext.HttpContext.Response.Body = new FakeStream();
 | 
			
		||||
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<ClientRateLimitMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
             _next = async (context) => {
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new ClientRateLimitMiddleware(_next, _loggerFactory.Object, _rateLimitCounterHandler);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_middleware_and_ratelimiting()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
 | 
			
		||||
                 new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
 | 
			
		||||
                     new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new Ocelot.Configuration.RateLimitRule("1s", 100, 3), 429))
 | 
			
		||||
                 new ReRouteBuilder()
 | 
			
		||||
                     .WithDownstreamReRoute(new DownstreamReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
 | 
			
		||||
                             new RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new RateLimitRule("1s", 100, 3), 429))
 | 
			
		||||
                         .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                         .Build())
 | 
			
		||||
                     .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                     .Build());
 | 
			
		||||
 | 
			
		||||
@@ -49,8 +72,13 @@
 | 
			
		||||
        public void should_call_middleware_withWhitelistClient()
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
 | 
			
		||||
                 new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
 | 
			
		||||
                     new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new  RateLimitRule( "1s", 100,3),429))
 | 
			
		||||
                 new ReRouteBuilder()
 | 
			
		||||
                     .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                         .WithEnableRateLimiting(true)
 | 
			
		||||
                         .WithRateLimitOptions(
 | 
			
		||||
                             new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule("1s", 100, 3), 429))
 | 
			
		||||
                         .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                         .Build())
 | 
			
		||||
                     .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                     .Build());
 | 
			
		||||
 | 
			
		||||
@@ -60,31 +88,10 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddMemoryCache();
 | 
			
		||||
            services.AddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseRateLimiting();
 | 
			
		||||
            app.Run(async context =>
 | 
			
		||||
            {
 | 
			
		||||
                context.Response.StatusCode = 200;
 | 
			
		||||
                await context.Response.WriteAsync("This is ratelimit test");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddlewareMultipleTime(int times)
 | 
			
		||||
@@ -93,11 +100,12 @@
 | 
			
		||||
  
 | 
			
		||||
            for (int i = 0; i < times; i++)
 | 
			
		||||
            {
 | 
			
		||||
                var request = new HttpRequestMessage(new HttpMethod("GET"), Url);
 | 
			
		||||
                var request = new HttpRequestMessage(new HttpMethod("GET"), _url);
 | 
			
		||||
                request.Headers.Add("ClientId", clientId);
 | 
			
		||||
                _downstreamContext.DownstreamRequest = request;
 | 
			
		||||
 | 
			
		||||
                var response = Client.SendAsync(request);
 | 
			
		||||
                responseStatusCode = (int)response.Result.StatusCode;
 | 
			
		||||
                _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
                _responseStatusCode = (int)_downstreamContext.HttpContext.Response.StatusCode;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -107,22 +115,58 @@
 | 
			
		||||
 
 | 
			
		||||
            for (int i = 0; i < 10; i++)
 | 
			
		||||
            {
 | 
			
		||||
                var request = new HttpRequestMessage(new HttpMethod("GET"), Url);
 | 
			
		||||
                var request = new HttpRequestMessage(new HttpMethod("GET"), _url);
 | 
			
		||||
                request.Headers.Add("ClientId", clientId);
 | 
			
		||||
                _downstreamContext.DownstreamRequest = request;
 | 
			
		||||
                _downstreamContext.HttpContext.Request.Headers.TryAdd("ClientId", clientId);
 | 
			
		||||
 | 
			
		||||
                var response = Client.SendAsync(request);
 | 
			
		||||
                responseStatusCode = (int)response.Result.StatusCode;
 | 
			
		||||
                _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
                _responseStatusCode = (int)_downstreamContext.HttpContext.Response.StatusCode;            
 | 
			
		||||
            }
 | 
			
		||||
         }      
 | 
			
		||||
 | 
			
		||||
        private void ThenresponseStatusCodeIs429()
 | 
			
		||||
        {
 | 
			
		||||
            responseStatusCode.ShouldBe(429);
 | 
			
		||||
            _responseStatusCode.ShouldBe(429);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenresponseStatusCodeIs200()
 | 
			
		||||
        {
 | 
			
		||||
            responseStatusCode.ShouldBe(200);
 | 
			
		||||
            _responseStatusCode.ShouldBe(200);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class FakeStream : Stream
 | 
			
		||||
    {
 | 
			
		||||
        public override void Flush()
 | 
			
		||||
        {
 | 
			
		||||
            throw new System.NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int Read(byte[] buffer, int offset, int count)
 | 
			
		||||
        {
 | 
			
		||||
            throw new System.NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override long Seek(long offset, SeekOrigin origin)
 | 
			
		||||
        {
 | 
			
		||||
            throw new System.NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void SetLength(long value)
 | 
			
		||||
        {
 | 
			
		||||
            throw new System.NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Write(byte[] buffer, int offset, int count)
 | 
			
		||||
        {
 | 
			
		||||
            //do nothing
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool CanRead { get; }
 | 
			
		||||
        public override bool CanSeek { get; }
 | 
			
		||||
        public override bool CanWrite => true;
 | 
			
		||||
        public override long Length { get; }
 | 
			
		||||
        public override long Position { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Request
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Request
 | 
			
		||||
{
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
@@ -10,6 +12,8 @@
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
 | 
			
		||||
    public class DownstreamRequestInitialiserMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
@@ -19,17 +23,16 @@
 | 
			
		||||
 | 
			
		||||
        readonly Mock<HttpRequest> _httpRequest;
 | 
			
		||||
 | 
			
		||||
        readonly Mock<RequestDelegate> _next;
 | 
			
		||||
        readonly Mock<OcelotRequestDelegate> _next;
 | 
			
		||||
 | 
			
		||||
        readonly Mock<IRequestMapper> _requestMapper;
 | 
			
		||||
 | 
			
		||||
        readonly Mock<IRequestScopedDataRepository> _repo;
 | 
			
		||||
 | 
			
		||||
        readonly Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
 | 
			
		||||
        readonly Mock<IOcelotLogger> _logger;
 | 
			
		||||
 | 
			
		||||
        Response<HttpRequestMessage> _mappedRequest;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
 | 
			
		||||
        public DownstreamRequestInitialiserMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -37,8 +40,7 @@
 | 
			
		||||
            _httpContext = new Mock<HttpContext>();
 | 
			
		||||
            _httpRequest = new Mock<HttpRequest>();
 | 
			
		||||
            _requestMapper = new Mock<IRequestMapper>();
 | 
			
		||||
            _repo = new Mock<IRequestScopedDataRepository>();
 | 
			
		||||
            _next = new Mock<RequestDelegate>();
 | 
			
		||||
            _next = new Mock<OcelotRequestDelegate>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
@@ -49,8 +51,9 @@
 | 
			
		||||
            _middleware = new DownstreamRequestInitialiserMiddleware(
 | 
			
		||||
                _next.Object, 
 | 
			
		||||
                _loggerFactory.Object, 
 | 
			
		||||
                _repo.Object, 
 | 
			
		||||
                _requestMapper.Object);
 | 
			
		||||
 | 
			
		||||
            _downstreamContext = new DownstreamContext(_httpContext.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -104,7 +107,7 @@
 | 
			
		||||
 | 
			
		||||
        private void WhenTheMiddlewareIsInvoked()
 | 
			
		||||
        {
 | 
			
		||||
           _middleware.Invoke(_httpContext.Object).GetAwaiter().GetResult();
 | 
			
		||||
           _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheContexRequestIsMappedToADownstreamRequest()
 | 
			
		||||
@@ -114,29 +117,28 @@
 | 
			
		||||
 | 
			
		||||
        private void ThenTheDownstreamRequestIsStored()
 | 
			
		||||
        {
 | 
			
		||||
            _repo.Verify(r => r.Add("DownstreamRequest", _mappedRequest.Data), Times.Once);
 | 
			
		||||
            _downstreamContext.DownstreamRequest.ShouldNotBeNull();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheDownstreamRequestIsNotStored()
 | 
			
		||||
        {
 | 
			
		||||
            _repo.Verify(r => r.Add("DownstreamRequest", It.IsAny<HttpRequestMessage>()), Times.Never);
 | 
			
		||||
            _downstreamContext.DownstreamRequest.ShouldBeNull();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenAPipelineErrorIsStored()
 | 
			
		||||
        {
 | 
			
		||||
            _repo.Verify(r => r.Add("OcelotMiddlewareError", true), Times.Once);
 | 
			
		||||
            _repo.Verify(r => r.Add("OcelotMiddlewareErrors", _mappedRequest.Errors), Times.Once);
 | 
			
		||||
            _downstreamContext.IsError.ShouldBeTrue();
 | 
			
		||||
            _downstreamContext.Errors.ShouldBe(_mappedRequest.Errors);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheNextMiddlewareIsInvoked()
 | 
			
		||||
        {
 | 
			
		||||
            _next.Verify(n => n(_httpContext.Object), Times.Once);
 | 
			
		||||
            _next.Verify(n => n(_downstreamContext), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheNextMiddlewareIsNotInvoked()
 | 
			
		||||
        {
 | 
			
		||||
            _next.Verify(n => n(It.IsAny<HttpContext>()), Times.Never);
 | 
			
		||||
            _next.Verify(n => n(It.IsAny<DownstreamContext>()), Times.Never);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,152 +0,0 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Request
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.UrlMatcher;
 | 
			
		||||
    using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Request.Builder;
 | 
			
		||||
    using Ocelot.Request.Middleware;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Ocelot.Requester.QoS;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
    public class HttpRequestBuilderMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IRequestCreator> _requestBuilder;
 | 
			
		||||
        private readonly Mock<IRequestScopedDataRepository> _scopedRepository;
 | 
			
		||||
        private readonly Mock<IQosProviderHouse> _qosProviderHouse;
 | 
			
		||||
        private readonly HttpRequestMessage _downstreamRequest;
 | 
			
		||||
        private OkResponse<Ocelot.Request.Request> _request;
 | 
			
		||||
        private OkResponse<string> _downstreamUrl;
 | 
			
		||||
        private OkResponse<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
 | 
			
		||||
        public HttpRequestBuilderMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _qosProviderHouse = new Mock<IQosProviderHouse>();
 | 
			
		||||
            _requestBuilder = new Mock<IRequestCreator>();
 | 
			
		||||
            _scopedRepository = new Mock<IRequestScopedDataRepository>();
 | 
			
		||||
 | 
			
		||||
            _downstreamRequest = new HttpRequestMessage();
 | 
			
		||||
 | 
			
		||||
            _scopedRepository
 | 
			
		||||
                .Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
 | 
			
		||||
                .Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_scoped_data_repository_correctly()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .WithHttpHandlerOptions(new HttpHandlerOptions(true, true,false))
 | 
			
		||||
                    .Build());
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
 | 
			
		||||
                .And(x => x.GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(new NoQoSProvider())))
 | 
			
		||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
 | 
			
		||||
                .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false, "", false)))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_scoped_data_repository_QosProviderError()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                    .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                    .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, true))
 | 
			
		||||
                    .Build());
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
 | 
			
		||||
                .And(x => x.GivenTheQosProviderHouseReturns(new ErrorResponse<IQoSProvider>(It.IsAny<Error>())))
 | 
			
		||||
                .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
 | 
			
		||||
                .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false, "", false)))
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheScopedDataRepositoryQosProviderError())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_qosProviderHouse.Object);
 | 
			
		||||
            services.AddSingleton(_requestBuilder.Object);
 | 
			
		||||
            services.AddSingleton(_scopedRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseHttpRequestBuilderMiddleware();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamUrlIs(string downstreamUrl)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamUrl = new OkResponse<string>(downstreamUrl);
 | 
			
		||||
            _scopedRepository
 | 
			
		||||
                .Setup(x => x.Get<string>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamUrl);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheQosProviderHouseReturns(Response<IQoSProvider> qosProvider)
 | 
			
		||||
        {
 | 
			
		||||
            _qosProviderHouse
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<ReRoute>()))
 | 
			
		||||
                .Returns(qosProvider);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            _scopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequestBuilderReturns(Ocelot.Request.Request request)
 | 
			
		||||
        {
 | 
			
		||||
            _request = new OkResponse<Ocelot.Request.Request>(request);
 | 
			
		||||
 | 
			
		||||
            _requestBuilder
 | 
			
		||||
                .Setup(x => x.Build(It.IsAny<HttpRequestMessage>(),
 | 
			
		||||
                                    It.IsAny<bool>(),
 | 
			
		||||
                                    It.IsAny<IQoSProvider>(),
 | 
			
		||||
                                    It.IsAny<bool>(),
 | 
			
		||||
                                    It.IsAny<bool>(),
 | 
			
		||||
                                    It.IsAny<string>(),
 | 
			
		||||
                                    It.IsAny<bool>()))
 | 
			
		||||
                .ReturnsAsync(_request);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheScopedDataRepositoryIsCalledCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            _scopedRepository
 | 
			
		||||
                .Verify(x => x.Add("Request", _request.Data), Times.Once());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheScopedDataRepositoryQosProviderError()
 | 
			
		||||
        {
 | 
			
		||||
            _scopedRepository
 | 
			
		||||
                .Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,86 +0,0 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Request
 | 
			
		||||
{
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
 | 
			
		||||
    using Ocelot.Request.Builder;
 | 
			
		||||
    using Ocelot.Requester.QoS;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class HttpRequestCreatorTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IRequestCreator _requestCreator;
 | 
			
		||||
        private readonly bool _isQos;
 | 
			
		||||
        private readonly IQoSProvider _qoSProvider;
 | 
			
		||||
        private readonly HttpRequestMessage _requestMessage;
 | 
			
		||||
        private readonly bool _useCookieContainer;
 | 
			
		||||
        private readonly bool _allowAutoRedirect;
 | 
			
		||||
        private Response<Ocelot.Request.Request> _response;
 | 
			
		||||
        private string _reRouteKey;
 | 
			
		||||
        private readonly bool _useTracing;
 | 
			
		||||
 | 
			
		||||
        public HttpRequestCreatorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _requestCreator = new HttpRequestCreator();
 | 
			
		||||
            _isQos = true;
 | 
			
		||||
            _qoSProvider = new NoQoSProvider();
 | 
			
		||||
            _useCookieContainer = false;
 | 
			
		||||
            _allowAutoRedirect = false;
 | 
			
		||||
 | 
			
		||||
            _requestMessage = new HttpRequestMessage();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void ShouldBuildRequest()
 | 
			
		||||
        {
 | 
			
		||||
            this.When(x => x.WhenIBuildARequest())
 | 
			
		||||
                .Then(x => x.ThenTheRequestContainsTheRequestMessage())
 | 
			
		||||
                .Then(x => x.ThenTheRequestContainsTheIsQos())
 | 
			
		||||
                .Then(x => x.ThenTheRequestContainsTheQosProvider())
 | 
			
		||||
                .Then(x => x.ThenTheRequestContainsUseCookieContainer())
 | 
			
		||||
                .Then(x => x.ThenTheRequestContainsUseTracing())
 | 
			
		||||
                .Then(x => x.ThenTheRequestContainsAllowAutoRedirect())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIBuildARequest()
 | 
			
		||||
        {
 | 
			
		||||
            _response = _requestCreator.Build(_requestMessage,
 | 
			
		||||
                    _isQos, _qoSProvider, _useCookieContainer, _allowAutoRedirect, _reRouteKey, _useTracing)
 | 
			
		||||
                .GetAwaiter()
 | 
			
		||||
                .GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheRequestContainsTheRequestMessage()
 | 
			
		||||
        {
 | 
			
		||||
            _response.Data.HttpRequestMessage.ShouldBe(_requestMessage);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheRequestContainsTheIsQos()
 | 
			
		||||
        {
 | 
			
		||||
            _response.Data.IsQos.ShouldBe(_isQos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheRequestContainsTheQosProvider()
 | 
			
		||||
        {
 | 
			
		||||
            _response.Data.QosProvider.ShouldBe(_qoSProvider);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheRequestContainsUseCookieContainer()
 | 
			
		||||
        {
 | 
			
		||||
            _response.Data.UseCookieContainer.ShouldBe(_useCookieContainer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheRequestContainsUseTracing()
 | 
			
		||||
        {
 | 
			
		||||
            _response.Data.IsTracing.ShouldBe(_useTracing);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheRequestContainsAllowAutoRedirect()
 | 
			
		||||
        {
 | 
			
		||||
            _response.Data.AllowAutoRedirect.ShouldBe(_allowAutoRedirect);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,13 +1,15 @@
 | 
			
		||||
namespace Ocelot.UnitTests.RequestId
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.RequestId
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Microsoft.Extensions.Primitives;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Linq;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
@@ -19,22 +21,32 @@
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class ReRouteRequestIdMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class ReRouteRequestIdMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly HttpRequestMessage _downstreamRequest;
 | 
			
		||||
        private Response<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private string _value;
 | 
			
		||||
        private string _key;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private readonly ReRouteRequestIdMiddleware _middleware;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private readonly Mock<IRequestScopedDataRepository> _repo;
 | 
			
		||||
 | 
			
		||||
        public ReRouteRequestIdMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRequest = new HttpRequestMessage();
 | 
			
		||||
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
 | 
			
		||||
                .Returns(new OkResponse<HttpRequestMessage>(_downstreamRequest));
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _repo = new Mock<IRequestScopedDataRepository>();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<ReRouteRequestIdMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                context.HttpContext.Response.Headers.Add("LSRequestId", context.HttpContext.TraceIdentifier);
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new ReRouteRequestIdMiddleware(_next, _loggerFactory.Object, _repo.Object);
 | 
			
		||||
            _downstreamContext.DownstreamRequest = _downstreamRequest;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -42,8 +54,11 @@
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                        .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                        .Build())
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build());
 | 
			
		||||
 | 
			
		||||
@@ -62,10 +77,13 @@
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build());
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                        .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                    .Build());
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
 | 
			
		||||
                .And(x => GivenThereIsNoGlobalRequestId())
 | 
			
		||||
@@ -79,10 +97,13 @@
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build());
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                        .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                    .Build());
 | 
			
		||||
 | 
			
		||||
            var requestId = Guid.NewGuid().ToString();
 | 
			
		||||
 | 
			
		||||
@@ -100,10 +121,13 @@
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
 | 
			
		||||
                new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "Get" })
 | 
			
		||||
                .Build());
 | 
			
		||||
                    .WithDownstreamReRoute(new DownstreamReRouteBuilder()
 | 
			
		||||
                        .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
                        .WithRequestIdKey("LSRequestId")
 | 
			
		||||
                        .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                        .Build())
 | 
			
		||||
                    .WithUpstreamHttpMethod(new List<string> {"Get"})
 | 
			
		||||
                    .Build());
 | 
			
		||||
 | 
			
		||||
            var requestId = Guid.NewGuid().ToString();
 | 
			
		||||
 | 
			
		||||
@@ -116,67 +140,57 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsNoGlobalRequestId()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>(null));
 | 
			
		||||
            _repo.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>(null));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequestIdWasSetGlobally()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>("alreadyset"));
 | 
			
		||||
            _repo.Setup(x => x.Get<string>("RequestId")).Returns(new OkResponse<string>("alreadyset"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheRequestIdIsSaved()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository.Verify(x => x.Add<string>("RequestId", _value), Times.Once);
 | 
			
		||||
            _repo.Verify(x => x.Add<string>("RequestId", _value), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheRequestIdIsUpdated()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository.Verify(x => x.Update<string>("RequestId", _value), Times.Once);
 | 
			
		||||
            _repo.Verify(x => x.Update<string>("RequestId", _value), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseRequestIdMiddleware();
 | 
			
		||||
 | 
			
		||||
            app.Run(x =>
 | 
			
		||||
            {
 | 
			
		||||
                x.Response.Headers.Add("LSRequestId", x.TraceIdentifier);
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
            _downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequestIdIsAddedToTheRequest(string key, string value)
 | 
			
		||||
        {
 | 
			
		||||
            _key = key;
 | 
			
		||||
            _value = value;
 | 
			
		||||
            Client.DefaultRequestHeaders.TryAddWithoutValidation(_key, _value);
 | 
			
		||||
            _downstreamContext.HttpContext.Request.Headers.TryAdd(_key, _value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheTraceIdIsAnything()
 | 
			
		||||
        {
 | 
			
		||||
            ResponseMessage.Headers.GetValues("LSRequestId").First().ShouldNotBeNullOrEmpty();
 | 
			
		||||
            StringValues value;
 | 
			
		||||
            _downstreamContext.HttpContext.Response.Headers.TryGetValue("LSRequestId", out value);
 | 
			
		||||
            value.First().ShouldNotBeNullOrEmpty();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheTraceIdIs(string expected)
 | 
			
		||||
        {
 | 
			
		||||
            ResponseMessage.Headers.GetValues("LSRequestId").First().ShouldBe(expected);
 | 
			
		||||
            StringValues value;
 | 
			
		||||
            _downstreamContext.HttpContext.Response.Headers.TryGetValue("LSRequestId", out value);
 | 
			
		||||
            value.First().ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
@@ -14,7 +17,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        private readonly DelegatingHandlerHandlerHouse _house;
 | 
			
		||||
        private Mock<IDelegatingHandlerHandlerProviderFactory> _factory;
 | 
			
		||||
        private readonly Mock<IDelegatingHandlerHandlerProvider> _provider;
 | 
			
		||||
        private Ocelot.Request.Request _request;
 | 
			
		||||
        private DownstreamReRoute _request;
 | 
			
		||||
        private Response<IDelegatingHandlerHandlerProvider> _result;
 | 
			
		||||
 | 
			
		||||
        public DelegatingHandlerHandlerHouseTests()
 | 
			
		||||
@@ -27,9 +30,10 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_create_and_store_provider()
 | 
			
		||||
        {
 | 
			
		||||
            var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("key").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheRequest(request))
 | 
			
		||||
            this.Given(x => GivenTheRequest(reRoute))
 | 
			
		||||
                .And(x => GivenTheProviderReturns())
 | 
			
		||||
                .When(x => WhenIGet())
 | 
			
		||||
                .Then(x => ThenTheFactoryIsCalled(1))
 | 
			
		||||
@@ -40,9 +44,10 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_get_provider()
 | 
			
		||||
        {
 | 
			
		||||
            var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("key").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheRequest(request))
 | 
			
		||||
            this.Given(x => GivenTheRequest(reRoute))
 | 
			
		||||
                .And(x => GivenTheProviderReturns())
 | 
			
		||||
                .And(x => WhenIGet())
 | 
			
		||||
                .And(x => GivenTheFactoryIsCleared())
 | 
			
		||||
@@ -55,15 +60,34 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error()
 | 
			
		||||
        {
 | 
			
		||||
            var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "key", false);
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("key").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheRequest(request))
 | 
			
		||||
            this.Given(x => GivenTheRequest(reRoute))
 | 
			
		||||
                .And(x => GivenTheProviderThrows())
 | 
			
		||||
                .When(x => WhenIGet())
 | 
			
		||||
                .And(x => ThenAnErrorIsReturned())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error_if_factory_errors()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("key").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheRequest(reRoute))
 | 
			
		||||
                .And(x => GivenTheProviderReturnsError())
 | 
			
		||||
                .When(x => WhenIGet())
 | 
			
		||||
                .Then(x => ThenAnUnknownErrorIsReturned())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenAnUnknownErrorIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsError.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenAnErrorIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsError.ShouldBeTrue();
 | 
			
		||||
@@ -72,7 +96,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
 | 
			
		||||
        private void GivenTheProviderThrows()
 | 
			
		||||
        {
 | 
			
		||||
            _factory.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Throws<Exception>();
 | 
			
		||||
            _factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Throws<Exception>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFactoryIsCleared()
 | 
			
		||||
@@ -90,14 +114,19 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
            _result = _house.Get(_request);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequest(Ocelot.Request.Request request)
 | 
			
		||||
        private void GivenTheRequest(DownstreamReRoute request)
 | 
			
		||||
        {
 | 
			
		||||
            _request = request;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheProviderReturns()
 | 
			
		||||
        {
 | 
			
		||||
            _factory.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Returns(_provider.Object);
 | 
			
		||||
            _factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheProviderReturnsError()
 | 
			
		||||
        {
 | 
			
		||||
            _factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new ErrorResponse<IDelegatingHandlerHandlerProvider>(It.IsAny<Error>()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheFactoryIsCalled(int times)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,13 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Ocelot.Requester.QoS;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
@@ -14,17 +19,29 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
    {
 | 
			
		||||
        private readonly DelegatingHandlerHandlerProviderFactory _factory;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Ocelot.Request.Request _request;
 | 
			
		||||
        private IDelegatingHandlerHandlerProvider _provider;
 | 
			
		||||
        private DownstreamReRoute _request;
 | 
			
		||||
        private Response<IDelegatingHandlerHandlerProvider> _provider;
 | 
			
		||||
        private readonly Mock<IDelegatingHandlerHandlerProvider> _allRoutesProvider;
 | 
			
		||||
        private readonly Mock<IQosProviderHouse> _qosProviderHouse;
 | 
			
		||||
        private readonly Mock<ITracingHandlerFactory> _tracingFactory;
 | 
			
		||||
 | 
			
		||||
        public DelegatingHandlerHandlerProviderFactoryTests()
 | 
			
		||||
        {
 | 
			
		||||
            _tracingFactory = new Mock<ITracingHandlerFactory>();
 | 
			
		||||
            _qosProviderHouse = new Mock<IQosProviderHouse>();
 | 
			
		||||
            _allRoutesProvider = new Mock<IDelegatingHandlerHandlerProvider>();
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _factory = new DelegatingHandlerHandlerProviderFactory(_loggerFactory.Object, _allRoutesProvider.Object, null);
 | 
			
		||||
            _factory = new DelegatingHandlerHandlerProviderFactory(_loggerFactory.Object, _allRoutesProvider.Object, _tracingFactory.Object, _qosProviderHouse.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheQosProviderHouseReturns(Response<IQoSProvider> qosProvider)
 | 
			
		||||
        {
 | 
			
		||||
            _qosProviderHouse
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
 | 
			
		||||
                .Returns(qosProvider);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_all_from_all_routes_provider_and_qos()
 | 
			
		||||
        {
 | 
			
		||||
@@ -34,9 +51,11 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
                () => new FakeDelegatingHandler(1)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "", false);
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowingRequest(request))
 | 
			
		||||
            this.Given(x => GivenTheFollowingRequest(reRoute))
 | 
			
		||||
                .And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
 | 
			
		||||
                .And(x => GivenTheAllRoutesProviderReturns(handlers))
 | 
			
		||||
                .When(x => WhenIGet())
 | 
			
		||||
                .Then(x => ThenThereIsDelegatesInProvider(3))
 | 
			
		||||
@@ -48,9 +67,10 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_provider_with_no_delegates()
 | 
			
		||||
        {
 | 
			
		||||
            var request = new Ocelot.Request.Request(new HttpRequestMessage(), false, null, true, true, "", false);
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(false)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowingRequest(request))
 | 
			
		||||
            this.Given(x => GivenTheFollowingRequest(reRoute))
 | 
			
		||||
                .And(x => GivenTheAllRoutesProviderReturns())
 | 
			
		||||
                .When(x => WhenIGet())
 | 
			
		||||
                .Then(x => ThenNoDelegatesAreInTheProvider())
 | 
			
		||||
@@ -60,9 +80,11 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_provider_with_qos_delegate()
 | 
			
		||||
        {
 | 
			
		||||
            var request = new Ocelot.Request.Request(new HttpRequestMessage(), true, null, true, true, "", false);
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowingRequest(request))
 | 
			
		||||
            this.Given(x => GivenTheFollowingRequest(reRoute))
 | 
			
		||||
                .And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
 | 
			
		||||
                .And(x => GivenTheAllRoutesProviderReturns())
 | 
			
		||||
                .When(x => WhenIGet())
 | 
			
		||||
                .Then(x => ThenThereIsDelegatesInProvider(1))
 | 
			
		||||
@@ -70,9 +92,28 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(true)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false)).WithReRouteKey("").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowingRequest(reRoute))
 | 
			
		||||
                .And(x => GivenTheQosProviderHouseReturns(new ErrorResponse<IQoSProvider>(It.IsAny<Error>())))
 | 
			
		||||
                .And(x => GivenTheAllRoutesProviderReturns())
 | 
			
		||||
                .When(x => WhenIGet())
 | 
			
		||||
                .Then(x => ThenAnErrorIsReturned())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenAnErrorIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _provider.IsError.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheDelegatesAreAddedCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            var delegates = _provider.Get();
 | 
			
		||||
            var delegates = _provider.Data.Get();
 | 
			
		||||
            var del = delegates[0].Invoke();
 | 
			
		||||
            var handler = (FakeDelegatingHandler) del;
 | 
			
		||||
            handler.Order.ShouldBe(0);
 | 
			
		||||
@@ -94,7 +135,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
 | 
			
		||||
        private void ThenItIsPolly(int i)
 | 
			
		||||
        {
 | 
			
		||||
            var delegates = _provider.Get();
 | 
			
		||||
            var delegates = _provider.Data.Get();
 | 
			
		||||
            var del = delegates[i].Invoke();
 | 
			
		||||
            del.ShouldBeOfType<PollyCircuitBreakingDelegatingHandler>();
 | 
			
		||||
        }
 | 
			
		||||
@@ -102,10 +143,10 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        private void ThenThereIsDelegatesInProvider(int count)
 | 
			
		||||
        {
 | 
			
		||||
            _provider.ShouldNotBeNull();
 | 
			
		||||
            _provider.Get().Count.ShouldBe(count);
 | 
			
		||||
            _provider.Data.Get().Count.ShouldBe(count);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFollowingRequest(Ocelot.Request.Request request)
 | 
			
		||||
        private void GivenTheFollowingRequest(DownstreamReRoute request)
 | 
			
		||||
        {
 | 
			
		||||
            _request = request;
 | 
			
		||||
        }
 | 
			
		||||
@@ -118,7 +159,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        private void ThenNoDelegatesAreInTheProvider()
 | 
			
		||||
        {
 | 
			
		||||
            _provider.ShouldNotBeNull();
 | 
			
		||||
            _provider.Get().Count.ShouldBe(0);
 | 
			
		||||
            _provider.Data.Get().Count.ShouldBe(0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,8 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
@@ -18,7 +20,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        private IHttpClientBuilder _builderResult;
 | 
			
		||||
        private IHttpClient _httpClient;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private Ocelot.Request.Request _request;
 | 
			
		||||
        private DownstreamReRoute _request;
 | 
			
		||||
 | 
			
		||||
        public HttpClientBuilderTests()
 | 
			
		||||
        {
 | 
			
		||||
@@ -62,13 +64,16 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
 | 
			
		||||
        private void GivenARequest()
 | 
			
		||||
        {
 | 
			
		||||
            _request = new Ocelot.Request.Request(null, false, null, false, false, "", false);
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(false)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false)).WithReRouteKey("").Build();
 | 
			
		||||
 | 
			
		||||
            _request = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheHouseReturns()
 | 
			
		||||
        {
 | 
			
		||||
            _house
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>()))
 | 
			
		||||
                .Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
 | 
			
		||||
                .Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,14 @@
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Ocelot.Requester.QoS;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
@@ -21,7 +22,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        private Mock<IDelegatingHandlerHandlerProvider> _provider;
 | 
			
		||||
        private Response<HttpResponseMessage> _response;
 | 
			
		||||
        private readonly HttpClientHttpRequester _httpClientRequester;
 | 
			
		||||
        private Ocelot.Request.Request _request;
 | 
			
		||||
        private DownstreamContext _request;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
 | 
			
		||||
@@ -30,7 +31,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
            _provider = new Mock<IDelegatingHandlerHandlerProvider>();
 | 
			
		||||
            _provider.Setup(x => x.Get()).Returns(new List<Func<DelegatingHandler>>());
 | 
			
		||||
            _house = new Mock<IDelegatingHandlerHandlerHouse>();
 | 
			
		||||
            _house.Setup(x => x.Get(It.IsAny<Ocelot.Request.Request>())).Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
 | 
			
		||||
            _house.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<IDelegatingHandlerHandlerProvider>(_provider.Object));
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _loggerFactory
 | 
			
		||||
@@ -43,7 +44,16 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_request_correctly()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x=>x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage() {  RequestUri = new Uri("http://www.bbc.co.uk") }, false, new NoQoSProvider(), false, false, "", false)))
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(false)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false)).WithReRouteKey("").Build();
 | 
			
		||||
 | 
			
		||||
            var context = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamReRoute = reRoute,
 | 
			
		||||
                DownstreamRequest = new HttpRequestMessage() { RequestUri = new Uri("http://www.bbc.co.uk") },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x=>x.GivenTheRequestIs(context))
 | 
			
		||||
                .When(x=>x.WhenIGetResponse())
 | 
			
		||||
                .Then(x => x.ThenTheResponseIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
@@ -52,13 +62,22 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_request_unable_to_complete_request()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") }, false, new NoQoSProvider(), false, false, "", false)))
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithIsQos(false)
 | 
			
		||||
                .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false)).WithReRouteKey("").Build();
 | 
			
		||||
 | 
			
		||||
            var context = new DownstreamContext(new DefaultHttpContext())
 | 
			
		||||
            {
 | 
			
		||||
                DownstreamReRoute = reRoute,
 | 
			
		||||
                DownstreamRequest = new HttpRequestMessage() { RequestUri = new Uri("http://localhost:60080") },
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheRequestIs(context))
 | 
			
		||||
                .When(x => x.WhenIGetResponse())
 | 
			
		||||
                .Then(x => x.ThenTheResponseIsCalledError())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequestIs(Ocelot.Request.Request request)
 | 
			
		||||
        private void GivenTheRequestIs(DownstreamContext request)
 | 
			
		||||
        {
 | 
			
		||||
            _request = request;            
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,81 +1,73 @@
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Requester
 | 
			
		||||
{
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Requester;
 | 
			
		||||
    using Ocelot.Requester.Middleware;
 | 
			
		||||
    using Ocelot.Requester.QoS;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
 | 
			
		||||
    public class HttpRequesterMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class HttpRequesterMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IHttpRequester> _requester;
 | 
			
		||||
        private OkResponse<HttpResponseMessage> _response;
 | 
			
		||||
        private OkResponse<Ocelot.Request.Request> _request;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private readonly HttpRequesterMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public HttpRequesterMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _requester = new Mock<IHttpRequester>();
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<HttpRequesterMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new HttpRequesterMiddleware(_next, _loggerFactory.Object, _requester.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_scoped_data_repository_correctly()
 | 
			
		||||
        public void should_call_services_correctly()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider(), false, false, "", false)))
 | 
			
		||||
            this.Given(x => x.GivenTheRequestIs())
 | 
			
		||||
                .And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
 | 
			
		||||
                .And(x => x.GivenTheScopedRepoReturns())
 | 
			
		||||
                .When(x => x.WhenICallTheMiddleware())
 | 
			
		||||
                .Then(x => x.ThenTheScopedRepoIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_requester.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        private void GivenTheRequestIs()
 | 
			
		||||
        {
 | 
			
		||||
            app.UseHttpRequesterMiddleware();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequestIs(Ocelot.Request.Request request)
 | 
			
		||||
        {
 | 
			
		||||
            _request = new OkResponse<Ocelot.Request.Request>(request);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<Ocelot.Request.Request>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_request);
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _downstreamContext.DownstreamReRoute = new DownstreamReRouteBuilder().Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRequesterReturns(HttpResponseMessage response)
 | 
			
		||||
        {
 | 
			
		||||
            _response = new OkResponse<HttpResponseMessage>(response);
 | 
			
		||||
            _requester
 | 
			
		||||
                .Setup(x => x.GetResponse(It.IsAny<Ocelot.Request.Request>()))
 | 
			
		||||
                .Setup(x => x.GetResponse(It.IsAny<DownstreamContext>()))
 | 
			
		||||
                .ReturnsAsync(_response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheScopedRepoReturns()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Add(It.IsAny<string>(), _response.Data))
 | 
			
		||||
                .Returns(new OkResponse());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheScopedRepoIsCalledCorrectly()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Verify(x => x.Add("HttpResponseMessage", _response.Data), Times.Once());
 | 
			
		||||
            _downstreamContext.DownstreamResponse.ShouldBe(_response.Data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
    public class QoSProviderFactoryTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IQoSProviderFactory _factory;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private DownstreamReRoute _reRoute;
 | 
			
		||||
        private IQoSProvider _result;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
@@ -31,7 +31,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_no_qos_provider()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithUpstreamHttpMethod(new List<string> { "get" })
 | 
			
		||||
                .WithIsQos(false)
 | 
			
		||||
                .Build();
 | 
			
		||||
@@ -51,7 +51,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
                .WithExceptionsAllowedBeforeBreaking(100)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
               .WithUpstreamHttpMethod(new List<string> { "get" })
 | 
			
		||||
               .WithIsQos(true)
 | 
			
		||||
               .WithQosOptions(qosOptions)
 | 
			
		||||
@@ -63,7 +63,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenAReRoute(ReRoute reRoute)
 | 
			
		||||
        private void GivenAReRoute(DownstreamReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        private readonly QosProviderHouse _qosProviderHouse;
 | 
			
		||||
        private Response _addResult;
 | 
			
		||||
        private Response<IQoSProvider> _getResult;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private DownstreamReRoute _reRoute;
 | 
			
		||||
        private readonly Mock<IQoSProviderFactory> _factory;
 | 
			
		||||
 | 
			
		||||
        public QosProviderHouseTests()
 | 
			
		||||
@@ -27,7 +27,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_store_qos_provider_on_first_request()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
 | 
			
		||||
                .Then(x => x.ThenItIsAdded())
 | 
			
		||||
@@ -37,7 +37,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_not_store_qos_provider_on_first_request()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
 | 
			
		||||
                .When(x => x.WhenWeGetTheQoSProvider(reRoute))
 | 
			
		||||
@@ -48,8 +48,8 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_store_qos_providers_by_key()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
            var reRouteTwo = new ReRouteBuilder().WithReRouteKey("testTwo").Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
            var reRouteTwo = new DownstreamReRouteBuilder().WithReRouteKey("testTwo").Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
 | 
			
		||||
                .And(x => x.GivenThereIsAQoSProvider(reRouteTwo, new FakePollyQoSProvider()))
 | 
			
		||||
@@ -63,7 +63,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error_if_no_qos_provider_with_key()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().Build();
 | 
			
		||||
 | 
			
		||||
            this.When(x => x.WhenWeGetTheQoSProvider(reRoute))
 | 
			
		||||
            .Then(x => x.ThenAnErrorIsReturned())
 | 
			
		||||
@@ -73,9 +73,9 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_get_new_qos_provider_if_reroute_qos_provider_has_changed()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithReRouteKey("test").Build();
 | 
			
		||||
 | 
			
		||||
            var reRouteTwo = new ReRouteBuilder().WithReRouteKey("test").WithIsQos(true).Build();
 | 
			
		||||
            var reRouteTwo = new DownstreamReRouteBuilder().WithReRouteKey("test").WithIsQos(true).Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
 | 
			
		||||
                .When(x => x.WhenWeGetTheQoSProvider(reRoute))
 | 
			
		||||
@@ -85,7 +85,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(ReRoute reRoute)
 | 
			
		||||
        private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(DownstreamReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
            _factory.Setup(x => x.Get(_reRoute)).Returns(new FakePollyQoSProvider());
 | 
			
		||||
@@ -112,7 +112,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAQoSProvider(ReRoute reRoute, IQoSProvider qoSProvider)
 | 
			
		||||
        private void GivenThereIsAQoSProvider(DownstreamReRoute reRoute, IQoSProvider qoSProvider)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
            _qoSProvider = qoSProvider;
 | 
			
		||||
@@ -120,7 +120,7 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
            _getResult = _qosProviderHouse.Get(reRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenWeGetTheQoSProvider(ReRoute reRoute)
 | 
			
		||||
        private void WhenWeGetTheQoSProvider(DownstreamReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _getResult = _qosProviderHouse.Get(reRoute);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,27 @@
 | 
			
		||||
using Butterfly.Client.Tracing;
 | 
			
		||||
using Moq;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Requester
 | 
			
		||||
{
 | 
			
		||||
    public class TracingHandlerFactoryTests
 | 
			
		||||
    {
 | 
			
		||||
        private TracingHandlerFactory _factory;
 | 
			
		||||
        private Mock<IServiceTracer> _tracer;
 | 
			
		||||
 | 
			
		||||
        public TracingHandlerFactoryTests()
 | 
			
		||||
        {
 | 
			
		||||
            _tracer = new Mock<IServiceTracer>();
 | 
			
		||||
            _factory = new TracingHandlerFactory(_tracer.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return()
 | 
			
		||||
        {
 | 
			
		||||
            var handler = _factory.Get();
 | 
			
		||||
            handler.ShouldBeOfType<OcelotHttpTracingHandler>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,32 +1,45 @@
 | 
			
		||||
namespace Ocelot.UnitTests.Responder
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Responder
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
    using System.Net.Http;
 | 
			
		||||
    using Microsoft.AspNetCore.Builder;
 | 
			
		||||
    using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Finder;
 | 
			
		||||
    using Ocelot.Errors;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Requester;
 | 
			
		||||
    using Ocelot.Responder;
 | 
			
		||||
    using Ocelot.Responder.Middleware;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
 | 
			
		||||
    public class ResponderMiddlewareTests : ServerHostedMiddlewareTest
 | 
			
		||||
    public class ResponderMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IHttpResponder> _responder;
 | 
			
		||||
        private readonly Mock<IErrorsToHttpStatusCodeMapper> _codeMapper;
 | 
			
		||||
        private OkResponse<HttpResponseMessage> _response;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private readonly ResponderMiddleware _middleware;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public ResponderMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _responder = new Mock<IHttpResponder>();
 | 
			
		||||
            _codeMapper = new Mock<IErrorsToHttpStatusCodeMapper>();
 | 
			
		||||
 | 
			
		||||
            GivenTheTestServerIsConfigured();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
            _logger = new Mock<IOcelotLogger>();
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<ResponderMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = async context => {
 | 
			
		||||
                //do nothing
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new ResponderMiddleware(_next, _responder.Object, _loggerFactory.Object, _codeMapper.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -39,7 +52,6 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_any_errors()
 | 
			
		||||
        {
 | 
			
		||||
@@ -50,33 +62,19 @@
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
 | 
			
		||||
        private void WhenICallTheMiddleware()
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton(_codeMapper.Object);
 | 
			
		||||
            services.AddSingleton(_responder.Object);
 | 
			
		||||
            services.AddSingleton(ScopedRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
 | 
			
		||||
        {
 | 
			
		||||
            app.UseResponderMiddleware();
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheHttpResponseMessageIs(HttpResponseMessage response)
 | 
			
		||||
        {
 | 
			
		||||
            _response = new OkResponse<HttpResponseMessage>(response);
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<HttpResponseMessage>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(_response);
 | 
			
		||||
            _downstreamContext.DownstreamResponse = response;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereAreNoPipelineErrors()
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<bool>(It.IsAny<string>()))
 | 
			
		||||
                .Returns(new OkResponse<bool>(false));
 | 
			
		||||
            _downstreamContext.Errors = new List<Error>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenThereAreNoErrors()
 | 
			
		||||
@@ -86,11 +84,7 @@
 | 
			
		||||
 | 
			
		||||
        private void GivenThereArePipelineErrors(Error error)
 | 
			
		||||
        {
 | 
			
		||||
            ScopedRepository
 | 
			
		||||
                .Setup(x => x.Get<bool>("OcelotMiddlewareError"))
 | 
			
		||||
                .Returns(new OkResponse<bool>(true));
 | 
			
		||||
            ScopedRepository.Setup(x => x.Get<List<Error>>("OcelotMiddlewareErrors"))
 | 
			
		||||
                .Returns(new OkResponse<List<Error>>(new List<Error>() { error }));
 | 
			
		||||
            _downstreamContext.Errors = new List<Error>(){error};
 | 
			
		||||
        }  
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
 | 
			
		||||
        private ServiceProviderConfiguration _serviceConfig;
 | 
			
		||||
        private IServiceDiscoveryProvider _result;
 | 
			
		||||
        private readonly ServiceDiscoveryProviderFactory _factory;
 | 
			
		||||
        private ReRoute _reRoute;
 | 
			
		||||
        private DownstreamReRoute _reRoute;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
 | 
			
		||||
        public ServiceProviderFactoryTests()
 | 
			
		||||
@@ -31,7 +31,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
 | 
			
		||||
            var serviceConfig = new ServiceProviderConfigurationBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder().Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
 | 
			
		||||
                .When(x => x.WhenIGetTheServiceProvider())
 | 
			
		||||
@@ -51,7 +51,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
 | 
			
		||||
                new DownstreamHostAndPort("abc.com", 80)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder().WithDownstreamAddresses(downstreamAddresses).Build();
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder().WithDownstreamAddresses(downstreamAddresses).Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
 | 
			
		||||
                .When(x => x.WhenIGetTheServiceProvider())
 | 
			
		||||
@@ -60,6 +60,23 @@ namespace Ocelot.UnitTests.ServiceDiscovery
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_consul_service_provider()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithServiceName("product")
 | 
			
		||||
                .WithUseServiceDiscovery(true)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var serviceConfig = new ServiceProviderConfigurationBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
 | 
			
		||||
                .When(x => x.WhenIGetTheServiceProvider())
 | 
			
		||||
                .Then(x => x.ThenTheServiceProviderIs<ConsulServiceDiscoveryProvider>())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheFollowingServicesAreReturned(List<DownstreamHostAndPort> downstreamAddresses)
 | 
			
		||||
        {
 | 
			
		||||
            var result = (ConfigurationServiceProvider)_result;
 | 
			
		||||
@@ -75,24 +92,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_consul_service_provider()
 | 
			
		||||
        {
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithServiceName("product")
 | 
			
		||||
                .WithUseServiceDiscovery(true)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            var serviceConfig = new ServiceProviderConfigurationBuilder()
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute))
 | 
			
		||||
                .When(x => x.WhenIGetTheServiceProvider())
 | 
			
		||||
                .Then(x => x.ThenTheServiceProviderIs<ConsulServiceDiscoveryProvider>())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig, ReRoute reRoute)
 | 
			
		||||
        private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig, DownstreamReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceConfig = serviceConfig;
 | 
			
		||||
            _reRoute = reRoute;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user