diff --git a/README.md b/README.md index 43b7b1a9..03b10a11 100644 --- a/README.md +++ b/README.md @@ -76,4 +76,8 @@ An example startup using a yaml file for configuration can be seen below. Curren This is pretty much all you need to get going.......more to come! +## Logging + +Ocelot uses the standard logging interfaces ILoggerFactory / ILogger as such you can use any logging provider you like such as default, nlog, serilog. + diff --git a/src/Ocelot/Configuration/Validator/ConfigurationValidator.cs b/src/Ocelot/Configuration/Validator/YamlConfigurationValidator.cs similarity index 97% rename from src/Ocelot/Configuration/Validator/ConfigurationValidator.cs rename to src/Ocelot/Configuration/Validator/YamlConfigurationValidator.cs index 494c2aa1..b69e9621 100644 --- a/src/Ocelot/Configuration/Validator/ConfigurationValidator.cs +++ b/src/Ocelot/Configuration/Validator/YamlConfigurationValidator.cs @@ -8,7 +8,7 @@ using Ocelot.Responses; namespace Ocelot.Configuration.Validator { - public class ConfigurationValidator : IConfigurationValidator + public class YamlConfigurationValidator : IConfigurationValidator { public Response IsValid(YamlConfiguration configuration) { diff --git a/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs b/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs index 4805df55..cca55afe 100644 --- a/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs @@ -35,10 +35,8 @@ namespace Ocelot.DependencyInjection // ocelot services. services.AddSingleton(); - services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); return services; } @@ -50,6 +48,8 @@ namespace Ocelot.DependencyInjection services.AddLogging(); // ocelot services. + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/Ocelot/Middleware/ExceptionHandlerMiddleware.cs b/src/Ocelot/Middleware/ExceptionHandlerMiddleware.cs index 7c222fa9..c53256c9 100644 --- a/src/Ocelot/Middleware/ExceptionHandlerMiddleware.cs +++ b/src/Ocelot/Middleware/ExceptionHandlerMiddleware.cs @@ -24,7 +24,16 @@ namespace Ocelot.Middleware } catch (Exception e) { - _logger.LogError(new EventId(1, "global error"), "Exception caught in global error handler", e); + var message = + $"Exception caught in global error handler, exception message: {e.Message}, exception stack: {e.StackTrace}"; + + if (e.InnerException != null) + { + message = $"{message}, inner exception message {e.InnerException.Message}, inner exception stack {e.InnerException.StackTrace}"; + } + + _logger.LogError(new EventId(1, "Ocelot Global Error"), message, e); + context.Response.StatusCode = 500; context.Response.ContentType = "application/json"; await context.Response.WriteAsync("Internal Server Error"); diff --git a/src/Ocelot/Middleware/OcelotMiddlewareConfiguration.cs b/src/Ocelot/Middleware/OcelotMiddlewareConfiguration.cs index ca9ad965..43391437 100644 --- a/src/Ocelot/Middleware/OcelotMiddlewareConfiguration.cs +++ b/src/Ocelot/Middleware/OcelotMiddlewareConfiguration.cs @@ -5,10 +5,34 @@ using Microsoft.AspNetCore.Http; public class OcelotMiddlewareConfiguration - { + { + /// + /// This is called after the global error handling middleware so any code before calling next.invoke + /// is the next thing called in the Ocelot pipeline. Anything after next.invoke is the last thing called + /// in the Ocelot pipeline before we go to the global error handler. + /// + public Func, Task> PreErrorResponderMiddleware { get; set; } + + /// + /// This is to allow the user to run any extra authentication before the Ocelot authentication + /// kicks in + /// public Func, Task> PreAuthenticationMiddleware { get; set; } + + /// + /// This allows the user to completely override the ocelot authentication middleware + /// public Func, Task> AuthenticationMiddleware { get; set; } + + /// + /// This is to allow the user to run any extra authorisation before the Ocelot authentication + /// kicks in + /// public Func, Task> PreAuthorisationMiddleware { get; set; } + + /// + /// This allows the user to completely override the ocelot authorisation middleware + /// public Func, Task> AuthorisationMiddleware { get; set; } } } \ No newline at end of file diff --git a/src/Ocelot/Middleware/OcelotMiddlewareExtensions.cs b/src/Ocelot/Middleware/OcelotMiddlewareExtensions.cs index 2ef92ab2..30813a5c 100644 --- a/src/Ocelot/Middleware/OcelotMiddlewareExtensions.cs +++ b/src/Ocelot/Middleware/OcelotMiddlewareExtensions.cs @@ -18,17 +18,31 @@ namespace Ocelot.Middleware public static class OcelotMiddlewareExtensions { + /// + /// Registers the Ocelot default middlewares + /// + /// + /// public static IApplicationBuilder UseOcelot(this IApplicationBuilder builder) { builder.UseOcelot(new OcelotMiddlewareConfiguration()); return builder; } + /// + /// Registers Ocelot with a combination of default middlewares and optional middlewares in the configuration + /// + /// + /// + /// public static IApplicationBuilder UseOcelot(this IApplicationBuilder builder, OcelotMiddlewareConfiguration middlewareConfiguration) { // This is registered to catch any global exceptions that are not handled builder.UseExceptionHandlerMiddleware(); + // Allow the user to respond with absolutely anything they want. + builder.UseIfNotNull(middlewareConfiguration.PreErrorResponderMiddleware); + // This is registered first so it can catch any errors and issue an appropriate response builder.UseHttpErrorResponderMiddleware(); diff --git a/test/Ocelot.UnitTests/Configuration/ConfigurationValidationTests.cs b/test/Ocelot.UnitTests/Configuration/ConfigurationValidationTests.cs index a0d34821..a2ca9b3e 100644 --- a/test/Ocelot.UnitTests/Configuration/ConfigurationValidationTests.cs +++ b/test/Ocelot.UnitTests/Configuration/ConfigurationValidationTests.cs @@ -16,7 +16,7 @@ namespace Ocelot.UnitTests.Configuration public ConfigurationValidationTests() { - _configurationValidator = new ConfigurationValidator(); + _configurationValidator = new YamlConfigurationValidator(); } [Fact]