public void DynamicState_WithoutHealthChecks_AssumesAllHealthy() { // Arrange var backend = _backendManager.GetOrCreateItem("abc", backend => { }); var endpoint1 = backend.EndpointManager.GetOrCreateItem("ep1", endpoint => endpoint.DynamicState.Value = new EndpointDynamicState(EndpointHealth.Healthy)); var endpoint2 = backend.EndpointManager.GetOrCreateItem("ep2", endpoint => endpoint.DynamicState.Value = new EndpointDynamicState(EndpointHealth.Unhealthy)); var endpoint3 = backend.EndpointManager.GetOrCreateItem("ep3", endpoint => endpoint.DynamicState.Value = new EndpointDynamicState(EndpointHealth.Unknown)); var endpoint4 = backend.EndpointManager.GetOrCreateItem("ep4", endpoint => endpoint.DynamicState.Value = new EndpointDynamicState(EndpointHealth.Healthy)); // Assert backend.DynamicState.Value.AllEndpoints.Should().BeEquivalentTo(endpoint1, endpoint2, endpoint3, endpoint4); backend.DynamicState.Value.HealthyEndpoints.Should().BeEquivalentTo(endpoint1, endpoint2, endpoint3, endpoint4); }
public void DynamicState_WithoutHealthChecks_AssumesAllHealthy() { // Arrange var backend = _backendManager.GetOrCreateItem("abc", backend => { }); var destination1 = backend.DestinationManager.GetOrCreateItem("d1", destination => destination.DynamicState.Value = new DestinationDynamicState(DestinationHealth.Healthy)); var destination2 = backend.DestinationManager.GetOrCreateItem("d2", destination => destination.DynamicState.Value = new DestinationDynamicState(DestinationHealth.Unhealthy)); var destination3 = backend.DestinationManager.GetOrCreateItem("d3", destination => destination.DynamicState.Value = new DestinationDynamicState(DestinationHealth.Unknown)); var destination4 = backend.DestinationManager.GetOrCreateItem("d4", destination => destination.DynamicState.Value = new DestinationDynamicState(DestinationHealth.Healthy)); // Assert Assert.Same(destination1, backend.DynamicState.Value.AllDestinations[0]); Assert.Same(destination2, backend.DynamicState.Value.AllDestinations[1]); Assert.Same(destination3, backend.DynamicState.Value.AllDestinations[2]); Assert.Same(destination4, backend.DynamicState.Value.AllDestinations[3]); Assert.Same(destination1, backend.DynamicState.Value.HealthyDestinations[0]); Assert.Same(destination2, backend.DynamicState.Value.HealthyDestinations[1]); Assert.Same(destination3, backend.DynamicState.Value.HealthyDestinations[2]); Assert.Same(destination4, backend.DynamicState.Value.HealthyDestinations[3]); }
public void DynamicState_WithoutHealthChecks_AssumesAllHealthy() { // Arrange var backend = _backendManager.GetOrCreateItem("abc", backend => { }); var endpoint1 = backend.EndpointManager.GetOrCreateItem("ep1", endpoint => endpoint.DynamicState.Value = new EndpointDynamicState(EndpointHealth.Healthy)); var endpoint2 = backend.EndpointManager.GetOrCreateItem("ep2", endpoint => endpoint.DynamicState.Value = new EndpointDynamicState(EndpointHealth.Unhealthy)); var endpoint3 = backend.EndpointManager.GetOrCreateItem("ep3", endpoint => endpoint.DynamicState.Value = new EndpointDynamicState(EndpointHealth.Unknown)); var endpoint4 = backend.EndpointManager.GetOrCreateItem("ep4", endpoint => endpoint.DynamicState.Value = new EndpointDynamicState(EndpointHealth.Healthy)); // Assert Assert.Equal(endpoint1, backend.DynamicState.Value.AllEndpoints[0]); Assert.Equal(endpoint2, backend.DynamicState.Value.AllEndpoints[1]); Assert.Equal(endpoint3, backend.DynamicState.Value.AllEndpoints[2]); Assert.Equal(endpoint4, backend.DynamicState.Value.AllEndpoints[3]); Assert.Equal(endpoint1, backend.DynamicState.Value.HealthyEndpoints[0]); Assert.Equal(endpoint2, backend.DynamicState.Value.HealthyEndpoints[1]); Assert.Equal(endpoint3, backend.DynamicState.Value.HealthyEndpoints[2]); Assert.Equal(endpoint4, backend.DynamicState.Value.HealthyEndpoints[3]); }
private void UpdateRuntimeBackends(DynamicConfigRoot config) { var desiredBackends = new HashSet <string>(StringComparer.Ordinal); foreach (var configBackendPair in config.Backends) { var configBackend = configBackendPair.Value; desiredBackends.Add(configBackendPair.Key); _backendManager.GetOrCreateItem( itemId: configBackendPair.Key, setupAction: backend => { UpdateRuntimeEndpoints(configBackend.Endpoints, backend.EndpointManager); var newConfig = new BackendConfig( new BackendConfig.BackendHealthCheckOptions( enabled: configBackend.HealthCheckOptions?.Enabled ?? false, interval: configBackend.HealthCheckOptions?.Interval ?? TimeSpan.FromSeconds(0), timeout: configBackend.HealthCheckOptions?.Timeout ?? TimeSpan.FromSeconds(0), port: configBackend.HealthCheckOptions?.Port ?? 0, path: configBackend.HealthCheckOptions?.Path ?? string.Empty), new BackendConfig.BackendLoadBalancingOptions( mode: BackendConfig.BackendLoadBalancingOptions.LoadBalancingMode.First)); var currentBackendConfig = backend.Config.Value; if (currentBackendConfig == null || currentBackendConfig.HealthCheckOptions.Enabled != newConfig.HealthCheckOptions.Enabled || currentBackendConfig.HealthCheckOptions.Interval != newConfig.HealthCheckOptions.Interval || currentBackendConfig.HealthCheckOptions.Timeout != newConfig.HealthCheckOptions.Timeout || currentBackendConfig.HealthCheckOptions.Port != newConfig.HealthCheckOptions.Port || currentBackendConfig.HealthCheckOptions.Path != newConfig.HealthCheckOptions.Path) { if (currentBackendConfig == null) { _logger.LogDebug("Backend {backendId} has been added.", configBackendPair.Key); } else { _logger.LogDebug("Backend {backendId} has changed.", configBackendPair.Key); } // Config changed, so update runtime backend backend.Config.Value = newConfig; } }); } foreach (var existingBackend in _backendManager.GetItems()) { if (!desiredBackends.Contains(existingBackend.BackendId)) { // NOTE 1: This is safe to do within the `foreach` loop // because `IBackendManager.GetItems` returns a copy of the list of backends. // // NOTE 2: Removing the backend from `IBackendManager` is safe and existing // ASP .NET Core endpoints will continue to work with their existing behavior (until those endpoints are updated) // and the Garbage Collector won't destroy this backend object while it's referenced elsewhere. _logger.LogDebug("Backend {backendId} has been removed.", existingBackend.BackendId); _backendManager.TryRemoveItem(existingBackend.BackendId); } } }