mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-23 00:32:50 +08:00
more logging, more readme, more refactoring
This commit is contained in:
parent
8582ba45a9
commit
af506b079a
148
README.md
148
README.md
@ -21,9 +21,12 @@ to do this.
|
||||
|
||||
## How to install
|
||||
|
||||
Ocelot is designed to work with ASP.NET core only and is currently built to netcoreapp1.4 [this](https://docs.microsoft.com/en-us/dotnet/articles/standard/library) documentation may prove helpful when working out if Ocelot would be suitable for you.
|
||||
Ocelot is designed to work with ASP.NET core only and is currently
|
||||
built to netcoreapp1.4 [this](https://docs.microsoft.com/en-us/dotnet/articles/standard/library) documentation may prove helpful when working out if Ocelot would be suitable for you.
|
||||
|
||||
Install Ocelot and it's dependecies using nuget. At the moment all we have is the pre version. Once we have something working in a half decent way we will drop a version.
|
||||
Install Ocelot and it's dependecies using nuget. At the moment
|
||||
all we have is the pre version. Once we have something working in
|
||||
a half decent way we will drop a version.
|
||||
|
||||
`Install-Package Ocelot -Pre`
|
||||
|
||||
@ -36,40 +39,45 @@ and an explained configuration can be found [here](https://github.com/TomPallist
|
||||
|
||||
## Startup
|
||||
|
||||
An example startup using a json file for configuration can be seen below. Currently this is the only way to get configuration into Ocelot.
|
||||
An example startup using a json file for configuration can be seen below.
|
||||
Currently this is the only way to get configuration into Ocelot.
|
||||
|
||||
public class Startup
|
||||
{
|
||||
public IConfigurationRoot Configuration { get; }
|
||||
|
||||
public Startup(IHostingEnvironment env)
|
||||
{
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(env.ContentRootPath)
|
||||
.AddJsonFile("configuration.json", optional: true, reloadOnChange: true)
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
|
||||
.AddJsonFile("configuration.json")
|
||||
.AddEnvironmentVariables();
|
||||
|
||||
Configuration = builder.Build();
|
||||
}
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
|
||||
|
||||
public IConfigurationRoot Configuration { get; }
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
Action<ConfigurationBuilderCachePart> settings = (x) =>
|
||||
{
|
||||
x.WithMicrosoftLogging(log =>
|
||||
{
|
||||
log.AddConsole(LogLevel.Debug);
|
||||
})
|
||||
.WithDictionaryHandle();
|
||||
};
|
||||
|
||||
services.AddOcelotOutputCaching(settings);
|
||||
services.AddOcelotFileConfiguration(Configuration);
|
||||
services.AddOcelot();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole();
|
||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
app.UseOcelot();
|
||||
}
|
||||
}
|
||||
@ -77,26 +85,120 @@ An example startup using a json file for configuration can be seen below. Curren
|
||||
|
||||
This is pretty much all you need to get going.......more to come!
|
||||
|
||||
## Routing
|
||||
|
||||
Ocelot's primary functionality is to take incomeing http requests and forward them on
|
||||
to a downstream service. At the moment in the form of another http request (in the future
|
||||
this could be any transport mechanism.).
|
||||
|
||||
Ocelot's describes the routing of one request to another as a ReRoute. In order to get
|
||||
anything working in Ocelot you need to set up a ReRoute in the configuration.
|
||||
|
||||
{
|
||||
"ReRoutes": [
|
||||
]
|
||||
}
|
||||
|
||||
In order to set up a ReRoute you need to add one to the json array called ReRoutes like
|
||||
the following.
|
||||
|
||||
{
|
||||
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts/{postId}",
|
||||
"UpstreamTemplate": "/posts/{postId}",
|
||||
"UpstreamHttpMethod": "Put"
|
||||
}
|
||||
|
||||
The DownstreamTemplate is the URL that this request will be forwarded to.
|
||||
The UpstreamTemplate is the URL that Ocelot will use to identity which
|
||||
DownstreamTemplate to use for a given request. Finally the UpstreamHttpMethod is used so
|
||||
Ocelot can distinguish between requests to the same URL and is obviously needed to work :)
|
||||
In Ocelot you can add placeholders for variables to your Templates in the form of {something}.
|
||||
The placeholder needs to be in both the DownstreamTemplate and UpstreamTemplate. If it is
|
||||
Ocelot will attempt to replace the placeholder with the correct variable value from the
|
||||
Upstream URL when the request comes in.
|
||||
|
||||
At the moment all Ocelot routing is case sensitive. I think I will turn this off by default
|
||||
in the future with an options to make Ocelot case sensitive per ReRoute.
|
||||
|
||||
## Authentication
|
||||
|
||||
TBC...
|
||||
|
||||
## Authorisation
|
||||
|
||||
TBC...
|
||||
|
||||
## Claims to Headers Tranformation
|
||||
|
||||
BC...
|
||||
|
||||
## Claims to Claims
|
||||
|
||||
BC...
|
||||
|
||||
## Claims to Query String Parameters Tranformation
|
||||
|
||||
BC...
|
||||
|
||||
## Logging
|
||||
|
||||
Ocelot uses the standard logging interfaces ILoggerFactory / ILogger<T> at the moment. This is encapsulated in IOcelotLogger with
|
||||
an implementation for the standard asp.net core logging stuff at the moment.
|
||||
Ocelot uses the standard logging interfaces ILoggerFactory / ILogger<T> at the moment.
|
||||
This is encapsulated in IOcelotLogger / IOcelotLoggerFactory with an implementation
|
||||
for the standard asp.net core logging stuff at the moment.
|
||||
|
||||
There are a bunch of debugging logs in the ocelot middlewares however I think the
|
||||
system probably needs more logging in the code it calls into. Other than the debugging
|
||||
there is a global error handler that should catch any errors thrown and log them as errors.
|
||||
|
||||
The reason for not just using bog standard framework logging is that I could not
|
||||
work out how to override the request id that get's logged when setting IncludeScopes
|
||||
to true for logging settings. Nicely onto the next feature.
|
||||
|
||||
## RequestId / CorrelationId
|
||||
|
||||
Ocelot supports a client sending a request id in the form of a header. If set Ocelot will
|
||||
use the requestid for logging as soon as it becomes available in the middleware pipeline.
|
||||
Ocelot will also forward the request id with the specified header to the downstream service.
|
||||
I'm not sure if have this spot on yet in terms of the pipeline order becasue there are a few
|
||||
that don't get the users request id at the moment and ocelot just logs not set for request id
|
||||
which sucks. You can still get the framework request id in the logs if you set
|
||||
IncludeScopes true in your logging config.
|
||||
|
||||
In order to use the requestid feature in your ReRoute configuration add this setting
|
||||
|
||||
"RequestIdKey": "OcRequestId"
|
||||
|
||||
In this example OcRequestId is the request header that contains the clients request id.
|
||||
|
||||
## Caching
|
||||
|
||||
Ocelot supports some very rudimentary caching at the moment provider by the [CacheManager](http://cachemanager.net/) project. This is an amazing project
|
||||
that is solving a lot of caching problems. I would reccomend using this package to cache with Ocelot. If you look at the example [here](https://github.com/TomPallister/Ocelot/blob/develop/test/Ocelot.ManualTest/Startup.cs)
|
||||
you can see how the cache manager is setup and then passed into the Ocelot AddOcelotOutputCaching configuration method. You can
|
||||
use any settings supported by the CacheManager package and just pass them in.
|
||||
Ocelot supports some very rudimentary caching at the moment provider by
|
||||
the [CacheManager](http://cachemanager.net/) project. This is an amazing project
|
||||
that is solving a lot of caching problems. I would reccomend using this package to
|
||||
cache with Ocelot. If you look at the example [here](https://github.com/TomPallister/Ocelot/blob/develop/test/Ocelot.ManualTest/Startup.cs)
|
||||
you can see how the cache manager is setup and then passed into the Ocelot
|
||||
AddOcelotOutputCaching configuration method. You can use any settings supported by
|
||||
the CacheManager package and just pass them in.
|
||||
|
||||
Anyway Ocelot currently supports caching on the URL of the downstream service and setting a TTL in seconds to expire the cache. More to come!
|
||||
Anyway Ocelot currently supports caching on the URL of the downstream service
|
||||
and setting a TTL in seconds to expire the cache. More to come!
|
||||
|
||||
In orde to use caching on a route in your ReRoute configuration add this setting.
|
||||
|
||||
"FileCacheOptions": { "TtlSeconds": 15 }
|
||||
|
||||
In this example ttl seconds is set to 15 which means the cache will expire after 15 seconds.
|
||||
|
||||
## Not supported
|
||||
|
||||
Ocelot does not support...
|
||||
* Chunked Encoding - Ocelot will always get the body size and return Content-Length header. Sorry
|
||||
if this doesn't work for your use case!
|
||||
* Chunked Encoding - Ocelot will always get the body size and return Content-Length
|
||||
header. Sorry if this doesn't work for your use case!
|
||||
* Fowarding a host header - The host header that you send to Ocelot will not be forwarded to
|
||||
the downstream service. Obviously this would break everything :(
|
||||
|
||||
## Coming up
|
||||
|
||||
You can see what we are working on [here](https://github.com/TomPallister/Ocelot/projects/1)
|
||||
|
||||
|
||||
|
@ -1,16 +1,14 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Ocelot.Authentication.Handler
|
||||
namespace Ocelot.Authentication.Handler
|
||||
{
|
||||
public class AuthenticationHandler
|
||||
{
|
||||
public AuthenticationHandler(string provider, RequestDelegate handler)
|
||||
public AuthenticationHandler(string provider, IHandler handler)
|
||||
{
|
||||
Provider = provider;
|
||||
Handler = handler;
|
||||
}
|
||||
|
||||
public string Provider { get; private set; }
|
||||
public RequestDelegate Handler { get; private set; }
|
||||
public IHandler Handler { get; private set; }
|
||||
}
|
||||
}
|
@ -23,7 +23,8 @@ namespace Ocelot.Authentication.Handler.Factory
|
||||
|
||||
if (!handler.IsError)
|
||||
{
|
||||
return new OkResponse<AuthenticationHandler>(new AuthenticationHandler(authOptions.Provider, handler.Data));
|
||||
return new OkResponse<AuthenticationHandler>(
|
||||
new AuthenticationHandler(authOptions.Provider, new RequestDelegateHandler(handler.Data)));
|
||||
}
|
||||
|
||||
return new ErrorResponse<AuthenticationHandler>(new List<Error>
|
||||
|
10
src/Ocelot/Authentication/Handler/IHandler.cs
Normal file
10
src/Ocelot/Authentication/Handler/IHandler.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Ocelot.Authentication.Handler
|
||||
{
|
||||
public interface IHandler
|
||||
{
|
||||
Task Handle(HttpContext context);
|
||||
}
|
||||
}
|
20
src/Ocelot/Authentication/Handler/RequestDelegateHandler.cs
Normal file
20
src/Ocelot/Authentication/Handler/RequestDelegateHandler.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Ocelot.Authentication.Handler
|
||||
{
|
||||
public class RequestDelegateHandler : IHandler
|
||||
{
|
||||
private readonly RequestDelegate _requestDelegate;
|
||||
|
||||
public RequestDelegateHandler(RequestDelegate requestDelegate)
|
||||
{
|
||||
_requestDelegate = requestDelegate;
|
||||
}
|
||||
|
||||
public async Task Handle(HttpContext context)
|
||||
{
|
||||
await _requestDelegate.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@ namespace Ocelot.Authentication.Middleware
|
||||
{
|
||||
_logger.LogDebug("calling authentication handler for ReRoute");
|
||||
|
||||
await authenticationHandler.Data.Handler.Invoke(context);
|
||||
await authenticationHandler.Data.Handler.Handle(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ namespace Ocelot.Cache.Middleware
|
||||
|
||||
_logger.LogDebug("succesfully called next middleware");
|
||||
|
||||
if (PipelineError())
|
||||
if (PipelineError)
|
||||
{
|
||||
_logger.LogDebug("there was a pipeline error for {downstreamUrlKey}", downstreamUrlKey);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
|
@ -26,9 +26,9 @@ namespace Ocelot.Errors.Middleware
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogDebug("calling middleware");
|
||||
_logger.LogDebug("ocelot pipeline started");
|
||||
|
||||
_requestScopedDataRepository.Add("RequestId", context.TraceIdentifier);
|
||||
_logger.LogDebug("calling next middleware");
|
||||
|
||||
await _next.Invoke(context);
|
||||
|
||||
@ -42,6 +42,8 @@ namespace Ocelot.Errors.Middleware
|
||||
_logger.LogError(message, e);
|
||||
await SetInternalServerErrorOnResponse(context);
|
||||
}
|
||||
|
||||
_logger.LogDebug("ocelot pipeline finished");
|
||||
}
|
||||
|
||||
private static async Task SetInternalServerErrorOnResponse(HttpContext context)
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.Headers.Middleware
|
||||
@ -10,24 +12,45 @@ namespace Ocelot.Headers.Middleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IAddHeadersToRequest _addHeadersToRequest;
|
||||
private readonly IOcelotLogger _logger;
|
||||
|
||||
public HttpRequestHeadersBuilderMiddleware(RequestDelegate next,
|
||||
IOcelotLoggerFactory loggerFactory,
|
||||
IRequestScopedDataRepository requestScopedDataRepository,
|
||||
IAddHeadersToRequest addHeadersToRequest)
|
||||
: base(requestScopedDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_addHeadersToRequest = addHeadersToRequest;
|
||||
_logger = loggerFactory.CreateLogger<HttpRequestHeadersBuilderMiddleware>();
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
_logger.LogDebug("started calling headers builder middleware");
|
||||
|
||||
if (DownstreamRoute.ReRoute.ClaimsToHeaders.Any())
|
||||
{
|
||||
_addHeadersToRequest.SetHeadersOnContext(DownstreamRoute.ReRoute.ClaimsToHeaders, context);
|
||||
_logger.LogDebug("this route has instructions to convert claims to headers");
|
||||
|
||||
var response = _addHeadersToRequest.SetHeadersOnContext(DownstreamRoute.ReRoute.ClaimsToHeaders, context);
|
||||
|
||||
if (response.IsError)
|
||||
{
|
||||
_logger.LogDebug("there was an error setting headers on context, setting pipeline error");
|
||||
|
||||
SetPipelineError(response.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogDebug("headers have been set on context");
|
||||
}
|
||||
|
||||
_logger.LogDebug("calling next middleware");
|
||||
|
||||
await _next.Invoke(context);
|
||||
|
||||
_logger.LogDebug("succesfully called next middleware");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,21 +46,24 @@ namespace Ocelot.Logging
|
||||
|
||||
public void LogDebug(string message, params object[] args)
|
||||
{
|
||||
_logger.LogDebug(GetMessageWithRequestId(message), args);
|
||||
_logger.LogDebug(GetMessageWithOcelotRequestId(message), args);
|
||||
}
|
||||
|
||||
public void LogError(string message, Exception exception)
|
||||
{
|
||||
_logger.LogError(GetMessageWithRequestId(message), exception);
|
||||
_logger.LogError(GetMessageWithOcelotRequestId(message), exception);
|
||||
}
|
||||
|
||||
private string GetMessageWithRequestId(string message)
|
||||
private string GetMessageWithOcelotRequestId(string message)
|
||||
{
|
||||
var requestId = _scopedDataRepository.Get<string>("RequestId");
|
||||
|
||||
return requestId.IsError
|
||||
? $"{message} : RequestId: Error"
|
||||
: $"{message} : RequestId: {requestId.Data}";
|
||||
if (requestId != null && !requestId.IsError)
|
||||
{
|
||||
return $"{message} : OcelotRequestId - {requestId.Data}";
|
||||
|
||||
}
|
||||
return $"{message} : OcelotRequestId - not set";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,23 +15,23 @@ namespace Ocelot.Middleware
|
||||
_requestScopedDataRepository = requestScopedDataRepository;
|
||||
}
|
||||
|
||||
public void SetPipelineError(List<Error> errors)
|
||||
public bool PipelineError
|
||||
{
|
||||
_requestScopedDataRepository.Add("OcelotMiddlewareError", true);
|
||||
_requestScopedDataRepository.Add("OcelotMiddlewareErrors", errors);
|
||||
}
|
||||
|
||||
public bool PipelineError()
|
||||
get
|
||||
{
|
||||
var response = _requestScopedDataRepository.Get<bool>("OcelotMiddlewareError");
|
||||
return response.Data;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Error> GetPipelineErrors()
|
||||
public List<Error> PipelineErrors
|
||||
{
|
||||
get
|
||||
{
|
||||
var response = _requestScopedDataRepository.Get<List<Error>>("OcelotMiddlewareErrors");
|
||||
return response.Data;
|
||||
}
|
||||
}
|
||||
|
||||
public DownstreamRoute DownstreamRoute
|
||||
{
|
||||
@ -87,7 +87,12 @@ namespace Ocelot.Middleware
|
||||
public void SetHttpResponseMessageThisRequest(HttpResponseMessage responseMessage)
|
||||
{
|
||||
_requestScopedDataRepository.Add("HttpResponseMessage", responseMessage);
|
||||
}
|
||||
|
||||
public void SetPipelineError(List<Error> errors)
|
||||
{
|
||||
_requestScopedDataRepository.Add("OcelotMiddlewareError", true);
|
||||
_requestScopedDataRepository.Add("OcelotMiddlewareErrors", errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ namespace Ocelot.Middleware
|
||||
builder.UseIfNotNull(middlewareConfiguration.PreErrorResponderMiddleware);
|
||||
|
||||
// This is registered first so it can catch any errors and issue an appropriate response
|
||||
builder.UseHttpErrorResponderMiddleware();
|
||||
builder.UseResponderMiddleware();
|
||||
|
||||
// Then we get the downstream route information
|
||||
builder.UseDownstreamRouteFinderMiddleware();
|
||||
@ -108,7 +108,7 @@ namespace Ocelot.Middleware
|
||||
// Everything should now be ready to build or HttpRequest
|
||||
builder.UseHttpRequestBuilderMiddleware();
|
||||
|
||||
//We fire off the request and set the response on the context in this middleware
|
||||
//We fire off the request and set the response on the scoped data repo
|
||||
builder.UseHttpRequesterMiddleware();
|
||||
|
||||
return builder;
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.QueryStrings.Middleware
|
||||
@ -10,24 +12,43 @@ namespace Ocelot.QueryStrings.Middleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IAddQueriesToRequest _addQueriesToRequest;
|
||||
private readonly IOcelotLogger _logger;
|
||||
|
||||
public QueryStringBuilderMiddleware(RequestDelegate next,
|
||||
IOcelotLoggerFactory loggerFactory,
|
||||
IRequestScopedDataRepository requestScopedDataRepository,
|
||||
IAddQueriesToRequest addQueriesToRequest)
|
||||
: base(requestScopedDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_addQueriesToRequest = addQueriesToRequest;
|
||||
_logger = loggerFactory.CreateLogger<QueryStringBuilderMiddleware>();
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
_logger.LogDebug("started calling query string builder middleware");
|
||||
|
||||
if (DownstreamRoute.ReRoute.ClaimsToQueries.Any())
|
||||
{
|
||||
_addQueriesToRequest.SetQueriesOnContext(DownstreamRoute.ReRoute.ClaimsToQueries, context);
|
||||
_logger.LogDebug("this route has instructions to convert claims to queries");
|
||||
|
||||
var response = _addQueriesToRequest.SetQueriesOnContext(DownstreamRoute.ReRoute.ClaimsToQueries, context);
|
||||
|
||||
if (response.IsError)
|
||||
{
|
||||
_logger.LogDebug("there was an error setting queries on context, setting pipeline error");
|
||||
|
||||
SetPipelineError(response.Errors);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogDebug("calling next middleware");
|
||||
|
||||
await _next.Invoke(context);
|
||||
|
||||
_logger.LogDebug("succesfully called next middleware");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Request.Builder;
|
||||
|
||||
@ -10,18 +12,23 @@ namespace Ocelot.Request.Middleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IRequestCreator _requestCreator;
|
||||
private readonly IOcelotLogger _logger;
|
||||
|
||||
public HttpRequestBuilderMiddleware(RequestDelegate next,
|
||||
IOcelotLoggerFactory loggerFactory,
|
||||
IRequestScopedDataRepository requestScopedDataRepository,
|
||||
IRequestCreator requestCreator)
|
||||
:base(requestScopedDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_requestCreator = requestCreator;
|
||||
_logger = loggerFactory.CreateLogger<HttpRequestBuilderMiddleware>();
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
_logger.LogDebug("started calling request builder middleware");
|
||||
|
||||
var buildResult = await _requestCreator
|
||||
.Build(context.Request.Method, DownstreamUrl, context.Request.Body,
|
||||
context.Request.Headers, context.Request.Cookies, context.Request.QueryString,
|
||||
@ -29,13 +36,20 @@ namespace Ocelot.Request.Middleware
|
||||
|
||||
if (buildResult.IsError)
|
||||
{
|
||||
_logger.LogDebug("IRequestCreator returned an error, setting pipeline error");
|
||||
|
||||
SetPipelineError(buildResult.Errors);
|
||||
return;
|
||||
}
|
||||
_logger.LogDebug("setting upstream request");
|
||||
|
||||
SetUpstreamRequestForThisRequest(buildResult.Data);
|
||||
|
||||
_logger.LogDebug("calling next middleware");
|
||||
|
||||
await _next.Invoke(context);
|
||||
|
||||
_logger.LogDebug("succesfully called next middleware");
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.RequestId.Middleware
|
||||
@ -10,22 +11,35 @@ namespace Ocelot.RequestId.Middleware
|
||||
public class RequestIdMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IOcelotLogger _logger;
|
||||
private readonly IRequestScopedDataRepository _requestScopedDataRepository;
|
||||
|
||||
public RequestIdMiddleware(RequestDelegate next,
|
||||
IOcelotLoggerFactory loggerFactory,
|
||||
IRequestScopedDataRepository requestScopedDataRepository)
|
||||
:base(requestScopedDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_logger = loggerFactory.CreateLogger<RequestIdMiddleware>();
|
||||
_requestScopedDataRepository = requestScopedDataRepository;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
SetTraceIdentifier(context);
|
||||
_logger.LogDebug("started calling request id middleware");
|
||||
|
||||
SetOcelotRequestId(context);
|
||||
|
||||
_logger.LogDebug("set request id");
|
||||
|
||||
_logger.LogDebug("calling next middleware");
|
||||
|
||||
await _next.Invoke(context);
|
||||
|
||||
_logger.LogDebug("succesfully called next middleware");
|
||||
}
|
||||
|
||||
private void SetTraceIdentifier(HttpContext context)
|
||||
private void SetOcelotRequestId(HttpContext context)
|
||||
{
|
||||
var key = DefaultRequestIdKey.Value;
|
||||
|
||||
@ -38,6 +52,8 @@ namespace Ocelot.RequestId.Middleware
|
||||
|
||||
if (context.Request.Headers.TryGetValue(key, out requestId))
|
||||
{
|
||||
_requestScopedDataRepository.Add("RequestId", requestId.First());
|
||||
|
||||
context.TraceIdentifier = requestId;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.Requester.Middleware
|
||||
@ -9,27 +11,38 @@ namespace Ocelot.Requester.Middleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IHttpRequester _requester;
|
||||
private readonly IOcelotLogger _logger;
|
||||
|
||||
public HttpRequesterMiddleware(RequestDelegate next,
|
||||
IOcelotLoggerFactory loggerFactory,
|
||||
IHttpRequester requester,
|
||||
IRequestScopedDataRepository requestScopedDataRepository)
|
||||
:base(requestScopedDataRepository)
|
||||
{
|
||||
_next = next;
|
||||
_requester = requester;
|
||||
_logger = loggerFactory.CreateLogger<HttpRequesterMiddleware>();
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
_logger.LogDebug("started calling requester middleware");
|
||||
|
||||
var response = await _requester.GetResponse(Request);
|
||||
|
||||
if (response.IsError)
|
||||
{
|
||||
_logger.LogDebug("IHttpRequester returned an error, setting pipeline error");
|
||||
|
||||
SetPipelineError(response.Errors);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogDebug("setting http response message");
|
||||
|
||||
SetHttpResponseMessageThisRequest(response.Data);
|
||||
|
||||
_logger.LogDebug("returning to calling middleware");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
namespace Ocelot.Responder.Middleware
|
||||
{
|
||||
public static class HttpResponderMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseHttpErrorResponderMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<HttpErrorResponderMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Middleware;
|
||||
|
||||
namespace Ocelot.Responder.Middleware
|
||||
{
|
||||
public class HttpErrorResponderMiddleware : OcelotMiddleware
|
||||
public class ResponderMiddleware : OcelotMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IHttpResponder _responder;
|
||||
private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
|
||||
private readonly IOcelotLogger _logger;
|
||||
|
||||
public HttpErrorResponderMiddleware(RequestDelegate next,
|
||||
public ResponderMiddleware(RequestDelegate next,
|
||||
IHttpResponder responder,
|
||||
IOcelotLoggerFactory loggerFactory,
|
||||
IRequestScopedDataRepository requestScopedDataRepository,
|
||||
IErrorsToHttpStatusCodeMapper codeMapper)
|
||||
:base(requestScopedDataRepository)
|
||||
@ -22,24 +26,38 @@ namespace Ocelot.Responder.Middleware
|
||||
_next = next;
|
||||
_responder = responder;
|
||||
_codeMapper = codeMapper;
|
||||
_logger = loggerFactory.CreateLogger<ResponderMiddleware>();
|
||||
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
_logger.LogDebug("started error responder middleware");
|
||||
|
||||
await _next.Invoke(context);
|
||||
|
||||
if (PipelineError())
|
||||
_logger.LogDebug("calling next middleware");
|
||||
|
||||
if (PipelineError)
|
||||
{
|
||||
var errors = GetPipelineErrors();
|
||||
_logger.LogDebug("there is a pipeline error, getting errors");
|
||||
|
||||
var errors = PipelineErrors;
|
||||
|
||||
_logger.LogDebug("received errors setting error response");
|
||||
|
||||
await SetErrorResponse(context, errors);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogDebug("no pipeline error, setting response");
|
||||
|
||||
var setResponse = await _responder.SetResponseOnHttpContext(context, HttpResponseMessage);
|
||||
|
||||
if (setResponse.IsError)
|
||||
{
|
||||
_logger.LogDebug("error setting response, returning error to client");
|
||||
|
||||
await SetErrorResponse(context, setResponse.Errors);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
namespace Ocelot.Responder.Middleware
|
||||
{
|
||||
public static class ResponderMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseResponderMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<ResponderMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,6 @@ namespace Ocelot.ManualTest
|
||||
|
||||
public IConfigurationRoot Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
Action<ConfigurationBuilderCachePart> settings = (x) =>
|
||||
@ -44,13 +43,10 @@ namespace Ocelot.ManualTest
|
||||
services.AddOcelot();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||
|
||||
loggerFactory.AddDebug();
|
||||
|
||||
app.UseOcelot();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"IncludeScopes": true,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
|
@ -41,7 +41,8 @@
|
||||
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts",
|
||||
"UpstreamTemplate": "/posts",
|
||||
"UpstreamHttpMethod": "Get",
|
||||
"FileCacheOptions": { "TtlSeconds": 15 }
|
||||
"FileCacheOptions": { "TtlSeconds": 15 },
|
||||
"RequestIdKey": "OcRequestId"
|
||||
},
|
||||
{
|
||||
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts/{postId}",
|
||||
|
@ -2,19 +2,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Authentication.Handler;
|
||||
using Ocelot.Authentication.Handler.Factory;
|
||||
using Ocelot.Authentication.Middleware;
|
||||
using Ocelot.Cache.Middleware;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
@ -29,19 +35,17 @@ namespace Ocelot.UnitTests.Authentication
|
||||
private readonly HttpClient _client;
|
||||
private HttpResponseMessage _result;
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
private Mock<IOcelotLoggerFactory> _mockLoggerFactory;
|
||||
|
||||
public AuthenticationMiddlewareTests()
|
||||
{
|
||||
_url = "http://localhost:51879";
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
_authFactory = new Mock<IAuthenticationHandlerFactory>();
|
||||
SetUpLogger();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton(_mockLoggerFactory.Object);
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_authFactory.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -53,6 +57,11 @@ namespace Ocelot.UnitTests.Authentication
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseAuthenticationMiddleware();
|
||||
|
||||
app.Run(async x =>
|
||||
{
|
||||
await x.Response.WriteAsync("The user is authenticated");
|
||||
});
|
||||
});
|
||||
|
||||
_server = new TestServer(builder);
|
||||
@ -60,28 +69,18 @@ namespace Ocelot.UnitTests.Authentication
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_next_middleware_if_route_is_not_authenticated()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().Build())))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenNoExceptionsAreThrown())
|
||||
.Then(x => x.ThenTheUserIsAuthenticated())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void SetUpLogger()
|
||||
private void ThenTheUserIsAuthenticated()
|
||||
{
|
||||
_mockLoggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
|
||||
_mockLoggerFactory
|
||||
.Setup(x => x.CreateLogger<AuthenticationMiddleware>())
|
||||
.Returns(logger.Object);
|
||||
}
|
||||
|
||||
private void ThenNoExceptionsAreThrown()
|
||||
{
|
||||
//todo not suck
|
||||
var content = _result.Content.ReadAsStringAsync().Result;
|
||||
content.ShouldBe("The user is authenticated");
|
||||
}
|
||||
|
||||
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)
|
||||
|
@ -6,9 +6,9 @@ using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Cache.Middleware;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
@ -31,19 +31,18 @@ namespace Ocelot.UnitTests.Authorization
|
||||
private readonly HttpClient _client;
|
||||
private HttpResponseMessage _result;
|
||||
private OkResponse<DownstreamRoute> _downstreamRoute;
|
||||
private Mock<IOcelotLoggerFactory> _mockLoggerFactory;
|
||||
|
||||
public AuthorisationMiddlewareTests()
|
||||
{
|
||||
_url = "http://localhost:51879";
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
_authService = new Mock<IAuthoriser>();
|
||||
SetUpLogger();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton(_mockLoggerFactory.Object);
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_authService.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -62,7 +61,7 @@ namespace Ocelot.UnitTests.Authorization
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_authorisation_service()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithIsAuthorised(true).Build())))
|
||||
.And(x => x.GivenTheAuthServiceReturns(new OkResponse<bool>(true)))
|
||||
@ -71,17 +70,6 @@ namespace Ocelot.UnitTests.Authorization
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void SetUpLogger()
|
||||
{
|
||||
_mockLoggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
|
||||
_mockLoggerFactory
|
||||
.Setup(x => x.CreateLogger<AuthorisationMiddleware>())
|
||||
.Returns(logger.Object);
|
||||
}
|
||||
|
||||
private void GivenTheAuthServiceReturns(Response<bool> expected)
|
||||
{
|
||||
_authService
|
||||
|
@ -6,6 +6,7 @@ using CacheManager.Core;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
using Ocelot.Cache.Middleware;
|
||||
@ -25,7 +26,6 @@ namespace Ocelot.UnitTests.Cache
|
||||
{
|
||||
private readonly Mock<IOcelotCache<HttpResponseMessage>> _cacheManager;
|
||||
private readonly Mock<IRequestScopedDataRepository> _scopedRepo;
|
||||
private Mock<IOcelotLoggerFactory> _mockLoggerFactory;
|
||||
private readonly string _url;
|
||||
private readonly TestServer _server;
|
||||
private readonly HttpClient _client;
|
||||
@ -37,14 +37,13 @@ namespace Ocelot.UnitTests.Cache
|
||||
_cacheManager = new Mock<IOcelotCache<HttpResponseMessage>>();
|
||||
_scopedRepo = new Mock<IRequestScopedDataRepository>();
|
||||
|
||||
SetUpLogger();
|
||||
|
||||
_url = "http://localhost:51879";
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_mockLoggerFactory.Object);
|
||||
x.AddSingleton(_cacheManager.Object);
|
||||
x.AddSingleton(_scopedRepo.Object);
|
||||
})
|
||||
@ -85,16 +84,6 @@ namespace Ocelot.UnitTests.Cache
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void SetUpLogger()
|
||||
{
|
||||
_mockLoggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
|
||||
_mockLoggerFactory
|
||||
.Setup(x => x.CreateLogger<OutputCacheMiddleware>())
|
||||
.Returns(logger.Object);
|
||||
}
|
||||
|
||||
private void GivenTheDownstreamRouteIs()
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Cache.Middleware;
|
||||
using Ocelot.Claims;
|
||||
@ -31,19 +32,19 @@ namespace Ocelot.UnitTests.Claims
|
||||
private readonly HttpClient _client;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private HttpResponseMessage _result;
|
||||
private Mock<IOcelotLoggerFactory> _mockLoggerFactory;
|
||||
|
||||
public ClaimsBuilderMiddlewareTests()
|
||||
{
|
||||
_url = "http://localhost:51879";
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
_addHeaders = new Mock<IAddClaimsToRequest>();
|
||||
SetUpLogger();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton(_mockLoggerFactory.Object);
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_addHeaders.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -62,7 +63,7 @@ namespace Ocelot.UnitTests.Claims
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_claims_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
@ -80,17 +81,6 @@ namespace Ocelot.UnitTests.Claims
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void SetUpLogger()
|
||||
{
|
||||
_mockLoggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
|
||||
_mockLoggerFactory
|
||||
.Setup(x => x.CreateLogger<ClaimsBuilderMiddleware>())
|
||||
.Returns(logger.Object);
|
||||
}
|
||||
|
||||
private void GivenTheAddClaimsToRequestReturns()
|
||||
{
|
||||
_addHeaders
|
||||
|
@ -5,8 +5,8 @@ using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Claims.Middleware;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.Finder;
|
||||
@ -29,19 +29,18 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
private readonly HttpClient _client;
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private HttpResponseMessage _result;
|
||||
private Mock<IOcelotLoggerFactory> _mockLoggerFactory;
|
||||
|
||||
public DownstreamRouteFinderMiddlewareTests()
|
||||
{
|
||||
_url = "http://localhost:51879";
|
||||
_downstreamRouteFinder = new Mock<IDownstreamRouteFinder>();
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
SetUpLogger();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton(_mockLoggerFactory.Object);
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_downstreamRouteFinder.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -60,7 +59,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteFinderReturns(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamTemplate("any old string").Build())))
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
@ -68,16 +67,6 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void SetUpLogger()
|
||||
{
|
||||
_mockLoggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
|
||||
_mockLoggerFactory
|
||||
.Setup(x => x.CreateLogger<DownstreamRouteFinderMiddleware>())
|
||||
.Returns(logger.Object);
|
||||
}
|
||||
|
||||
private void ThenTheScopedDataRepositoryIsCalledCorrectly()
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
@ -30,19 +31,18 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
private Response<DownstreamRoute> _downstreamRoute;
|
||||
private HttpResponseMessage _result;
|
||||
private OkResponse<DownstreamUrl> _downstreamUrl;
|
||||
private Mock<IOcelotLoggerFactory> _mockLoggerFactory;
|
||||
|
||||
public DownstreamUrlCreatorMiddlewareTests()
|
||||
{
|
||||
_url = "http://localhost:51879";
|
||||
_downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamUrlPathPlaceholderReplacer>();
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
SetUpLogger();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton(_mockLoggerFactory.Object);
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_downstreamUrlTemplateVariableReplacer.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -61,7 +61,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamTemplate("any old string").Build())))
|
||||
.And(x => x.TheUrlReplacerReturns("any old string"))
|
||||
@ -70,18 +70,6 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
private void SetUpLogger()
|
||||
{
|
||||
_mockLoggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||
|
||||
var logger = new Mock<IOcelotLogger>();
|
||||
|
||||
_mockLoggerFactory
|
||||
.Setup(x => x.CreateLogger<DownstreamUrlCreatorMiddleware>())
|
||||
.Returns(logger.Object);
|
||||
}
|
||||
|
||||
private void TheUrlReplacerReturns(string downstreamUrl)
|
||||
{
|
||||
_downstreamUrl = new OkResponse<DownstreamUrl>(new DownstreamUrl(downstreamUrl));
|
||||
|
@ -6,14 +6,17 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||
using Ocelot.Headers;
|
||||
using Ocelot.Headers.Middleware;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
@ -35,9 +38,13 @@ namespace Ocelot.UnitTests.Headers
|
||||
_url = "http://localhost:51879";
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
_addHeaders = new Mock<IAddHeadersToRequest>();
|
||||
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_addHeaders.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -56,7 +63,7 @@ namespace Ocelot.UnitTests.Headers
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_add_headers_to_request_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
@ -68,13 +75,13 @@ namespace Ocelot.UnitTests.Headers
|
||||
.Build());
|
||||
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddHeadersToRequestReturns("123"))
|
||||
.And(x => x.GivenTheAddHeadersToRequestReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAddHeadersToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheAddHeadersToRequestReturns(string claimValue)
|
||||
private void GivenTheAddHeadersToRequestReturns()
|
||||
{
|
||||
_addHeaders
|
||||
.Setup(x => x.SetHeadersOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
|
@ -6,12 +6,15 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Configuration;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Headers.Middleware;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.QueryStrings;
|
||||
using Ocelot.QueryStrings.Middleware;
|
||||
using Ocelot.Responses;
|
||||
@ -38,6 +41,8 @@ namespace Ocelot.UnitTests.QueryStrings
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_addQueries.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -56,7 +61,7 @@ namespace Ocelot.UnitTests.QueryStrings
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_add_queries_correctly()
|
||||
{
|
||||
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
@ -70,7 +75,7 @@ namespace Ocelot.UnitTests.QueryStrings
|
||||
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
|
||||
.And(x => x.GivenTheAddHeadersToRequestReturns())
|
||||
.When(x => x.WhenICallTheMiddleware())
|
||||
.Then(x => x.ThenTheAddHeadersToRequestIsCalledCorrectly())
|
||||
.Then(x => x.ThenTheAddQueriesToRequestIsCalledCorrectly())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
@ -82,7 +87,7 @@ namespace Ocelot.UnitTests.QueryStrings
|
||||
.Returns(new OkResponse());
|
||||
}
|
||||
|
||||
private void ThenTheAddHeadersToRequestIsCalledCorrectly()
|
||||
private void ThenTheAddQueriesToRequestIsCalledCorrectly()
|
||||
{
|
||||
_addQueries
|
||||
.Verify(x => x.SetQueriesOnContext(It.IsAny<List<ClaimToThing>>(),
|
||||
|
@ -7,11 +7,13 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Request.Builder;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.Responses;
|
||||
@ -37,10 +39,11 @@ namespace Ocelot.UnitTests.Request
|
||||
_url = "http://localhost:51879";
|
||||
_requestBuilder = new Mock<IRequestCreator>();
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_requestBuilder.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -59,7 +62,7 @@ namespace Ocelot.UnitTests.Request
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
|
||||
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
|
||||
|
@ -8,11 +8,14 @@ using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Configuration.Builder;
|
||||
using Ocelot.DownstreamRouteFinder;
|
||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Request.Middleware;
|
||||
using Ocelot.RequestId.Middleware;
|
||||
using Ocelot.Responses;
|
||||
using Shouldly;
|
||||
@ -36,10 +39,11 @@ namespace Ocelot.UnitTests.RequestId
|
||||
{
|
||||
_url = "http://localhost:51879";
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
.UseUrls(_url)
|
||||
|
@ -6,8 +6,11 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.QueryStrings.Middleware;
|
||||
using Ocelot.Requester;
|
||||
using Ocelot.Requester.Middleware;
|
||||
using Ocelot.Responder;
|
||||
@ -33,10 +36,11 @@ namespace Ocelot.UnitTests.Requester
|
||||
_url = "http://localhost:51879";
|
||||
_requester = new Mock<IHttpRequester>();
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_requester.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
})
|
||||
@ -55,7 +59,7 @@ namespace Ocelot.UnitTests.Requester
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_call_scoped_data_repository_correctly()
|
||||
{
|
||||
this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),new CookieContainer())))
|
||||
.And(x => x.GivenTheRequesterReturns(new HttpResponseMessage()))
|
||||
|
@ -5,8 +5,10 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Ocelot.Infrastructure.RequestData;
|
||||
using Ocelot.Logging;
|
||||
using Ocelot.Responder;
|
||||
using Ocelot.Responder.Middleware;
|
||||
using Ocelot.Responses;
|
||||
@ -15,7 +17,7 @@ using Xunit;
|
||||
|
||||
namespace Ocelot.UnitTests.Responder
|
||||
{
|
||||
public class HttpErrorResponderMiddlewareTests : IDisposable
|
||||
public class ResponderMiddlewareTests : IDisposable
|
||||
{
|
||||
private readonly Mock<IHttpResponder> _responder;
|
||||
private readonly Mock<IRequestScopedDataRepository> _scopedRepository;
|
||||
@ -26,16 +28,17 @@ namespace Ocelot.UnitTests.Responder
|
||||
private HttpResponseMessage _result;
|
||||
private OkResponse<HttpResponseMessage> _response;
|
||||
|
||||
public HttpErrorResponderMiddlewareTests()
|
||||
public ResponderMiddlewareTests()
|
||||
{
|
||||
_url = "http://localhost:51879";
|
||||
_responder = new Mock<IHttpResponder>();
|
||||
_scopedRepository = new Mock<IRequestScopedDataRepository>();
|
||||
_codeMapper = new Mock<IErrorsToHttpStatusCodeMapper>();
|
||||
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(x =>
|
||||
{
|
||||
x.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||
x.AddLogging();
|
||||
x.AddSingleton(_codeMapper.Object);
|
||||
x.AddSingleton(_responder.Object);
|
||||
x.AddSingleton(_scopedRepository.Object);
|
||||
@ -47,7 +50,7 @@ namespace Ocelot.UnitTests.Responder
|
||||
.UseUrls(_url)
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseHttpErrorResponderMiddleware();
|
||||
app.UseResponderMiddleware();
|
||||
});
|
||||
|
||||
_server = new TestServer(builder);
|
||||
@ -55,7 +58,7 @@ namespace Ocelot.UnitTests.Responder
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void happy_path()
|
||||
public void should_not_return_any_errors()
|
||||
{
|
||||
this.Given(x => x.GivenTheHttpResponseMessageIs(new HttpResponseMessage()))
|
||||
.And(x => x.GivenThereAreNoPipelineErrors())
|
Loading…
x
Reference in New Issue
Block a user