Пример #1
0
        public void Endpoints_ReturnsAllEndpoints_FromMultipleDataSources()
        {
            // Arrange
            var endpoint1           = CreateEndpoint("/a");
            var endpoint2           = CreateEndpoint("/b");
            var endpoint3           = CreateEndpoint("/c");
            var endpoint4           = CreateEndpoint("/d");
            var endpoint5           = CreateEndpoint("/e");
            var compositeDataSource = new CompositeEndpointDataSource(new[]
            {
                new DefaultEndpointDataSource(new Endpoint[] { endpoint1, endpoint2 }),
                new DefaultEndpointDataSource(new Endpoint[] { endpoint3, endpoint4 }),
                new DefaultEndpointDataSource(new Endpoint[] { endpoint5 }),
            });

            // Act
            var endpoints = compositeDataSource.Endpoints;

            // Assert
            Assert.Collection(
                endpoints,
                (ep) => Assert.Same(endpoint1, ep),
                (ep) => Assert.Same(endpoint2, ep),
                (ep) => Assert.Same(endpoint3, ep),
                (ep) => Assert.Same(endpoint4, ep),
                (ep) => Assert.Same(endpoint5, ep));
        }
Пример #2
0
        public EndpointRoutingMiddleware(
            MatcherFactory matcherFactory,
            CompositeEndpointDataSource endpointDataSource,
            ILogger <EndpointRoutingMiddleware> logger,
            RequestDelegate next)
        {
            if (matcherFactory == null)
            {
                throw new ArgumentNullException(nameof(matcherFactory));
            }

            if (endpointDataSource == null)
            {
                throw new ArgumentNullException(nameof(endpointDataSource));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            _matcherFactory     = matcherFactory;
            _endpointDataSource = endpointDataSource;
            _logger             = logger;
            _next = next;
        }
Пример #3
0
 public NameBasedEndpointFinder(
     CompositeEndpointDataSource endpointDataSource,
     ILogger <NameBasedEndpointFinder> logger)
 {
     _endpointDatasource = endpointDataSource;
     _logger             = logger;
 }
Пример #4
0
        public DefaultLinkGenerator(
            ParameterPolicyFactory parameterPolicyFactory,
            CompositeEndpointDataSource dataSource,
            ObjectPool <UriBuildingContext> uriBuildingContextPool,
            IOptions <RouteOptions> routeOptions,
            ILogger <DefaultLinkGenerator> logger,
            IServiceProvider serviceProvider)
        {
            _parameterPolicyFactory = parameterPolicyFactory;
            _uriBuildingContextPool = uriBuildingContextPool;
            _logger          = logger;
            _serviceProvider = serviceProvider;

            // We cache TemplateBinder instances per-Endpoint for performance, but we want to wipe out
            // that cache is the endpoints change so that we don't allow unbounded memory growth.
            _cache = new DataSourceDependentCache <ConcurrentDictionary <RouteEndpoint, TemplateBinder> >(dataSource, (_) =>
            {
                // We don't eagerly fill this cache because there's no real reason to. Unlike URL matching, we don't
                // need to build a big data structure up front to be correct.
                return(new ConcurrentDictionary <RouteEndpoint, TemplateBinder>());
            });

            // Cached to avoid per-call allocation of a delegate on lookup.
            _createTemplateBinder = CreateTemplateBinder;

            _globalLinkOptions = new LinkOptions()
            {
                AppendTrailingSlash   = routeOptions.Value.AppendTrailingSlash,
                LowercaseQueryStrings = routeOptions.Value.LowercaseQueryStrings,
                LowercaseUrls         = routeOptions.Value.LowercaseUrls,
            };
        }
Пример #5
0
        public RouteValuesBasedEndpointFinder(
            CompositeEndpointDataSource endpointDataSource,
            ObjectPool <UriBuildingContext> objectPool,
            IInlineConstraintResolver inlineConstraintResolver)
        {
            _endpointDataSource       = endpointDataSource;
            _objectPool               = objectPool;
            _inlineConstraintResolver = inlineConstraintResolver;

            BuildOutboundMatches();
        }
        public RouteValuesBasedEndpointFinder(
            CompositeEndpointDataSource endpointDataSource,
            ObjectPool <UriBuildingContext> objectPool)
        {
            _endpointDataSource = endpointDataSource;
            _objectPool         = objectPool;

            // Build initial matches
            BuildOutboundMatches();

            // Register for changes in endpoints
            Extensions.Primitives.ChangeToken.OnChange(
                _endpointDataSource.GetChangeToken,
                HandleChange);
        }
Пример #7
0
        public void CreatesShallowCopyOf_ListOfEndpoints()
        {
            // Arrange
            var endpoint1           = CreateEndpoint("/a");
            var endpoint2           = CreateEndpoint("/b");
            var dataSource          = new DefaultEndpointDataSource(new Endpoint[] { endpoint1, endpoint2 });
            var compositeDataSource = new CompositeEndpointDataSource(new[] { dataSource });

            // Act
            var endpoints = compositeDataSource.Endpoints;

            // Assert
            Assert.NotSame(endpoints, dataSource.Endpoints);
            Assert.Equal(endpoints, dataSource.Endpoints);
        }
Пример #8
0
        public void ConsumerChangeToken_IsRefreshed_WhenDataSourceCallbackFires()
        {
            // Arrange1
            var endpoint1           = CreateEndpoint("/a");
            var dataSource1         = new DynamicEndpointDataSource(endpoint1);
            var compositeDataSource = new CompositeEndpointDataSource(new[] { dataSource1 });

            // Act1
            var endpoints = compositeDataSource.Endpoints;

            // Assert1
            var changeToken1 = compositeDataSource.GetChangeToken();
            var token        = Assert.IsType <CancellationChangeToken>(changeToken1);

            Assert.False(token.HasChanged); // initial state

            // Arrange2
            var endpoint2 = CreateEndpoint("/b");

            // Act2
            dataSource1.AddEndpoint(endpoint2);

            // Assert2
            Assert.True(changeToken1.HasChanged);                    // old token is expected to be changed
            var changeToken2 = compositeDataSource.GetChangeToken(); // new token is in a unchanged state

            Assert.NotSame(changeToken2, changeToken1);
            token = Assert.IsType <CancellationChangeToken>(changeToken2);
            Assert.False(token.HasChanged);

            // Arrange3
            var endpoint3 = CreateEndpoint("/c");

            // Act2
            dataSource1.AddEndpoint(endpoint3);

            // Assert2
            Assert.True(changeToken2.HasChanged);                    // old token is expected to be changed
            var changeToken3 = compositeDataSource.GetChangeToken(); // new token is in a unchanged state

            Assert.NotSame(changeToken3, changeToken2);
            Assert.NotSame(changeToken3, changeToken1);
            token = Assert.IsType <CancellationChangeToken>(changeToken3);
            Assert.False(token.HasChanged);
        }
Пример #9
0
        public void DataSourceChanges_AreReflected_InEndpoints()
        {
            // Arrange1
            var endpoint1           = CreateEndpoint("/a");
            var dataSource1         = new DynamicEndpointDataSource(endpoint1);
            var compositeDataSource = new CompositeEndpointDataSource(new[] { dataSource1 });

            // Act1
            var endpoints = compositeDataSource.Endpoints;

            // Assert1
            var endpoint = Assert.Single(endpoints);

            Assert.Same(endpoint1, endpoint);

            // Arrange2
            var endpoint2 = CreateEndpoint("/b");

            // Act2
            dataSource1.AddEndpoint(endpoint2);

            // Assert2
            Assert.Collection(
                compositeDataSource.Endpoints,
                (ep) => Assert.Same(endpoint1, ep),
                (ep) => Assert.Same(endpoint2, ep));

            // Arrange3
            var endpoint3 = CreateEndpoint("/c");

            // Act2
            dataSource1.AddEndpoint(endpoint3);

            // Assert2
            Assert.Collection(
                compositeDataSource.Endpoints,
                (ep) => Assert.Same(endpoint1, ep),
                (ep) => Assert.Same(endpoint2, ep),
                (ep) => Assert.Same(endpoint3, ep));
        }
Пример #10
0
        // Initialization is async to avoid blocking threads while reflection and things
        // of that nature take place.
        //
        // We've seen cases where startup is very slow if we  allow multiple threads to race
        // while initializing the set of endpoints/routes. Doing CPU intensive work is a
        // blocking operation if you have a low core count and enough work to do.
        private Task <Matcher> InitializeAsync()
        {
            if (_initializationTask != null)
            {
                return(_initializationTask);
            }

            var initializationTask = new TaskCompletionSource <Matcher>();

            if (Interlocked.CompareExchange <Task <Matcher> >(
                    ref _initializationTask,
                    initializationTask.Task,
                    null) == null)
            {
                // This thread won the race, do the initialization.
                var dataSource = new CompositeEndpointDataSource(_options.Value.DataSources);
                var matcher    = _matcherFactory.CreateMatcher(dataSource);
                initializationTask.SetResult(matcher);
            }

            return(_initializationTask);
        }
Пример #11
0
 public RouteValuesAddressScheme(CompositeEndpointDataSource dataSource)
 {
     _cache = new DataSourceDependentCache <StateEntry>(dataSource, Initialize);
 }
Пример #12
0
 public IntAddressScheme(CompositeEndpointDataSource dataSource)
 {
     _dataSource = dataSource;
 }
 public CustomRouteValuesBasedEndpointFinder(
     CompositeEndpointDataSource endpointDataSource,
     ObjectPool <UriBuildingContext> objectPool)
     : base(endpointDataSource, objectPool)
 {
 }
Пример #14
0
 public CustomRouteValuesBasedAddressScheme(CompositeEndpointDataSource dataSource)
     : base(dataSource)
 {
 }
Пример #15
0
 public EndpointNameAddressScheme(CompositeEndpointDataSource dataSource)
 {
     _cache = new DataSourceDependentCache <Dictionary <string, Endpoint[]> >(dataSource, Initialize);
 }