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); }
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(); } }
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(); }
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); }
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); }
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); }