Beispiel #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);
        }
Beispiel #2
0
        public void DynamicState_ReactsToDestinationChanges()
        {
            var cluster = new ClusterInfo("abc");

            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;

            Assert.Contains(destination, state2.AllDestinations);

            cluster.Destinations.TryRemove("d1", out var _);
            cluster.ProcessDestinationChanges();
            Assert.NotSame(state2, cluster.DynamicState);
            var state3 = cluster.DynamicState;

            Assert.Empty(state3.AllDestinations);
        }
Beispiel #3
0
        private static ClusterInfo CreateCluster(bool passive, bool active, params DestinationInfo[] destinations)
        {
            var cluster = new ClusterInfo("cluster0");

            cluster.Config = new ClusterConfig(
                new Cluster
            {
                Id          = cluster.ClusterId,
                HealthCheck = new HealthCheckOptions()
                {
                    Passive = new PassiveHealthCheckOptions()
                    {
                        Policy  = "policy0",
                        Enabled = passive,
                    },
                    Active = new ActiveHealthCheckOptions()
                    {
                        Enabled = active,
                        Policy  = "policy1",
                    },
                },
            },
                default);

            foreach (var destination in destinations)
            {
                cluster.Destinations.TryAdd(destination.DestinationId, destination);
            }

            cluster.ProcessDestinationChanges();

            return(cluster);
        }
Beispiel #4
0
        public void DynamicState_WithoutHealthChecks_AssumesAllHealthy()
        {
            var cluster      = new ClusterInfo("abc");
            var destination1 = cluster.Destinations.GetOrAdd("d1", id => new DestinationInfo(id)
            {
                Health = { Active = DestinationHealth.Healthy }
            });
            var destination2 = cluster.Destinations.GetOrAdd("d2", id => new DestinationInfo(id)
            {
                Health = { Active = DestinationHealth.Unhealthy }
            });
            var destination3 = cluster.Destinations.GetOrAdd("d3", id => new DestinationInfo(id)); // Unknown health state
            var destination4 = cluster.Destinations.GetOrAdd("d4", id => new DestinationInfo(id)
            {
                Health = { Passive = DestinationHealth.Healthy }
            });

            cluster.ProcessDestinationChanges();

            var sorted = cluster.DynamicState.AllDestinations.OrderBy(d => d.DestinationId).ToList();

            Assert.Same(destination1, sorted[0]);
            Assert.Same(destination2, sorted[1]);
            Assert.Same(destination3, sorted[2]);
            Assert.Same(destination4, sorted[3]);

            sorted = cluster.DynamicState.HealthyDestinations.OrderBy(d => d.DestinationId).ToList();
            Assert.Same(destination1, sorted[0]);
            Assert.Same(destination2, sorted[1]);
            Assert.Same(destination3, sorted[2]);
            Assert.Same(destination4, sorted[3]);
        }
        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);

            clusterInfo.Config = clusterConfig;
            clusterInfo.Destinations.GetOrAdd("destination0", id => new DestinationInfo(id));
            clusterInfo.Destinations.GetOrAdd("destination1", id => new DestinationInfo(id));

            clusterInfo.ProcessDestinationChanges();

            return(clusterInfo);
        }
        public async Task Invoke_NoHealthyEndpoints_CallsNext()
        {
            var httpClient = new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object);
            var cluster1   = new ClusterInfo(clusterId: "cluster1");

            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.Destinations.GetOrAdd(
                "destination1",
                id => new DestinationInfo(id)
            {
                Config = new DestinationConfig(new Destination {
                    Address = "https://localhost:123/a/b/"
                }),
                Health = { Active = DestinationHealth.Unhealthy },
            });

            cluster1.ProcessDestinationChanges();

            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);
        }
Beispiel #7
0
        internal ClusterInfo GetCluster()
        {
            var cluster            = new ClusterInfo("cluster-1");
            var destinationManager = cluster.Destinations;

            destinationManager.GetOrAdd("dest-A", id => new DestinationInfo(id));
            destinationManager.GetOrAdd(AffinitizedDestinationName, id => new DestinationInfo(id));
            destinationManager.GetOrAdd("dest-C", id => new DestinationInfo(id));
            cluster.Config = ClusterConfig;
            cluster.ProcessDestinationChanges();
            return(cluster);
        }
        public async Task Invoke_SetsFeatures()
        {
            var httpClient = new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object);
            var cluster1   = new ClusterInfo(clusterId: "cluster1");

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

            cluster1.ProcessDestinationChanges();

            var aspNetCoreEndpoints = new List <Endpoint>();
            var routeConfig         = new RouteConfig(
                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.ClusterSnapshot);

            Assert.Equal(StatusCodes.Status418ImATeapot, httpContext.Response.StatusCode);
        }
Beispiel #9
0
        internal ClusterInfo GetCluster()
        {
            var cluster = new ClusterInfo("cluster-1");

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

            cluster.ProcessDestinationChanges();
            return(cluster);
        }
        private ClusterInfo GetClusterInfo(string id, int destinationCount, int?failureThreshold = null)
        {
            var metadata = failureThreshold != null
                ? new Dictionary <string, string> {
                { ConsecutiveFailuresHealthPolicyOptions.ThresholdMetadataName, failureThreshold.ToString() }
            }
                : null;
            var clusterConfig = new ClusterConfig(
                new Cluster
            {
                Id          = id,
                HealthCheck = new HealthCheckOptions()
                {
                    Active = new ActiveHealthCheckOptions
                    {
                        Enabled = true,
                        Policy  = "policy",
                        Path    = "/api/health/",
                    },
                },
                Metadata = metadata,
            },
                null);
            var clusterInfo = new ClusterInfo(id);

            clusterInfo.Config = clusterConfig;
            for (var i = 0; i < destinationCount; i++)
            {
                var destinationConfig = new DestinationConfig(new Destination {
                    Address = $"https://localhost:1000{i}/{id}/", Health = $"https://localhost:2000{i}/{id}/"
                });
                var destinationId = $"destination{i}";
                clusterInfo.Destinations.GetOrAdd(destinationId, id => new DestinationInfo(id)
                {
                    Config = destinationConfig
                });
            }

            clusterInfo.ProcessDestinationChanges();

            return(clusterInfo);
        }
Beispiel #11
0
        public void DynamicState_WithHealthChecks_HonorsHealthState()
        {
            var cluster = new ClusterInfo("abc");

            EnableHealthChecks(cluster);
            var destination1 = cluster.Destinations.GetOrAdd("d1", id => new DestinationInfo(id)
            {
                Health = { Active = DestinationHealth.Healthy }
            });
            var destination2 = cluster.Destinations.GetOrAdd("d2", id => new DestinationInfo(id)
            {
                Health = { Active = DestinationHealth.Unhealthy }
            });
            var destination3 = cluster.Destinations.GetOrAdd("d3", id => new DestinationInfo(id)); // Unknown health state
            var destination4 = cluster.Destinations.GetOrAdd("d4", id => new DestinationInfo(id)
            {
                Health = { Passive = DestinationHealth.Healthy }
            });
            var destination5 = cluster.Destinations.GetOrAdd("d5", id => new DestinationInfo(id)
            {
                Health = { Passive = DestinationHealth.Unhealthy }
            });

            cluster.ProcessDestinationChanges();

            Assert.Equal(5, cluster.DynamicState.AllDestinations.Count);
            var sorted = cluster.DynamicState.AllDestinations.OrderBy(d => d.DestinationId).ToList();

            Assert.Same(destination1, sorted[0]);
            Assert.Same(destination2, sorted[1]);
            Assert.Same(destination3, sorted[2]);
            Assert.Same(destination4, sorted[3]);
            Assert.Same(destination5, sorted[4]);

            Assert.Equal(3, cluster.DynamicState.HealthyDestinations.Count);
            sorted = cluster.DynamicState.HealthyDestinations.OrderBy(d => d.DestinationId).ToList();
            Assert.Same(destination1, sorted[0]);
            Assert.Same(destination3, sorted[1]);
            Assert.Same(destination4, sorted[2]);
        }
Beispiel #12
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);
        }