Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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]);
        }
Esempio n. 3
0
        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);
                }
            }
        }