Exemple #1
0
        public void ValidateConstruction_WhenModelHasNullProviderResultsRepositoryPolicy_ShouldShouldBeInvalid()
        {
            // Arrange
            CalculatorResiliencePolicies model = new CalculatorResiliencePolicies()
            {
                CalculationsRepository           = Policy.NoOpAsync(),
                ProviderResultsRepository        = null,
                ProviderSourceDatasetsRepository = Policy.NoOpAsync(),
                CacheProvider = Policy.NoOpAsync(),
                Messenger     = Policy.NoOpAsync()
            };
            CalculatorResiliencePoliciesValidator validator = new CalculatorResiliencePoliciesValidator();

            // Act
            ValidationResult result = validator.Validate(model);

            // Assert
            result
            .IsValid
            .Should()
            .BeFalse();

            result
            .Errors
            .Count
            .Should().Be(1);

            result
            .Errors[0]
            .ErrorMessage
            .Should().Contain("ProviderResultsRepository");
        }
Exemple #2
0
        private static CalculatorResiliencePolicies CreateResiliencePolicies(PolicySettings policySettings)
        {
            BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

            CalculatorResiliencePolicies resiliencePolicies = new CalculatorResiliencePolicies()
            {
                ProviderResultsRepository        = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                ProviderSourceDatasetsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                CacheProvider          = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy),
                Messenger              = ResiliencePolicyHelpers.GenerateMessagingPolicy(totalNetworkRequestsPolicy),
                CalculationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                JobsApiClient          = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy)
            };

            return(resiliencePolicies);
        }
Exemple #3
0
        public void ValidateConstruction_WhenModelIsValid_ResultShouldBeValid()
        {
            // Arrange
            CalculatorResiliencePolicies model = new CalculatorResiliencePolicies()
            {
                CalculationsRepository           = Policy.NoOpAsync(),
                ProviderResultsRepository        = Policy.NoOpAsync(),
                ProviderSourceDatasetsRepository = Policy.NoOpAsync(),
                CacheProvider = Policy.NoOpAsync(),
                Messenger     = Policy.NoOpAsync()
            };
            CalculatorResiliencePoliciesValidator validator = new CalculatorResiliencePoliciesValidator();

            // Act
            ValidationResult result = validator.Validate(model);

            // Assert
            result
            .IsValid
            .Should()
            .BeTrue();
        }
        public void RegisterComponents(IServiceCollection builder)
        {
            builder.AddScoped <ICalculationEngineService, CalculationEngineService>();
            builder.AddScoped <ICalculationEngine, CalculationEngine>();
            builder.AddScoped <IAllocationFactory, AllocationFactory>();
            builder.AddScoped <IJobManagement, JobManagement>();
            builder.AddSingleton <IProviderSourceDatasetVersionKeyProvider, ProviderSourceDatasetVersionKeyProvider>();
            builder.AddSingleton <IFileSystemAccess, FileSystemAccess>();

            builder.AddSingleton <IAssemblyService, AssemblyService>();
            builder.AddSingleton <ICalculationAggregationService, CalculationAggregationService>();
            builder.AddScoped <ICalculationEnginePreviewService, CalculationEnginePreviewService>();

            builder.AddSingleton <IFileSystemCacheSettings, FileSystemCacheSettings>();
            builder.AddSingleton <IFileSystemCache, FileSystemCache>();

            builder.AddSingleton <IProviderSourceDatasetsRepository, ProviderSourceDatasetsRepository>((ctx) =>
            {
                CosmosDbSettings providerSourceDatasetsCosmosSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", providerSourceDatasetsCosmosSettings);

                providerSourceDatasetsCosmosSettings.ContainerName = "providerdatasets";

                CosmosRepository calcsCosmosRepository = new CosmosRepository(providerSourceDatasetsCosmosSettings, new CosmosClientOptions()
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = 8,
                    MaxTcpConnectionsPerEndpoint = 4,
                    ConsistencyLevel             = ConsistencyLevel.Eventual,
                    AllowBulkExecution           = true,
                });

                ICalculatorResiliencePolicies calculatorResiliencePolicies = ctx.GetService <ICalculatorResiliencePolicies>();

                return(new ProviderSourceDatasetsRepository(calcsCosmosRepository, calculatorResiliencePolicies));
            });

            builder.AddSingleton <IProviderResultCalculationsHashProvider, ProviderResultCalculationsHashProvider>();

            builder.AddSingleton <IProviderResultsRepository, ProviderResultsRepository>((ctx) =>
            {
                CosmosDbSettings calcResultsDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", calcResultsDbSettings);

                calcResultsDbSettings.ContainerName = "calculationresults";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(calcResultsDbSettings, new CosmosClientOptions()
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = 8,
                    MaxTcpConnectionsPerEndpoint = 2,
                    // MaxRetryWaitTimeOnRateLimitedRequests = new TimeSpan(0, 0, 30),
                    AllowBulkExecution = true,
                });

                ILogger logger = ctx.GetService <ILogger>();

                IProviderResultCalculationsHashProvider calculationsHashProvider = ctx.GetService <IProviderResultCalculationsHashProvider>();

                ICalculatorResiliencePolicies calculatorResiliencePolicies = ctx.GetService <ICalculatorResiliencePolicies>();

                IResultsApiClient resultsApiClient = ctx.GetService <IResultsApiClient>();

                IJobManagement jobManagement = ctx.GetService <IJobManagement>();

                return(new ProviderResultsRepository(
                           calcsCosmosRepostory,
                           logger,
                           calculationsHashProvider,
                           calculatorResiliencePolicies,
                           resultsApiClient,
                           jobManagement));
            });

            builder
            .AddSingleton <IBlobContainerRepository, BlobContainerRepository>();

            builder
            .AddSingleton <ICalculationsRepository, CalculationsRepository>();

            builder
            .AddSingleton <IDatasetAggregationsRepository, DatasetAggregationsRepository>();

            builder
            .AddSingleton <ICancellationTokenProvider, InactiveCancellationTokenProvider>();

            MapperConfiguration calculationsConfig = new MapperConfiguration(c =>
            {
                c.AddProfile <CalculationsMappingProfile>();
                c.AddProfile <CalcEngineMappingProfile>();
            });

            builder
            .AddSingleton(calculationsConfig.CreateMapper());

            builder.AddSingleton <IUserProfileProvider, UserProfileProvider>();

            builder.AddCalculationsInterServiceClient(Configuration, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddSpecificationsInterServiceClient(Configuration, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddJobsInterServiceClient(Configuration, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddPoliciesInterServiceClient(Configuration, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddResultsInterServiceClient(Configuration, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddDatasetsInterServiceClient(Configuration, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddProvidersInterServiceClient(Configuration, handlerLifetime: Timeout.InfiniteTimeSpan);

            builder.AddEngineSettings(Configuration);

            builder.AddServiceBus(Configuration, "calcengine");

            builder.AddCaching(Configuration);

            builder.AddApplicationInsightsTelemetry();
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Api.CalcEngine");
            builder.AddApplicationInsightsServiceName(Configuration, "CalculateFunding.Api.CalcEngine");

            builder.AddLogging("CalculateFunding.Api.CalcEngine");

            builder.AddTelemetry();

            builder.AddSearch(Configuration);
            builder
            .AddSingleton <ISearchRepository <ProviderCalculationResultsIndex>, SearchRepository <ProviderCalculationResultsIndex> >();

            builder.AddFeatureToggling(Configuration);

            PolicySettings policySettings = ServiceCollectionExtensions.GetPolicySettings(Configuration);
            CalculatorResiliencePolicies calcResiliencePolicies = CreateResiliencePolicies(policySettings);

            builder.AddSingleton <ICalculatorResiliencePolicies>(calcResiliencePolicies);
            builder.AddSingleton <IJobManagementResiliencePolicies>((ctx) => new JobManagementResiliencePolicies()
            {
                JobsApiClient = calcResiliencePolicies.JobsApiClient
            });

            builder.AddSingleton <IValidator <ICalculatorResiliencePolicies>, CalculatorResiliencePoliciesValidator>();
            builder.AddSingleton <ICalculationEngineServiceValidator, CalculationEngineServiceValidator>();
            builder.AddSingleton <ISpecificationAssemblyProvider, SpecificationAssemblyProvider>();
            builder.AddSingleton <IBlobClient>(ctx =>
            {
                BlobStorageOptions options = new BlobStorageOptions();

                Configuration.Bind("AzureStorageSettings", options);

                options.ContainerName = "source";

                IBlobContainerRepository blobContainerRepository = new BlobContainerRepository(options);
                return(new BlobClient(blobContainerRepository));
            });

            builder.AddApiKeyMiddlewareSettings((IConfigurationRoot)Configuration);

            builder.AddHttpContextAccessor();

            builder.AddHealthCheckMiddleware();

            if (Configuration.IsSwaggerEnabled())
            {
                builder.ConfigureSwaggerServices(title: "CalcEngine Microservice API", version: "v1");
            }
        }
Exemple #5
0
        private static IServiceProvider Register(IServiceCollection builder, IConfigurationRoot config)
        {
            builder.AddSingleton <OnCalcsGenerateAllocationResults>();
            builder.AddSingleton <OnCalculationGenerateFailure>();
            builder.AddSingleton <ICalculationEngineService, CalculationEngineService>();
            builder.AddSingleton <ICalculationEngine, CalculationEngine>();
            builder.AddSingleton <IAllocationFactory, AllocationFactory>();
            builder.AddSingleton <IJobHelperService, JobHelperService>();

            builder.AddSingleton <IProviderSourceDatasetsRepository, ProviderSourceDatasetsRepository>((ctx) =>
            {
                CosmosDbSettings providerSourceDatasetsCosmosSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", providerSourceDatasetsCosmosSettings);

                providerSourceDatasetsCosmosSettings.CollectionName = "providerdatasets";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(providerSourceDatasetsCosmosSettings);

                EngineSettings engineSettings = ctx.GetService <EngineSettings>();

                return(new ProviderSourceDatasetsRepository(calcsCosmosRepostory, engineSettings));
            });

            builder.AddSingleton <Services.Calculator.Interfaces.IProviderResultsRepository, Services.CalcEngine.ProviderResultsRepository>((ctx) =>
            {
                CosmosDbSettings calcResultsDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", calcResultsDbSettings);

                calcResultsDbSettings.CollectionName = "calculationresults";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(calcResultsDbSettings);

                ISearchRepository <CalculationProviderResultsIndex> calculationProviderResultsSearchRepository = ctx.GetService <ISearchRepository <CalculationProviderResultsIndex> >();

                ISearchRepository <ProviderCalculationResultsIndex> providerCalculationResultsSearchRepository = ctx.GetService <ISearchRepository <ProviderCalculationResultsIndex> >();

                ISpecificationsRepository specificationsRepository = ctx.GetService <ISpecificationsRepository>();

                ILogger logger = ctx.GetService <ILogger>();

                IFeatureToggle featureToggle = ctx.GetService <IFeatureToggle>();

                EngineSettings engineSettings = ctx.GetService <EngineSettings>();

                return(new Services.CalcEngine.ProviderResultsRepository(
                           calcsCosmosRepostory,
                           calculationProviderResultsSearchRepository,
                           specificationsRepository,
                           logger,
                           providerCalculationResultsSearchRepository,
                           featureToggle,
                           engineSettings));
            });

            builder.AddSingleton <ISourceFileRepository, SourceFileRepository>((ctx) =>
            {
                BlobStorageOptions blobStorageOptions = new BlobStorageOptions();

                config.Bind("CommonStorageSettings", blobStorageOptions);

                blobStorageOptions.ContainerName = "source";

                return(new SourceFileRepository(blobStorageOptions));
            });

            builder
            .AddSingleton <ISpecificationsRepository, SpecificationsRepository>();

            builder
            .AddSingleton <Services.Calculator.Interfaces.ICalculationsRepository, Services.Calculator.CalculationsRepository>();

            builder
            .AddSingleton <IDatasetAggregationsRepository, DatasetAggregationsRepository>();

            builder
            .AddSingleton <ICancellationTokenProvider, InactiveCancellationTokenProvider>();

            builder
            .AddSingleton <ISourceCodeService, SourceCodeService>();

            builder.AddCalcsInterServiceClient(config);
            builder.AddSpecificationsInterServiceClient(config);

            builder.AddJobsInterServiceClient(config);

            builder.AddDatasetsInterServiceClient(config);

            builder.AddEngineSettings(config);

            builder.AddServiceBus(config);

            builder.AddCaching(config);

            builder.AddApplicationInsights(config, "CalculateFunding.Functions.CalcEngine");

            builder.AddApplicationInsightsTelemetryClient(config, "CalculateFunding.Functions.CalcEngine");

            builder.AddLogging("CalculateFunding.Functions.CalcEngine", config);

            builder.AddTelemetry();

            builder.AddSearch(config);

            builder.AddFeatureToggling(config);

            PolicySettings policySettings = builder.GetPolicySettings(config);
            CalculatorResiliencePolicies calcResiliencePolicies = CreateResiliencePolicies(policySettings);

            builder.AddSingleton <ICalculatorResiliencePolicies>(calcResiliencePolicies);
            builder.AddSingleton <IJobHelperResiliencePolicies>(calcResiliencePolicies);

            builder.AddSingleton <IValidator <ICalculatorResiliencePolicies>, CalculatorResiliencePoliciesValidator>();

            return(builder.BuildServiceProvider());
        }
        private static IServiceProvider Register(IServiceCollection builder, IConfigurationRoot config)
        {
            builder.AddSingleton <IUserProfileProvider, UserProfileProvider>();


            builder.AddSingleton <IConfiguration>(config);
            builder.AddCaching(config);

            // These registrations of the functions themselves are just for the DebugQueue. Ideally we don't want these registered in production
            if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
            {
                builder.AddScoped <OnCalcsGenerateAllocationResults>();
                builder.AddScoped <OnCalculationGenerateFailure>();
            }

            builder.AddScoped <ICalculationEngineService, CalculationEngineService>();
            builder.AddScoped <ICalculationEngine, CalculationEngine>();
            builder.AddScoped <IAllocationFactory, AllocationFactory>();
            builder.AddScoped <IDeadletterService, DeadletterService>();
            builder.AddScoped <IJobManagement, JobManagement>();
            builder.AddSingleton <IProviderSourceDatasetVersionKeyProvider, ProviderSourceDatasetVersionKeyProvider>();
            builder.AddSingleton <IFileSystemAccess, FileSystemAccess>();

            builder.AddSingleton <IAssemblyService, AssemblyService>();
            builder.AddSingleton <ICalculationAggregationService, CalculationAggregationService>();
            builder.AddScoped <ICalculationEnginePreviewService, CalculationEnginePreviewService>();

            builder.AddSingleton <IFileSystemCacheSettings, FileSystemCacheSettings>();
            builder.AddSingleton <IFileSystemCache, FileSystemCache>();

            builder.AddSingleton <IProviderSourceDatasetsRepository, ProviderSourceDatasetsRepository>((ctx) =>
            {
                CosmosDbSettings providerSourceDatasetsCosmosSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", providerSourceDatasetsCosmosSettings);

                providerSourceDatasetsCosmosSettings.ContainerName = "providerdatasets";

                CosmosRepository calcsCosmosRepository = new CosmosRepository(providerSourceDatasetsCosmosSettings, new CosmosClientOptions()
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = 8,
                    MaxTcpConnectionsPerEndpoint = 4,
                    ConsistencyLevel             = ConsistencyLevel.Eventual,
                    AllowBulkExecution           = true,
                    // MaxRetryAttemptsOnRateLimitedRequests = 1,
                    // MaxRetryWaitTimeOnRateLimitedRequests = new TimeSpan(0, 0, 30),
                });

                ICalculatorResiliencePolicies calculatorResiliencePolicies = ctx.GetService <ICalculatorResiliencePolicies>();

                return(new ProviderSourceDatasetsRepository(calcsCosmosRepository, calculatorResiliencePolicies));
            });

            builder.AddSingleton <IProviderResultCalculationsHashProvider, ProviderResultCalculationsHashProvider>();

            builder.AddSingleton <IProviderResultsRepository, ProviderResultsRepository>((ctx) =>
            {
                CosmosDbSettings calcResultsDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", calcResultsDbSettings);

                calcResultsDbSettings.ContainerName = "calculationresults";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(calcResultsDbSettings, new CosmosClientOptions()
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = 8,
                    MaxTcpConnectionsPerEndpoint = 2,
                    // MaxRetryWaitTimeOnRateLimitedRequests = new TimeSpan(0, 0, 30),
                    AllowBulkExecution = true,
                });

                ILogger logger = ctx.GetService <ILogger>();

                IProviderResultCalculationsHashProvider calculationsHashProvider = ctx.GetService <IProviderResultCalculationsHashProvider>();

                ICalculatorResiliencePolicies calculatorResiliencePolicies = ctx.GetService <ICalculatorResiliencePolicies>();

                IResultsApiClient resultsApiClient = ctx.GetService <IResultsApiClient>();

                IJobManagement jobManagement = ctx.GetService <IJobManagement>();

                return(new ProviderResultsRepository(
                           calcsCosmosRepostory,
                           logger,
                           calculationsHashProvider,
                           calculatorResiliencePolicies,
                           resultsApiClient,
                           jobManagement));
            });

            builder.AddSingleton <ISourceFileRepository, SourceFileRepository>((ctx) =>
            {
                BlobStorageOptions blobStorageOptions = new BlobStorageOptions();

                config.Bind("AzureStorageSettings", blobStorageOptions);

                blobStorageOptions.ContainerName = "source";

                IBlobContainerRepository blobContainerRepository = new BlobContainerRepository(blobStorageOptions);
                return(new SourceFileRepository(blobContainerRepository));
            });

            builder
            .AddSingleton <Services.CalcEngine.Interfaces.ICalculationsRepository, Services.CalcEngine.CalculationsRepository>();

            builder
            .AddSingleton <IDatasetAggregationsRepository, DatasetAggregationsRepository>();

            builder
            .AddSingleton <ICancellationTokenProvider, InactiveCancellationTokenProvider>();

            builder
            .AddSingleton <ISourceCodeService, SourceCodeService>();

            MapperConfiguration calculationsConfig = new MapperConfiguration(c =>
            {
                c.AddProfile <CalculationsMappingProfile>();
                c.AddProfile <CalcEngineMappingProfile>();
            });

            builder
            .AddSingleton(calculationsConfig.CreateMapper());

            builder.AddScoped <IUserProfileProvider, UserProfileProvider>();

            builder.AddCalculationsInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddSpecificationsInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddJobsInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddPoliciesInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddResultsInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddDatasetsInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);

            builder.AddEngineSettings(config);

            builder.AddServiceBus(config, "calcengine");

            builder.AddCaching(config);

            builder.AddApplicationInsightsTelemetryClient(config, "CalculateFunding.Functions.CalcEngine");
            builder.AddApplicationInsightsServiceName(config, "CalculateFunding.Functions.CalcEngine");

            builder.AddLogging("CalculateFunding.Functions.CalcEngine", config);

            builder.AddTelemetry();

            builder.AddSearch(config);
            builder
            .AddSingleton <ISearchRepository <ProviderCalculationResultsIndex>, SearchRepository <ProviderCalculationResultsIndex> >();

            builder.AddFeatureToggling(config);

            PolicySettings policySettings = ServiceCollectionExtensions.GetPolicySettings(config);
            CalculatorResiliencePolicies calcResiliencePolicies = CreateResiliencePolicies(policySettings);

            builder.AddSingleton <ICalculatorResiliencePolicies>(calcResiliencePolicies);
            builder.AddSingleton <IJobManagementResiliencePolicies>((ctx) => new JobManagementResiliencePolicies()
            {
                JobsApiClient = calcResiliencePolicies.JobsApiClient
            });

            builder.AddSingleton <IValidator <ICalculatorResiliencePolicies>, CalculatorResiliencePoliciesValidator>();
            builder.AddSingleton <ICalculationEngineServiceValidator, CalculationEngineServiceValidator>();
            builder.AddSingleton <ISpecificationAssemblyProvider, SpecificationAssemblyProvider>();
            builder.AddSingleton <IBlobClient>(ctx =>
            {
                BlobStorageOptions options = new BlobStorageOptions();

                config.Bind("AzureStorageSettings", options);

                options.ContainerName = "source";

                IBlobContainerRepository blobContainerRepository = new BlobContainerRepository(options);
                return(new BlobClient(blobContainerRepository));
            });

            ServicePointManager.DefaultConnectionLimit = 200;

            return(builder.BuildServiceProvider());
        }