Feature/downstream aggregation (#248)

* started messing around with this on the train last night

* mega hacking away to change middleware into Ocelot iddleware

* scoped data repo back in

* broken commit getting tests working

* another broken commit farting around with tests

* all unit tests passing again

* mw pipeline for ocelot...still loads of hacks but getting there now to get acceptance tests working, then fix config so you can have aggregate and then imlement multiplexer, then mapping to response...loads to do

* all tests passing before aggregation feature implemented

* removed all the request middleware stuff we dont need it

* updated how errors work...tho i think there could be edge case here when aggregating because one downstream could error and this would effect another

* removed multiplexer so you dont have to send route down, this isnt very thread safe...sigh

* hacking around getting the config for aggregates in, this might change

* refactored builder and unit tests passing now

* Updated a bunch of ports for tests

* plugged in code to create reroutes that are aggregates

* made multiplexer a class

* hacked test to death

* simple aggregator done, initial validation done

* removed request id from context, it is still specific for http request

* now aggregates to json always

* docs for aggregate reroutes

* Updated docs
This commit is contained in:
Tom Pallister
2018-02-27 08:22:47 +00:00
committed by GitHub
parent 2573657ec2
commit d1926268ac
137 changed files with 4032 additions and 2007 deletions

View File

@ -1,4 +1,6 @@
using System.Net;
using Ocelot.Errors;
using Ocelot.Middleware;
namespace Ocelot.UnitTests.Cache
{
@ -6,6 +8,7 @@ namespace Ocelot.UnitTests.Cache
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Cache;
@ -13,26 +16,37 @@ namespace Ocelot.UnitTests.Cache
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Logging;
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
public class OutputCacheMiddlewareTests : ServerHostedMiddlewareTest
public class OutputCacheMiddlewareTests
{
private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
private Mock<IOcelotLoggerFactory> _loggerFactory;
private Mock<IOcelotLogger> _logger;
private OutputCacheMiddleware _middleware;
private DownstreamContext _downstreamContext;
private OcelotRequestDelegate _next;
private CachedResponse _response;
private IRegionCreator _regionCreator;
public OutputCacheMiddlewareTests()
{
_cacheManager = new Mock<IOcelotCache<CachedResponse>>();
_regionCreator = new RegionCreator();
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_logger = new Mock<IOcelotLogger>();
_loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
_next = async context => {
//do nothing
};
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
GivenTheTestServerIsConfigured();
_downstreamContext.DownstreamRequest = new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123");
}
[Fact]
@ -41,7 +55,6 @@ namespace Ocelot.UnitTests.Cache
var cachedResponse = new CachedResponse(HttpStatusCode.OK, new Dictionary<string, IEnumerable<string>>(), "", new Dictionary<string, IEnumerable<string>>());
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereIsADownstreamUrl())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheCacheGetIsCalledCorrectly())
.BDDfy();
@ -53,24 +66,15 @@ namespace Ocelot.UnitTests.Cache
this.Given(x => x.GivenResponseIsNotCached())
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereAreNoErrors())
.And(x => x.GivenThereIsADownstreamUrl())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheCacheAddIsCalledCorrectly())
.BDDfy();
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
private void WhenICallTheMiddleware()
{
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_cacheManager.Object);
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton<IRegionCreator, RegionCreator>();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseOutputCacheMiddleware();
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager.Object, _regionCreator);
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
}
private void GivenThereIsACachedResponse(CachedResponse response)
@ -83,38 +87,30 @@ namespace Ocelot.UnitTests.Cache
private void GivenResponseIsNotCached()
{
ScopedRepository
.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
.Returns(new OkResponse<HttpResponseMessage>(new HttpResponseMessage()));
_downstreamContext.DownstreamResponse = new HttpResponseMessage();
}
private void GivenTheDownstreamRouteIs()
{
var reRoute = new ReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100, "kanken"))
.WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100, "kanken"))
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
_downstreamContext.TemplatePlaceholderNameAndValues = downstreamRoute.TemplatePlaceholderNameAndValues;
_downstreamContext.DownstreamReRoute = downstreamRoute.ReRoute.DownstreamReRoute[0];
}
private void GivenThereAreNoErrors()
{
ScopedRepository
.Setup(x => x.Get<bool>("OcelotMiddlewareError"))
.Returns(new OkResponse<bool>(false));
}
_downstreamContext.Errors = new List<Error>();
private void GivenThereIsADownstreamUrl()
{
ScopedRepository
.Setup(x => x.Get<string>("DownstreamUrl"))
.Returns(new OkResponse<string>("anything"));
}
private void ThenTheCacheGetIsCalledCorrectly()