Esempio n. 1
0
        private static void SetDefaultApiOptions(HttpClient httpClient, ApiClientConfigurationOptions options)
        {
            Guard.ArgumentNotNull(httpClient, nameof(httpClient));
            Guard.ArgumentNotNull(options, nameof(options));

            if (string.IsNullOrWhiteSpace(options.ApiEndpoint))
            {
                throw new InvalidOperationException("options EndPoint is null or empty string");
            }

            string baseAddress = options.ApiEndpoint;

            if (!baseAddress.EndsWith("/", StringComparison.CurrentCulture))
            {
                baseAddress = $"{baseAddress}/";
            }

            UserProfile userProfile = new UserProfile()
            {
                Id        = "setuserpermissions",
                Firstname = "Set",
                Lastname  = "User Permissions",
                UPN       = "*****@*****.**",
            };

            httpClient.BaseAddress = new Uri(baseAddress, UriKind.Absolute);
            httpClient.DefaultRequestHeaders?.Add(OcpApimSubscriptionKey, options.ApiKey);
            httpClient.DefaultRequestHeaders?.Add(SfaUsernameProperty, userProfile.Fullname);
            httpClient.DefaultRequestHeaders?.Add(SfaUserIdProperty, userProfile.Id);

            httpClient.DefaultRequestHeaders?.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders?.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
            httpClient.DefaultRequestHeaders?.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
        }
Esempio n. 2
0
        public static IServiceCollection AddProfilingInterServiceClient(this IServiceCollection builder, IConfiguration config,
                                                                        TimeSpan[] retryTimeSpans = null, int numberOfExceptionsBeforeCircuitBreaker = 100, TimeSpan circuitBreakerFailurePeriod = default, TimeSpan handlerLifetime = default)
        {
            if (retryTimeSpans == null)
            {
                retryTimeSpans = new[] { TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5) };
            }

            if (circuitBreakerFailurePeriod == default)
            {
                circuitBreakerFailurePeriod = TimeSpan.FromMinutes(1);
            }

            var httpBuilder = builder.AddHttpClient(HttpClientKeys.Profiling,
                                                    (httpClient) =>
            {
                ApiOptions apiOptions = new ApiOptions();

                config.Bind(ClientName, apiOptions);

                ApiClientConfigurationOptions.SetDefaultApiClientConfigurationOptions(httpClient, apiOptions);
            })
                              .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
                              .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
                              .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod))
                              .AddUserProfilerHeaderPropagation();

            // if a life time for the handler has been set then set it on the client builder
            if (handlerLifetime != default)
            {
                httpBuilder.SetHandlerLifetime(Timeout.InfiniteTimeSpan);
            }

            builder.AddSingleton <ICancellationTokenProvider, InactiveCancellationTokenProvider>();

            builder.AddSingleton <IAzureBearerTokenProxy, AzureBearerTokenProxy>();

            builder.AddSingleton <IProfilingApiClient>((ctx) =>
            {
                IHttpClientFactory httpClientFactory = ctx.GetService <IHttpClientFactory>();
                ILogger logger = ctx.GetService <ILogger>();
                ICancellationTokenProvider cancellationTokenProvider = ctx.GetService <ICancellationTokenProvider>();

                IAzureBearerTokenProxy azureBearerTokenProxy = ctx.GetService <IAzureBearerTokenProxy>();
                ICacheProvider cacheProvider = ctx.GetService <ICacheProvider>();

                AzureBearerTokenOptions azureBearerTokenOptions = new AzureBearerTokenOptions();
                config.Bind("providerProfilingAzureBearerTokenOptions", azureBearerTokenOptions);

                AzureBearerTokenProvider bearerTokenProvider = new AzureBearerTokenProvider(azureBearerTokenProxy, cacheProvider, azureBearerTokenOptions);

                return(new ProfilingApiClient(httpClientFactory, HttpClientKeys.Profiling, logger, bearerTokenProvider, cancellationTokenProvider));
            });

            return(builder);
        }
        public static IServiceCollection AddFundingDataServiceInterServiceClient(
            this IServiceCollection builder,
            IConfiguration config,
            TimeSpan[] retryTimeSpans = null,
            int numberOfExceptionsBeforeCircuitBreaker = 100,
            TimeSpan circuitBreakerFailurePeriod       = default,
            TimeSpan handlerLifetime = default)
        {
            retryTimeSpans ??= new[]
            {
                TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5)
            };


            if (circuitBreakerFailurePeriod == default)
            {
                circuitBreakerFailurePeriod = TimeSpan.FromMinutes(1);
            }

            IHttpClientBuilder httpBuilder = builder.AddHttpClient(HttpClientKeys.FDZ,
                                                                   (httpClient) =>
            {
                ApiOptions apiOptions = new ApiOptions();

                config.Bind(ClientName, apiOptions);

                ApiClientConfigurationOptions.SetDefaultApiClientConfigurationOptions(httpClient, apiOptions);
            })
                                             .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
                                             .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
                                             .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod))
                                             .AddUserProfilerHeaderPropagation();

            // if a life time for the handler has been set then set it on the client builder
            if (handlerLifetime != default)
            {
                httpBuilder.SetHandlerLifetime(Timeout.InfiniteTimeSpan);
            }

            builder.AddSingleton <IFundingDataZoneApiClient, FundingDataZoneApiClient>();

            return(builder);
        }
        private static void AddHttpClientForClientKey(string clientKey,
                                                      string uri,
                                                      string key,
                                                      IServiceCollection serviceCollection)
        {
            serviceCollection.AddHttpClient(clientKey,
                                            c =>
            {
                ApiClientConfigurationOptions opts = new ApiClientConfigurationOptions
                {
                    ApiEndpoint = uri,
                    ApiKey      = key
                };

                SetDefaultApiClientConfigurationOptions(c, opts);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(RetryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(NumberOfExceptionsBeforeCircuitBreaker,
                                                                    CircuitBreakerFailurePeriod));
        }
        private static void SetDefaultApiClientConfigurationOptions(HttpClient httpClient,
                                                                    ApiClientConfigurationOptions options)
        {
            if (options.ApiEndpoint.IsNullOrWhitespace())
            {
                throw new InvalidOperationException("options EndPoint is null or empty string");
            }

            var baseAddress = options.ApiEndpoint;

            if (!baseAddress.EndsWith("/", StringComparison.CurrentCulture))
            {
                baseAddress = $"{baseAddress}/";
            }

            httpClient.BaseAddress = new Uri(baseAddress, UriKind.Absolute);
            httpClient.DefaultRequestHeaders?.Add(ApiClientHeaders.ApiKey, options.ApiKey);
            httpClient.DefaultRequestHeaders?.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders?.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
            httpClient.DefaultRequestHeaders?.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
        }
Esempio n. 6
0
        public override void Configure(IServiceCollection services)
        {
            TimeSpan[] retryTimeSpans = new[] { TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5) };
            int        numberOfExceptionsBeforeCircuitBreaker = 100;
            TimeSpan   circuitBreakerFailurePeriod            = TimeSpan.FromMinutes(1);

            IServiceProvider serviceProvider = services.BuildServiceProvider();


            services.AddHttpClient(HttpClientKeys.Calculations,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("calcsClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.Results,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("resultsClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.Specifications,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("specsClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.Datasets,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("datasetsClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.Scenarios,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("scenariosClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.TestEngine,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("testEngineClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.Users,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("usersClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.Jobs,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("jobsClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services
            .AddSingleton <ICalculationsApiClient, CalculationsApiClient>();

            services
            .AddSingleton <IResultsApiClient, ResultsApiClient>();

            services
            .AddSingleton <ISpecsApiClient, SpecsApiClient>();

            services
            .AddSingleton <IDatasetsApiClient, DatasetsApiClient>();

            services
            .AddSingleton <IScenariosApiClient, ScenariosApiClient>();

            services
            .AddSingleton <ITestEngineApiClient, TestEngineApiClient>();

            services
            .AddSingleton <IUsersApiClient, UsersApiClient>();

            services
            .AddSingleton <IJobsApiClient, JobsApiClient>();
        }
Esempio n. 7
0
        private static void SetDefaultApiClientConfigurationOptions(HttpClient httpClient, ApiClientConfigurationOptions options, IServiceCollection services)
        {
            Guard.ArgumentNotNull(httpClient, nameof(httpClient));
            Guard.ArgumentNotNull(options, nameof(options));
            Guard.ArgumentNotNull(services, nameof(services));

            if (string.IsNullOrWhiteSpace(options.ApiEndpoint))
            {
                throw new InvalidOperationException("options EndPoint is null or empty string");
            }

            string baseAddress = options.ApiEndpoint;

            if (!baseAddress.EndsWith("/", StringComparison.CurrentCulture))
            {
                baseAddress = $"{baseAddress}/";
            }

            IServiceProvider serviceProvider = services.BuildServiceProvider();

            IUserProfileService userProfileService = serviceProvider.GetService <IUserProfileService>();

            UserProfile userProfile = userProfileService.GetUser();

            httpClient.BaseAddress = new Uri(baseAddress, UriKind.Absolute);
            httpClient.DefaultRequestHeaders?.Add(ApiClientHeaders.ApiKey, options.ApiKey);
            httpClient.DefaultRequestHeaders?.Add(ApiClientHeaders.Username, userProfile.Fullname);
            httpClient.DefaultRequestHeaders?.Add(ApiClientHeaders.UserId, userProfile.Id);

            httpClient.DefaultRequestHeaders?.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders?.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
            httpClient.DefaultRequestHeaders?.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
        }
Esempio n. 8
0
        private static void SetDefaultApiClientConfigurationOptions(HttpClient httpClient, ApiClientConfigurationOptions options, string apiBase)
        {
            string baseAddress = options.ApiEndpoint;

            if (!baseAddress.EndsWith("/", StringComparison.CurrentCulture))
            {
                baseAddress = $"{baseAddress}/";
            }

            baseAddress += apiBase;

            if (!baseAddress.EndsWith("/", StringComparison.CurrentCulture))
            {
                baseAddress = $"{baseAddress}/";
            }

            httpClient.BaseAddress = new Uri(baseAddress, UriKind.Absolute);
            httpClient.DefaultRequestHeaders?.Add(ApiClientHeaders.ApiKey, options.ApiKey);
            httpClient.DefaultRequestHeaders?.Add(ApiClientHeaders.Username, "testuser");
            httpClient.DefaultRequestHeaders?.Add(ApiClientHeaders.UserId, "b001af14-3754-4cb1-9980-359e850700a8");

            httpClient.DefaultRequestHeaders?.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders?.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
            httpClient.DefaultRequestHeaders?.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
        }
Esempio n. 9
0
        public override void Configure(IServiceCollection services)
        {
            TimeSpan[] retryTimeSpans = HostingEnvironment.IsDevelopment() ?
                                        new[] { TimeSpan.FromMinutes(10) } :
            new[] { TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5) };
            int      numberOfExceptionsBeforeCircuitBreaker = 100;
            TimeSpan circuitBreakerFailurePeriod            = HostingEnvironment.IsDevelopment() ? TimeSpan.FromMinutes(10) : TimeSpan.FromMinutes(1);

            services.AddCalculationsInterServiceClient(Configuration);
            services.AddResultsInterServiceClient(Configuration);
            services.AddProvidersInterServiceClient(Configuration);
            services.AddPoliciesInterServiceClient(Configuration);
            services.AddSpecificationsInterServiceClient(Configuration);
            services.AddDatasetsInterServiceClient(Configuration);
            services.AddJobsInterServiceClient(Configuration);
            services.AddGraphInterServiceClient(Configuration);
            services.AddFundingDataServiceInterServiceClient(Configuration);
            services.AddProfilingInterServiceClient(Configuration);

            services.AddHttpClient(HttpClientKeys.Scenarios,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("scenariosClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.TestEngine,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("testEngineClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.Users,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("usersClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services.AddHttpClient(HttpClientKeys.Publishing,
                                   c =>
            {
                ApiClientConfigurationOptions opts = GetConfigurationOptions <ApiClientConfigurationOptions>("publishingClient");

                SetDefaultApiClientConfigurationOptions(c, opts, services);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            services
            .AddSingleton <IUserProfileProvider, UserProfileProvider>();

            services
            .AddSingleton <ICacheProvider, StackExchangeRedisClientCacheProvider>();

            services
            .AddSingleton <ITemplateBuilderApiClient, TemplateBuilderApiClient>();

            services
            .AddSingleton <IScenariosApiClient, ScenariosApiClient>();

            services
            .AddSingleton <ITestEngineApiClient, TestEngineApiClient>();

            services
            .AddSingleton <IUsersApiClient, UsersApiClient>();

            services
            .AddSingleton <IPublishingApiClient, PublishingApiClient>();

            RedisSettings redisSettings = new RedisSettings();

            Configuration.Bind("redisSettings", redisSettings);

            services.AddSingleton(redisSettings);
        }
Esempio n. 10
0
        private static IServiceProvider Register(IServiceCollection builder, IConfigurationRoot config)
        {
            builder.AddSingleton <OnCreateAllocationLineResultStatusUpdates>();
            builder.AddSingleton <OnCreateAllocationLineResultStatusUpdatesFailure>();
            builder.AddSingleton <OnCreateInstructAllocationLineResultStatusUpdates>();
            builder.AddSingleton <OnCreateInstructAllocationLineResultStatusUpdatesFailure>();
            builder.AddSingleton <OnFetchProviderProfileEvent>();
            builder.AddSingleton <OnFetchProviderProfileFailure>();
            builder.AddSingleton <OnMigrateFeedIndexIdEvent>();
            builder.AddSingleton <OnMigrateResultVersionsEvent>();
            builder.AddSingleton <OnProviderResultsPublishedEvent>();
            builder.AddSingleton <OnProviderResultsPublishedFailure>();
            builder.AddSingleton <OnProviderResultsSpecificationCleanup>();
            builder.AddSingleton <OnReIndexAllocationNotificationFeeds>();
            builder.AddSingleton <OnReIndexCalculationResults>();
            builder.AddSingleton <OnCalculationResultsCsvGeneration>();
            builder.AddSingleton <OnCalculationResultsCsvGenerationTimer>();
            builder.AddSingleton <ICalculationResultsRepository, CalculationResultsRepository>();
            builder.AddSingleton <IResultsService, ResultsService>();
            builder.AddSingleton <IPublishedResultsService, PublishedResultsService>();
            builder.AddSingleton <IResultsSearchService, ResultsSearchService>();
            builder.AddSingleton <ICalculationProviderResultsSearchService, CalculationProviderResultsSearchService>();
            builder.AddSingleton <IProviderImportMappingService, ProviderImportMappingService>();
            builder.AddSingleton <IAllocationNotificationsFeedsSearchService, AllocationNotificationsFeedsSearchService>();
            builder.AddSingleton <ICalculationsRepository, CalculationsRepository>();
            builder.AddSingleton <IValidator <MasterProviderModel>, MasterProviderModelValidator>();
            builder.AddSingleton <IProviderVariationAssemblerService, ProviderVariationAssemblerService>();
            builder.AddSingleton <IProviderVariationsService, ProviderVariationsService>();
            builder.AddSingleton <IProviderService, ProviderService>();
            builder.AddSingleton <IJobHelperService, JobHelperService>();
            builder.AddSingleton <IProviderCalculationResultsReIndexerService, ProviderCalculationResultsReIndexerService>();

            builder.AddSingleton <IProviderVariationsStorageRepository, ProviderVariationsStorageRepository>((ctx) =>
            {
                BlobStorageOptions blobStorageOptions = new BlobStorageOptions();

                config.Bind("CommonStorageSettings", blobStorageOptions);

                blobStorageOptions.ContainerName = "providervariations";

                return(new ProviderVariationsStorageRepository(blobStorageOptions));
            });

            MapperConfiguration resultsConfig = new MapperConfiguration(c =>
            {
                c.AddProfile <DatasetsMappingProfile>();
                c.AddProfile <ResultServiceMappingProfile>();
                c.AddProfile <ProviderMappingProfile>();
            });

            builder
            .AddSingleton(resultsConfig.CreateMapper());

            builder.AddCaching(config);

            builder.AddSingleton <ICalculationResultsRepository, CalculationResultsRepository>((ctx) =>
            {
                CosmosDbSettings calssDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", calssDbSettings);

                calssDbSettings.CollectionName = "calculationresults";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(calssDbSettings);

                return(new CalculationResultsRepository(calcsCosmosRepostory));
            });

            builder.AddSingleton <IProviderSourceDatasetRepository, ProviderSourceDatasetRepository>((ctx) =>
            {
                CosmosDbSettings provDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", provDbSettings);

                provDbSettings.CollectionName = "providerdatasets";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(provDbSettings);

                return(new ProviderSourceDatasetRepository(calcsCosmosRepostory));
            });

            builder.AddSingleton <IPublishedProviderResultsRepository, PublishedProviderResultsRepository>((ctx) =>
            {
                CosmosDbSettings resultsDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", resultsDbSettings);

                resultsDbSettings.CollectionName = "publishedproviderresults";

                CosmosRepository resultsRepostory = new CosmosRepository(resultsDbSettings);

                return(new PublishedProviderResultsRepository(resultsRepostory));
            });

            builder.AddSingleton <IProviderChangesRepository, ProviderChangesRepository>((ctx) =>
            {
                CosmosDbSettings cosmosSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosSettings);

                cosmosSettings.CollectionName = "publishedproviderchanges";

                CosmosRepository resultsRepostory = new CosmosRepository(cosmosSettings);

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

                return(new ProviderChangesRepository(resultsRepostory, logger));
            });

            builder
            .AddSingleton <ISpecificationsRepository, SpecificationsRepository>();

            builder
            .AddSingleton <IPublishedProviderResultsAssemblerService, PublishedProviderResultsAssemblerService>();

            builder.AddSingleton <IPublishedProviderResultsSettings, PublishedProviderResultsSettings>((ctx) =>
            {
                PublishedProviderResultsSettings settings = new PublishedProviderResultsSettings();

                config.Bind("PublishedProviderResultsSettings", settings);

                return(settings);
            });

            builder.AddSingleton <IVersionRepository <PublishedAllocationLineResultVersion>, VersionRepository <PublishedAllocationLineResultVersion> >((ctx) =>
            {
                CosmosDbSettings versioningDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", versioningDbSettings);

                versioningDbSettings.CollectionName = "publishedproviderresults";

                CosmosRepository resultsRepostory = new CosmosRepository(versioningDbSettings);

                return(new VersionRepository <PublishedAllocationLineResultVersion>(resultsRepostory));
            });

            builder
            .AddSingleton <IBlobClient, AzureStorage.BlobClient>((ctx) =>
            {
                AzureStorageSettings storageSettings = new AzureStorageSettings();

                config.Bind("AzureStorageSettings", storageSettings);

                storageSettings.ContainerName = "calculationresultscsv";

                return(new AzureStorage.BlobClient(storageSettings));
            });


            builder.AddSearch(config);

            builder.AddServiceBus(config);

            builder.AddCaching(config);

            builder.AddApplicationInsights(config, "CalculateFunding.Functions.Results");
            builder.AddApplicationInsightsTelemetryClient(config, "CalculateFunding.Functions.Results");
            builder.AddLogging("CalculateFunding.Functions.Results");
            builder.AddTelemetry();

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

            builder.AddFeatureToggling(config);

            builder.AddSingleton <IPublishedAllocationLineLogicalResultVersionService, PublishedAllocationLineLogicalResultVersionService>();

            builder.AddSingleton <ICancellationTokenProvider, InactiveCancellationTokenProvider>();

            builder.AddSingleton <IAzureBearerTokenProxy, AzureBearerTokenProxy>();

            builder.AddHttpClient(HttpClientKeys.Profiling,
                                  c =>
            {
                ApiClientConfigurationOptions opts = new ApiClientConfigurationOptions();
                config.Bind("providerProfilingClient", opts);

                SetDefaultApiClientConfigurationOptions(c, opts, builder);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(retryTimeSpans))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(numberOfExceptionsBeforeCircuitBreaker, circuitBreakerFailurePeriod));

            builder.AddSingleton <IProfilingApiClient>((ctx) =>
            {
                IFeatureToggle featureToggle = ctx.GetService <IFeatureToggle>();

                bool enableMockProvider = featureToggle.IsProviderProfilingServiceDisabled();

                if (enableMockProvider)
                {
                    return(new MockProviderProfilingRepository());
                }
                else
                {
                    IHttpClientFactory httpClientFactory = ctx.GetService <IHttpClientFactory>();
                    ILogger logger = ctx.GetService <ILogger>();
                    ICancellationTokenProvider cancellationTokenProvider = ctx.GetService <ICancellationTokenProvider>();

                    IAzureBearerTokenProxy azureBearerTokenProxy = ctx.GetService <IAzureBearerTokenProxy>();
                    ICacheProvider cacheProvider = ctx.GetService <ICacheProvider>();

                    AzureBearerTokenOptions azureBearerTokenOptions = new AzureBearerTokenOptions();
                    config.Bind("providerProfilingAzureBearerTokenOptions", azureBearerTokenOptions);

                    AzureBearerTokenProvider bearerTokenProvider = new AzureBearerTokenProvider(azureBearerTokenProxy, cacheProvider, azureBearerTokenOptions);

                    return(new ProfilingApiClient(httpClientFactory, HttpClientKeys.Profiling, logger, bearerTokenProvider, cancellationTokenProvider));
                }
            });

            PolicySettings     policySettings            = builder.GetPolicySettings(config);
            ResiliencePolicies resultsResiliencePolicies = CreateResiliencePolicies(policySettings);

            builder.AddSingleton <IResultsResiliencePolicies>(resultsResiliencePolicies);
            builder.AddSingleton <IJobHelperResiliencePolicies>(resultsResiliencePolicies);

            return(builder.BuildServiceProvider());
        }