using FrameworkBLL.EventSub; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace FrameworkSL.Controllers.EventSub { /// /// Replaces app.MapSubscribeHandler() with a dynamic implementation. /// /// Dapr calls GET /dapr/subscribe at sidecar startup to discover which /// topics this app subscribes to. Instead of returning a static list from /// [Topic] attributes, this controller queries MEVENTTYPE in the system DB /// and returns one subscription per active EventTypeId — all routed to /// /eventsub/handle. /// /// Adding a new event type in MEVENTTYPE automatically creates the Dapr /// subscription on next app restart. No code change required. /// [ApiController] public class DaprSubscribeController : ControllerBase { private readonly IDaprSubscriptionBLL _bll; private readonly ILogger _logger; public DaprSubscribeController( IDaprSubscriptionBLL bll, ILogger logger) { _bll = bll; _logger = logger; } [HttpGet("/dapr/subscribe")] public async Task GetSubscriptions(CancellationToken ct) { try { var subscriptions = await _bll.GetSubscriptionsAsync(ct).ConfigureAwait(false); _logger.LogInformation( "Dapr subscribe: returning {Count} dynamic subscription(s)", subscriptions.Count); // Log first few topics to aid debugging — visible at startup var preview = string.Join(", ", subscriptions .Select(s => s.Topic) .Distinct() .Take(5)); if (subscriptions.Count > 0) _logger.LogInformation("Dapr subscribe: topics (first 5) = [{Topics}]{More}", preview, subscriptions.Select(s => s.Topic).Distinct().Count() > 5 ? " …" : ""); return Ok(subscriptions); } catch (OperationCanceledException) when (ct.IsCancellationRequested) { return StatusCode(503, "Service unavailable — subscription load cancelled"); } catch (Exception ex) { // 503 tells Dapr sidecar to retry GET /dapr/subscribe instead of // locking in an empty subscription list for the lifetime of the process. _logger.LogError(ex, "Dapr subscribe: BLL failed — returning 503 so Dapr retries subscription registration"); return StatusCode(503, "Service unavailable — subscription data not ready"); } } } }