mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 15:10:50 +08:00 
			
		
		
		
	Feature/#246 (#252)
* failing test * failing test but needs real butterfly server running..need to fix that...also worked out ive broken tracing...yey * brought in butterfly source code so i can work out how to write acceptance tests for this... * fixed the bug but still need to fix tracing * tracing working again across services but need to make tracing hook into new Ocelot middleware as it still uses asp.net middleware * removed butterfly libs brought in for testing
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								docs/favicon.ico
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/favicon.ico
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 8.1 KiB  | 
@@ -21,7 +21,7 @@ All you need to do to hook into your own IdentityServer is add the following to
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        services
 | 
			
		||||
            .AddOcelot(Configuration)
 | 
			
		||||
            .AddOcelot()
 | 
			
		||||
            .AddAdministration("/administration", options);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -51,7 +51,7 @@ The secret is the client secret that Ocelot's internal IdentityServer will use t
 | 
			
		||||
    public virtual void ConfigureServices(IServiceCollection services)
 | 
			
		||||
    {
 | 
			
		||||
        services
 | 
			
		||||
            .AddOcelot(Configuration)
 | 
			
		||||
            .AddOcelot()
 | 
			
		||||
            .AddAdministration("/administration", "secret");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ If you want to authenticate using JWT tokens maybe from a provider like Auth0 yo
 | 
			
		||||
                x.Audience = "test";
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        services.AddOcelot(Configuration);
 | 
			
		||||
        services.AddOcelot();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Then map the authentication provider key to a ReRoute in your configuration e.g.
 | 
			
		||||
@@ -111,7 +111,7 @@ In order to use IdentityServer bearer tokens register your IdentityServer servic
 | 
			
		||||
        services.AddAuthentication()
 | 
			
		||||
            .AddIdentityServerAuthentication(authenticationProviderKey, options);
 | 
			
		||||
 | 
			
		||||
        services.AddOcelot(Configuration);
 | 
			
		||||
        services.AddOcelot();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Then map the authentication provider key to a ReRoute in your configuration e.g.
 | 
			
		||||
 
 | 
			
		||||
@@ -109,7 +109,7 @@ If you add the following when you register your services Ocelot will attempt to
 | 
			
		||||
.. code-block:: csharp
 | 
			
		||||
 | 
			
		||||
 services
 | 
			
		||||
    .AddOcelot(Configuration)
 | 
			
		||||
    .AddOcelot()
 | 
			
		||||
    .AddStoreOcelotConfigurationInConsul();
 | 
			
		||||
 | 
			
		||||
You also need to add the following to your configuration.json. This is how Ocelot
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ In order to enable Rafty in Ocelot you must make the following changes to your S
 | 
			
		||||
    public virtual void ConfigureServices(IServiceCollection services)
 | 
			
		||||
    {
 | 
			
		||||
         services
 | 
			
		||||
            .AddOcelot(Configuration)
 | 
			
		||||
            .AddOcelot()
 | 
			
		||||
            .AddAdministration("/administration", "secret")
 | 
			
		||||
            .AddRafty();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ In your ConfigureServices method
 | 
			
		||||
.. code-block:: csharp
 | 
			
		||||
 | 
			
		||||
    services
 | 
			
		||||
        .AddOcelot(Configuration)
 | 
			
		||||
        .AddOcelot()
 | 
			
		||||
        .AddOpenTracing(option =>
 | 
			
		||||
        {
 | 
			
		||||
            //this is the url that the butterfly collector server is running on...
 | 
			
		||||
 
 | 
			
		||||
@@ -11,11 +11,11 @@ namespace Ocelot.Configuration.Repository
 | 
			
		||||
{
 | 
			
		||||
    public class ConsulFileConfigurationPoller : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private IOcelotLogger _logger; 
 | 
			
		||||
        private IFileConfigurationRepository _repo;
 | 
			
		||||
        private IFileConfigurationSetter _setter;
 | 
			
		||||
        private readonly IOcelotLogger _logger; 
 | 
			
		||||
        private readonly IFileConfigurationRepository _repo;
 | 
			
		||||
        private readonly IFileConfigurationSetter _setter;
 | 
			
		||||
        private string _previousAsJson;
 | 
			
		||||
        private Timer _timer;
 | 
			
		||||
        private readonly Timer _timer;
 | 
			
		||||
        private bool _polling;
 | 
			
		||||
 | 
			
		||||
        public ConsulFileConfigurationPoller(IOcelotLoggerFactory factory, IFileConfigurationRepository repo, IFileConfigurationSetter setter)
 | 
			
		||||
@@ -77,4 +77,4 @@ namespace Ocelot.Configuration.Repository
 | 
			
		||||
            _timer.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
using Butterfly.Client.Tracing;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
 | 
			
		||||
@@ -146,10 +147,14 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
 | 
			
		||||
            //these get picked out later and added to http request
 | 
			
		||||
            _provider = new DelegatingHandlerHandlerProvider();
 | 
			
		||||
            _services.TryAddSingleton<IDelegatingHandlerHandlerProvider>(_provider);
 | 
			
		||||
            _services.AddTransient<ITracingHandler, NoTracingHandler>();
 | 
			
		||||
            _services.TryAddSingleton<IDelegatingHandlerHandlerProvider>(_provider);            
 | 
			
		||||
            _services.TryAddSingleton<IMultiplexer, Multiplexer>();
 | 
			
		||||
            _services.TryAddSingleton<IResponseAggregator, SimpleJsonResponseAggregator>();
 | 
			
		||||
            _services.AddSingleton<ITracingHandlerFactory, TracingHandlerFactory>();
 | 
			
		||||
 | 
			
		||||
            // We add this here so that we can always inject something into the factory for IoC..
 | 
			
		||||
            _services.AddSingleton<IServiceTracer, FakeServiceTracer>();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IOcelotAdministrationBuilder AddAdministration(string path, string secret)
 | 
			
		||||
@@ -192,7 +197,8 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
 | 
			
		||||
        public IOcelotBuilder AddOpenTracing(Action<ButterflyOptions> settings)
 | 
			
		||||
        {
 | 
			
		||||
            _services.AddTransient<ITracingHandler, OcelotHttpTracingHandler>();
 | 
			
		||||
            // Earlier we add FakeServiceTracer and need to remove it here before we add butterfly
 | 
			
		||||
            _services.RemoveAll<IServiceTracer>();
 | 
			
		||||
            _services.AddButterfly(settings);   
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -173,23 +173,34 @@
 | 
			
		||||
            var ocelotConfigurationRepository =
 | 
			
		||||
                (IOcelotConfigurationRepository) builder.ApplicationServices.GetService(
 | 
			
		||||
                    typeof(IOcelotConfigurationRepository));
 | 
			
		||||
 | 
			
		||||
            var ocelotConfigurationCreator =
 | 
			
		||||
                (IOcelotConfigurationCreator) builder.ApplicationServices.GetService(
 | 
			
		||||
                    typeof(IOcelotConfigurationCreator));
 | 
			
		||||
 | 
			
		||||
            var fileConfigFromConsul = await consulFileConfigRepo.Get();
 | 
			
		||||
 | 
			
		||||
            if (fileConfigFromConsul.Data == null)
 | 
			
		||||
            {
 | 
			
		||||
                config = await setter.Set(fileConfig.Value);
 | 
			
		||||
                var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                var ocelotConfig = await ocelotConfigurationCreator.Create(fileConfigFromConsul.Data);
 | 
			
		||||
 | 
			
		||||
                if(ocelotConfig.IsError)
 | 
			
		||||
                {
 | 
			
		||||
                    return new ErrorResponse(ocelotConfig.Errors);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                config = await ocelotConfigurationRepository.AddOrReplace(ocelotConfig.Data);
 | 
			
		||||
 | 
			
		||||
                if (config.IsError)
 | 
			
		||||
                {
 | 
			
		||||
                    return new ErrorResponse(config.Errors);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //todo - this starts the poller if it has been registered...please this is so bad.
 | 
			
		||||
                var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
    <DebugSymbols>True</DebugSymbols>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.5" />
 | 
			
		||||
     <PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" /> 
 | 
			
		||||
    <PackageReference Include="FluentValidation" Version="7.2.1" />
 | 
			
		||||
    <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.1.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
@@ -8,17 +9,17 @@ namespace Ocelot.Requester
 | 
			
		||||
{
 | 
			
		||||
    public class DelegatingHandlerHandlerProviderFactory : IDelegatingHandlerHandlerProviderFactory
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ITracingHandler _tracingHandler;
 | 
			
		||||
        private readonly ITracingHandlerFactory _factory;
 | 
			
		||||
        private readonly IOcelotLoggerFactory _loggerFactory;
 | 
			
		||||
        private readonly IDelegatingHandlerHandlerProvider _allRoutesProvider;
 | 
			
		||||
        private readonly IQosProviderHouse _qosProviderHouse;
 | 
			
		||||
 | 
			
		||||
        public DelegatingHandlerHandlerProviderFactory(IOcelotLoggerFactory loggerFactory, 
 | 
			
		||||
            IDelegatingHandlerHandlerProvider allRoutesProvider, 
 | 
			
		||||
            ITracingHandler tracingHandler,
 | 
			
		||||
            IDelegatingHandlerHandlerProvider allRoutesProvider,
 | 
			
		||||
            ITracingHandlerFactory factory,
 | 
			
		||||
            IQosProviderHouse qosProviderHouse)
 | 
			
		||||
        {
 | 
			
		||||
            _tracingHandler = tracingHandler;
 | 
			
		||||
            _factory = factory;
 | 
			
		||||
            _loggerFactory = loggerFactory;
 | 
			
		||||
            _allRoutesProvider = allRoutesProvider;
 | 
			
		||||
            _qosProviderHouse = qosProviderHouse;
 | 
			
		||||
@@ -37,7 +38,7 @@ namespace Ocelot.Requester
 | 
			
		||||
 | 
			
		||||
            if (request.HttpHandlerOptions.UseTracing)
 | 
			
		||||
            {
 | 
			
		||||
                provider.Add(() => (DelegatingHandler)_tracingHandler);
 | 
			
		||||
                provider.Add(() => (DelegatingHandler)_factory.Get());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (request.IsQos)
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,10 @@ namespace Ocelot.Requester
 | 
			
		||||
        {
 | 
			
		||||
            var provider = _house.Get(request);
 | 
			
		||||
 | 
			
		||||
            var handlers = provider.Data.Get();
 | 
			
		||||
 | 
			
		||||
            //todo handle error
 | 
			
		||||
            provider.Data.Get()
 | 
			
		||||
            handlers
 | 
			
		||||
                .Select(handler => handler)
 | 
			
		||||
                .Reverse()
 | 
			
		||||
                .ToList()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								src/Ocelot/Requester/ITracingHandlerFactory.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/Ocelot/Requester/ITracingHandlerFactory.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
namespace Ocelot.Requester
 | 
			
		||||
{
 | 
			
		||||
    public interface ITracingHandlerFactory
 | 
			
		||||
    {
 | 
			
		||||
        ITracingHandler Get();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -12,11 +12,6 @@ namespace Ocelot.Requester
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class NoTracingHandler : DelegatingHandler, ITracingHandler
 | 
			
		||||
    {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class OcelotHttpTracingHandler : DelegatingHandler, ITracingHandler
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IServiceTracer _tracer;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								src/Ocelot/Requester/TracingHandlerFactory.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/Ocelot/Requester/TracingHandlerFactory.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
using Butterfly.Client.Tracing;
 | 
			
		||||
using Butterfly.OpenTracing;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Requester
 | 
			
		||||
{
 | 
			
		||||
    public class TracingHandlerFactory : ITracingHandlerFactory
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IServiceTracer _tracer;
 | 
			
		||||
 | 
			
		||||
        public TracingHandlerFactory(IServiceTracer tracer)
 | 
			
		||||
        {
 | 
			
		||||
            _tracer = tracer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ITracingHandler Get()
 | 
			
		||||
        {
 | 
			
		||||
            return new OcelotHttpTracingHandler(_tracer);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class FakeServiceTracer : IServiceTracer
 | 
			
		||||
    {
 | 
			
		||||
        public ITracer Tracer { get; }
 | 
			
		||||
        public string ServiceName { get; }
 | 
			
		||||
        public string Environment { get; }
 | 
			
		||||
        public string Identity { get; }
 | 
			
		||||
        public ISpan Start(ISpanBuilder spanBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            throw new System.NotImplementedException();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,53 +1,48 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
			
		||||
    <TargetFramework>netcoreapp2.0</TargetFramework>
 | 
			
		||||
    <RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
 | 
			
		||||
    <AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
 | 
			
		||||
    <OutputType>Exe</OutputType>
 | 
			
		||||
    <PackageId>Ocelot.AcceptanceTests</PackageId>
 | 
			
		||||
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
			
		||||
    <RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
 | 
			
		||||
    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
 | 
			
		||||
    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
 | 
			
		||||
    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Update="configuration.json;appsettings.json">
 | 
			
		||||
      <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>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="CacheManager.Serialization.Json" Version="1.1.1" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
 | 
			
		||||
    <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
 | 
			
		||||
    <PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
 | 
			
		||||
    <PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
 | 
			
		||||
    <PackageReference Include="Consul" Version="0.7.2.3" />
 | 
			
		||||
    <PackageReference Include="xunit" Version="2.3.1" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
			
		||||
    <TargetFramework>netcoreapp2.0</TargetFramework>
 | 
			
		||||
    <RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
 | 
			
		||||
    <AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
 | 
			
		||||
    <OutputType>Exe</OutputType>
 | 
			
		||||
    <PackageId>Ocelot.AcceptanceTests</PackageId>
 | 
			
		||||
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
			
		||||
    <RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
 | 
			
		||||
    <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
 | 
			
		||||
    <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
 | 
			
		||||
    <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Update="configuration.json;appsettings.json">
 | 
			
		||||
      <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>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="CacheManager.Serialization.Json" Version="1.1.1" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20171031-01" />
 | 
			
		||||
    <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.DotNet.InternalAbstractions" Version="1.0.500-preview2-1-003177" />
 | 
			
		||||
    <PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
 | 
			
		||||
    <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>
 | 
			
		||||
@@ -26,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
 | 
			
		||||
{
 | 
			
		||||
@@ -105,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();
 | 
			
		||||
 
 | 
			
		||||
@@ -25,25 +25,24 @@ namespace Ocelot.ManualTest
 | 
			
		||||
                        .AddEnvironmentVariables();
 | 
			
		||||
                })
 | 
			
		||||
                .ConfigureServices(s => {
 | 
			
		||||
 | 
			
		||||
                    s.AddAuthentication()
 | 
			
		||||
                     s.AddAuthentication()
 | 
			
		||||
                        .AddJwtBearer("TestKey", x =>
 | 
			
		||||
                        {
 | 
			
		||||
                            x.Authority = "test";
 | 
			
		||||
                            x.Audience = "test";
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                    s.AddOcelot()
 | 
			
		||||
                        .AddCacheManager(x =>
 | 
			
		||||
                        {
 | 
			
		||||
                            x.WithDictionaryHandle();
 | 
			
		||||
                        })
 | 
			
		||||
                        .AddOpenTracing(option =>
 | 
			
		||||
                        {
 | 
			
		||||
                            option.CollectorUrl = "http://localhost:9618";
 | 
			
		||||
                            option.Service = "Ocelot.ManualTest";
 | 
			
		||||
                        })
 | 
			
		||||
                        .AddAdministration("/administration", "secret");
 | 
			
		||||
                     s.AddOcelot()
 | 
			
		||||
                         .AddCacheManager(x =>
 | 
			
		||||
                         {
 | 
			
		||||
                             x.WithDictionaryHandle();
 | 
			
		||||
                         })
 | 
			
		||||
                         .AddOpenTracing(option =>
 | 
			
		||||
                         {
 | 
			
		||||
                             option.CollectorUrl = "http://localhost:9618";
 | 
			
		||||
                             option.Service = "Ocelot.ManualTest";
 | 
			
		||||
                         })
 | 
			
		||||
                         .AddAdministration("/administration", "secret");
 | 
			
		||||
                })
 | 
			
		||||
                .ConfigureLogging((hostingContext, logging) =>
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,13 +8,13 @@
 | 
			
		||||
      "DownstreamHostAndPorts": [
 | 
			
		||||
        {
 | 
			
		||||
          "Host": "localhost",
 | 
			
		||||
          "Port": 5001
 | 
			
		||||
          "Port": 5007
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "HttpHandlerOptions": {
 | 
			
		||||
        "AllowAutoRedirect": true,
 | 
			
		||||
        "UseCookieContainer": true,
 | 
			
		||||
        "UseTracing": false
 | 
			
		||||
        "UseTracing": true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,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>
 | 
			
		||||
 
 | 
			
		||||
@@ -23,13 +23,15 @@ namespace Ocelot.UnitTests.Requester
 | 
			
		||||
        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, _qosProviderHouse.Object);
 | 
			
		||||
            _factory = new DelegatingHandlerHandlerProviderFactory(_loggerFactory.Object, _allRoutesProvider.Object, _tracingFactory.Object, _qosProviderHouse.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheQosProviderHouseReturns(Response<IQoSProvider> qosProvider)
 | 
			
		||||
 
 | 
			
		||||
@@ -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>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user