Skip to content

Commit

Permalink
messing around (#230)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomPallister authored Feb 13, 2018
1 parent 947a145 commit 6f177fb
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 9 deletions.
11 changes: 8 additions & 3 deletions src/Ocelot/Cache/CachedResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ namespace Ocelot.Cache
public class CachedResponse
{
public CachedResponse(
HttpStatusCode statusCode = HttpStatusCode.OK,
Dictionary<string, IEnumerable<string>> headers = null,
string body = null
HttpStatusCode statusCode,
Dictionary<string, IEnumerable<string>> headers,
string body,
Dictionary<string, IEnumerable<string>> contentHeaders

)
{
StatusCode = statusCode;
Headers = headers ?? new Dictionary<string, IEnumerable<string>>();
ContentHeaders = contentHeaders ?? new Dictionary<string, IEnumerable<string>>();
Body = body ?? "";
}

public HttpStatusCode StatusCode { 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; }
}
}
13 changes: 12 additions & 1 deletion src/Ocelot/Cache/Middleware/OutputCacheMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,21 @@ internal HttpResponseMessage CreateHttpResponseMessage(CachedResponse cached)
}

var response = new HttpResponseMessage(cached.StatusCode);

foreach (var header in cached.Headers)
{
response.Headers.Add(header.Key, header.Value);
}

var content = new MemoryStream(Convert.FromBase64String(cached.Body));

response.Content = new StreamContent(content);

foreach (var header in cached.ContentHeaders)
{
response.Content.Headers.Add(header.Key, header.Value);
}

return response;
}

Expand All @@ -109,7 +117,10 @@ internal async Task<CachedResponse> CreateCachedResponse(HttpResponseMessage res
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;
}
}
Expand Down
1 change: 1 addition & 0 deletions test/Ocelot.AcceptanceTests/CachingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public void should_return_cached_response()
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.And(x => _steps.ThenTheContentLengthIs(16))
.BDDfy();
}

Expand Down
5 changes: 5 additions & 0 deletions test/Ocelot.AcceptanceTests/Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -457,5 +457,10 @@ public void ThenTheRequestIdIsReturned(string expected)
{
_response.Headers.GetValues(RequestIdKey).First().ShouldBe(expected);
}

public void ThenTheContentLengthIs(int expected)
{
_response.Content.Headers.ContentLength.ShouldBe(expected);
}
}
}
2 changes: 1 addition & 1 deletion test/Ocelot.ManualTest/ManualTestStartup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ public void Configure(IApplicationBuilder app)
app.UseOcelot().Wait();
}
}
}
}
3 changes: 1 addition & 2 deletions test/Ocelot.ManualTest/configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@
"UpstreamHttpMethod": [ "Get" ],
"HttpHandlerOptions": {
"AllowAutoRedirect": true,
"UseCookieContainer": true,
"UseTracing": true
"UseCookieContainer": true
},
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
Expand Down
131 changes: 131 additions & 0 deletions test/Ocelot.UnitTests/Cache/OutputCacheMiddlewareRealCacheTests.cs
Original file line number Diff line number Diff line change
@@ -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"));
}
}
}
6 changes: 4 additions & 2 deletions test/Ocelot.UnitTests/Cache/OutputCacheMiddlewareTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Ocelot.UnitTests.Cache
using System.Net;

namespace Ocelot.UnitTests.Cache
{
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -36,7 +38,7 @@ public OutputCacheMiddlewareTests()
[Fact]
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))
.And(x => x.GivenTheDownstreamRouteIs())
.And(x => x.GivenThereIsADownstreamUrl())
Expand Down

0 comments on commit 6f177fb

Please sign in to comment.