mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
messing around (#230)
This commit is contained in:
parent
947a1450d0
commit
6f177fbf5b
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user