using System; using System.Collections.Generic; using System.Linq; using Manager.Services; using ManagerService.Data; using ManagerService.DTOs; using ManagerService.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Mqtt.Client.AspNetCore.Services; using Newtonsoft.Json; using NSwag.Annotations; namespace ManagerService.Controllers { [Authorize] // TODO Add ROLES (Roles = "Admin") [ApiController, Route("api/[controller]")] [OpenApiTag("Device", Description = "Device management")] public class DeviceController : ControllerBase { private DeviceDatabaseService _deviceService; private ConfigurationDatabaseService _configurationService; private readonly ILogger _logger; private readonly MyInfoMateDbContext _myInfoMateDbContext; IHexIdGeneratorService idService = new HexIdGeneratorService(); public DeviceController(ILogger logger, DeviceDatabaseService deviceService, ConfigurationDatabaseService configurationService, MyInfoMateDbContext myInfoMateDbContext) { _logger = logger; _deviceService = deviceService; _configurationService = configurationService; _myInfoMateDbContext = myInfoMateDbContext; } /// /// Get a list of all devices /// /// id instance [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 500)] [HttpGet] public ObjectResult Get([FromQuery] string instanceId) { try { //List devices = _deviceService.GetAll(instanceId); List devices = _myInfoMateDbContext.Devices.Include(d => d.Configuration).ToList(); return new OkObjectResult(devices.Select(d => d.ToDTO())); } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Get a specific device /// /// id device [AllowAnonymous] [ProducesResponseType(typeof(DeviceDetailDTO), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{id}/detail")] public ObjectResult GetDetail(string id) { try { //OldDevice device = _deviceService.GetById(id); Device device = _myInfoMateDbContext.Devices.Include(d => d.Configuration).FirstOrDefault(i => i.Id == id); if (device == null) throw new KeyNotFoundException("This device was not found"); return new OkObjectResult(device.ToDetailDTO()); } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create a new device /// /// New device info [AllowAnonymous] [ProducesResponseType(typeof(DeviceDetailDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 409)] [ProducesResponseType(typeof(string), 500)] [HttpPost] public ObjectResult Create([FromBody] DeviceDetailDTO newDevice) { try { if (newDevice == null) throw new ArgumentNullException("Device param is null"); //var configuration = _configurationService.GetById(newDevice.configurationId); var configuration = _myInfoMateDbContext.Configurations.FirstOrDefault(c => c.Id == newDevice.configurationId); if (configuration == null) throw new KeyNotFoundException("Configuration does not exist"); //OldDevice device = new OldDevice(); Device device = new Device().FromDTO(newDevice); device.Id = idService.GenerateHexId(); var deviceDB = _myInfoMateDbContext.Devices.FirstOrDefault(d => d.Identifier == newDevice.identifier); if (deviceDB != null) { // Update info device = deviceDB; //device = _deviceService.GetByIdentifier(newDevice.identifier); device.DateUpdate = DateTime.Now.ToUniversalTime(); } else { // Creation device.Identifier = newDevice.identifier; device.DateCreation = DateTime.Now.ToUniversalTime(); } device.InstanceId = newDevice.instanceId; device.Name = newDevice.name; device.ConfigurationId = newDevice.configurationId; device.IpAddressETH = newDevice.ipAddressETH; device.IpAddressWLAN = newDevice.ipAddressWLAN; device.Connected = newDevice.connected; device.ConnectionLevel = newDevice.connectionLevel; device.LastConnectionLevel = newDevice.lastConnectionLevel; device.BatteryLevel = newDevice.batteryLevel; device.LastBatteryLevel = newDevice.lastBatteryLevel; //OldDevice deviceCreated = _deviceService.IsExistIdentifier(newDevice.identifier) ? _deviceService.Update(device.Id, device) : _deviceService.Create(device); if (deviceDB != null) { _myInfoMateDbContext.Update(device); } else { _myInfoMateDbContext.Add(device); } _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(device.ToDTO()); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (InvalidOperationException ex) { return new ConflictObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Update a device /// /// Device to update [ProducesResponseType(typeof(DeviceDetailDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut] public ObjectResult Update([FromBody] DeviceDetailDTO updatedDevice) { try { if (updatedDevice == null) throw new ArgumentNullException("Device param is null"); //OldDevice device = _deviceService.GetById(updatedDevice.id); Device device = _myInfoMateDbContext.Devices.FirstOrDefault(d => d.Id == updatedDevice.id); if (device == null) throw new KeyNotFoundException("Device does not exist"); // Todo add some verification ? device.Name = updatedDevice.name; device.InstanceId = updatedDevice.instanceId; device.Identifier = updatedDevice.identifier; device.IpAddressWLAN = updatedDevice.ipAddressWLAN; device.IpAddressETH = updatedDevice.ipAddressETH; device.Connected = updatedDevice.connected; device.ConnectionLevel = updatedDevice.connectionLevel; device.LastConnectionLevel = updatedDevice.lastConnectionLevel; device.BatteryLevel = updatedDevice.batteryLevel; device.LastBatteryLevel = updatedDevice.lastBatteryLevel; //OldDevice deviceModified = _deviceService.Update(updatedDevice.id, device); _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(device.ToDTO()); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Update device main info /// /// Device to update [ProducesResponseType(typeof(DeviceDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut("mainInfos")] public ObjectResult UpdateMainInfos([FromBody] DeviceDTO deviceIn) { try { if (deviceIn == null) throw new ArgumentNullException("Device param is null"); //OldDevice device = _deviceService.GetById(deviceIn.id); Device device = _myInfoMateDbContext.Devices.FirstOrDefault(d => d.Id == deviceIn.id); if (device == null) throw new KeyNotFoundException("Device does not exist"); //var configuration = _configurationService.GetById(deviceIn.configurationId); var configuration = _myInfoMateDbContext.Configurations.FirstOrDefault(c => c.Id == deviceIn.configurationId); if (configuration == null) throw new KeyNotFoundException("Configuration does not exist"); // Todo add some verification ? device.Name = deviceIn.name; device.Connected = deviceIn.connected; //device.Configuration = configuration.Label; device.ConfigurationId = deviceIn.configurationId; //OldDevice deviceModified = _deviceService.Update(device.Id, device); _myInfoMateDbContext.SaveChanges(); MqttClientService.PublishMessage($"player/{device.Id}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); return new OkObjectResult(device.ToDTO()); } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Delete a device /// /// Id of device to delete [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("{id}")] public ObjectResult Delete(string id) { try { if (id == null) throw new ArgumentNullException("Device param is null"); Device device = _myInfoMateDbContext.Devices.FirstOrDefault(d => d.Id == id); if (device == null) throw new KeyNotFoundException("Device does not exist"); _myInfoMateDbContext.Remove(device); _myInfoMateDbContext.SaveChanges(); //_deviceService.Remove(id); return new ObjectResult("The device has been deleted") { StatusCode = 202 }; } catch (ArgumentNullException ex) { return new BadRequestObjectResult(ex.Message) { }; } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } } }