in DeviceBridge/Startup.cs [45:114]
public void ConfigureServices(IServiceCollection services)
{
_logger.Info("Configuring services");
string kvUrl = Environment.GetEnvironmentVariable("KV_URL");
// Build cache from Key Vault
var secretsService = new SecretsProvider(kvUrl);
var idScope = secretsService.GetIdScopeAsync(_logger).Result;
var sasKey = secretsService.GetIotcSasKeyAsync(_logger).Result;
var sqlConnectionString = Utils.GetSqlConnectionString(_logger, secretsService);
// Override defaults
var customMaxPoolSize = Environment.GetEnvironmentVariable("MAX_POOL_SIZE");
var customConnectionBatchSize = Environment.GetEnvironmentVariable("DEVICE_CONNECTION_BATCH_SIZE");
var customConnectionBatchIntervalMs = Environment.GetEnvironmentVariable("DEVICE_CONNECTION_BATCH_INTERVAL_MS");
uint maxPoolSize = (customMaxPoolSize != null && customMaxPoolSize != string.Empty) ? Convert.ToUInt32(customMaxPoolSize, 10) : ConnectionManager.DeafultMaxPoolSize;
uint rampupBatchSize = (customConnectionBatchSize != null && customConnectionBatchSize != string.Empty) ? Convert.ToUInt32(customConnectionBatchSize, 10) : SubscriptionScheduler.DefaultConnectionBatchSize;
uint rampupBatchIntervalMs = (customConnectionBatchIntervalMs != null && customConnectionBatchIntervalMs != string.Empty) ? Convert.ToUInt32(customConnectionBatchIntervalMs, 10) : SubscriptionScheduler.DefaultConnectionBatchIntervalMs;
_logger.SetProperty("idScope", idScope);
_logger.SetProperty("cv", Guid.NewGuid()); // CV for all background operations
services.AddHttpContextAccessor();
// Start services
services.AddSingleton<ISecretsProvider>(secretsService);
services.AddSingleton(_logger);
services.AddSingleton<IEncryptionService, EncryptionService>();
services.AddSingleton<IStorageProvider>(provider => new StorageProvider(sqlConnectionString, provider.GetRequiredService<IEncryptionService>()));
services.AddSingleton<IConnectionManager>(provider => new ConnectionManager(provider.GetRequiredService<Logger>(), idScope, sasKey, maxPoolSize, provider.GetRequiredService<IStorageProvider>()));
services.AddSingleton<ISubscriptionCallbackFactory, SubscriptionCallbackFactory>();
services.AddSingleton<IConnectionStatusSubscriptionService, ConnectionStatusSubscriptionService>();
services.AddSingleton<IDataSubscriptionService, DataSubscriptionService>();
services.AddSingleton<ISubscriptionScheduler>(provider => new SubscriptionScheduler(provider.GetRequiredService<Logger>(), provider.GetRequiredService<IConnectionManager>(), provider.GetRequiredService<IStorageProvider>(), provider.GetRequiredService<ISubscriptionCallbackFactory>(), rampupBatchSize, rampupBatchIntervalMs));
services.AddSingleton<IBridgeService, BridgeService>();
services.AddHttpClient("RetryClient").AddPolicyHandler(GetRetryPolicy(_logger));
services.AddHostedService<ExpiredConnectionCleanupHostedService>();
services.AddHostedService<SubscriptionStartupHostedService>();
services.AddHostedService<SubscriptionSchedulerHostedService>();
services.AddHostedService<HubCacheGcHostedService>();
services.AddAuthentication(o =>
{
o.DefaultScheme = SchemesNamesConst.TokenAuthenticationDefaultScheme;
})
.AddScheme<TokenAuthenticationOptions, TokenAuthenticationHandler>(SchemesNamesConst.TokenAuthenticationDefaultScheme, o => { });
services.AddControllers(options =>
{
options.Filters.Add(new AuthorizeFilter());
});
services.AddHealthChecks();
services.AddSwaggerGen(options =>
{
// Set XML comments.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);
options.CustomOperationIds(apiDesc => apiDesc.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : null);
// Type mappers for custom serialization.
options.MapType(typeof(DeviceSubscriptionType), () => DeviceSubscriptionType.Schema);
options.MapType(typeof(DeviceTwin), () => DeviceTwin.Schema);
});
}