Пример #1
0
        public void DynamicState_ReactsToDestinationStateChanges()
        {
            var cluster = new ClusterInfo("abc");

            EnableHealthChecks(cluster);
            cluster.ProcessDestinationChanges();

            var state1 = cluster.DynamicState;

            Assert.NotNull(state1);
            Assert.Empty(state1.AllDestinations);

            var destination = cluster.Destinations.GetOrAdd("d1", id => new DestinationInfo(id));

            cluster.ProcessDestinationChanges();
            Assert.NotSame(state1, cluster.DynamicState);
            var state2 = cluster.DynamicState;

            destination.Health.Active = DestinationHealth.Unhealthy;
            cluster.UpdateDynamicState();
            Assert.NotSame(state2, cluster.DynamicState);
            var state3 = cluster.DynamicState;

            Assert.Contains(destination, state3.AllDestinations);
            Assert.Empty(state3.HealthyDestinations);

            destination.Health.Active = DestinationHealth.Healthy;
            cluster.UpdateDynamicState();
            Assert.NotSame(state3, cluster.DynamicState);
            var state4 = cluster.DynamicState;

            Assert.Contains(destination, state4.AllDestinations);
            Assert.Contains(destination, state4.HealthyDestinations);
        }
Пример #2
0
        private ClusterInfo GetClusterInfo(string id, string policy, bool enabled = true)
        {
            var clusterConfig = new ClusterConfig(
                new Cluster
            {
                Id          = id,
                HealthCheck = new HealthCheckOptions
                {
                    Passive = new PassiveHealthCheckOptions
                    {
                        Enabled = enabled,
                        Policy  = policy,
                    }
                }
            },
                null);
            var clusterInfo = new ClusterInfo(id, new DestinationManager());

            clusterInfo.Config = clusterConfig;
            clusterInfo.DestinationManager.GetOrCreateItem("destination0", d => { });
            clusterInfo.DestinationManager.GetOrCreateItem("destination1", d => { });

            clusterInfo.UpdateDynamicState();

            return(clusterInfo);
        }
        public void ProbingCompleted(ClusterInfo cluster, IReadOnlyList <DestinationProbingResult> probingResults)
        {
            var threshold = GetFailureThreshold(cluster);
            var changed   = false;

            for (var i = 0; i < probingResults.Count; i++)
            {
                var destination = probingResults[i].Destination;

                var count     = _failureCounters.GetOrCreateValue(destination);
                var newHealth = EvaluateHealthState(threshold, probingResults[i].Response, count);

                var healthState = destination.Health;
                if (newHealth != healthState.Active)
                {
                    healthState.Active = newHealth;
                    changed            = true;
                    if (newHealth == DestinationHealth.Unhealthy)
                    {
                        Log.ActiveDestinationHealthStateIsSetToUnhealthy(_logger, destination.DestinationId, cluster.ClusterId);
                    }
                    else
                    {
                        Log.ActiveDestinationHealthStateIsSet(_logger, destination.DestinationId, cluster.ClusterId, newHealth);
                    }
                }
            }

            if (changed)
            {
                cluster.UpdateDynamicState();
            }
        }
Пример #4
0
        public async Task Invoke_NoHealthyEndpoints_CallsNext()
        {
            var httpClient = new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object);
            var cluster1   = new ClusterInfo(
                clusterId: "cluster1",
                destinationManager: new DestinationManager());

            cluster1.Config = new ClusterConfig(
                new Cluster()
            {
                HealthCheck = new HealthCheckOptions
                {
                    Active = new ActiveHealthCheckOptions
                    {
                        Enabled  = true,
                        Timeout  = Timeout.InfiniteTimeSpan,
                        Interval = Timeout.InfiniteTimeSpan,
                        Policy   = "Any5xxResponse",
                    }
                }
            },
                httpClient);
            var destination1 = cluster1.DestinationManager.GetOrCreateItem(
                "destination1",
                destination =>
            {
                destination.Config = new DestinationConfig(new Destination {
                    Address = "https://localhost:123/a/b/"
                });
                destination.Health.Active = DestinationHealth.Unhealthy;
            });

            cluster1.UpdateDynamicState();

            var aspNetCoreEndpoints = new List <Endpoint>();
            var routeConfig         = new RouteConfig(
                proxyRoute: new ProxyRoute(),
                cluster: cluster1,
                transformer: null);
            var aspNetCoreEndpoint = CreateAspNetCoreEndpoint(routeConfig);

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

            httpContext.SetEndpoint(aspNetCoreEndpoint);

            var sut = Create <DestinationInitializerMiddleware>();

            await sut.Invoke(httpContext);

            var feature = httpContext.Features.Get <IReverseProxyFeature>();

            Assert.NotNull(feature);
            Assert.Single(feature.AllDestinations);
            Assert.Empty(feature.AvailableDestinations);

            Assert.Equal(StatusCodes.Status418ImATeapot, httpContext.Response.StatusCode);
        }
            public void SetActive(ClusterInfo cluster, IEnumerable <NewActiveDestinationHealth> newHealthStates)
            {
                foreach (var newHealthState in newHealthStates)
                {
                    newHealthState.Destination.Health.Active = newHealthState.NewActiveHealth;
                }

                cluster.UpdateDynamicState();
            }
Пример #6
0
        internal ClusterInfo GetCluster()
        {
            var destinationManager = new DestinationManager();

            destinationManager.GetOrCreateItem("dest-A", d => { });
            destinationManager.GetOrCreateItem(AffinitizedDestinationName, d => { });
            destinationManager.GetOrCreateItem("dest-C", d => { });

            var cluster = new ClusterInfo("cluster-1", destinationManager);

            cluster.Config = ClusterConfig;
            cluster.UpdateDynamicState();
            return(cluster);
        }
Пример #7
0
        public async Task Invoke_SetsFeatures()
        {
            var httpClient = new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object);
            var cluster1   = new ClusterInfo(
                clusterId: "cluster1",
                destinationManager: new DestinationManager());

            cluster1.Config = new ClusterConfig(new Cluster(), httpClient);
            var destination1 = cluster1.DestinationManager.GetOrCreateItem(
                "destination1",
                destination =>
            {
                destination.Config = new DestinationConfig(new Destination {
                    Address = "https://localhost:123/a/b/"
                });
            });

            cluster1.UpdateDynamicState();

            var aspNetCoreEndpoints = new List <Endpoint>();
            var routeConfig         = new RouteConfig(
                new RouteInfo("route1"),
                proxyRoute: new ProxyRoute(),
                cluster1,
                transformer: null);
            var aspNetCoreEndpoint = CreateAspNetCoreEndpoint(routeConfig);

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

            httpContext.SetEndpoint(aspNetCoreEndpoint);

            var sut = Create <DestinationInitializerMiddleware>();

            await sut.Invoke(httpContext);

            var proxyFeature = httpContext.GetRequiredProxyFeature();

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

            Assert.Equal(200, httpContext.Response.StatusCode);
        }
        internal ClusterInfo GetCluster()
        {
            var destinationManager = new DestinationManager();

            destinationManager.GetOrCreateItem("dest-A", d => { });

            var cluster = new ClusterInfo("cluster-1", destinationManager);

            cluster.Config = new ClusterConfig(new Cluster
            {
                SessionAffinity = new SessionAffinityOptions
                {
                    Enabled       = true,
                    Mode          = "Mode-B",
                    FailurePolicy = "Policy-1",
                }
            },
                                               new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object));

            cluster.UpdateDynamicState();
            return(cluster);
        }
Пример #9
0
        public void DynamicState_ManuallyUpdated()
        {
            var cluster = new ClusterInfo("abc");

            var state1 = cluster.DynamicState;

            Assert.NotNull(state1);
            Assert.Empty(state1.AllDestinations);

            cluster.ProcessDestinationChanges();
            var state2 = cluster.DynamicState;

            Assert.NotSame(state1, state2);
            Assert.NotNull(state2);
            Assert.Empty(state2.AllDestinations);

            cluster.Config = new ClusterConfig(new Cluster(), httpClient: new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object));
            Assert.Same(state2, cluster.DynamicState);

            cluster.UpdateDynamicState();
            Assert.NotSame(state2, cluster.DynamicState);
            Assert.Empty(cluster.DynamicState.AllDestinations);
        }