using System; using Microsoft.Extensions.Configuration; namespace FinlyticCore.Models; /// /// Represents the network and security settings used to connect to the central MQTT broker. /// public class MqttConfiguration { /// /// Gets or sets the host address or IP of the MQTT broker. /// public string Host { get; set; } = string.Empty; /// /// Gets or sets the port number for the connection. Defaults to 1883. /// public int Port { get; set; } = 1883; /// /// Gets or sets the unique client identifier used when registering with the broker. /// public string ClientId { get; set; } = string.Empty; /// /// Gets or sets the username for authentication (optional). /// public string? Username { get; set; } /// /// Gets or sets the password for authentication (optional). /// public string? Password { get; set; } /// /// Builds an from application configuration, understanding both the /// colon-separated key style (MQTT:Host, used by appsettings.json) and the double-underscore /// style (MQTT__Host, used by container environment variables). Every one of the eight service MQTT /// clients previously duplicated this lookup inline; centralizing it here means a new configuration key /// (e.g. authentication) only has to be wired up once. /// /// The application configuration to read MQTT settings from. /// /// The service-specific client ID prefix to fall back to when no MQTT:ClientId/MQTT__ClientId /// is configured (e.g. "FinlyticAssets"). A random suffix is always appended to the resolved client ID /// (whether it came from configuration or from this default) to avoid the broker rejecting a duplicate /// client ID when a service reconnects or runs multiple instances. /// /// /// A populated . and are left /// unless both are actually configured, so connections to brokers without /// authentication enabled remain anonymous and continue to work unchanged. /// /// Thrown when is . public static MqttConfiguration FromConfiguration(IConfiguration configuration, string defaultClientId) { ArgumentNullException.ThrowIfNull(configuration); var host = configuration["MQTT:Host"] ?? configuration["MQTT__Host"] ?? "localhost"; var portRaw = configuration["MQTT:Port"] ?? configuration["MQTT__Port"] ?? "1883"; var port = int.TryParse(portRaw, out var parsedPort) ? parsedPort : 1883; var configuredClientId = configuration["MQTT:ClientId"] ?? configuration["MQTT__ClientId"]; var clientId = $"{(string.IsNullOrWhiteSpace(configuredClientId) ? defaultClientId : configuredClientId)}_{Guid.NewGuid():N}"; // Optional authentication: only set Username/Password when the broker actually requires them. // The broker this system currently runs against has no authentication configured, so leaving both // unset here must keep the connection anonymous (see ManagedMqttClient.ConnectAsync). var username = configuration["MQTT:Username"] ?? configuration["MQTT__Username"]; var password = configuration["MQTT:Password"] ?? configuration["MQTT__Password"]; return new MqttConfiguration { Host = host, Port = port, ClientId = clientId, Username = string.IsNullOrWhiteSpace(username) ? null : username, Password = string.IsNullOrWhiteSpace(password) ? null : password }; } }