mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
Expand other branch pipes (#416)
* Expand other branch pipes * Expand other branch pipes * Expand other branch pipes * optimization Expand other branch pipes ,Add Unit test * I hope to add two attributes to IOcelotBuilder for easy extension.
This commit is contained in:
parent
8f4ae03290
commit
5c940acf0e
@ -4,11 +4,15 @@ using System;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using IdentityServer4.AccessTokenValidation;
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using Ocelot.Middleware.Multiplexer;
|
using Ocelot.Middleware.Multiplexer;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
{
|
{
|
||||||
public interface IOcelotBuilder
|
public interface IOcelotBuilder
|
||||||
{
|
{
|
||||||
|
IServiceCollection Services { get; }
|
||||||
|
IConfiguration Configuration { get; }
|
||||||
IOcelotBuilder AddStoreOcelotConfigurationInConsul();
|
IOcelotBuilder AddStoreOcelotConfigurationInConsul();
|
||||||
|
|
||||||
IOcelotBuilder AddCacheManager(Action<ConfigurationBuilderCachePart> settings);
|
IOcelotBuilder AddCacheManager(Action<ConfigurationBuilderCachePart> settings);
|
||||||
|
@ -55,6 +55,10 @@ namespace Ocelot.DependencyInjection
|
|||||||
private readonly IServiceCollection _services;
|
private readonly IServiceCollection _services;
|
||||||
private readonly IConfiguration _configurationRoot;
|
private readonly IConfiguration _configurationRoot;
|
||||||
|
|
||||||
|
public IServiceCollection Services => _services;
|
||||||
|
|
||||||
|
public IConfiguration Configuration => _configurationRoot;
|
||||||
|
|
||||||
public OcelotBuilder(IServiceCollection services, IConfiguration configurationRoot)
|
public OcelotBuilder(IServiceCollection services, IConfiguration configurationRoot)
|
||||||
{
|
{
|
||||||
_configurationRoot = configurationRoot;
|
_configurationRoot = configurationRoot;
|
||||||
|
@ -29,6 +29,12 @@
|
|||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, Action<OcelotPipelineConfiguration> pipelineConfiguration)
|
||||||
|
{
|
||||||
|
var config = new OcelotPipelineConfiguration();
|
||||||
|
pipelineConfiguration?.Invoke(config);
|
||||||
|
return await builder.UseOcelot(config);
|
||||||
|
}
|
||||||
public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, OcelotPipelineConfiguration pipelineConfiguration)
|
public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, OcelotPipelineConfiguration pipelineConfiguration)
|
||||||
{
|
{
|
||||||
var configuration = await CreateConfiguration(builder);
|
var configuration = await CreateConfiguration(builder);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
namespace Ocelot.Middleware
|
namespace Ocelot.Middleware
|
||||||
{
|
{
|
||||||
|
using Ocelot.Middleware.Pipeline;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class OcelotPipelineConfiguration
|
public class OcelotPipelineConfiguration
|
||||||
@ -38,5 +40,9 @@
|
|||||||
/// This allows the user to implement there own query string manipulation logic
|
/// This allows the user to implement there own query string manipulation logic
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<DownstreamContext, Func<Task>, Task> PreQueryStringBuilderMiddleware { get; set; }
|
public Func<DownstreamContext, Func<Task>, Task> PreQueryStringBuilderMiddleware { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// This is an extension that will branch to different pipes
|
||||||
|
/// </summary>
|
||||||
|
public List<Func<IOcelotPipelineBuilder, Func<DownstreamContext, bool>>> MapWhenOcelotPipeline { get; } = new List<Func<IOcelotPipelineBuilder, Func<DownstreamContext, bool>>>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,8 @@ namespace Ocelot.Middleware.Pipeline
|
|||||||
var diagnosticListener = (DiagnosticListener)app.ApplicationServices.GetService(typeof(DiagnosticListener));
|
var diagnosticListener = (DiagnosticListener)app.ApplicationServices.GetService(typeof(DiagnosticListener));
|
||||||
var middlewareName = ocelotDelegate.Target.GetType().Name;
|
var middlewareName = ocelotDelegate.Target.GetType().Name;
|
||||||
|
|
||||||
OcelotRequestDelegate wrapped = context => {
|
OcelotRequestDelegate wrapped = context =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Write(diagnosticListener, "Ocelot.MiddlewareStarted", middlewareName, context);
|
Write(diagnosticListener, "Ocelot.MiddlewareStarted", middlewareName, context);
|
||||||
@ -160,6 +161,28 @@ namespace Ocelot.Middleware.Pipeline
|
|||||||
return app.Use(next => new MapWhenMiddleware(next, options).Invoke);
|
return app.Use(next => new MapWhenMiddleware(next, options).Invoke);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IOcelotPipelineBuilder MapWhen(this IOcelotPipelineBuilder app, Func<IOcelotPipelineBuilder, Predicate> pipelineBuilderFunc)
|
||||||
|
{
|
||||||
|
if (app == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(app));
|
||||||
|
}
|
||||||
|
if (pipelineBuilderFunc == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(pipelineBuilderFunc));
|
||||||
|
}
|
||||||
|
var branchBuilder = app.New();
|
||||||
|
var predicate = pipelineBuilderFunc.Invoke(app);
|
||||||
|
var branch = branchBuilder.Build();
|
||||||
|
|
||||||
|
var options = new MapWhenOptions
|
||||||
|
{
|
||||||
|
Predicate = predicate,
|
||||||
|
Branch = branch
|
||||||
|
};
|
||||||
|
return app.Use(next => new MapWhenMiddleware(next, options).Invoke);
|
||||||
|
}
|
||||||
|
|
||||||
private static Func<T, DownstreamContext, IServiceProvider, Task> Compile<T>(MethodInfo methodinfo, ParameterInfo[] parameters)
|
private static Func<T, DownstreamContext, IServiceProvider, Task> Compile<T>(MethodInfo methodinfo, ParameterInfo[] parameters)
|
||||||
{
|
{
|
||||||
var middleware = typeof(T);
|
var middleware = typeof(T);
|
||||||
|
@ -28,6 +28,15 @@ namespace Ocelot.Middleware.Pipeline
|
|||||||
// It also sets the Request Id if anything is set globally
|
// It also sets the Request Id if anything is set globally
|
||||||
builder.UseExceptionHandlerMiddleware();
|
builder.UseExceptionHandlerMiddleware();
|
||||||
|
|
||||||
|
//Expand other branch pipes
|
||||||
|
if (pipelineConfiguration.MapWhenOcelotPipeline != null)
|
||||||
|
{
|
||||||
|
foreach (var pipeline in pipelineConfiguration.MapWhenOcelotPipeline)
|
||||||
|
{
|
||||||
|
builder.MapWhen(pipeline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the request is for websockets upgrade we fork into a different pipeline
|
// If the request is for websockets upgrade we fork into a different pipeline
|
||||||
builder.MapWhen(context => context.HttpContext.WebSockets.IsWebSocketRequest,
|
builder.MapWhen(context => context.HttpContext.WebSockets.IsWebSocketRequest,
|
||||||
app =>
|
app =>
|
||||||
|
@ -3,8 +3,13 @@ namespace Ocelot.UnitTests.Middleware
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
|
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||||
|
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||||
|
using Ocelot.LoadBalancer.Middleware;
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
using Ocelot.Middleware.Pipeline;
|
using Ocelot.Middleware.Pipeline;
|
||||||
|
using Ocelot.Request.Middleware;
|
||||||
|
using Ocelot.WebSockets.Middleware;
|
||||||
using Pivotal.Discovery.Client;
|
using Pivotal.Discovery.Client;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using Steeltoe.Common.Discovery;
|
using Steeltoe.Common.Discovery;
|
||||||
@ -26,6 +31,16 @@ namespace Ocelot.UnitTests.Middleware
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_expand_pipeline()
|
||||||
|
{
|
||||||
|
this.Given(_ => GivenTheDepedenciesAreSetUp())
|
||||||
|
.When(_ => WhenIExpandBuild())
|
||||||
|
.Then(_ => ThenThePipelineIsBuilt())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void ThenThePipelineIsBuilt()
|
private void ThenThePipelineIsBuilt()
|
||||||
{
|
{
|
||||||
_handlers.ShouldNotBeNull();
|
_handlers.ShouldNotBeNull();
|
||||||
@ -36,6 +51,23 @@ namespace Ocelot.UnitTests.Middleware
|
|||||||
_handlers = _builder.BuildOcelotPipeline(new OcelotPipelineConfiguration());
|
_handlers = _builder.BuildOcelotPipeline(new OcelotPipelineConfiguration());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WhenIExpandBuild()
|
||||||
|
{
|
||||||
|
OcelotPipelineConfiguration configuration = new OcelotPipelineConfiguration();
|
||||||
|
configuration.MapWhenOcelotPipeline.Add((app) =>
|
||||||
|
{
|
||||||
|
app.UseDownstreamRouteFinderMiddleware();
|
||||||
|
app.UseDownstreamRequestInitialiser();
|
||||||
|
app.UseLoadBalancingMiddleware();
|
||||||
|
app.UseDownstreamUrlCreatorMiddleware();
|
||||||
|
app.UseWebSocketsProxyMiddleware();
|
||||||
|
|
||||||
|
return context => context.HttpContext.WebSockets.IsWebSocketRequest;
|
||||||
|
});
|
||||||
|
_handlers = _builder.BuildOcelotPipeline(new OcelotPipelineConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void GivenTheDepedenciesAreSetUp()
|
private void GivenTheDepedenciesAreSetUp()
|
||||||
{
|
{
|
||||||
IConfigurationBuilder test = new ConfigurationBuilder();
|
IConfigurationBuilder test = new ConfigurationBuilder();
|
||||||
|
@ -79,6 +79,8 @@ namespace Ocelot.UnitTests.Middleware
|
|||||||
del.Invoke(_downstreamContext);
|
del.Invoke(_downstreamContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void ThenTheFuncIsInThePipeline()
|
private void ThenTheFuncIsInThePipeline()
|
||||||
{
|
{
|
||||||
_counter.ShouldBe(1);
|
_counter.ShouldBe(1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user