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:
Tom Pallister 2018-03-01 12:58:36 +00:00 committed by GitHub
parent 18c34aa998
commit 9f1fb002c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 449 additions and 100 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -21,7 +21,7 @@ All you need to do to hook into your own IdentityServer is add the following to
}; };
services services
.AddOcelot(Configuration) .AddOcelot()
.AddAdministration("/administration", options); .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) public virtual void ConfigureServices(IServiceCollection services)
{ {
services services
.AddOcelot(Configuration) .AddOcelot()
.AddAdministration("/administration", "secret"); .AddAdministration("/administration", "secret");
} }

View File

@ -63,7 +63,7 @@ If you want to authenticate using JWT tokens maybe from a provider like Auth0 yo
x.Audience = "test"; x.Audience = "test";
}); });
services.AddOcelot(Configuration); services.AddOcelot();
} }
Then map the authentication provider key to a ReRoute in your configuration e.g. 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() services.AddAuthentication()
.AddIdentityServerAuthentication(authenticationProviderKey, options); .AddIdentityServerAuthentication(authenticationProviderKey, options);
services.AddOcelot(Configuration); services.AddOcelot();
} }
Then map the authentication provider key to a ReRoute in your configuration e.g. Then map the authentication provider key to a ReRoute in your configuration e.g.

View File

@ -109,7 +109,7 @@ If you add the following when you register your services Ocelot will attempt to
.. code-block:: csharp .. code-block:: csharp
services services
.AddOcelot(Configuration) .AddOcelot()
.AddStoreOcelotConfigurationInConsul(); .AddStoreOcelotConfigurationInConsul();
You also need to add the following to your configuration.json. This is how Ocelot You also need to add the following to your configuration.json. This is how Ocelot

View File

@ -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) public virtual void ConfigureServices(IServiceCollection services)
{ {
services services
.AddOcelot(Configuration) .AddOcelot()
.AddAdministration("/administration", "secret") .AddAdministration("/administration", "secret")
.AddRafty(); .AddRafty();
} }

View File

@ -12,7 +12,7 @@ In your ConfigureServices method
.. code-block:: csharp .. code-block:: csharp
services services
.AddOcelot(Configuration) .AddOcelot()
.AddOpenTracing(option => .AddOpenTracing(option =>
{ {
//this is the url that the butterfly collector server is running on... //this is the url that the butterfly collector server is running on...

View File

@ -11,11 +11,11 @@ namespace Ocelot.Configuration.Repository
{ {
public class ConsulFileConfigurationPoller : IDisposable public class ConsulFileConfigurationPoller : IDisposable
{ {
private IOcelotLogger _logger; private readonly IOcelotLogger _logger;
private IFileConfigurationRepository _repo; private readonly IFileConfigurationRepository _repo;
private IFileConfigurationSetter _setter; private readonly IFileConfigurationSetter _setter;
private string _previousAsJson; private string _previousAsJson;
private Timer _timer; private readonly Timer _timer;
private bool _polling; private bool _polling;
public ConsulFileConfigurationPoller(IOcelotLoggerFactory factory, IFileConfigurationRepository repo, IFileConfigurationSetter setter) public ConsulFileConfigurationPoller(IOcelotLoggerFactory factory, IFileConfigurationRepository repo, IFileConfigurationSetter setter)

View File

@ -1,3 +1,4 @@
using Butterfly.Client.Tracing;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Ocelot.Middleware.Multiplexer; using Ocelot.Middleware.Multiplexer;
@ -147,9 +148,13 @@ namespace Ocelot.DependencyInjection
//these get picked out later and added to http request //these get picked out later and added to http request
_provider = new DelegatingHandlerHandlerProvider(); _provider = new DelegatingHandlerHandlerProvider();
_services.TryAddSingleton<IDelegatingHandlerHandlerProvider>(_provider); _services.TryAddSingleton<IDelegatingHandlerHandlerProvider>(_provider);
_services.AddTransient<ITracingHandler, NoTracingHandler>();
_services.TryAddSingleton<IMultiplexer, Multiplexer>(); _services.TryAddSingleton<IMultiplexer, Multiplexer>();
_services.TryAddSingleton<IResponseAggregator, SimpleJsonResponseAggregator>(); _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) public IOcelotAdministrationBuilder AddAdministration(string path, string secret)
@ -192,7 +197,8 @@ namespace Ocelot.DependencyInjection
public IOcelotBuilder AddOpenTracing(Action<ButterflyOptions> settings) 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); _services.AddButterfly(settings);
return this; return this;
} }

View File

@ -173,23 +173,34 @@
var ocelotConfigurationRepository = var ocelotConfigurationRepository =
(IOcelotConfigurationRepository) builder.ApplicationServices.GetService( (IOcelotConfigurationRepository) builder.ApplicationServices.GetService(
typeof(IOcelotConfigurationRepository)); typeof(IOcelotConfigurationRepository));
var ocelotConfigurationCreator = var ocelotConfigurationCreator =
(IOcelotConfigurationCreator) builder.ApplicationServices.GetService( (IOcelotConfigurationCreator) builder.ApplicationServices.GetService(
typeof(IOcelotConfigurationCreator)); typeof(IOcelotConfigurationCreator));
var fileConfigFromConsul = await consulFileConfigRepo.Get(); var fileConfigFromConsul = await consulFileConfigRepo.Get();
if (fileConfigFromConsul.Data == null) if (fileConfigFromConsul.Data == null)
{ {
config = await setter.Set(fileConfig.Value); config = await setter.Set(fileConfig.Value);
var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
} }
else else
{ {
var ocelotConfig = await ocelotConfigurationCreator.Create(fileConfigFromConsul.Data); var ocelotConfig = await ocelotConfigurationCreator.Create(fileConfigFromConsul.Data);
if(ocelotConfig.IsError) if(ocelotConfig.IsError)
{ {
return new ErrorResponse(ocelotConfig.Errors); return new ErrorResponse(ocelotConfig.Errors);
} }
config = await ocelotConfigurationRepository.AddOrReplace(ocelotConfig.Data); 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. //todo - this starts the poller if it has been registered...please this is so bad.
var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller)); var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
} }

View File

@ -23,7 +23,7 @@
<DebugSymbols>True</DebugSymbols> <DebugSymbols>True</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <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="FluentValidation" Version="7.2.1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.1.0" /> <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />

View File

@ -1,3 +1,4 @@
using System;
using System.Net.Http; using System.Net.Http;
using Ocelot.Configuration; using Ocelot.Configuration;
using Ocelot.Logging; using Ocelot.Logging;
@ -8,17 +9,17 @@ namespace Ocelot.Requester
{ {
public class DelegatingHandlerHandlerProviderFactory : IDelegatingHandlerHandlerProviderFactory public class DelegatingHandlerHandlerProviderFactory : IDelegatingHandlerHandlerProviderFactory
{ {
private readonly ITracingHandler _tracingHandler; private readonly ITracingHandlerFactory _factory;
private readonly IOcelotLoggerFactory _loggerFactory; private readonly IOcelotLoggerFactory _loggerFactory;
private readonly IDelegatingHandlerHandlerProvider _allRoutesProvider; private readonly IDelegatingHandlerHandlerProvider _allRoutesProvider;
private readonly IQosProviderHouse _qosProviderHouse; private readonly IQosProviderHouse _qosProviderHouse;
public DelegatingHandlerHandlerProviderFactory(IOcelotLoggerFactory loggerFactory, public DelegatingHandlerHandlerProviderFactory(IOcelotLoggerFactory loggerFactory,
IDelegatingHandlerHandlerProvider allRoutesProvider, IDelegatingHandlerHandlerProvider allRoutesProvider,
ITracingHandler tracingHandler, ITracingHandlerFactory factory,
IQosProviderHouse qosProviderHouse) IQosProviderHouse qosProviderHouse)
{ {
_tracingHandler = tracingHandler; _factory = factory;
_loggerFactory = loggerFactory; _loggerFactory = loggerFactory;
_allRoutesProvider = allRoutesProvider; _allRoutesProvider = allRoutesProvider;
_qosProviderHouse = qosProviderHouse; _qosProviderHouse = qosProviderHouse;
@ -37,7 +38,7 @@ namespace Ocelot.Requester
if (request.HttpHandlerOptions.UseTracing) if (request.HttpHandlerOptions.UseTracing)
{ {
provider.Add(() => (DelegatingHandler)_tracingHandler); provider.Add(() => (DelegatingHandler)_factory.Get());
} }
if (request.IsQos) if (request.IsQos)

View File

@ -26,8 +26,10 @@ namespace Ocelot.Requester
{ {
var provider = _house.Get(request); var provider = _house.Get(request);
var handlers = provider.Data.Get();
//todo handle error //todo handle error
provider.Data.Get() handlers
.Select(handler => handler) .Select(handler => handler)
.Reverse() .Reverse()
.ToList() .ToList()

View File

@ -0,0 +1,7 @@
namespace Ocelot.Requester
{
public interface ITracingHandlerFactory
{
ITracingHandler Get();
}
}

View File

@ -12,11 +12,6 @@ namespace Ocelot.Requester
{ {
} }
public class NoTracingHandler : DelegatingHandler, ITracingHandler
{
}
public class OcelotHttpTracingHandler : DelegatingHandler, ITracingHandler public class OcelotHttpTracingHandler : DelegatingHandler, ITracingHandler
{ {
private readonly IServiceTracer _tracer; private readonly IServiceTracer _tracer;

View 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();
}
}
}

View 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();
}
}
}

View File

@ -4,13 +4,10 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Text; using System.Text;
using System.Threading;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Newtonsoft.Json; using Newtonsoft.Json;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File; using Ocelot.Configuration.File;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
@ -275,7 +272,11 @@ namespace Ocelot.AcceptanceTests
private void GivenIWaitForTheConfigToReplicateToOcelot() private void GivenIWaitForTheConfigToReplicateToOcelot()
{ {
Thread.Sleep(10000); var stopWatch = Stopwatch.StartNew();
while (stopWatch.ElapsedMilliseconds < 10000)
{
//do nothing!
}
} }
private void GivenTheConsulConfigurationIs(FileConfiguration config) private void GivenTheConsulConfigurationIs(FileConfiguration config)

View File

@ -1,5 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<VersionPrefix>0.0.0-dev</VersionPrefix> <VersionPrefix>0.0.0-dev</VersionPrefix>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
@ -13,22 +12,18 @@
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Update="configuration.json;appsettings.json"> <None Update="configuration.json;appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" /> <ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
<ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" /> <ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CacheManager.Serialization.Json" Version="1.1.1" /> <PackageReference Include="CacheManager.Serialization.Json" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
@ -48,6 +43,6 @@
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" /> <PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="Consul" Version="0.7.2.3" /> <PackageReference Include="Consul" Version="0.7.2.3" />
<PackageReference Include="xunit" Version="2.3.1" /> <PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -26,6 +26,8 @@ using Ocelot.ServiceDiscovery;
using Shouldly; using Shouldly;
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder; using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
using Ocelot.AcceptanceTests.Caching; using Ocelot.AcceptanceTests.Caching;
using Butterfly.Client.AspNetCore;
using Butterfly.Client.Tracing;
namespace Ocelot.AcceptanceTests namespace Ocelot.AcceptanceTests
{ {
@ -105,6 +107,49 @@ namespace Ocelot.AcceptanceTests
_ocelotClient = _ocelotServer.CreateClient(); _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) public void GivenOcelotIsRunningWithMiddleareBeforePipeline<T>(Func<object, Task> callback)
{ {
_webHostBuilder = new WebHostBuilder(); _webHostBuilder = new WebHostBuilder();

View File

@ -25,7 +25,6 @@ namespace Ocelot.ManualTest
.AddEnvironmentVariables(); .AddEnvironmentVariables();
}) })
.ConfigureServices(s => { .ConfigureServices(s => {
s.AddAuthentication() s.AddAuthentication()
.AddJwtBearer("TestKey", x => .AddJwtBearer("TestKey", x =>
{ {

View File

@ -8,13 +8,13 @@
"DownstreamHostAndPorts": [ "DownstreamHostAndPorts": [
{ {
"Host": "localhost", "Host": "localhost",
"Port": 5001 "Port": 5007
} }
], ],
"HttpHandlerOptions": { "HttpHandlerOptions": {
"AllowAutoRedirect": true, "AllowAutoRedirect": true,
"UseCookieContainer": true, "UseCookieContainer": true,
"UseTracing": false "UseTracing": true
} }
}, },
{ {

View File

@ -50,6 +50,7 @@
<PackageReference Include="Shouldly" Version="3.0.0-beta0003" /> <PackageReference Include="Shouldly" Version="3.0.0-beta0003" />
<PackageReference Include="TestStack.BDDfy" Version="4.3.2" /> <PackageReference Include="TestStack.BDDfy" Version="4.3.2" />
<PackageReference Include="xunit" Version="2.3.1" /> <PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="Butterfly.Client.AspNetCore" Version="0.0.8" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -23,13 +23,15 @@ namespace Ocelot.UnitTests.Requester
private Response<IDelegatingHandlerHandlerProvider> _provider; private Response<IDelegatingHandlerHandlerProvider> _provider;
private readonly Mock<IDelegatingHandlerHandlerProvider> _allRoutesProvider; private readonly Mock<IDelegatingHandlerHandlerProvider> _allRoutesProvider;
private readonly Mock<IQosProviderHouse> _qosProviderHouse; private readonly Mock<IQosProviderHouse> _qosProviderHouse;
private readonly Mock<ITracingHandlerFactory> _tracingFactory;
public DelegatingHandlerHandlerProviderFactoryTests() public DelegatingHandlerHandlerProviderFactoryTests()
{ {
_tracingFactory = new Mock<ITracingHandlerFactory>();
_qosProviderHouse = new Mock<IQosProviderHouse>(); _qosProviderHouse = new Mock<IQosProviderHouse>();
_allRoutesProvider = new Mock<IDelegatingHandlerHandlerProvider>(); _allRoutesProvider = new Mock<IDelegatingHandlerHandlerProvider>();
_loggerFactory = new Mock<IOcelotLoggerFactory>(); _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) private void GivenTheQosProviderHouseReturns(Response<IQoSProvider> qosProvider)

View File

@ -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>();
}
}
}