messing around (#230)

This commit is contained in:
Tom Pallister 2018-02-13 23:00:41 +00:00 committed by GitHub
parent 947a1450d0
commit 6f177fbf5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 163 additions and 9 deletions

View File

@ -6,13 +6,16 @@ namespace Ocelot.Cache
public class CachedResponse public class CachedResponse
{ {
public CachedResponse( public CachedResponse(
HttpStatusCode statusCode = HttpStatusCode.OK, HttpStatusCode statusCode,
Dictionary<string, IEnumerable<string>> headers = null, Dictionary<string, IEnumerable<string>> headers,
string body = null string body,
Dictionary<string, IEnumerable<string>> contentHeaders
) )
{ {
StatusCode = statusCode; StatusCode = statusCode;
Headers = headers ?? new Dictionary<string, IEnumerable<string>>(); Headers = headers ?? new Dictionary<string, IEnumerable<string>>();
ContentHeaders = contentHeaders ?? new Dictionary<string, IEnumerable<string>>();
Body = body ?? ""; Body = body ?? "";
} }
@ -20,6 +23,8 @@ namespace Ocelot.Cache
public Dictionary<string, IEnumerable<string>> Headers { get; private set; } public Dictionary<string, IEnumerable<string>> Headers { get; private set; }
public Dictionary<string, IEnumerable<string>> ContentHeaders { get; private set; }
public string Body { get; private set; } public string Body { get; private set; }
} }
} }

View File

@ -82,13 +82,21 @@ namespace Ocelot.Cache.Middleware
} }
var response = new HttpResponseMessage(cached.StatusCode); var response = new HttpResponseMessage(cached.StatusCode);
foreach (var header in cached.Headers) foreach (var header in cached.Headers)
{ {
response.Headers.Add(header.Key, header.Value); response.Headers.Add(header.Key, header.Value);
} }
var content = new MemoryStream(Convert.FromBase64String(cached.Body)); var content = new MemoryStream(Convert.FromBase64String(cached.Body));
response.Content = new StreamContent(content); response.Content = new StreamContent(content);
foreach (var header in cached.ContentHeaders)
{
response.Content.Headers.Add(header.Key, header.Value);
}
return response; return response;
} }
@ -109,7 +117,10 @@ namespace Ocelot.Cache.Middleware
body = Convert.ToBase64String(content); body = Convert.ToBase64String(content);
} }
var cached = new CachedResponse(statusCode, headers, body); var contentHeaders = response?.Content?.Headers.ToDictionary(v => v.Key, v => v.Value);
var cached = new CachedResponse(statusCode, headers, body, contentHeaders);
return cached; return cached;
} }
} }

View File

@ -61,6 +61,7 @@ namespace Ocelot.AcceptanceTests
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.And(x => _steps.ThenTheContentLengthIs(16))
.BDDfy(); .BDDfy();
} }

View File

@ -457,5 +457,10 @@ namespace Ocelot.AcceptanceTests
{ {
_response.Headers.GetValues(RequestIdKey).First().ShouldBe(expected); _response.Headers.GetValues(RequestIdKey).First().ShouldBe(expected);
} }
public void ThenTheContentLengthIs(int expected)
{
_response.Content.Headers.ContentLength.ShouldBe(expected);
}
} }
} }

View File

@ -76,8 +76,7 @@
"UpstreamHttpMethod": [ "Get" ], "UpstreamHttpMethod": [ "Get" ],
"HttpHandlerOptions": { "HttpHandlerOptions": {
"AllowAutoRedirect": true, "AllowAutoRedirect": true,
"UseCookieContainer": true, "UseCookieContainer": true
"UseTracing": true
}, },
"QoSOptions": { "QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3, "ExceptionsAllowedBeforeBreaking": 3,

View File

@ -0,0 +1,131 @@
using Ocelot.Infrastructure.RequestData;
namespace Ocelot.UnitTests.Cache
{
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using CacheManager.Core;
using Shouldly;
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Cache;
using Ocelot.Cache.Middleware;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Logging;
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
public class OutputCacheMiddlewareRealCacheTests : ServerHostedMiddlewareTest
{
private IOcelotCache<CachedResponse> _cacheManager;
private CachedResponse _response;
private IRequestScopedDataRepository _repo;
public OutputCacheMiddlewareRealCacheTests()
{
ScopedRepository
.Setup(sr => sr.Get<HttpRequestMessage>("DownstreamRequest"))
.Returns(new OkResponse<HttpRequestMessage>(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123")));
GivenTheTestServerIsConfigured();
}
[Fact]
public void should_cache_content_headers()
{
var content = new StringContent("{\"Test\": 1}")
{
Headers = { ContentType = new MediaTypeHeaderValue("application/json")}
};
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = content,
};
this.Given(x => x.GivenResponseIsNotCached(response))
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereAreNoErrors())
.And(x => x.GivenThereIsADownstreamUrl())
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheContentTypeHeaderIsCached())
.BDDfy();
}
private void ThenTheContentTypeHeaderIsCached()
{
var result = _cacheManager.Get("GET-https://some.url/blah?abcd=123", "kanken");
var header = result.ContentHeaders["Content-Type"];
header.First().ShouldBe("application/json");
}
protected override void GivenTheTestServerServicesAreConfigured(IServiceCollection services)
{
var cacheManagerOutputCache = CacheFactory.Build<CachedResponse>("OcelotOutputCache", x =>
{
x.WithDictionaryHandle();
});
_cacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
services.AddSingleton<ICacheManager<CachedResponse>>(cacheManagerOutputCache);
services.AddSingleton<IOcelotCache<CachedResponse>>(_cacheManager);
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddLogging();
services.AddSingleton(_cacheManager);
services.AddSingleton(ScopedRepository.Object);
services.AddSingleton<IRegionCreator, RegionCreator>();
}
protected override void GivenTheTestServerPipelineIsConfigured(IApplicationBuilder app)
{
app.UseOutputCacheMiddleware();
}
private void GivenResponseIsNotCached(HttpResponseMessage message)
{
ScopedRepository
.Setup(x => x.Get<HttpResponseMessage>("HttpResponseMessage"))
.Returns(new OkResponse<HttpResponseMessage>(message));
}
private void GivenTheDownstreamRouteIs()
{
var reRoute = new ReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100, "kanken"))
.WithUpstreamHttpMethod(new List<string> { "Get" })
.Build();
var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))
.Returns(new OkResponse<DownstreamRoute>(downstreamRoute));
}
private void GivenThereAreNoErrors()
{
ScopedRepository
.Setup(x => x.Get<bool>("OcelotMiddlewareError"))
.Returns(new OkResponse<bool>(false));
}
private void GivenThereIsADownstreamUrl()
{
ScopedRepository
.Setup(x => x.Get<string>("DownstreamUrl"))
.Returns(new OkResponse<string>("anything"));
}
}
}

View File

@ -1,4 +1,6 @@
namespace Ocelot.UnitTests.Cache using System.Net;
namespace Ocelot.UnitTests.Cache
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -36,7 +38,7 @@
[Fact] [Fact]
public void should_returned_cached_item_when_it_is_in_cache() public void should_returned_cached_item_when_it_is_in_cache()
{ {
var cachedResponse = new CachedResponse(); var cachedResponse = new CachedResponse(HttpStatusCode.OK, new Dictionary<string, IEnumerable<string>>(), "", new Dictionary<string, IEnumerable<string>>());
this.Given(x => x.GivenThereIsACachedResponse(cachedResponse)) this.Given(x => x.GivenThereIsACachedResponse(cachedResponse))
.And(x => x.GivenTheDownstreamRouteIs()) .And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereIsADownstreamUrl()) .And(x => x.GivenThereIsADownstreamUrl())