Ejemplo n.º 1
0
        private void UpdateRuntimeRoutes(DynamicConfigRoot config)
        {
            var desiredRoutes = new HashSet <string>(StringComparer.Ordinal);
            var changed       = false;

            foreach (var configRoute in config.Routes)
            {
                desiredRoutes.Add(configRoute.RouteId);

                // Note that this can be null, and that is fine. The resulting route may match
                // but would then fail to route, which is exactly what we were instructed to do in this case
                // since no valid backend was specified.
                var backendOrNull = _backendManager.TryGetItem(configRoute.BackendId);

                _routeManager.GetOrCreateItem(
                    itemId: configRoute.RouteId,
                    setupAction: route =>
                {
                    var currentRouteConfig = route.Config.Value;
                    if (currentRouteConfig == null ||
                        currentRouteConfig.HasConfigChanged(configRoute, backendOrNull))
                    {
                        // Config changed, so update runtime route
                        changed = true;
                        if (currentRouteConfig == null)
                        {
                            _logger.LogDebug("Route {routeId} has been added.", configRoute.RouteId);
                        }
                        else
                        {
                            _logger.LogDebug("Route {routeId} has changed.", configRoute.RouteId);
                        }

                        var newConfig      = _routeEndpointBuilder.Build(configRoute, backendOrNull, route);
                        route.Config.Value = newConfig;
                    }
                });
            }

            foreach (var existingRoute in _routeManager.GetItems())
            {
                if (!desiredRoutes.Contains(existingRoute.RouteId))
                {
                    // NOTE 1: This is safe to do within the `foreach` loop
                    // because `IRouteManager.GetItems` returns a copy of the list of routes.
                    //
                    // NOTE 2: Removing the route from `IRouteManager` is safe and existing
                    // ASP .NET Core endpoints will continue to work with their existing behavior since
                    // their copy of `RouteConfig` is immutable and remains operational in whichever state is was in.
                    _logger.LogDebug("Route {routeId} has been removed.", existingRoute.RouteId);
                    _routeManager.TryRemoveItem(existingRoute.RouteId);
                    changed = true;
                }
            }

            if (changed)
            {
                var aspNetCoreEndpoints = new List <AspNetCore.Http.Endpoint>();
                foreach (var existingRoute in _routeManager.GetItems())
                {
                    var runtimeConfig = existingRoute.Config.Value;
                    if (runtimeConfig?.AspNetCoreEndpoints != null)
                    {
                        aspNetCoreEndpoints.AddRange(runtimeConfig.AspNetCoreEndpoints);
                    }
                }

                // This is where the new routes take effect!
                _dynamicEndpointDataSource.Update(aspNetCoreEndpoints);
            }
        }