using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using StellaOps.Scheduler.Queue; using StellaOps.Scheduler.WebService.GraphJobs.Events; using StellaOps.Scheduler.WebService.Options; using System; namespace StellaOps.Scheduler.WebService.EventWebhooks; internal static class WebhookRateLimiterServiceCollectionExtensions { public static IServiceCollection AddSchedulerWebhookRateLimiter( this IServiceCollection services, IConfiguration configuration, IHostEnvironment environment) { ArgumentNullException.ThrowIfNull(services); ArgumentNullException.ThrowIfNull(configuration); ArgumentNullException.ThrowIfNull(environment); services.RemoveAll(); if (environment.IsEnvironment("Testing")) { services.AddSingleton(); return services; } var eventsOptions = new SchedulerEventsOptions(); configuration.GetSection("Scheduler:Events").Bind(eventsOptions); eventsOptions.Webhooks ??= new SchedulerInboundWebhooksOptions(); eventsOptions.Webhooks.Conselier ??= SchedulerWebhookOptions.CreateDefault("conselier"); eventsOptions.Webhooks.Excitor ??= SchedulerWebhookOptions.CreateDefault("excitor"); if (!eventsOptions.Webhooks.Conselier.Enabled && !eventsOptions.Webhooks.Excitor.Enabled) { services.AddSingleton(); return services; } var queueOptions = new SchedulerQueueOptions(); configuration.GetSection("scheduler:queue").Bind(queueOptions); if (queueOptions.Kind != SchedulerQueueTransportKind.Redis || string.IsNullOrWhiteSpace(queueOptions.Redis.ConnectionString)) { throw new InvalidOperationException( "Scheduler inbound webhooks require scheduler:queue Redis connection outside the Testing environment."); } var redisOptions = new SchedulerRedisQueueOptions { ConnectionString = queueOptions.Redis.ConnectionString, Database = queueOptions.Redis.Database, InitializationTimeout = queueOptions.Redis.InitializationTimeout }; services.AddSingleton(sp => new RedisWebhookRateLimiter( redisOptions, sp.GetRequiredService(), sp.GetService())); return services; } }