From ed1e08f4433f7307bb77cdb47d6f09e339504022 Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Sun, 25 Jul 2021 00:18:15 +0200 Subject: [PATCH] Add mqtt + changed first char of all DTO (Json deserialization fix) --- Manager.Interfaces/DTO/PlayerMessageDTO.cs | 13 ++ Manager.Interfaces/DTO/SubSection/MapDTO.cs | 26 +-- Manager.Interfaces/DTO/SubSection/MenuDTO.cs | 2 +- .../DTO/SubSection/SliderDTO.cs | 12 +- Manager.Interfaces/DTO/SubSection/VideoDTO.cs | 2 +- Manager.Interfaces/DTO/SubSection/WebDTO.cs | 2 +- .../Controllers/AuthenticationController.cs | 9 +- .../Controllers/ConfigurationController.cs | 6 + .../Controllers/DeviceController.cs | 4 + .../Controllers/SectionController.cs | 75 ++++----- .../Extensions/AppSettingsProvider.cs | 10 ++ .../AspCoreMqttClientOptionBuilder.cs | 15 ++ .../Extensions/BrokerHostSettings.cs | 8 + ManagerService/Extensions/ClientSettings.cs | 9 ++ ManagerService/Extensions/ExternalService.cs | 11 ++ .../Extensions/IMqttClientService.cs | 14 ++ .../Extensions/MqttClientService.cs | 151 ++++++++++++++++++ .../Extensions/MqttClientServiceProvider.cs | 12 ++ .../Extensions/ServiceCollectionExtension.cs | 53 ++++++ ManagerService/ManagerService.csproj | 1 + ManagerService/Startup.cs | 26 +++ ManagerService/appsettings.json | 10 ++ 22 files changed, 407 insertions(+), 64 deletions(-) create mode 100644 Manager.Interfaces/DTO/PlayerMessageDTO.cs create mode 100644 ManagerService/Extensions/AppSettingsProvider.cs create mode 100644 ManagerService/Extensions/AspCoreMqttClientOptionBuilder.cs create mode 100644 ManagerService/Extensions/BrokerHostSettings.cs create mode 100644 ManagerService/Extensions/ClientSettings.cs create mode 100644 ManagerService/Extensions/ExternalService.cs create mode 100644 ManagerService/Extensions/IMqttClientService.cs create mode 100644 ManagerService/Extensions/MqttClientService.cs create mode 100644 ManagerService/Extensions/MqttClientServiceProvider.cs create mode 100644 ManagerService/Extensions/ServiceCollectionExtension.cs diff --git a/Manager.Interfaces/DTO/PlayerMessageDTO.cs b/Manager.Interfaces/DTO/PlayerMessageDTO.cs new file mode 100644 index 0000000..7ac6be5 --- /dev/null +++ b/Manager.Interfaces/DTO/PlayerMessageDTO.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Manager.Interfaces.Models +{ + public class PlayerMessageDTO + { + public bool configChanged { get; set; } + + public bool isDeleted { get; set; } + } +} diff --git a/Manager.Interfaces/DTO/SubSection/MapDTO.cs b/Manager.Interfaces/DTO/SubSection/MapDTO.cs index 7f01de1..bb6cbac 100644 --- a/Manager.Interfaces/DTO/SubSection/MapDTO.cs +++ b/Manager.Interfaces/DTO/SubSection/MapDTO.cs @@ -7,27 +7,27 @@ namespace Manager.Interfaces.DTO { public class MapDTO { - public int Zoom { get; set; } // Default = 18 - public MapTypeApp MapType { get; set; } // Default = Hybrid - public List Points { get; set; } - public string IconResourceId { get; set; } - public string IconSource { get; set; } // url to resource id (local) or on internet + public int zoom { get; set; } // Default = 18 + public MapTypeApp mapType { get; set; } // Default = Hybrid + public List points { get; set; } + public string iconResourceId { get; set; } + public string iconSource { get; set; } // url to resource id (local) or on internet } public class GeoPointDTO { - public int Id { get; set; } - public List Title { get; set; } - public List Description { get; set; } - public List Images { get; set; } - public string Latitude { get; set; } - public string Longitude { get; set; } + public int id { get; set; } + public List title { get; set; } + public List description { get; set; } + public List images { get; set; } + public string latitude { get; set; } + public string longitude { get; set; } } public class ImageGeoPoint { - public string ImageResourceId { get; set; } - public string ImageSource { get; set; } // url to resource id (local) or on internet + public string imageResourceId { get; set; } + public string imageSource { get; set; } // url to resource id (local) or on internet } public enum MapTypeApp diff --git a/Manager.Interfaces/DTO/SubSection/MenuDTO.cs b/Manager.Interfaces/DTO/SubSection/MenuDTO.cs index f9cf955..2d8ac20 100644 --- a/Manager.Interfaces/DTO/SubSection/MenuDTO.cs +++ b/Manager.Interfaces/DTO/SubSection/MenuDTO.cs @@ -7,6 +7,6 @@ namespace Manager.Interfaces.DTO public class MenuDTO { //public string Title { get; set; } // Dictionary with all languages - public List Sections { get; set; } + public List sections { get; set; } } } diff --git a/Manager.Interfaces/DTO/SubSection/SliderDTO.cs b/Manager.Interfaces/DTO/SubSection/SliderDTO.cs index c4f44e1..df2af38 100644 --- a/Manager.Interfaces/DTO/SubSection/SliderDTO.cs +++ b/Manager.Interfaces/DTO/SubSection/SliderDTO.cs @@ -7,14 +7,14 @@ namespace Manager.Interfaces.DTO { public class SliderDTO { - public List Images { get; set; } + public List images { get; set; } } public class ImageDTO { - public List Title { get; set; } - public List Description { get; set; } - public string ResourceId { get; set; } - public string Source { get; set; } // url to resource id (local) or on internet - public int Order { get; set; } // Order to show + public List title { get; set; } + public List description { get; set; } + public string resourceId { get; set; } + public string source { get; set; } // url to resource id (local) or on internet + public int order { get; set; } // Order to show } } diff --git a/Manager.Interfaces/DTO/SubSection/VideoDTO.cs b/Manager.Interfaces/DTO/SubSection/VideoDTO.cs index 02d62e0..dfd18b2 100644 --- a/Manager.Interfaces/DTO/SubSection/VideoDTO.cs +++ b/Manager.Interfaces/DTO/SubSection/VideoDTO.cs @@ -7,6 +7,6 @@ namespace Manager.Interfaces.DTO public class VideoDTO { //public string Title { get; set; } // Dictionary with all languages - public string Source { get; set; } // url to resource id (local) or on internet + public string source { get; set; } // url to resource id (local) or on internet } } diff --git a/Manager.Interfaces/DTO/SubSection/WebDTO.cs b/Manager.Interfaces/DTO/SubSection/WebDTO.cs index 384a093..f458ecf 100644 --- a/Manager.Interfaces/DTO/SubSection/WebDTO.cs +++ b/Manager.Interfaces/DTO/SubSection/WebDTO.cs @@ -7,6 +7,6 @@ namespace Manager.Interfaces.DTO public class WebDTO { //public string Title { get; set; } // Dictionary with all languages - public string Source { get; set; } // url to resource id (local) or on internet + public string source { get; set; } // url to resource id (local) or on internet } } diff --git a/ManagerService/Controllers/AuthenticationController.cs b/ManagerService/Controllers/AuthenticationController.cs index 78f8673..fb31ee2 100644 --- a/ManagerService/Controllers/AuthenticationController.cs +++ b/ManagerService/Controllers/AuthenticationController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; +using Mqtt.Client.AspNetCore.Services; using NSwag.Annotations; using System; using System.Collections.Generic; @@ -26,12 +27,16 @@ namespace ManagerService.Service.Controllers private readonly ILogger _logger; private readonly TokensService _tokensService; private readonly UserDatabaseService _UserDatabaseService; + private readonly DeviceDatabaseService _DeviceDatabaseService; + private readonly ConfigurationDatabaseService _ConfigurationDatabaseService; - public AuthenticationController(ILogger logger, TokensService tokensService, UserDatabaseService UserDatabaseService) + public AuthenticationController(ILogger logger, TokensService tokensService, UserDatabaseService UserDatabaseService, DeviceDatabaseService DeviceDatabaseService, ConfigurationDatabaseService ConfigurationDatabaseService) { _logger = logger; _tokensService = tokensService; _UserDatabaseService = UserDatabaseService; + _DeviceDatabaseService = DeviceDatabaseService; + _ConfigurationDatabaseService = ConfigurationDatabaseService; } /// @@ -55,6 +60,8 @@ namespace ManagerService.Service.Controllers if (user == null) throw new KeyNotFoundException("User not found"); + MqttClientService.SetServices(_DeviceDatabaseService, _ConfigurationDatabaseService); + return new OkObjectResult(token); } catch (UnauthorizedAccessException ex) diff --git a/ManagerService/Controllers/ConfigurationController.cs b/ManagerService/Controllers/ConfigurationController.cs index 8ea0b29..8ae1fa4 100644 --- a/ManagerService/Controllers/ConfigurationController.cs +++ b/ManagerService/Controllers/ConfigurationController.cs @@ -9,6 +9,8 @@ using ManagerService.Service.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using Mqtt.Client.AspNetCore.Services; +using Newtonsoft.Json; using NSwag.Annotations; namespace ManagerService.Controllers @@ -151,6 +153,8 @@ namespace ManagerService.Controllers Configuration configurationModified = _configurationService.Update(updatedConfiguration.Id, configuration); + MqttClientService.PublishMessage($"config/{configurationModified.Id}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); + return new OkObjectResult(configurationModified.ToDTO()); } catch (ArgumentNullException ex) @@ -189,6 +193,8 @@ namespace ManagerService.Controllers _configurationService.Remove(id); + MqttClientService.PublishMessage($"config/{id}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true, isDeleted = true })); + return new ObjectResult("The configuration has been deleted") { StatusCode = 202 }; } diff --git a/ManagerService/Controllers/DeviceController.cs b/ManagerService/Controllers/DeviceController.cs index 9c582fd..35484e0 100644 --- a/ManagerService/Controllers/DeviceController.cs +++ b/ManagerService/Controllers/DeviceController.cs @@ -12,6 +12,8 @@ using ManagerService.Service.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using Mqtt.Client.AspNetCore.Services; +using Newtonsoft.Json; using NSwag.Annotations; namespace ManagerService.Controllers @@ -237,6 +239,8 @@ namespace ManagerService.Controllers Device deviceModified = _deviceService.Update(device.Id, device); + MqttClientService.PublishMessage($"player/{device.Id}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); + return new OkObjectResult(deviceModified.ToDTO()); } catch (ArgumentNullException ex) diff --git a/ManagerService/Controllers/SectionController.cs b/ManagerService/Controllers/SectionController.cs index b8688fb..2ce3e94 100644 --- a/ManagerService/Controllers/SectionController.cs +++ b/ManagerService/Controllers/SectionController.cs @@ -4,6 +4,7 @@ using Manager.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; +using Mqtt.Client.AspNetCore.Services; using Newtonsoft.Json; using NSwag.Annotations; using System; @@ -275,17 +276,17 @@ namespace ManagerService.Controllers switch (newSection.Type) { case SectionType.Map: mapDTO = new MapDTO(); - mapDTO.MapType = MapTypeApp.hybrid; - mapDTO.Zoom = 18; + mapDTO.mapType = MapTypeApp.hybrid; + mapDTO.zoom = 18; - mapDTO.Points = new List() { + mapDTO.points = new List() { new GeoPointDTO() { - Id = 0, - Title = section.Title, - Description = section.Description, - Latitude = "50.416639", - Longitude= "4.879169", - Images = new List() + id = 0, + title = section.Title, + description = section.Description, + latitude = "50.416639", + longitude= "4.879169", + images = new List() } }; @@ -294,51 +295,27 @@ namespace ManagerService.Controllers case SectionType.Slider: sliderDTO = new SliderDTO(); ImageDTO imageDTO = new ImageDTO(); - imageDTO.Title = section.Title; - imageDTO.Description = section.Description; - imageDTO.Source = null; - sliderDTO.Images = new List(); - sliderDTO.Images.Add(imageDTO); + imageDTO.title = section.Title; + imageDTO.description = section.Description; + imageDTO.source = null; + sliderDTO.images = new List(); + sliderDTO.images.Add(imageDTO); section.Data = JsonConvert.SerializeObject(sliderDTO); // Include all info from specific section as JSON break; case SectionType.Video: VideoDTO videoDTO = new VideoDTO(); - videoDTO.Source = ""; + videoDTO.source = ""; section.Data = JsonConvert.SerializeObject(videoDTO); // Include all info from specific section as JSON break; case SectionType.Web: WebDTO webDTO = new WebDTO(); - webDTO.Source = ""; + webDTO.source = ""; section.Data = JsonConvert.SerializeObject(webDTO); // Include all info from specific section as JSON break; case SectionType.Menu: MenuDTO menuDTO = new MenuDTO(); - menuDTO.Sections = new List(); - /*SectionDTO section0DTO = new SectionDTO(); - section0DTO.IsSubSection = true; - section0DTO.Label = newSection.Label; - section0DTO.ImageId = newSection.ImageId; - section0DTO.ConfigurationId = newSection.ConfigurationId; - section0DTO.DateCreation = DateTime.Now; - section0DTO.ParentId = null; - section0DTO.Type = SectionType.Map; - section0DTO.Data = JsonConvert.SerializeObject(mapDTO); - - - SectionDTO section1DTO = new SectionDTO(); - section0DTO.IsSubSection = true; - section0DTO.Label = newSection.Label; - section0DTO.ImageId = newSection.ImageId; - section0DTO.ConfigurationId = newSection.ConfigurationId; - section0DTO.DateCreation = DateTime.Now; - section0DTO.ParentId = null; - section0DTO.Type = SectionType.Slider; - section1DTO.IsSubSection = true; - section1DTO.Data = JsonConvert.SerializeObject(sliderDTO);*/ - - /*menuDTO.Sections.Add(section0DTO); - menuDTO.Sections.Add(section1DTO);*/ + menuDTO.sections = new List(); section.Data = JsonConvert.SerializeObject(menuDTO); // Include all info from specific section as JSON break; } @@ -448,6 +425,8 @@ namespace ManagerService.Controllers Section sectionModified = _sectionService.Update(updatedSection.Id, section); + MqttClientService.PublishMessage($"config/{sectionModified.ConfigurationId}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); + return new OkObjectResult(sectionModified.ToDTO()); } catch (ArgumentNullException ex) @@ -494,6 +473,10 @@ namespace ManagerService.Controllers _sectionService.Update(section.Id, section); } + if (updatedSectionsOrder.Count > 0) { + MqttClientService.PublishMessage($"config/{updatedSectionsOrder[0].ConfigurationId}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); + } + return new ObjectResult("Sections order has been successfully modified") { StatusCode = 200 }; } catch (ArgumentNullException ex) @@ -598,5 +581,15 @@ namespace ManagerService.Controllers { return new ObjectResult("MenuDTO") { StatusCode = 200 }; } + + /// + /// Useless, just to generate dto code + /// + [ProducesResponseType(typeof(PlayerMessageDTO), 200)] + [HttpGet("PlayerMessageDTO")] + public ObjectResult PlayerMessageDTO() + { + return new ObjectResult("PlayerMessageDTO") { StatusCode = 200 }; + } } } diff --git a/ManagerService/Extensions/AppSettingsProvider.cs b/ManagerService/Extensions/AppSettingsProvider.cs new file mode 100644 index 0000000..62a3cb4 --- /dev/null +++ b/ManagerService/Extensions/AppSettingsProvider.cs @@ -0,0 +1,10 @@ +using Mqtt.Client.AspNetCore.Settings; + +namespace ManagerService.Extensions +{ + public class AppSettingsProvider + { + public static BrokerHostSettings BrokerHostSettings; + public static ClientSettings ClientSettings; + } +} diff --git a/ManagerService/Extensions/AspCoreMqttClientOptionBuilder.cs b/ManagerService/Extensions/AspCoreMqttClientOptionBuilder.cs new file mode 100644 index 0000000..71d0b63 --- /dev/null +++ b/ManagerService/Extensions/AspCoreMqttClientOptionBuilder.cs @@ -0,0 +1,15 @@ +using MQTTnet.Client.Options; +using System; + +namespace Mqtt.Client.AspNetCore.Options +{ + public class AspCoreMqttClientOptionBuilder : MqttClientOptionsBuilder + { + public IServiceProvider ServiceProvider { get; } + + public AspCoreMqttClientOptionBuilder(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } + } +} diff --git a/ManagerService/Extensions/BrokerHostSettings.cs b/ManagerService/Extensions/BrokerHostSettings.cs new file mode 100644 index 0000000..feb8efe --- /dev/null +++ b/ManagerService/Extensions/BrokerHostSettings.cs @@ -0,0 +1,8 @@ +namespace Mqtt.Client.AspNetCore.Settings +{ + public class BrokerHostSettings + { + public string Host { set; get; } + public int Port { set; get; } + } +} diff --git a/ManagerService/Extensions/ClientSettings.cs b/ManagerService/Extensions/ClientSettings.cs new file mode 100644 index 0000000..ca876a9 --- /dev/null +++ b/ManagerService/Extensions/ClientSettings.cs @@ -0,0 +1,9 @@ +namespace Mqtt.Client.AspNetCore.Settings +{ + public class ClientSettings + { + public string Id { set; get; } + public string UserName { set; get; } + public string Password { set; get; } + } +} diff --git a/ManagerService/Extensions/ExternalService.cs b/ManagerService/Extensions/ExternalService.cs new file mode 100644 index 0000000..4ed6a04 --- /dev/null +++ b/ManagerService/Extensions/ExternalService.cs @@ -0,0 +1,11 @@ +namespace Mqtt.Client.AspNetCore.Services +{ + public class ExternalService + { + private readonly IMqttClientService mqttClientService; + public ExternalService(MqttClientServiceProvider provider) + { + mqttClientService = provider.MqttClientService; + } + } +} diff --git a/ManagerService/Extensions/IMqttClientService.cs b/ManagerService/Extensions/IMqttClientService.cs new file mode 100644 index 0000000..3157670 --- /dev/null +++ b/ManagerService/Extensions/IMqttClientService.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.Hosting; +using MQTTnet.Client.Connecting; +using MQTTnet.Client.Disconnecting; +using MQTTnet.Client.Receiving; + +namespace Mqtt.Client.AspNetCore.Services +{ + public interface IMqttClientService : IHostedService, + IMqttClientConnectedHandler, + IMqttClientDisconnectedHandler, + IMqttApplicationMessageReceivedHandler + { + } +} diff --git a/ManagerService/Extensions/MqttClientService.cs b/ManagerService/Extensions/MqttClientService.cs new file mode 100644 index 0000000..922ad23 --- /dev/null +++ b/ManagerService/Extensions/MqttClientService.cs @@ -0,0 +1,151 @@ +using Manager.Interfaces.Models; +using Manager.Services; +using MQTTnet; +using MQTTnet.Client; +using MQTTnet.Client.Connecting; +using MQTTnet.Client.Disconnecting; +using MQTTnet.Client.Options; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Mqtt.Client.AspNetCore.Services +{ + public class MqttClientService : IMqttClientService + { + private static IMqttClient mqttClient; + private IMqttClientOptions options; + static DeviceDatabaseService _deviceDatabaseService; + static ConfigurationDatabaseService _configurationDatabaseService; + + public static string lastTopic; + public static long lastTimeTopic; + + public MqttClientService(IMqttClientOptions options) + { + var server = "localhost"; +#if DEBUG + server = "192.168.31.96"; +#endif + this.options = options; + this.options = new MqttClientOptionsBuilder() + .WithClientId(options.ClientId) + .WithTcpServer(server) + .WithCredentials(options.Credentials.Username, options.Credentials.Password) + .WithCleanSession() + .Build(); + mqttClient = new MqttFactory().CreateMqttClient(); + ConfigureMqttClient(); + } + + private void ConfigureMqttClient() + { + mqttClient.ConnectedHandler = this; + mqttClient.DisconnectedHandler = this; + mqttClient.ApplicationMessageReceivedHandler = this; + } + + public Task HandleApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs e) + { + var payload = ""; + if (e.ApplicationMessage.Payload != null) + { + payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload); + } + + var topic = e.ApplicationMessage.Topic; + + var currentTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + + try + { + var deserialized = JsonConvert.DeserializeObject>(payload); + + switch (topic.Split("/")[0]) { + case "player": + var test = topic.Split("/")[1]; // Get device id + + if (topic == "player/status") { + var deviceId = (string)deserialized["deviceId"]; + var connectedStatus = (bool)deserialized["connected"]; + + Device device = _deviceDatabaseService.GetById(deviceId); + + if (device != null) + { + device.Connected = connectedStatus; + + _deviceDatabaseService.Update(device.Id, device); + } + } + break; + } + + } catch (Exception ex) + { + + } + + return null; + } + + public async Task HandleConnectedAsync(MqttClientConnectedEventArgs eventArgs) + { + System.Console.WriteLine("connected"); + await mqttClient.SubscribeAsync("#"); + } + + public async Task HandleDisconnectedAsync(MqttClientDisconnectedEventArgs eventArgs) + { + if (!mqttClient.IsConnected) + { + await mqttClient.ReconnectAsync(); + } + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + await mqttClient.ConnectAsync(options); + if (!mqttClient.IsConnected) + { + await mqttClient.ReconnectAsync(); + } + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + if(cancellationToken.IsCancellationRequested) + { + var disconnectOption = new MqttClientDisconnectOptions + { + ReasonCode = MqttClientDisconnectReason.NormalDisconnection, + ReasonString = "NormalDiconnection" + }; + await mqttClient.DisconnectAsync(disconnectOption, cancellationToken); + } + await mqttClient.DisconnectAsync(); + } + + public static async Task PublishMessage(string topic, string message) + { + var mqttMessage = new MqttApplicationMessageBuilder() + .WithTopic(topic) + .WithPayload(message) + .WithExactlyOnceQoS() + .WithRetainFlag() + .Build(); + + if (mqttClient.IsConnected) + await mqttClient.PublishAsync(mqttMessage); + } + + public static void SetServices(DeviceDatabaseService _DeviceDatabaseService, ConfigurationDatabaseService _ConfigurationDatabaseService) + { + _deviceDatabaseService = _DeviceDatabaseService; + _configurationDatabaseService = _ConfigurationDatabaseService; + } + } +} diff --git a/ManagerService/Extensions/MqttClientServiceProvider.cs b/ManagerService/Extensions/MqttClientServiceProvider.cs new file mode 100644 index 0000000..1223eb6 --- /dev/null +++ b/ManagerService/Extensions/MqttClientServiceProvider.cs @@ -0,0 +1,12 @@ +namespace Mqtt.Client.AspNetCore.Services +{ + public class MqttClientServiceProvider + { + public readonly IMqttClientService MqttClientService; + + public MqttClientServiceProvider(IMqttClientService mqttClientService) + { + MqttClientService = mqttClientService; + } + } +} diff --git a/ManagerService/Extensions/ServiceCollectionExtension.cs b/ManagerService/Extensions/ServiceCollectionExtension.cs new file mode 100644 index 0000000..dab80ed --- /dev/null +++ b/ManagerService/Extensions/ServiceCollectionExtension.cs @@ -0,0 +1,53 @@ +using ManagerService.Extensions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Mqtt.Client.AspNetCore.Options; +using Mqtt.Client.AspNetCore.Services; +using Mqtt.Client.AspNetCore.Settings; +using MQTTnet.Client.Options; +using System; + +namespace MyCore.Service.Extensions +{ + public static class ServiceCollectionExtension + { + + public static IServiceCollection AddMqttClientHostedService(this IServiceCollection services) + { + services.AddMqttClientServiceWithConfig(aspOptionBuilder => + { + var clientSettings = AppSettingsProvider.ClientSettings; + var brokerHostSettings = AppSettingsProvider.BrokerHostSettings; + + aspOptionBuilder + .WithCredentials(clientSettings.UserName, clientSettings.Password) + .WithClientId(clientSettings.Id) + .WithTcpServer(brokerHostSettings.Host, brokerHostSettings.Port); + }); + return services; + } + + private static IServiceCollection AddMqttClientServiceWithConfig(this IServiceCollection services, Action configure) + { + // No need as we implement options in service (localhost) + services.AddSingleton(serviceProvider => + { + var optionBuilder = new AspCoreMqttClientOptionBuilder(serviceProvider); + configure(optionBuilder); + return optionBuilder.Build(); + }); + services.AddSingleton(); + services.AddSingleton(serviceProvider => + { + return serviceProvider.GetService(); + }); + services.AddSingleton(serviceProvider => + { + var mqttClientService = serviceProvider.GetService(); + var mqttClientServiceProvider = new MqttClientServiceProvider(mqttClientService); + return mqttClientServiceProvider; + }); + return services; + } + } +} diff --git a/ManagerService/ManagerService.csproj b/ManagerService/ManagerService.csproj index a90c988..5140a69 100644 --- a/ManagerService/ManagerService.csproj +++ b/ManagerService/ManagerService.csproj @@ -8,6 +8,7 @@ + diff --git a/ManagerService/Startup.cs b/ManagerService/Startup.cs index b5419b4..ac857e5 100644 --- a/ManagerService/Startup.cs +++ b/ManagerService/Startup.cs @@ -2,6 +2,7 @@ using Manager.Framework.Business; using Manager.Framework.Models; using Manager.Interfaces.Models; using Manager.Services; +using ManagerService.Extensions; using ManagerService.Service; using ManagerService.Service.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; @@ -18,6 +19,8 @@ using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; +using Mqtt.Client.AspNetCore.Settings; +using MyCore.Service.Extensions; using NSwag; using NSwag.Generation.AspNetCore; using NSwag.Generation.Processors.Security; @@ -36,10 +39,32 @@ namespace ManagerService public Startup(IConfiguration configuration) { Configuration = configuration; + + MapConfiguration(); } public IConfiguration Configuration { get; } + private void MapConfiguration() + { + MapBrokerHostSettings(); + MapClientSettings(); + } + + private void MapBrokerHostSettings() + { + BrokerHostSettings brokerHostSettings = new BrokerHostSettings(); + Configuration.GetSection(nameof(BrokerHostSettings)).Bind(brokerHostSettings); + AppSettingsProvider.BrokerHostSettings = brokerHostSettings; + } + + private void MapClientSettings() + { + ClientSettings clientSettings = new ClientSettings(); + Configuration.GetSection(nameof(ClientSettings)).Bind(clientSettings); + AppSettingsProvider.ClientSettings = clientSettings; + } + // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { @@ -107,6 +132,7 @@ namespace ManagerService }; }); + services.AddMqttClientHostedService(); services.AddScoped(typeof(ProfileLogic)); services.AddScoped(); services.AddScoped(); diff --git a/ManagerService/appsettings.json b/ManagerService/appsettings.json index ef793a5..c3f3356 100644 --- a/ManagerService/appsettings.json +++ b/ManagerService/appsettings.json @@ -22,5 +22,15 @@ "Audience": "the client of your app", "IdType": "Name", "TokenExpiryInHours": 2 + }, + "BrokerHostSettings": { + "Host": "localhost", + "Port": 1883 + }, + + "ClientSettings": { + "Id": "ManagerService", + "UserName": "admin", + "Password": "mdlf2021!" } }