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"); }
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); }
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"); } }
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()); }