private static void TryAddDefaultPolicy(this IServiceCollection services, ISafeLogger logger, AuthorizationOptions x, string scheme) { if (x.DefaultPolicy?.AuthenticationSchemes.Count != 0) { logger?.Info(() => $"Skipping default policy build; '{string.Join(",", x.DefaultPolicy?.AuthenticationSchemes ?? Enumerable.Empty<string>())}' already registered."); return; } logger?.Info(() => $"Registering default policy with scheme '{scheme}'."); x.DefaultPolicy = new AuthorizationPolicyBuilder(scheme) .RequireAuthenticatedUserExtended(services) .Build(); }
public void AddCloudMetricsPublisher(IMetricsBuilder builder, ISafeLogger logger, AzureOptions options) { logger.Info(() => "Adding Application Insights Metrics & Health Checks Reporting"); builder.PushToApplicationInsights(p => { p.MetricsSampleEventName = Constants.Events.MetricsSample; p.HealthCheckEventName = Constants.Events.HealthCheck; p.PublishHealthChecks = true; p.PublishHealthy = false; p.PublishMetrics = true; }); }
public async Task StartAsync(CancellationToken cancellationToken) { if (!_options.CurrentValue.Enabled) { return; } _logger.Info(() => "Starting schema discovery..."); var schemaRelativeDir = _options.CurrentValue.SchemaFolder; if (!string.IsNullOrWhiteSpace(schemaRelativeDir)) { if (schemaRelativeDir.StartsWith("/") || schemaRelativeDir.StartsWith("\\")) { schemaRelativeDir = schemaRelativeDir.Substring(1); } var schemaDir = Path.Combine(_environment.ContentRootPath, schemaRelativeDir); if (Directory.Exists(schemaDir)) { _logger.Info(() => "Found schemas in {SchemaDir}", schemaDir); var revision = await UpdateSchemaAsync(schemaRelativeDir, _options.CurrentValue.ApplicationId ?? Constants.Schemas.DefaultApplicationId); if (revision != 0) { _logger.Info(() => "Schema updated to revision {Revision}", revision); } else { _logger.Info(() => "Schema is unchanged"); } } } }
private static void ScanForGeneratedObjects(this IServiceCollection services, string backendType, IConfiguration security, ISafeLogger logger, string rootPath, Assembly assembly) { foreach (var type in assembly.GetExportedTypes()) { if (!type.IsAbstract || !type.IsSealed) { continue; } if (type.Name != "ServiceCollectionExtensions") { continue; } var method = type.GetMethod("AddGenerated", new[] { typeof(IServiceCollection), typeof(IConfiguration), typeof(string) }); if (method == null) { continue; } Type batchOptionsType; switch (backendType) { case nameof(DocumentDb): batchOptionsType = typeof(DocumentDbBatchOptions); break; case nameof(SqlServer): batchOptionsType = typeof(SqlServerBatchOptions); break; case nameof(Sqlite): batchOptionsType = typeof(SqliteBatchOptions); break; default: throw new ArgumentOutOfRangeException(); } logger.Info(() => "Found generated objects API in {AssemblyName}", assembly.GetName().Name); method.MakeGenericMethod(batchOptionsType) .Invoke(null, new object[] { services, security, rootPath }); } }
private void OnSettingsChanged(BackgroundTaskOptions changed) { _logger.Info(() => "Background task options changed, recycling the host."); Stop(); Start(); }
public static IServiceCollection AddHq(this IServiceCollection services, IWebHostEnvironment env, IConfiguration config, ISafeLogger logger) { var subject = Assembly.GetCallingAssembly(); if (!(config is IConfigurationRoot configRoot)) { throw new ArgumentException("HQ requires access to the root configuration.", nameof(config)); } services.TryAddSingleton(configRoot); services.TryAddSingleton(services); var hq = configRoot.GetSection("HQ"); // // Core Services: services.AddTypeResolver(); services.AddLocalTimestamps(); services.AddSafeLogging(); services.AddValidOptions(); services.AddTraceContext(); // // Platform Services: services.AddSecurityPolicies(hq.GetSection("Security"), hq.GetSection("SuperUser"), logger); services.AddVersioning(hq.GetSection("Versioning")); services.AddMultiTenancy <IdentityTenant, IdentityApplication>(hq.GetSection("MultiTenancy")) .AddIdentityTenantContextStore <IdentityTenant>() .AddIdentityApplicationContextStore <IdentityApplication>(); // // Platform APIs: services .AddOperationsApi(hq.GetSection("Ops")) .AddPlatformApi(hq.GetSection("Api")) .AddBackgroundTasksApi(hq.GetSection("BackgroundTasks")) .AddConfigurationApi(configRoot, hq.GetSection("Configuration")) .AddIdentityApi(hq.GetSection("IdentityApi")) .AddSchemaApi(hq.GetSection("Schema")) .AddMetaApi(hq.GetSection("Meta")); var tasksBuilder = services.AddBackgroundTasks(hq.GetSection("BackgroundTasks")); var identityBuilder = services.AddIdentityExtended(hq.GetSection("Identity")); var runtimeBuilder = services.AddRuntimeApi(hq.GetSection("Runtime")); var schemaBuilder = services.AddSchemaDiscovery(hq.GetSection("Schema")); // // Cloud: var cloud = configRoot.GetSection("Cloud"); switch (cloud["Provider"]) { case nameof(Azure): { var options = new AzureOptions(); cloud.FastBind(options); services.AddCloudServices(logger, options); break; } } // // Backend Services: var backend = configRoot.GetSection("Backend"); var dbConfig = backend.GetSection("DbOptions"); if (dbConfig?.Value == null) { dbConfig = null; } var backendType = backend["Type"]; if (string.IsNullOrWhiteSpace(backendType)) { logger.Warn(() => "No backend type found!"); } else { logger.Info(() => "Installing {BackendType} back-end services.", backendType); } switch (backendType) { case nameof(DocumentDb): tasksBuilder.AddDocumentDbBackgroundTaskStore(backend.GetConnectionString("Tasks")); identityBuilder.AddDocumentDbIdentityStore <IdentityUserExtended, IdentityRoleExtended, IdentityTenant, IdentityApplication>(backend.GetConnectionString("Identity")); runtimeBuilder.AddDocumentDbRuntimeStores(backend.GetConnectionString("Runtime"), ConnectionScope.ByRequest, dbConfig); schemaBuilder.AddDocumentDbSchemaStores(backend.GetConnectionString("Schema")); break; case nameof(SqlServer): tasksBuilder.AddSqlServerBackgroundTasksStore(backend.GetConnectionString("Tasks"), r => r.GetRequiredService <IServerTimestampService>().GetCurrentTime()); identityBuilder.AddSqlServerIdentityStore <IdentityUserExtended, IdentityRoleExtended, IdentityTenant, IdentityApplication>(backend.GetConnectionString("Identity"), ConnectionScope.ByRequest, dbConfig); runtimeBuilder.AddSqlServerRuntime(backend.GetConnectionString("Runtime"), ConnectionScope.ByRequest, dbConfig); schemaBuilder.AddSqlServerSchemaStores(); break; case nameof(Sqlite): tasksBuilder.AddSqliteBackgroundTasksStore(backend.GetConnectionString("Tasks")); identityBuilder.AddSqliteIdentityStore <IdentityUserExtended, IdentityRoleExtended, IdentityTenant, IdentityApplication>(backend.GetConnectionString("Identity"), ConnectionScope.ByRequest, dbConfig); runtimeBuilder.AddSqliteRuntime(backend.GetConnectionString("Runtime"), ConnectionScope.ByRequest, dbConfig); schemaBuilder.AddSqliteSchemaStores(); break; default: throw new ArgumentOutOfRangeException(backendType, typeof(string), null); } // // Runtime Services: { var runtimeOptions = new RuntimeOptions(); hq.GetSection("Runtime").FastBind(runtimeOptions); if (runtimeOptions.EnableRest) { services.AddRestRuntime(); logger.Info(() => "REST is enabled."); } if (runtimeOptions.EnableGraphQl) { services.AddGraphQlRuntime(); logger.Info(() => "GraphQL is enabled."); } } // // Notification Services: services.AddEmailNotifications(hq.GetSection("Email")); // // Media Services: // // Custom Objects: services.ScanForGeneratedObjects(backendType, hq.GetSection("Security"), logger, "/api", subject); return(services); }
public void AddCloudTelemetry(IServiceCollection services, ISafeLogger logger, AzureOptions options) { logger.Info(() => "Adding Application Insights Telemetry"); services.AddApplicationInsightsTelemetry(options.ApplicationInsights); }