mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 10:35:28 +08:00 
			
		
		
		
	messing around (#230)
This commit is contained in:
		@@ -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())
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user