public async Task IMiddlewareBuilder_UseRouting_NoUse() { // arrange var path = new Tracer(); Endpoint <Context> selectedEndpoint = null; var stack = new MiddlewareBuilder <Context>() .Use(path.TestMiddleware("A")) .UseRouting() .Use(path.TestMiddleware("B")) .Use(async(context, next) => { context.Feature <EndpointFeature <Context> >().TryGetEndpoint(context, out selectedEndpoint); await next(context); }) .Use(path.TestMiddleware("C")) .Build(); // act await stack(new Context()); // assert // no exception till here Assert.Null(selectedEndpoint); Assert.Equal("ABC", path.Trace); }
public async Task IMiddlewareBuilder_UseRoutingDataExtractor_Simple() { // arrange var tracer = new Tracer(); var middleware = new MiddlewareBuilder <Context>() .Use(tracer.TestMiddleware("A")) .UseRoutingKey(c => c.Features.Get <string>(), "^(?<area>.*)-home-(?<action>.*)$", "^xyz\\.(?<action>.*)$" ) .UseRoutes( new Route <Context>(StringRouter.Match("action", "create"), b => b.Use(tracer.TestMiddleware("B"))), new Route <Context>(StringRouter.Match("action", "delete"), b => b.Use(tracer.TestMiddleware("C"))) ) .Build(); // act var context = new Context(); context.Features.Set("xyz.delete"); await middleware(context); // assert Assert.Equal("AC", tracer.Trace); }
public void Configure(MiddlewareBuilder builder) { builder .Use <LoggerMiddleware>() .Use <StaticFilesMiddleware>() .Use <MvcMiddleware>(); }
public async Task IMiddlewareBuilder_UseRoute_OneBranchNotMet() { // arrange var builder = new MiddlewareBuilder <Context>(); var path = new Tracer(); builder.Use(path.TestMiddleware("A")); builder.UseRoutes(new Route <Context>(context => false, branchBuilder => { branchBuilder.Use(path.TestMiddleware("C")); } )); builder.Use(path.TestMiddleware("B")); var stack = builder.Build(); // act await stack(new Context()); // assert // no exception till here Assert.Equal("AB", path.Trace); }
public async Task MiddlewareBuilder_Use_LinearOrder() { // arrange var builder = new MiddlewareBuilder <Context>(); var list = new List <string>(); // act builder.Use(next => { return(async context => { list.Add("A"); await next(context); list.Add("Z"); }); }); builder.Use(next => { return(async context => { list.Add("B"); await next(context); list.Add("Y"); }); }); builder.Use(next => { return(async context => { list.Add("C"); await next(context); list.Add("X"); }); }); var executeAsync = builder.Build(); var x = new Context(); await executeAsync(x); // assert Assert.Collection(list, l => Assert.Equal("A", l), l => Assert.Equal("B", l), l => Assert.Equal("C", l), l => Assert.Equal("X", l), l => Assert.Equal("Y", l), l => Assert.Equal("Z", l) ); }
public async Task Can_Integrate_With_Polly_Policies_Async() { var pollyPolicy = Policy .Handle <CustomException>() .CircuitBreakerAsync( exceptionsAllowedBeforeBreaking: 2, durationOfBreak: TimeSpan.FromSeconds(1)); var policy = MiddlewareBuilder.BuildAsync( new PollyMiddleware <string, int>(pollyPolicy)); var calledCount = 0; await Assert.ThrowsAsync <CustomException>(async() => await policy.RunAsync("context", ct => { calledCount++; throw new CustomException(); }, CancellationToken.None)); await Assert.ThrowsAsync <CustomException>(async() => await policy.RunAsync("context", ct => { calledCount++; throw new CustomException(); }, CancellationToken.None)); await Assert.ThrowsAsync <BrokenCircuitException>(async() => await policy.RunAsync("context", ct => { calledCount++; throw new CustomException(); }, CancellationToken.None)); calledCount.ShouldBe(2); }
public void UseStartup <T>() where T : IConfigurator, new() { var config = new T(); var builder = new MiddlewareBuilder(); config.Configure(builder); middleware = builder.Build(); }
public void Configure <T>() where T : IConfigurator, new() { var config = new T(); var builder = new MiddlewareBuilder(); config.Configure(builder); middleware = builder.Build(); var iocBuilder = new IocBuilder(); config.ConfigureServices(iocBuilder); Services = iocBuilder.Build(); }
public async Task PolicyBuilder_Async() { var called = false; var noop = MiddlewareBuilder.BuildAsync <string, int>(); var result = await noop.RunAsync("context", async ct => { called = true; await Task.Delay(5, ct); return(1); }, CancellationToken.None); called.ShouldBeTrue(); result.ShouldBe(1); }
public async Task MiddlewareBuilder_Build_Empty() { // arrange var builder = new MiddlewareBuilder <Context>(); // act var executeAsync = builder.Build(); var ctx = new Context(); await executeAsync(ctx); // assert // .. no exception till here. }
public async Task MiddlewareBuilder_Build_ForNullContext() { // arrange var builder = new MiddlewareBuilder <Context>(); // act builder.Use(next => { return(async context => { await next(context); }); }); var executeAsync = builder.Build(); await executeAsync(null); // assert // .. no exception till here. }
public async Task MiddlewareBuilder_Error_Handler_Async() { var called = false; var noop = MiddlewareBuilder.BuildAsync( new ErrorHandlingMiddleware <string, int, InvalidOperationException>()); var result = await noop.RunAsync("context", async ct => { called = true; await Task.Delay(5, ct); throw new InvalidOperationException(); }, CancellationToken.None); called.ShouldBeTrue(); result.ShouldBe(0); }
public async Task IMiddlewareBuilder_UseEndpoints_WithoutUseRouting() { // arrange var path = new Tracer(); var stack = new MiddlewareBuilder <Context>() .Use(path.TestMiddleware("A")) .UseEndpoints(endpoints => { }) .Build(); // act await stack(new Context()); // assert // no exception till here }
public async Task IMiddlewareBuilder_UseRouting_MultipleEndpointWithoutBranches(string routingKey, string expectedTrace, string expectedEndpointName) { // arrange var path = new Tracer(); string actualInvokedEndpoint = null; Endpoint <Context> selectedEndpoint = null; var stack = new MiddlewareBuilder <Context>() .Use(path.TestMiddleware("A")) .UseRouting() .Use(path.TestMiddleware("B")) .Use(async(context, next) => { context.Feature <EndpointFeature <Context> >().TryGetEndpoint(context, out selectedEndpoint); await next(context); }) .Use(path.TestMiddleware("C")) .UseEndpoints(endpoints => { endpoints.MapLambda("A_Endpoint", context => { actualInvokedEndpoint = "A_Endpoint"; }) .Requires(c => c.Feature <string>() == "A"); endpoints.MapLambda("B_Endpoint", context => { actualInvokedEndpoint = "B_Endpoint"; }) .Requires(c => c.Feature <string>() == "B"); }) .Use(path.TestMiddleware("D")) .UseEndpoints(endpoints => { endpoints.MapLambda("C_Endpoint", context => { actualInvokedEndpoint = "C_Endpoint"; }) .Requires(c => c.Feature <string>() == "C"); endpoints.MapLambda("D_Endpoint", context => { actualInvokedEndpoint = "D_Endpoint"; }) .Requires(c => c.Feature <string>() == "D"); }) .Use(path.TestMiddleware("E")) .Build(); // act await stack(new Context(routingKey)); // assert // no exception till here Assert.Equal(expectedEndpointName, selectedEndpoint?.DisplayName); Assert.Equal(expectedEndpointName, actualInvokedEndpoint); Assert.Equal(expectedTrace, path.Trace); }
[InlineData("ABC", false, false, true, null)] // none selected (even with sub tree eval) public async Task IMiddlewareBuilder_UseRouting_MultipleEndpoint(string expectedTrace, bool routeDPredicate, bool routeEPredicate, bool routeFPredicate, string expectedEndpointName) { // arrange var path = new Tracer(); string actualInvokedEndpoint = null; Endpoint <Context> selectedEndpoint = null; var stack = new MiddlewareBuilder <Context>() .Use(path.TestMiddleware("A")) .UseRouting() .Use(path.TestMiddleware("B")) .Use(async(context, next) => { context.Feature <EndpointFeature <Context> >().TryGetEndpoint(context, out selectedEndpoint); await next(context); }) .Use(path.TestMiddleware("C")) .UseRoutes( new(context => routeDPredicate, branchMiddlewareBuilder => branchMiddlewareBuilder .Use(path.TestMiddleware("D")) .UseEndpoints(endpoints => endpoints.MapLambda("D_Endpoint", context => { actualInvokedEndpoint = "D_Endpoint"; })) ), new(context => routeEPredicate, branchMiddlewareBuilder => branchMiddlewareBuilder .UseRoutes( new(context => !routeFPredicate, branchMiddlewareBuilder => branchMiddlewareBuilder .Use(path.TestMiddleware("E")) .UseEndpoints(endpoints => endpoints.MapLambda("E_Endpoint", context => { actualInvokedEndpoint = "E_Endpoint"; })) ), new(context => routeFPredicate, branchMiddlewareBuilder => branchMiddlewareBuilder .Use(path.TestMiddleware("F")) .UseEndpoints(endpoints => endpoints.MapLambda("F_Endpoint", context => { actualInvokedEndpoint = "F_Endpoint"; })) ) ) ) ) .Build(); // act await stack(new Context()); // assert // no exception till here Assert.Equal(expectedEndpointName, selectedEndpoint?.DisplayName); Assert.Equal(expectedTrace, path.Trace); Assert.Equal(expectedEndpointName, actualInvokedEndpoint); }
public async Task FeatureCollection_Add_ByContextConstructor() { string value = null; // arrange var stack = new MiddlewareBuilder <Context>() .Use(async(context, next) => { value = context.Features.Get <string>(); await next(context); }) .Build(); // act await stack(new Context("Hello")); // assert Assert.Equal("Hello", value); }
public async Task IMiddlewareBuilder_UseRoute_Empty() { // arrange var builder = new MiddlewareBuilder <Context>(); var path = new Tracer(); builder.Use(path.TestMiddleware("A")); builder.UseRoutes(); builder.Use(path.TestMiddleware("B")); var stack = builder.Build(); // act await stack(new Context()); // assert // no exception till here Assert.Equal("AB", path.Trace); }
/// <summary> /// Produces a callable middleware chain from the configured middlewares. /// /// </summary> /// <returns>A callable <see cref="HandleMessageMiddleware"/></returns> public HandleMessageMiddleware Build() { _configure?.Invoke(this); // We reverse the middleware array so that the declaration order matches the execution order // (i.e. russian doll). var middlewares = _middlewares .Select(m => m()) .Reverse() .ToList(); if (_handlerMiddleware != null) { // Handler middleware needs to be last in the chain, so we keep an explicit reference to // it and add it here middlewares.Insert(0, _handlerMiddleware); } return(MiddlewareBuilder.BuildAsync(middlewares.ToArray())); }
private TcpClientIo(TcpClientIoOptions tcpClientIoOptions, ILogger <TcpClientIo <TId, TRequest, TResponse> > logger) { var pipe = new Pipe(); Id = Guid.NewGuid(); _logger = logger; _options = tcpClientIoOptions ?? TcpClientIoOptions.Default; _batchRules = TcpBatchRules <TResponse> .Default; _baseCancellationTokenSource = new CancellationTokenSource(); _baseCancellationToken = _baseCancellationTokenSource.Token; _bufferBlockRequests = new BufferBlock <SerializedRequest>(); var middleware = new MiddlewareBuilder <ITcpBatch <TResponse> >() .RegisterCancellationActionInWait((tcs, hasOwnToken) => { if (_disposing || hasOwnToken) { tcs.TrySetCanceled(); } else if (!_disposing && _pipelineReadEnded) { tcs.TrySetException(TcpClientIoException.ConnectionBroken()); } }) .RegisterDuplicateActionInSet((batch, newBatch) => _batchRules.Update(batch, newBatch.Single())) .RegisterCompletionActionInSet(() => _consumingResetEvent.Set()); _completeResponses = new WaitingDictionary <TId, ITcpBatch <TResponse> >(middleware); _arrayPool = ArrayPool <byte> .Create(); var bitConverterHelper = new BitConverterHelper(_options); _serializer = new TcpSerializer <TRequest>(bitConverterHelper, length => _arrayPool.Rent(length)); _deserializer = new TcpDeserializer <TId, TResponse>(bitConverterHelper); _writeResetEvent = new AsyncManualResetEvent(); _readResetEvent = new AsyncManualResetEvent(); _consumingResetEvent = new AsyncManualResetEvent(); _deserializePipeReader = pipe.Reader; _deserializePipeWriter = pipe.Writer; }
public async Task IMiddlewareBuilder_UseRoutingKey_Simple() { // arrange var tracer = new Tracer(); var middleware = new MiddlewareBuilder <Context>() .Use(tracer.TestMiddleware("A")) .UseRoutingKey(c => c.Features.Get <string>()) .UseRoutes( new Route <Context>(StringRouter.ByRoutingKey("xyz.create"), b => b.Use(tracer.TestMiddleware("B"))), new Route <Context>(StringRouter.ByRoutingKey("xyz.delete"), b => b.Use(tracer.TestMiddleware("C"))) ) .Build(); // act var context = new Context(); context.Features.Set("xyz.delete"); await middleware(context); // assert Assert.Equal("AC", tracer.Trace); }
public async Task MiddlewareBuilder_New_DoesNotReuseUseCalls() { // arrange IMiddlewareBuilder <Context> builder = new MiddlewareBuilder <Context>(); var list = new List <string>(); builder.Use(next => { return(async context => { list.Add("D"); await next(context); }); }); // act var newBuilder = builder.New(); newBuilder.Use(next => { return(async context => { list.Add("C"); await next(context); }); }); var executeAsync = newBuilder.Build(); var x = new Context(); await executeAsync(x); // assert Assert.Collection(list, l => Assert.Equal("C", l) ); }
public async Task IEndpointRouteBuilder_MapLambda_EndpointBuilderRequires() { // arrange string result = ""; var stack = new MiddlewareBuilder <Context>() .UseRouting() .UseRoutingKey(c => c.Feature <string>(), @"^(?<xyz>.*)/(?<action>.*)$") .UseEndpoints(endpoints => { endpoints.MapLambda("X", _ => result = "X") .Requires(StringRouter.Match("action", "X")); endpoints.MapLambda("Y", _ => result = "Y") .Requires(StringRouter.Match("action", "Y")); }) .Build(); // act await stack(new Context("x/Y")); // assert Assert.Equal("Y", result); }
public void ConfigureMiddleware(MiddlewareBuilder mb) { mb.Use <MvcMiddleware>(); }
public void Configure(MiddlewareBuilder middlewareBuilder) { middlewareBuilder.Use <MvcMiddleware>(); //middlewareBuilder.Use<HtmlFileMiddleware>(); //middlewareBuilder.Use<LoggingMiddleware>(); }