mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 19:50:49 +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:
		
							
								
								
									
										372
									
								
								test/Ocelot.AcceptanceTests/AggregateTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										372
									
								
								test/Ocelot.AcceptanceTests/AggregateTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,372 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    public class AggregateTests : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private IWebHost _serviceOneBuilder;
 | 
			
		||||
        private IWebHost _serviceTwoBuilder;
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
        private string _downstreamPathOne;
 | 
			
		||||
        private string _downstreamPathTwo;
 | 
			
		||||
 | 
			
		||||
        public AggregateTests()
 | 
			
		||||
        {
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_with_simple_url()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51885,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51886,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Tom"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string> 
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var expected = "{\"Laura\":{Hello from Laura},\"Tom\":{Hello from Tom}}";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51885", "/", 200, "{Hello from Laura}"))
 | 
			
		||||
                .Given(x => x.GivenServiceTwoIsRunning("http://localhost:51886", "/", 200, "{Hello from Tom}"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe(expected))
 | 
			
		||||
                .And(x => ThenTheDownstreamUrlPathShouldBe("/", "/"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_with_simple_url_one_service_404()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51881,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51882,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Tom"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var expected = "{\"Laura\":,\"Tom\":{Hello from Tom}}";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51881", "/", 404, ""))
 | 
			
		||||
                .Given(x => x.GivenServiceTwoIsRunning("http://localhost:51882", "/", 200, "{Hello from Tom}"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe(expected))
 | 
			
		||||
                .And(x => ThenTheDownstreamUrlPathShouldBe("/", "/"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_with_simple_url_both_service_404()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51883,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/laura",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Laura"
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51884,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/tom",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            Key = "Tom"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                Aggregates = new List<FileAggregateReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileAggregateReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
                            UpstreamHost = "localhost",
 | 
			
		||||
                            ReRouteKeys = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "Tom",
 | 
			
		||||
                                "Laura"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var expected = "{\"Laura\":,\"Tom\":}";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51883", "/", 404, ""))
 | 
			
		||||
                .Given(x => x.GivenServiceTwoIsRunning("http://localhost:51884", "/", 404, ""))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe(expected))
 | 
			
		||||
                .And(x => ThenTheDownstreamUrlPathShouldBe("/", "/"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_be_thread_safe()
 | 
			
		||||
        {
 | 
			
		||||
            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.GivenServiceOneIsRunning("http://localhost:51878", "/", 200, "{Hello from Laura}"))
 | 
			
		||||
                .Given(x => x.GivenServiceTwoIsRunning("http://localhost:51880", "/", 200, "{Hello from Tom}"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIMakeLotsOfDifferentRequestsToTheApiGateway())
 | 
			
		||||
                .And(x => ThenTheDownstreamUrlPathShouldBe("/", "/"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenServiceOneIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceOneBuilder = new WebHostBuilder()
 | 
			
		||||
                .UseUrls(baseUrl)
 | 
			
		||||
                .UseKestrel()
 | 
			
		||||
                .UseContentRoot(Directory.GetCurrentDirectory())
 | 
			
		||||
                .UseIISIntegration()
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.UsePathBase(basePath);
 | 
			
		||||
                    app.Run(async context =>
 | 
			
		||||
                    {   
 | 
			
		||||
                        _downstreamPathOne = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
 | 
			
		||||
 | 
			
		||||
                        if(_downstreamPathOne != basePath)
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync("downstream path didnt match base path");
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync(responseBody);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            _serviceOneBuilder.Start();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenServiceTwoIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceOneBuilder = new WebHostBuilder()
 | 
			
		||||
                .UseUrls(baseUrl)
 | 
			
		||||
                .UseKestrel()
 | 
			
		||||
                .UseContentRoot(Directory.GetCurrentDirectory())
 | 
			
		||||
                .UseIISIntegration()
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.UsePathBase(basePath);
 | 
			
		||||
                    app.Run(async context =>
 | 
			
		||||
                    {   
 | 
			
		||||
                        _downstreamPathTwo = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
 | 
			
		||||
 | 
			
		||||
                        if(_downstreamPathTwo != basePath)
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync("downstream path didnt match base path");
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync(responseBody);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            _serviceOneBuilder.Start();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPathOne, string expectedDownstreamPath)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamPathOne.ShouldBe(expectedDownstreamPathOne);
 | 
			
		||||
            _downstreamPathTwo.ShouldBe(expectedDownstreamPath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceOneBuilder?.Dispose();
 | 
			
		||||
            _serviceTwoBuilder?.Dispose();
 | 
			
		||||
            _steps.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										225
									
								
								test/Ocelot.AcceptanceTests/ButterflyTracingTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								test/Ocelot.AcceptanceTests/ButterflyTracingTests.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using Butterfly.Client.AspNetCore;
 | 
			
		||||
using static Rafty.Infrastructure.Wait;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    public class ButterflyTracingTests : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private IWebHost _serviceOneBuilder;
 | 
			
		||||
        private IWebHost _serviceTwoBuilder;
 | 
			
		||||
        private IWebHost _fakeButterfly;
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
        private string _downstreamPathOne;
 | 
			
		||||
        private string _downstreamPathTwo;
 | 
			
		||||
        private int _butterflyCalled;
 | 
			
		||||
 | 
			
		||||
        public ButterflyTracingTests()
 | 
			
		||||
        {
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_forward_tracing_information_from_ocelot_and_downstream_services()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/api/values",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51887,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/api001/values",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            HttpHandlerOptions = new FileHttpHandlerOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                UseTracing  = true
 | 
			
		||||
                            },
 | 
			
		||||
                            QoSOptions = new FileQoSOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                ExceptionsAllowedBeforeBreaking = 3,
 | 
			
		||||
                                DurationOfBreak = 10,
 | 
			
		||||
                                TimeoutValue = 5000
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamPathTemplate = "/api/values",
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51888,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/api002/values",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string> { "Get" },
 | 
			
		||||
                            HttpHandlerOptions = new FileHttpHandlerOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                UseTracing  = true
 | 
			
		||||
                            },
 | 
			
		||||
                            QoSOptions = new FileQoSOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                ExceptionsAllowedBeforeBreaking = 3,
 | 
			
		||||
                                DurationOfBreak = 10,
 | 
			
		||||
                                TimeoutValue = 5000
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var butterflyUrl = "http://localhost:9618";
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenServiceOneIsRunning("http://localhost:51887", "/api/values", 200, "Hello from Laura", butterflyUrl))
 | 
			
		||||
                .And(x => GivenServiceTwoIsRunning("http://localhost:51888", "/api/values", 200, "Hello from Tom", butterflyUrl))
 | 
			
		||||
                .And(x => GivenFakeButterfly(butterflyUrl))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunningUsingButterfly(butterflyUrl))
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/api001/values"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                 .When(x => _steps.WhenIGetUrlOnTheApiGateway("/api002/values"))
 | 
			
		||||
                 .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                 .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Tom"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            var commandOnAllStateMachines = WaitFor(5000).Until(() => _butterflyCalled == 4);
 | 
			
		||||
 | 
			
		||||
            commandOnAllStateMachines.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenServiceOneIsRunning(string baseUrl, string basePath, int statusCode, string responseBody, string butterflyUrl)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceOneBuilder = new WebHostBuilder()
 | 
			
		||||
                .UseUrls(baseUrl)
 | 
			
		||||
                .UseKestrel()
 | 
			
		||||
                .UseContentRoot(Directory.GetCurrentDirectory())
 | 
			
		||||
                .UseIISIntegration()
 | 
			
		||||
                .ConfigureServices(services => {
 | 
			
		||||
                    services.AddButterfly(option =>
 | 
			
		||||
                    {
 | 
			
		||||
                        option.CollectorUrl = butterflyUrl;
 | 
			
		||||
                        option.Service = "Service One";
 | 
			
		||||
                        option.IgnoredRoutesRegexPatterns = new string[0];
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.UsePathBase(basePath);
 | 
			
		||||
                    app.Run(async context =>
 | 
			
		||||
                    {   
 | 
			
		||||
                        _downstreamPathOne = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
 | 
			
		||||
 | 
			
		||||
                        if(_downstreamPathOne != basePath)
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync("downstream path didnt match base path");
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync(responseBody);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            _serviceOneBuilder.Start();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenFakeButterfly(string baseUrl)
 | 
			
		||||
        {
 | 
			
		||||
            _fakeButterfly = new WebHostBuilder()
 | 
			
		||||
                .UseUrls(baseUrl)
 | 
			
		||||
                .UseKestrel()
 | 
			
		||||
                .UseContentRoot(Directory.GetCurrentDirectory())
 | 
			
		||||
                .UseIISIntegration()
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.Run(async context =>
 | 
			
		||||
                    {
 | 
			
		||||
                        _butterflyCalled++;
 | 
			
		||||
                        await context.Response.WriteAsync("OK...");
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            _fakeButterfly.Start();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenServiceTwoIsRunning(string baseUrl, string basePath, int statusCode, string responseBody, string butterflyUrl)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceTwoBuilder = new WebHostBuilder()
 | 
			
		||||
                .UseUrls(baseUrl)
 | 
			
		||||
                .UseKestrel()
 | 
			
		||||
                .UseContentRoot(Directory.GetCurrentDirectory())
 | 
			
		||||
                .UseIISIntegration()
 | 
			
		||||
                .ConfigureServices(services => {
 | 
			
		||||
                    services.AddButterfly(option =>
 | 
			
		||||
                    {
 | 
			
		||||
                        option.CollectorUrl = butterflyUrl;
 | 
			
		||||
                        option.Service = "Service Two";
 | 
			
		||||
                        option.IgnoredRoutesRegexPatterns = new string[0];
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.UsePathBase(basePath);
 | 
			
		||||
                    app.Run(async context =>
 | 
			
		||||
                    {   
 | 
			
		||||
                        _downstreamPathTwo = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
 | 
			
		||||
 | 
			
		||||
                        if(_downstreamPathTwo != basePath)
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync("downstream path didnt match base path");
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            context.Response.StatusCode = statusCode;
 | 
			
		||||
                            await context.Response.WriteAsync(responseBody);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            _serviceTwoBuilder.Start();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPathOne, string expectedDownstreamPath)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamPathOne.ShouldBe(expectedDownstreamPathOne);
 | 
			
		||||
            _downstreamPathTwo.ShouldBe(expectedDownstreamPath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceOneBuilder?.Dispose();
 | 
			
		||||
            _serviceTwoBuilder?.Dispose();
 | 
			
		||||
            _fakeButterfly?.Dispose();
 | 
			
		||||
            _steps.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -37,7 +37,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51899,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -51,13 +51,13 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                .Given(x => x.GivenTheServiceNowReturns("http://localhost:51879", 200, "Hello from Tom"))
 | 
			
		||||
                .Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
@@ -80,7 +80,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51899,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -94,13 +94,13 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunningUsingJsonSerializedCache())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                .Given(x => x.GivenTheServiceNowReturns("http://localhost:51879", 200, "Hello from Tom"))
 | 
			
		||||
                .Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
@@ -122,7 +122,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51899,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -136,13 +136,13 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                .Given(x => x.GivenTheServiceNowReturns("http://localhost:51879", 200, "Hello from Tom"))
 | 
			
		||||
                .Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
 | 
			
		||||
                .And(x => x.GivenTheCacheExpires())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51877,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -46,7 +46,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
 | 
			
		||||
@@ -69,7 +69,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51877,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -80,7 +80,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
 | 
			
		||||
@@ -103,7 +103,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51877,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -114,7 +114,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
 | 
			
		||||
@@ -137,7 +137,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51877,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -148,7 +148,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
 | 
			
		||||
@@ -171,7 +171,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51877,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -182,7 +182,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
 | 
			
		||||
@@ -205,7 +205,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51877,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -216,7 +216,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51877", "/api/products/1", 200, "Some Product"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/PRODUCTS/1"))
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51876,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -81,7 +81,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/ClientRateLimit"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", "/api/ClientRateLimit"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit",1))
 | 
			
		||||
@@ -109,7 +109,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51876,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -140,7 +140,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/ClientRateLimit"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", "/api/ClientRateLimit"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 4))
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,10 @@ using System.Diagnostics;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
@@ -275,7 +272,11 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
 | 
			
		||||
        private void GivenIWaitForTheConfigToReplicateToOcelot()
 | 
			
		||||
        {
 | 
			
		||||
            Thread.Sleep(10000);
 | 
			
		||||
            var stopWatch = Stopwatch.StartNew();
 | 
			
		||||
            while (stopWatch.ElapsedMilliseconds < 10000)
 | 
			
		||||
            {
 | 
			
		||||
                //do nothing!
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheConsulConfigurationIs(FileConfiguration config)
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_pre_query_string_builder_middleware()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new OcelotMiddlewareConfiguration
 | 
			
		||||
            var configuration = new OcelotPipelineConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                AuthorisationMiddleware = async (ctx, next) =>
 | 
			
		||||
                {
 | 
			
		||||
@@ -75,7 +75,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_authorisation_middleware()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new OcelotMiddlewareConfiguration
 | 
			
		||||
            var configuration = new OcelotPipelineConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                AuthorisationMiddleware = async (ctx, next) =>
 | 
			
		||||
                {
 | 
			
		||||
@@ -118,7 +118,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_authentication_middleware()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new OcelotMiddlewareConfiguration
 | 
			
		||||
            var configuration = new OcelotPipelineConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                AuthenticationMiddleware = async (ctx, next) =>
 | 
			
		||||
                {
 | 
			
		||||
@@ -161,7 +161,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_pre_error_middleware()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new OcelotMiddlewareConfiguration
 | 
			
		||||
            var configuration = new OcelotPipelineConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                PreErrorResponderMiddleware = async (ctx, next) =>
 | 
			
		||||
                {
 | 
			
		||||
@@ -204,7 +204,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_pre_authorisation_middleware()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new OcelotMiddlewareConfiguration
 | 
			
		||||
            var configuration = new OcelotPipelineConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                PreAuthorisationMiddleware = async (ctx, next) =>
 | 
			
		||||
                {
 | 
			
		||||
@@ -247,7 +247,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_pre_http_authentication_middleware()
 | 
			
		||||
        {
 | 
			
		||||
            var configuration = new OcelotMiddlewareConfiguration
 | 
			
		||||
            var configuration = new OcelotPipelineConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                PreAuthenticationMiddleware = async (ctx, next) =>
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51871,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -54,7 +54,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Laz"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51871", "/", 200, "Laz"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenIAddAHeader("Laz", "D"))
 | 
			
		||||
@@ -80,7 +80,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51871,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -93,7 +93,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Location", "http://www.bbc.co.uk/"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51871", "/", 200, "Location", "http://www.bbc.co.uk/"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
			
		||||
    <TargetFramework>netcoreapp2.0</TargetFramework>
 | 
			
		||||
@@ -20,16 +19,13 @@
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </None>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
  <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
 | 
			
		||||
</ItemGroup>
 | 
			
		||||
 | 
			
		||||
    <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="CacheManager.Serialization.Json" Version="1.1.1" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
 | 
			
		||||
@@ -52,6 +48,6 @@
 | 
			
		||||
    <PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
 | 
			
		||||
    <PackageReference Include="Consul" Version="0.7.2.3" />
 | 
			
		||||
    <PackageReference Include="xunit" Version="2.3.1" />
 | 
			
		||||
     <PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" /> 
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 51879,
 | 
			
		||||
                                Port = 51872,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -57,7 +57,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51879", "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51872", "Hello from Laura"))
 | 
			
		||||
                .Given(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .Given(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -92,7 +92,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 51879,
 | 
			
		||||
                                Port = 51872,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -122,7 +122,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51879", "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAPossiblyBrokenServiceRunningOn("http://localhost:51872", "Hello from Laura"))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51880/", 200, "Hello from Tom"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51873,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -50,7 +50,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51873"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -73,7 +73,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51873,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -85,7 +85,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
 | 
			
		||||
            var requestId = Guid.NewGuid().ToString();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51873"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", requestId))
 | 
			
		||||
@@ -108,7 +108,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51873,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamScheme = "http",
 | 
			
		||||
@@ -124,7 +124,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
 | 
			
		||||
            var requestId = Guid.NewGuid().ToString();
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51873"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", requestId))
 | 
			
		||||
 
 | 
			
		||||
@@ -298,7 +298,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 51879,
 | 
			
		||||
                                Port = 51874,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        UpstreamPathTemplate = "/vacancy/",
 | 
			
		||||
@@ -315,7 +315,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 51879,
 | 
			
		||||
                                Port = 51874,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        UpstreamPathTemplate = "/vacancy/{vacancyId}",
 | 
			
		||||
@@ -326,7 +326,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/v1/vacancy/1", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51874", "/api/v1/vacancy/1", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/vacancy/1"))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
@@ -24,6 +26,8 @@ using Ocelot.ServiceDiscovery;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
 | 
			
		||||
using Ocelot.AcceptanceTests.Caching;
 | 
			
		||||
using Butterfly.Client.AspNetCore;
 | 
			
		||||
using Butterfly.Client.Tracing;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
@@ -103,6 +107,49 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal void GivenOcelotIsRunningUsingButterfly(string butterflyUrl)
 | 
			
		||||
        {
 | 
			
		||||
            _webHostBuilder = new WebHostBuilder();
 | 
			
		||||
 | 
			
		||||
            _webHostBuilder
 | 
			
		||||
                .ConfigureAppConfiguration((hostingContext, config) =>
 | 
			
		||||
                {
 | 
			
		||||
                    config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
 | 
			
		||||
                    var env = hostingContext.HostingEnvironment;
 | 
			
		||||
                    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
 | 
			
		||||
                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
 | 
			
		||||
                    config.AddJsonFile("configuration.json");
 | 
			
		||||
                    config.AddEnvironmentVariables();
 | 
			
		||||
                })
 | 
			
		||||
                .ConfigureServices(s =>
 | 
			
		||||
                {
 | 
			
		||||
                    s.AddOcelot()
 | 
			
		||||
                    .AddOpenTracing(option =>
 | 
			
		||||
                    {
 | 
			
		||||
                        //this is the url that the butterfly collector server is running on...
 | 
			
		||||
                        option.CollectorUrl = butterflyUrl;
 | 
			
		||||
                        option.Service = "Ocelot";
 | 
			
		||||
                    });
 | 
			
		||||
                })
 | 
			
		||||
                .Configure(app =>
 | 
			
		||||
                {
 | 
			
		||||
                    app.Use(async (context, next) =>
 | 
			
		||||
                    {
 | 
			
		||||
                        await next.Invoke();
 | 
			
		||||
                    });
 | 
			
		||||
                    app.UseOcelot().Wait();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            _ocelotServer = new TestServer(_webHostBuilder);
 | 
			
		||||
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
/*
 | 
			
		||||
        public void GivenIHaveAddedXForwardedForHeader(string value)
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotClient.DefaultRequestHeaders.TryAddWithoutValidation("X-Forwarded-For", value);
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        public void GivenOcelotIsRunningWithMiddleareBeforePipeline<T>(Func<object, Task> callback)
 | 
			
		||||
        {
 | 
			
		||||
            _webHostBuilder = new WebHostBuilder();
 | 
			
		||||
@@ -336,7 +383,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void GivenOcelotIsRunning(OcelotMiddlewareConfiguration ocelotMiddlewareConfig)
 | 
			
		||||
        public void GivenOcelotIsRunning(OcelotPipelineConfiguration ocelotPipelineConfig)
 | 
			
		||||
        {
 | 
			
		||||
            var builder = new ConfigurationBuilder()
 | 
			
		||||
                .SetBasePath(Directory.GetCurrentDirectory())
 | 
			
		||||
@@ -373,7 +420,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                })
 | 
			
		||||
                .Configure(a =>
 | 
			
		||||
                {
 | 
			
		||||
                    a.UseOcelot(ocelotMiddlewareConfig).Wait();
 | 
			
		||||
                    a.UseOcelot(ocelotPipelineConfig).Wait();
 | 
			
		||||
                }));
 | 
			
		||||
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
@@ -552,7 +599,6 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            _response.StatusCode.ShouldBe(expectedHttpStatusCode);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public void ThenTheStatusCodeShouldBe(int expectedHttpStatusCode)
 | 
			
		||||
        {
 | 
			
		||||
            var responseStatusCode = (int)_response.StatusCode;
 | 
			
		||||
@@ -579,5 +625,51 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        {
 | 
			
		||||
            _response.Content.Headers.ContentLength.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void WhenIMakeLotsOfDifferentRequestsToTheApiGateway()
 | 
			
		||||
        {
 | 
			
		||||
            int numberOfRequests = 100;
 | 
			
		||||
            var aggregateUrl = "/";
 | 
			
		||||
            var aggregateExpected = "{\"Laura\":{Hello from Laura},\"Tom\":{Hello from Tom}}";
 | 
			
		||||
            var tomUrl = "/tom";
 | 
			
		||||
            var tomExpected = "{Hello from Tom}";
 | 
			
		||||
            var lauraUrl = "/laura";
 | 
			
		||||
            var lauraExpected = "{Hello from Laura}";
 | 
			
		||||
            var random = new Random();
 | 
			
		||||
 | 
			
		||||
            var aggregateTasks = new Task[numberOfRequests];
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < numberOfRequests; i++)
 | 
			
		||||
            {
 | 
			
		||||
                aggregateTasks[i] = Fire(aggregateUrl, aggregateExpected, random);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var tomTasks = new Task[numberOfRequests];
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < numberOfRequests; i++)
 | 
			
		||||
            {
 | 
			
		||||
                tomTasks[i] = Fire(tomUrl, tomExpected, random);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var lauraTasks = new Task[numberOfRequests];
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < numberOfRequests; i++)
 | 
			
		||||
            {
 | 
			
		||||
                lauraTasks[i] = Fire(lauraUrl, lauraExpected, random);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Task.WaitAll(lauraTasks);
 | 
			
		||||
            Task.WaitAll(tomTasks);
 | 
			
		||||
            Task.WaitAll(aggregateTasks);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task Fire(string url, string expectedBody, Random random)
 | 
			
		||||
        {
 | 
			
		||||
            var request = new HttpRequestMessage(new HttpMethod("GET"), url);
 | 
			
		||||
            await Task.Delay(random.Next(0, 2));
 | 
			
		||||
            var response = await _ocelotClient.SendAsync(request);
 | 
			
		||||
            var content = await response.Content.ReadAsStringAsync();
 | 
			
		||||
            content.ShouldBe(expectedBody);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "localhost",
 | 
			
		||||
                                    Port = 51879,
 | 
			
		||||
                                    Port = 51875,
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -49,7 +49,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -75,7 +75,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 51879,
 | 
			
		||||
                                Port = 51875,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -101,7 +101,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -142,7 +142,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 51879,
 | 
			
		||||
                                Port = 51875,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -152,7 +152,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -192,7 +192,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 51879,
 | 
			
		||||
                                Port = 51875,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -202,7 +202,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
@@ -227,7 +227,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            new FileHostAndPort
 | 
			
		||||
                            {
 | 
			
		||||
                                Host = "localhost",
 | 
			
		||||
                                Port = 51879,
 | 
			
		||||
                                Port = 51875,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        UpstreamPathTemplate = "/",
 | 
			
		||||
@@ -237,7 +237,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(configuration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user