From 5e40190c6d8a649e60f762a2f48ff1828d30aafb Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Wed, 4 Aug 2021 18:07:21 +0200 Subject: [PATCH] Add import and export configuration method --- .../DTO/ExportConfigurationDTO.cs | 13 + Manager.Interfaces/DTO/ResourceDTO.cs | 1 + Manager.Interfaces/DTO/ResourceDetailDTO.cs | 16 -- Manager.Interfaces/Manager.Interfaces.csproj | 1 + Manager.Interfaces/Models/Configuration.cs | 17 +- Manager.Interfaces/Models/Resource.cs | 16 +- .../Controllers/ConfigurationController.cs | 231 +++++++++++++++++- .../Controllers/ResourceController.cs | 19 +- ManagerService/appsettings.json | 1 - 9 files changed, 269 insertions(+), 46 deletions(-) create mode 100644 Manager.Interfaces/DTO/ExportConfigurationDTO.cs delete mode 100644 Manager.Interfaces/DTO/ResourceDetailDTO.cs diff --git a/Manager.Interfaces/DTO/ExportConfigurationDTO.cs b/Manager.Interfaces/DTO/ExportConfigurationDTO.cs new file mode 100644 index 0000000..e0727cf --- /dev/null +++ b/Manager.Interfaces/DTO/ExportConfigurationDTO.cs @@ -0,0 +1,13 @@ +using DevExpress.Xpo; +using System; +using System.Collections.Generic; + +namespace Manager.Interfaces.DTO +{ + public class ExportConfigurationDTO : ConfigurationDTO + { + public List sections { get; set; } + public List resources { get; set; } + } + +} \ No newline at end of file diff --git a/Manager.Interfaces/DTO/ResourceDTO.cs b/Manager.Interfaces/DTO/ResourceDTO.cs index c9bb169..331c4d7 100644 --- a/Manager.Interfaces/DTO/ResourceDTO.cs +++ b/Manager.Interfaces/DTO/ResourceDTO.cs @@ -10,6 +10,7 @@ namespace Manager.Interfaces.DTO public string id { get; set; } public ResourceType type { get; set; } public string label { get; set; } + public DateTime dateCreation { get; set; } public string data { get; set; } } } diff --git a/Manager.Interfaces/DTO/ResourceDetailDTO.cs b/Manager.Interfaces/DTO/ResourceDetailDTO.cs deleted file mode 100644 index ee392b0..0000000 --- a/Manager.Interfaces/DTO/ResourceDetailDTO.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Manager.Interfaces.Models; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Manager.Interfaces.DTO -{ - public class ResourceDetailDTO - { - public string id { get; set; } - public ResourceType type { get; set; } - public string label { get; set; } - public DateTime dateCreation { get; set; } - public string data { get; set; } - } -} diff --git a/Manager.Interfaces/Manager.Interfaces.csproj b/Manager.Interfaces/Manager.Interfaces.csproj index d66e047..f6da939 100644 --- a/Manager.Interfaces/Manager.Interfaces.csproj +++ b/Manager.Interfaces/Manager.Interfaces.csproj @@ -5,6 +5,7 @@ + diff --git a/Manager.Interfaces/Models/Configuration.cs b/Manager.Interfaces/Models/Configuration.cs index aab5f8d..28a8dc3 100644 --- a/Manager.Interfaces/Models/Configuration.cs +++ b/Manager.Interfaces/Models/Configuration.cs @@ -25,9 +25,6 @@ namespace Manager.Interfaces.Models [BsonElement("SecondaryColor")] public string SecondaryColor { get; set; } - [BsonElement("SectionIds")] - public List SectionIds { get; set; } // Get children - [BsonElement("Languages")] public List Languages { get; set; } // fr, en, de, nl => Sélection dans une liste déjà établie dans l'application ! @@ -46,5 +43,19 @@ namespace Manager.Interfaces.Models secondaryColor = SecondaryColor }; } + + public ExportConfigurationDTO ToExportDTO(List sections, List resources) { + return new ExportConfigurationDTO() + { + id = Id, + label = Label, + dateCreation = DateCreation, + primaryColor = PrimaryColor, + languages = Languages, + secondaryColor = SecondaryColor, + sections = sections, + resources = resources + }; + } } } diff --git a/Manager.Interfaces/Models/Resource.cs b/Manager.Interfaces/Models/Resource.cs index 46baeb5..ecc7826 100644 --- a/Manager.Interfaces/Models/Resource.cs +++ b/Manager.Interfaces/Models/Resource.cs @@ -31,29 +31,17 @@ namespace Manager.Interfaces.Models [BsonRequired] public string Data { get; set; } - public ResourceDTO ToDTO() + public ResourceDTO ToDTO(bool isExport = false) { return new ResourceDTO() { id = Id, label = Label, type = Type, - data = Type != ResourceType.Image ? Data : null, - }; - } - - public ResourceDetailDTO ToDetailDTO() - { - return new ResourceDetailDTO() - { - id = Id, - label = Label, - type = Type, - data = Data, + data = isExport ? Data : null, dateCreation = DateCreation }; } - } public enum ResourceType diff --git a/ManagerService/Controllers/ConfigurationController.cs b/ManagerService/Controllers/ConfigurationController.cs index 61648b3..841c0ad 100644 --- a/ManagerService/Controllers/ConfigurationController.cs +++ b/ManagerService/Controllers/ConfigurationController.cs @@ -21,12 +21,16 @@ namespace ManagerService.Controllers public class ConfigurationController : ControllerBase { private ConfigurationDatabaseService _configurationService; + private SectionDatabaseService _sectionService; + private ResourceDatabaseService _resourceService; private readonly ILogger _logger; - public ConfigurationController(ILogger logger, ConfigurationDatabaseService configurationService) + public ConfigurationController(ILogger logger, ConfigurationDatabaseService configurationService, SectionDatabaseService sectionService, ResourceDatabaseService resourceService) { _logger = logger; _configurationService = configurationService; + _sectionService = sectionService; + _resourceService = resourceService; } /// @@ -211,5 +215,230 @@ namespace ManagerService.Controllers return new ObjectResult(ex.Message) { StatusCode = 500 }; } } + + + /// + /// Export a configuration + /// + /// Id of configuration to export + [ProducesResponseType(typeof(ExportConfigurationDTO), 200)] + [ProducesResponseType(typeof(string), 400)] + [ProducesResponseType(typeof(string), 404)] + [ProducesResponseType(typeof(string), 500)] + [HttpGet("{id}/export")] + public ObjectResult Export(string id) + { + try + { + if (id == null) + throw new ArgumentNullException("Configuration param is null"); + + Configuration configuration = _configurationService.GetById(id); + if (configuration == null) + throw new KeyNotFoundException("Configuration does not exist"); + + List sectionDTOs = _sectionService.GetAllFromConfiguration(configuration.Id).Select(s => s.ToDTO()).ToList(); + List resourceDTOs = new List(); + + foreach (var section in sectionDTOs) + { + if (section.imageId != null) { + addResourceToList(resourceDTOs, section.imageId); + } + + switch (section.type) { + case SectionType.Map: + MapDTO mapDTO = JsonConvert.DeserializeObject(section.data); + if (mapDTO.iconResourceId != null) + { + addResourceToList(resourceDTOs, mapDTO.iconResourceId); + } + + foreach (var point in mapDTO.points) { + foreach (var image in point.images) { + if (image.imageResourceId != null) + { + addResourceToList(resourceDTOs, image.imageResourceId); + } + } + } + + break; + case SectionType.Slider: + SliderDTO sliderDTO = JsonConvert.DeserializeObject(section.data); + foreach (var image in sliderDTO.images) + { + if (image.resourceId != null) + { + addResourceToList(resourceDTOs, image.resourceId); + } + } + break; + case SectionType.Menu: + case SectionType.Web: + case SectionType.Video: + default: + break; + } + } + + return new OkObjectResult(configuration.ToExportDTO(sectionDTOs, resourceDTOs)); + + } + 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 }; + } + } + + /// + /// Import a configuration + /// + /// Configuration to import + [ProducesResponseType(typeof(string), 202)] + [ProducesResponseType(typeof(string), 400)] + [ProducesResponseType(typeof(string), 404)] + [ProducesResponseType(typeof(string), 409)] + [ProducesResponseType(typeof(string), 500)] + [HttpPost("import")] + public ObjectResult Import([FromBody] ExportConfigurationDTO exportConfiguration) + { + try + { + if (exportConfiguration == null) + throw new ArgumentNullException("File to import is null"); + + Configuration configuration = _configurationService.GetById(exportConfiguration.id); + if (configuration != null) + throw new InvalidOperationException("Configuration already exist in the system"); + + configuration = new Configuration(); + configuration.Id = exportConfiguration.id; + configuration.Label = exportConfiguration.label; + configuration.DateCreation = exportConfiguration.dateCreation; + configuration.PrimaryColor = exportConfiguration.primaryColor; + configuration.SecondaryColor = exportConfiguration.secondaryColor; + configuration.Languages = exportConfiguration.languages; + + _configurationService.Create(configuration); + + foreach (var section in exportConfiguration.sections.Where(s => !_sectionService.IsExist(s.id))) + { + Section newSection = new Section(); + newSection.Id = section.id; + newSection.Label = section.label; + newSection.Title = section.title; + newSection.Description = section.description; + newSection.Order = section.order; // if one day we can use same section in multiple configuration, need to change that + newSection.Type = section.type; + newSection.ImageId = section.imageId; + newSection.ImageSource = section.imageSource; + newSection.ConfigurationId = section.configurationId; + newSection.IsSubSection = section.isSubSection; + newSection.ParentId = section.parentId; + newSection.Data = section.data; + newSection.DateCreation = section.dateCreation; + + if (newSection.ImageId != null) + { + createResource(exportConfiguration.resources.Where(r => r.id == newSection.ImageId).FirstOrDefault()); + } + + _sectionService.Create(newSection); + + switch (section.type) + { + case SectionType.Map: + MapDTO mapDTO = JsonConvert.DeserializeObject(section.data); + if (mapDTO.iconResourceId != null) + { + createResource(exportConfiguration.resources.Where(r => r.id == mapDTO.iconResourceId).FirstOrDefault()); + } + + foreach (var point in mapDTO.points) + { + foreach (var image in point.images) + { + if (image.imageResourceId != null) + { + createResource(exportConfiguration.resources.Where(r => r.id == image.imageResourceId).FirstOrDefault()); + } + } + } + + break; + case SectionType.Slider: + SliderDTO sliderDTO = JsonConvert.DeserializeObject(section.data); + foreach (var image in sliderDTO.images) + { + if (image.resourceId != null) + { + createResource(exportConfiguration.resources.Where(r => r.id == image.resourceId).FirstOrDefault()); + } + } + break; + case SectionType.Menu: + case SectionType.Web: + case SectionType.Video: + default: + break; + } + } + + return new ObjectResult("The configuration has been successfully imported") { StatusCode = 202 }; + + } + 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 }; + } + } + + private void createResource(ResourceDTO resourceExport) + { + if (resourceExport != null) + { + Resource resource = new Resource(); + resource.Id = resourceExport.id; + resource.Type = resourceExport.type; + resource.Label = resourceExport.label; + resource.DateCreation = resourceExport.dateCreation; + resource.Data = resourceExport.data; + + if (!_resourceService.IsExist(resourceExport.id)) + _resourceService.Create(resource); + } + } + + private List addResourceToList(List resourceDTOs, string resourceId) { + if (!resourceDTOs.Select(r => r.id).Contains(resourceId)) { + Resource resource = _resourceService.GetById(resourceId); + + if (resource != null) { + resourceDTOs.Add(resource.ToDTO(true)); + } + } + return resourceDTOs; + } } } diff --git a/ManagerService/Controllers/ResourceController.cs b/ManagerService/Controllers/ResourceController.cs index 9df17fc..025512b 100644 --- a/ManagerService/Controllers/ResourceController.cs +++ b/ManagerService/Controllers/ResourceController.cs @@ -62,7 +62,7 @@ namespace ManagerService.Controllers /// /// id resource [AllowAnonymous] - [ProducesResponseType(typeof(ResourceDetailDTO), 200)] + [ProducesResponseType(typeof(ResourceDTO), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{id}/detail")] @@ -75,7 +75,7 @@ namespace ManagerService.Controllers if (resource == null) throw new KeyNotFoundException("This resource was not found"); - return new OkObjectResult(resource.ToDetailDTO()); + return new OkObjectResult(resource.ToDTO()); } catch (KeyNotFoundException ex) { @@ -140,12 +140,9 @@ namespace ManagerService.Controllers { try { - - var test = label; - var test0 = type; - /*if (uploadResource == null) - throw new ArgumentNullException("Resource param is null");*/ - ResourceDetailDTO uploadResource = new ResourceDetailDTO(); + if (label == null || type == null) + throw new ArgumentNullException("One of resource params is null"); + ResourceDTO uploadResource = new ResourceDTO(); uploadResource.type = (ResourceType) Enum.Parse(typeof(ResourceType), type); uploadResource.label = label; @@ -200,7 +197,7 @@ namespace ManagerService.Controllers [ProducesResponseType(typeof(string), 409)] [ProducesResponseType(typeof(string), 500)] [HttpPost] - public ObjectResult Create([FromBody] ResourceDetailDTO newResource) + public ObjectResult Create([FromBody] ResourceDTO newResource) { try { @@ -237,12 +234,12 @@ namespace ManagerService.Controllers /// Update a resource /// /// Resource to update - [ProducesResponseType(typeof(ResourceDetailDTO), 200)] + [ProducesResponseType(typeof(ResourceDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut] - public ObjectResult Update([FromBody] ResourceDetailDTO updatedResource) + public ObjectResult Update([FromBody] ResourceDTO updatedResource) { try { diff --git a/ManagerService/appsettings.json b/ManagerService/appsettings.json index c3f3356..c50bf66 100644 --- a/ManagerService/appsettings.json +++ b/ManagerService/appsettings.json @@ -27,7 +27,6 @@ "Host": "localhost", "Port": 1883 }, - "ClientSettings": { "Id": "ManagerService", "UserName": "admin",