Example #1
0
        public void Should_build_a_chain_with_correct_modules_composition_and_disposition_when_optional_modules_are_enabled()
        {
            var configuration = Substitute.For <IClusterClientConfiguration>();

            configuration.Modules.Returns(null as List <IRequestModule>);
            configuration.AdaptiveThrottling.Returns(new AdaptiveThrottlingOptions("foo"));
            configuration.ReplicaBudgeting.Returns(new ReplicaBudgetingOptions("foo"));

            var storageProvider = Substitute.For <IReplicaStorageProvider>();

            var modules = RequestModuleChainBuilder.BuildChain(configuration, storageProvider);

            modules.Should().HaveCount(14);

            modules[0].Should().BeOfType <ErrorCatchingModule>();
            modules[1].Should().BeOfType <RequestTransformationModule>();
            modules[2].Should().BeOfType <OperationNameFallbackModule>();
            modules[3].Should().BeOfType <RequestPriorityApplicationModule>();
            modules[4].Should().BeOfType <LoggingModule>();
            modules[5].Should().BeOfType <ResponseTransformationModule>();
            modules[6].Should().BeOfType <ErrorCatchingModule>();
            modules[7].Should().BeOfType <RequestValidationModule>();
            modules[8].Should().BeOfType <TimeoutValidationModule>();
            modules[9].Should().BeOfType <RequestRetryModule>();
            modules[10].Should().BeOfType <AdaptiveThrottlingModule>();
            modules[11].Should().BeOfType <ReplicaBudgetingModule>();
            modules[12].Should().BeOfType <AbsoluteUrlSenderModule>();
            modules[13].Should().BeOfType <RequestExecutionModule>();
        }
Example #2
0
        public void Should_build_a_chain_with_correct_modules_composition_and_disposition()
        {
            var configuration = Substitute.For <IClusterClientConfiguration>();

            configuration.Modules.Returns(new List <IRequestModule> {
                module1, module2
            });

            var storageProvider = Substitute.For <IReplicaStorageProvider>();

            var modules = RequestModuleChainBuilder.BuildChain(configuration, storageProvider);

            modules.Should().HaveCount(14);

            modules[0].Should().BeOfType <ErrorCatchingModule>();
            modules[1].Should().BeOfType <RequestTransformationModule>();
            modules[2].Should().BeOfType <OperationNameFallbackModule>();
            modules[3].Should().BeOfType <RequestPriorityApplicationModule>();
            modules[4].Should().BeSameAs(module1);
            modules[5].Should().BeSameAs(module2);
            modules[6].Should().BeOfType <LoggingModule>();
            modules[7].Should().BeOfType <ResponseTransformationModule>();
            modules[8].Should().BeOfType <ErrorCatchingModule>();
            modules[9].Should().BeOfType <RequestValidationModule>();
            modules[10].Should().BeOfType <TimeoutValidationModule>();
            modules[11].Should().BeOfType <RequestRetryModule>();
            modules[12].Should().BeOfType <AbsoluteUrlSenderModule>();
            modules[13].Should().BeOfType <RequestExecutionModule>();
        }
Example #3
0
        /// <summary>
        /// Creates a <see cref="ClusterClient"/> instance using given <paramref name="log"/> and <paramref name="setup"/> delegate.
        /// </summary>
        /// <exception cref="ClusterClientException">Configuration was incomplete or invalid.</exception>
        public ClusterClient(ILog log, ClusterClientSetup setup)
        {
            configuration = new ClusterClientConfiguration(log ?? new SilentLog());

            setup(configuration);

            configuration.ValidateOrDie();
            configuration.AugmentWithDefaults();

            if (configuration.ReplicaTransform != null)
            {
                configuration.ClusterProvider = new TransformingClusterProvider(configuration.ClusterProvider, configuration.ReplicaTransform);
            }

            if (configuration.TransferDistributedContext)
            {
                configuration.Transport = new TransportWithDistributedContext(configuration.Transport);
            }

            if (configuration.EnableTracing)
            {
                configuration.Transport = new TransportWithTracing(configuration.Transport);
            }

            configuration.Transport = new TransportWithAuxiliaryHeaders(configuration.Transport, configuration);

            ReplicaStorageProvider = ReplicaStorageProviderFactory.Create(configuration.ReplicaStorageScope);

            var modules = RequestModuleChainBuilder.BuildChain(configuration, ReplicaStorageProvider);

            pipelineDelegate = RequestModuleChainBuilder.BuildChainDelegate(modules);
        }
Example #4
0
        public void Should_build_a_delegate_which_invokes_all_modules_in_correct_order()
        {
            var chainDelegate = RequestModuleChainBuilder.BuildChainDelegate(new[] { module1, module2, module3, module4 });

            chainDelegate(context).Result.Status.Should().Be(ClusterResultStatus.UnexpectedException);

            calledModules.Should().Equal(module1, module2, module3, module4);
        }
Example #5
0
        public void Should_respect_removed_built_in_modules_when_building_a_chain()
        {
            var config = new ClusterClientConfiguration(new SilentLog());

            config.RemoveRequestModule(RequestModule.AbsoluteUrlSender);

            var chain = RequestModuleChainBuilder.BuildChain(config, Substitute.For <IReplicaStorageProvider>());

            chain.Should().NotContain(module => module is AbsoluteUrlSenderModule);
        }
Example #6
0
        public void Should_add_optional_modules_for_some_module_once()
        {
            var configuration = Substitute.For <IClusterClientConfiguration>();

            configuration.Logging.Returns(new LoggingOptions());

            configuration.Modules.Returns(
                new Dictionary <Type, RelatedModules>
            {
                [typeof(GlobalErrorCatchingModule)] = new RelatedModules
                {
                    Before =
                    {
                        new AdaptiveThrottlingModule(new AdaptiveThrottlingOptions("foo")),
                    }
                },
                [typeof(AdaptiveThrottlingModule)] = new RelatedModules
                {
                    After =
                    {
                        new ReplicaBudgetingModule(new ReplicaBudgetingOptions("foo"))
                    }
                },
                [typeof(AuxiliaryHeadersModule)] = new RelatedModules
                {
                    After =
                    {
                        new GlobalErrorCatchingModule()
                    }
                }
            });

            var storageProvider = Substitute.For <IReplicaStorageProvider>();

            var modules = RequestModuleChainBuilder.BuildChain(configuration, storageProvider);

            modules.Should().HaveCount(15);

            modules[0].Should().BeOfType <LeakPreventionModule>();
            modules[1].Should().BeOfType <AdaptiveThrottlingModule>();
            modules[2].Should().BeOfType <ReplicaBudgetingModule>();
            modules[3].Should().BeOfType <GlobalErrorCatchingModule>();
            modules[4].Should().BeOfType <RequestTransformationModule>();
            modules[5].Should().BeOfType <AuxiliaryHeadersModule>();
            modules[6].Should().BeOfType <GlobalErrorCatchingModule>();
            modules[7].Should().BeOfType <LoggingModule>();
            modules[8].Should().BeOfType <ResponseTransformationModule>();
            modules[9].Should().BeOfType <ErrorCatchingModule>();
            modules[10].Should().BeOfType <RequestValidationModule>();
            modules[11].Should().BeOfType <TimeoutValidationModule>();
            modules[12].Should().BeOfType <RequestRetryModule>();
            modules[13].Should().BeOfType <AbsoluteUrlSenderModule>();
            modules[14].Should().BeOfType <RequestExecutionModule>();
        }
Example #7
0
        public void Should_respect_removed_custom_modules_when_building_a_chain()
        {
            var config = new ClusterClientConfiguration(new SilentLog());

            config.SetupThreadPoolLimitsTuning();

            config.RemoveRequestModule(RequestModule.ThreadPoolTuning);

            var chain = RequestModuleChainBuilder.BuildChain(config, Substitute.For <IReplicaStorageProvider>());

            chain.Should().NotContain(module => module is ThreadPoolTuningModule);
        }
Example #8
0
        public void Should_build_a_delegate_which_checks_cancellation_token_before_each_module_invocation()
        {
            var tokenSource = new CancellationTokenSource();
            var token       = tokenSource.Token;

            tokenSource.Cancel();

            context.CancellationToken.Returns(token);

            var chainDelegate = RequestModuleChainBuilder.BuildChainDelegate(new[] { module1, module2, module3, module4 });

            chainDelegate(context).Result.Status.Should().Be(ClusterResultStatus.Canceled);

            calledModules.Should().BeEmpty();
        }
        /// <summary>
        /// Creates a <see cref="ClusterClient"/> instance using given <paramref name="log"/> and <paramref name="setup"/> delegate.
        /// </summary>
        /// <exception cref="ClusterClientException">Configuration was incomplete or invalid.</exception>
        public ClusterClient(ILog log, ClusterClientSetup setup)
        {
            configuration = new ClusterClientConfiguration(log ?? new SilentLog());

            setup(configuration);

            configuration.ValidateOrDie();
            configuration.AugmentWithDefaults();
            configuration.ApplyReplicaTransform();
            configuration.SetupRequestTimeoutHeader();

            ReplicaStorageProvider = ReplicaStorageProviderFactory.Create(configuration.ReplicaStorageScope);

            var modules = RequestModuleChainBuilder.BuildChain(configuration, ReplicaStorageProvider);

            pipelineDelegate = RequestModuleChainBuilder.BuildChainDelegate(modules);

            defaultParameters = RequestParameters.Empty
                                .WithStrategy(configuration.DefaultRequestStrategy)
                                .WithPriority(configuration.DefaultPriority)
                                .WithConnectionTimeout(configuration.DefaultConnectionTimeout);
        }
Example #10
0
        public void Members_of_RequestModules_should_be_ordered_in_pipeline_order()
        {
            var configuration = new ClusterClientConfiguration(new SilentLog());

            configuration.TargetServiceName = string.Empty;

            configuration.SetupAdaptiveThrottling();
            configuration.SetupReplicaBudgeting();
            configuration.SetupHttpMethodValidation();
            configuration.SetupThreadPoolLimitsTuning();

            var chain = RequestModuleChainBuilder.BuildChain(configuration, new PerInstanceReplicaStorageProvider());

            var values = (RequestModule[])Enum.GetValues(typeof(RequestModule));

            values.Should().HaveCount(chain.Count);

            for (var i = 0; i < values.Length; i++)
            {
                RequestModulesMapping.GetModuleType(values[i]).Should().Be(chain[i].GetType());
            }
        }
Example #11
0
        public void Should_build_a_chain_with_correct_modules_composition_and_disposition()
        {
            var configuration = Substitute.For <IClusterClientConfiguration>();

            configuration.Modules.Returns(
                new Dictionary <Type, RelatedModules>
            {
                [typeof(LoggingModule)] = new RelatedModules
                {
                    Before = { module1, module2 }
                }
            });

            configuration.Logging.Returns(new LoggingOptions());

            var storageProvider = Substitute.For <IReplicaStorageProvider>();

            var modules = RequestModuleChainBuilder.BuildChain(configuration, storageProvider);

            modules.Should().HaveCount(14);

            modules[0].Should().BeOfType <LeakPreventionModule>();
            modules[1].Should().BeOfType <GlobalErrorCatchingModule>();
            modules[2].Should().BeOfType <RequestTransformationModule>();
            modules[3].Should().BeOfType <AuxiliaryHeadersModule>();
            modules[4].Should().BeSameAs(module1);
            modules[5].Should().BeSameAs(module2);
            modules[6].Should().BeOfType <LoggingModule>();
            modules[7].Should().BeOfType <ResponseTransformationModule>();
            modules[8].Should().BeOfType <ErrorCatchingModule>();
            modules[9].Should().BeOfType <RequestValidationModule>();
            modules[10].Should().BeOfType <TimeoutValidationModule>();
            modules[11].Should().BeOfType <RequestRetryModule>();
            modules[12].Should().BeOfType <AbsoluteUrlSenderModule>();
            modules[13].Should().BeOfType <RequestExecutionModule>();
        }