Beispiel #1
0
    public void ReassignProxyRequest_Success()
    {
        var client  = new HttpMessageInvoker(new SocketsHttpHandler());
        var context = new DefaultHttpContext();
        var d1      = new DestinationState("d1");
        var d2      = new DestinationState("d2");
        var cc1     = new ClusterConfig()
        {
            ClusterId = "c1"
        };
        var cm1 = new ClusterModel(cc1, client);
        var cs1 = new ClusterState("c1")
        {
            Model = cm1
        };
        var r1 = new RouteModel(new RouteConfig()
        {
            RouteId = "r1"
        }, cs1, HttpTransformer.Empty);
        var feature = new ReverseProxyFeature()
        {
            AllDestinations       = d1,
            AvailableDestinations = d1,
            Cluster            = cm1,
            Route              = r1,
            ProxiedDestination = d1,
        };

        context.Features.Set <IReverseProxyFeature>(feature);

        var cc2 = new ClusterConfig()
        {
            ClusterId = "cc2"
        };
        var cm2 = new ClusterModel(cc2, client);
        var cs2 = new ClusterState("cs2")
        {
            DestinationsState = new ClusterDestinationsState(d2, d2),
            Model             = cm2,
        };

        context.ReassignProxyRequest(cs2);

        var newFeature = context.GetReverseProxyFeature();

        Assert.NotSame(feature, newFeature);
        Assert.Same(d2, newFeature.AllDestinations);
        Assert.Same(d2, newFeature.AvailableDestinations);
        Assert.Same(d1, newFeature.ProxiedDestination); // Copied unmodified.
        Assert.Same(cm2, newFeature.Cluster);
        Assert.Same(r1, newFeature.Route);
    }
    public async Task Invoke_SetsFeatures()
    {
        var httpClient = new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object);
        var cluster1   = new ClusterState(clusterId: "cluster1");

        cluster1.Model = new ClusterModel(new ClusterConfig(), httpClient);
        var destination1 = cluster1.Destinations.GetOrAdd(
            "destination1",
            id => new DestinationState(id)
        {
            Model = new DestinationModel(new DestinationConfig {
                Address = "https://localhost:123/a/b/"
            })
        });

        cluster1.DestinationsState = new ClusterDestinationsState(new[] { destination1 }, new[] { destination1 });

        var aspNetCoreEndpoints = new List <Endpoint>();
        var routeConfig         = new RouteModel(
            config: new RouteConfig(),
            cluster1,
            HttpTransformer.Default);
        var aspNetCoreEndpoint = CreateAspNetCoreEndpoint(routeConfig);

        aspNetCoreEndpoints.Add(aspNetCoreEndpoint);
        var httpContext = new DefaultHttpContext();

        httpContext.SetEndpoint(aspNetCoreEndpoint);

        var sut = Create <ProxyPipelineInitializerMiddleware>();

        await sut.Invoke(httpContext);

        var proxyFeature = httpContext.GetReverseProxyFeature();

        Assert.NotNull(proxyFeature);
        Assert.NotNull(proxyFeature.AvailableDestinations);
        Assert.Equal(1, proxyFeature.AvailableDestinations.Count);
        Assert.Same(destination1, proxyFeature.AvailableDestinations[0]);
        Assert.Same(cluster1.Model, proxyFeature.Cluster);

        Assert.Equal(StatusCodes.Status418ImATeapot, httpContext.Response.StatusCode);
    }
        public async Task Invoke_Works()
        {
            var events = TestEventListener.Collect();

            var httpContext = new DefaultHttpContext();

            httpContext.Request.Method      = "GET";
            httpContext.Request.Scheme      = "https";
            httpContext.Request.Host        = new HostString("example.com");
            httpContext.Request.Path        = "/api/test";
            httpContext.Request.QueryString = new QueryString("?a=b&c=d");

            var httpClient         = new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object);
            var httpRequestOptions = new RequestProxyOptions
            {
                Timeout = TimeSpan.FromSeconds(60),
                Version = HttpVersion.Version11,
#if NET
                VersionPolicy = HttpVersionPolicy.RequestVersionExact,
#endif
            };
            var cluster1      = new ClusterInfo(clusterId: "cluster1");
            var clusterConfig = new ClusterConfig(new Cluster()
            {
                HttpRequest = httpRequestOptions
            },
                                                  httpClient);
            var destination1 = cluster1.Destinations.GetOrAdd(
                "destination1",
                id => new DestinationInfo(id)
            {
                Config = new DestinationConfig(new Destination {
                    Address = "https://localhost:123/a/b/"
                })
            });
            var routeConfig = new RouteConfig(
                proxyRoute: new ProxyRoute()
            {
                RouteId = "Route-1"
            },
                cluster: cluster1,
                transformer: null);

            httpContext.Features.Set <IReverseProxyFeature>(
                new ReverseProxyFeature()
            {
                AvailableDestinations = new List <DestinationInfo>()
                {
                    destination1
                }.AsReadOnly(),
                ClusterSnapshot = clusterConfig,
                RouteSnapshot   = routeConfig,
            });
            httpContext.Features.Set(cluster1);

            var tcs1 = new TaskCompletionSource <bool>();
            var tcs2 = new TaskCompletionSource <bool>();

            Mock <IHttpProxy>()
            .Setup(h => h.ProxyAsync(
                       httpContext,
                       It.Is <string>(uri => uri == "https://localhost:123/a/b/"),
                       httpClient,
                       It.Is <RequestProxyOptions>(requestOptions =>
                                                   requestOptions.Timeout == httpRequestOptions.Timeout &&
                                                   requestOptions.Version == httpRequestOptions.Version
#if NET
                                                   && requestOptions.VersionPolicy == httpRequestOptions.VersionPolicy
#endif
                                                   ),
                       It.Is <HttpTransformer>(transformer => transformer == null)))
            .Returns(
                async() =>
            {
                tcs1.TrySetResult(true);
                await tcs2.Task;
            })
            .Verifiable();

            var sut = Create <ProxyInvokerMiddleware>();

            Assert.Equal(0, cluster1.ConcurrencyCounter.Value);
            Assert.Equal(0, destination1.ConcurrentRequestCount);

            var task = sut.Invoke(httpContext);
            if (task.IsFaulted)
            {
                // Something went wrong, don't hang the test.
                await task;
            }

            Mock <IHttpProxy>().Verify();

            await tcs1.Task; // Wait until we get to the proxying step.
            Assert.Equal(1, cluster1.ConcurrencyCounter.Value);
            Assert.Equal(1, destination1.ConcurrentRequestCount);

            Assert.Same(destination1, httpContext.GetReverseProxyFeature().ProxiedDestination);

            tcs2.TrySetResult(true);
            await task;
            Assert.Equal(0, cluster1.ConcurrencyCounter.Value);
            Assert.Equal(0, destination1.ConcurrentRequestCount);

            var invoke = Assert.Single(events, e => e.EventName == "ProxyInvoke");
            Assert.Equal(3, invoke.Payload.Count);
            Assert.Equal(cluster1.ClusterId, (string)invoke.Payload[0]);
            Assert.Equal(routeConfig.ProxyRoute.RouteId, (string)invoke.Payload[1]);
            Assert.Equal(destination1.DestinationId, (string)invoke.Payload[2]);
        }