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:
aqa510415008 2018-07-20 00:45:46 +08:00 committed by Tom Pallister
parent 8f4ae03290
commit 5c940acf0e
10 changed files with 107 additions and 21 deletions

View File

@ -4,11 +4,15 @@ using System;
using System.Net.Http;
using IdentityServer4.AccessTokenValidation;
using Ocelot.Middleware.Multiplexer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
namespace Ocelot.DependencyInjection
{
public interface IOcelotBuilder
{
IServiceCollection Services { get; }
IConfiguration Configuration { get; }
IOcelotBuilder AddStoreOcelotConfigurationInConsul();
IOcelotBuilder AddCacheManager(Action<ConfigurationBuilderCachePart> settings);

View File

@ -55,6 +55,10 @@ namespace Ocelot.DependencyInjection
private readonly IServiceCollection _services;
private readonly IConfiguration _configurationRoot;
public IServiceCollection Services => _services;
public IConfiguration Configuration => _configurationRoot;
public OcelotBuilder(IServiceCollection services, IConfiguration configurationRoot)
{
_configurationRoot = configurationRoot;

View File

@ -29,6 +29,12 @@
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)
{
var configuration = await CreateConfiguration(builder);

View File

@ -1,6 +1,8 @@
namespace Ocelot.Middleware
{
using Ocelot.Middleware.Pipeline;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class OcelotPipelineConfiguration
@ -38,5 +40,9 @@
/// This allows the user to implement there own query string manipulation logic
/// </summary>
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>>>();
}
}

View File

@ -80,7 +80,8 @@ namespace Ocelot.Middleware.Pipeline
var diagnosticListener = (DiagnosticListener)app.ApplicationServices.GetService(typeof(DiagnosticListener));
var middlewareName = ocelotDelegate.Target.GetType().Name;
OcelotRequestDelegate wrapped = context => {
OcelotRequestDelegate wrapped = context =>
{
try
{
Write(diagnosticListener, "Ocelot.MiddlewareStarted", middlewareName, context);
@ -160,6 +161,28 @@ namespace Ocelot.Middleware.Pipeline
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)
{
var middleware = typeof(T);

View File

@ -28,6 +28,15 @@ namespace Ocelot.Middleware.Pipeline
// It also sets the Request Id if anything is set globally
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
builder.MapWhen(context => context.HttpContext.WebSockets.IsWebSocketRequest,
app =>

View File

@ -3,8 +3,13 @@ namespace Ocelot.UnitTests.Middleware
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.DownstreamUrlCreator.Middleware;
using Ocelot.LoadBalancer.Middleware;
using Ocelot.Middleware;
using Ocelot.Middleware.Pipeline;
using Ocelot.Request.Middleware;
using Ocelot.WebSockets.Middleware;
using Pivotal.Discovery.Client;
using Shouldly;
using Steeltoe.Common.Discovery;
@ -26,6 +31,16 @@ namespace Ocelot.UnitTests.Middleware
.BDDfy();
}
[Fact]
public void should_expand_pipeline()
{
this.Given(_ => GivenTheDepedenciesAreSetUp())
.When(_ => WhenIExpandBuild())
.Then(_ => ThenThePipelineIsBuilt())
.BDDfy();
}
private void ThenThePipelineIsBuilt()
{
_handlers.ShouldNotBeNull();
@ -36,6 +51,23 @@ namespace Ocelot.UnitTests.Middleware
_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()
{
IConfigurationBuilder test = new ConfigurationBuilder();

View File

@ -79,6 +79,8 @@ namespace Ocelot.UnitTests.Middleware
del.Invoke(_downstreamContext);
}
private void ThenTheFuncIsInThePipeline()
{
_counter.ShouldBe(1);