Implement mapping of HttpResponseMessage to CachedResponse to fix #152 (#153)

* changed name to cache options to fix issue #146

* Add acceptance test that exposes JSON deserialization bug from issue #146

- Create InMemoryJsonHandle for CacheManager that mimics DictionaryHandle but uses ICacheSerializer to serialize/deserialize values instead of saving references
- Add CacheManager.Serialization.Json package
- Add StartupWithCustomCacheHandle class that extends Startup and overrides ConfigureServices to register InMemoryJsonHandle
- Add GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache method to initiate Ocelot with StartupWithCustomCacheHandle
- Add test should_return_response_200_with_simple_url_when_using_jsonserialized_cache

* Create Acceptance test that exposes issue #152

- Add GivenOcelotIsRunningUsingJsonSerializedCache() that initializes Ocelot with InMemoryJsonHandle
- Add should_return_cached_response_when_using_jsonserialized_cache test

* Change Consul port to 9502 on should_return_response_200_with_simple_url_when_using_jsonserialized_cache() test

* Implement mapping of HttpResponseMessage to CachedResponse to enable distributed caching

- Add CachedResponse class that holds HttpResponse data
- Add mapping methods in OutputCacheMiddleware to create HttpResponseMessage from CachedResponse and vice versa
- Replace HttpResponseMessage with CachedResponse in services registrations
- Replace HttpResponseMessage with CachedResponse in OutputCacheController's IOcelotCache

* Fix unit tests for OutputCacheMiddleware and OutputCacheController by replacing HttpResponseMessage with CachedResponse

* Add .editorconfig with default identation settings (spaces with size 4)

* Re-format broken files with new identation settings

* Add Startup_WithConsul_And_CustomCacheHandle class

- Use Startup_WithConsul_And_CustomCacheHandle in GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache step

* Do minor cleanups

- Rename StartupWithCustomCacheHandle to Startup_WithCustomCacheHandle for better readability
- Remove cachemanager settings Action in Startup since it is not used anymore

* Drop Task in CreateHttpResponseMessage - unnecessary overhead

* Make setters private in CachedResponse

- Rework CreateCachedResponse to use new CachedResponse constructor
This commit is contained in:
Charalampos Chomenidis
2017-11-25 16:47:17 +02:00
committed by Tom Pallister
parent 3b27bb376e
commit 48b5a32676
15 changed files with 401 additions and 46 deletions

View File

@ -23,6 +23,7 @@ using Ocelot.Middleware;
using Ocelot.ServiceDiscovery;
using Shouldly;
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
using Ocelot.AcceptanceTests.Caching;
namespace Ocelot.AcceptanceTests
{
@ -74,9 +75,9 @@ namespace Ocelot.AcceptanceTests
/// </summary>
public void GivenOcelotIsRunning()
{
_webHostBuilder = new WebHostBuilder();
_webHostBuilder.ConfigureServices(s =>
_webHostBuilder = new WebHostBuilder();
_webHostBuilder.ConfigureServices(s =>
{
s.AddSingleton(_webHostBuilder);
});
@ -107,6 +108,21 @@ namespace Ocelot.AcceptanceTests
_ocelotClient = _ocelotServer.CreateClient();
}
public void GivenOcelotIsRunningUsingJsonSerializedCache()
{
_webHostBuilder = new WebHostBuilder();
_webHostBuilder.ConfigureServices(s =>
{
s.AddSingleton(_webHostBuilder);
});
_ocelotServer = new TestServer(_webHostBuilder
.UseStartup<Startup_WithCustomCacheHandle>());
_ocelotClient = _ocelotServer.CreateClient();
}
public void GivenOcelotIsRunningUsingConsulToStoreConfig()
{
_webHostBuilder = new WebHostBuilder();
@ -122,16 +138,31 @@ namespace Ocelot.AcceptanceTests
_ocelotClient = _ocelotServer.CreateClient();
}
public void GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache()
{
_webHostBuilder = new WebHostBuilder();
_webHostBuilder.ConfigureServices(s =>
{
s.AddSingleton(_webHostBuilder);
});
_ocelotServer = new TestServer(_webHostBuilder
.UseStartup<Startup_WithConsul_And_CustomCacheHandle>());
_ocelotClient = _ocelotServer.CreateClient();
}
internal void ThenTheResponseShouldBe(FileConfiguration expected)
{
var response = JsonConvert.DeserializeObject<FileConfiguration>(_response.Content.ReadAsStringAsync().Result);
response.GlobalConfiguration.AdministrationPath.ShouldBe(expected.GlobalConfiguration.AdministrationPath);
response.GlobalConfiguration.RequestIdKey.ShouldBe(expected.GlobalConfiguration.RequestIdKey);
response.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Host);
response.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Port);
for(var i = 0; i < response.ReRoutes.Count; i++)
for (var i = 0; i < response.ReRoutes.Count; i++)
{
response.ReRoutes[i].DownstreamHost.ShouldBe(expected.ReRoutes[i].DownstreamHost);
response.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expected.ReRoutes[i].DownstreamPathTemplate);
@ -155,7 +186,7 @@ namespace Ocelot.AcceptanceTests
var configuration = builder.Build();
_webHostBuilder = new WebHostBuilder();
_webHostBuilder.ConfigureServices(s =>
_webHostBuilder.ConfigureServices(s =>
{
s.AddSingleton(_webHostBuilder);
});
@ -172,7 +203,7 @@ namespace Ocelot.AcceptanceTests
})
.WithDictionaryHandle();
};
s.AddOcelot(configuration);
})
.ConfigureLogging(l =>
@ -299,12 +330,12 @@ namespace Ocelot.AcceptanceTests
public void WhenIGetUrlOnTheApiGatewayMultipleTimes(string url, int times)
{
var tasks = new Task[times];
for (int i = 0; i < times; i++)
{
var urlCopy = url;
tasks[i] = GetForServiceDiscoveryTest(urlCopy);
Thread.Sleep(_random.Next(40,60));
Thread.Sleep(_random.Next(40, 60));
}
Task.WaitAll(tasks);
@ -327,7 +358,7 @@ namespace Ocelot.AcceptanceTests
request.Headers.Add("ClientId", clientId);
_response = _ocelotClient.SendAsync(request).Result;
}
}
}
public void WhenIGetUrlOnTheApiGateway(string url, string requestId)
{