RED-9868 - Import older template zip with incompatible component rules breaks the stack #702

Merged
corina.olariu.ext1 merged 1 commits from RED-9868-update into master 2024-08-29 10:40:36 +02:00
3 changed files with 280 additions and 203 deletions

View File

@ -96,7 +96,34 @@ public interface DossierTemplateResource {
@ResponseStatus(value = HttpStatus.NO_CONTENT)
@PostMapping(value = DOSSIER_TEMPLATE_PATH + IMPORT_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Receives an archive to import", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Archive have successfully imported"), @ApiResponse(responseCode = "400", description = "Validation failed during import"), @ApiResponse(responseCode = "404", description = "The dossier template to update does not exist")})
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Archive have successfully imported"), @ApiResponse(responseCode = "400", description = "Import process stuck in one of the steps:"
+ "0 - Reading the archive content\n"
+ "\n"
+ "1 - store information about the dossier template\n"
+ "\n"
+ "2 - store the colors\n"
+ "\n"
+ "3 - store the watermarks\n"
+ "\n"
+ "4 - store the dossier status\n"
+ "\n"
+ "5 - store the dossier attributes\n"
+ "\n"
+ "6 - store the file attributes\n"
+ "\n"
+ "7 - store the report templates\n"
+ "\n"
+ "8 - store the legal basis\n"
+ "\n"
+ "9 - store the file attribute configuration\n"
+ "\n"
+ "10 - store the component definitions\n"
+ "\n"
+ "11 - store the component mappings\n"
+ "\n"
+ "12 - store the types and entities\n"
+ "\n"
+ "13 - store the rules and component rules"), @ApiResponse(responseCode = "404", description = "The dossier template to update does not exist")})
DossierTemplateModel importDossierTemplate(@Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file,
@RequestParam(value = DOSSIER_TEMPLATE_ID, required = false) String dossierTemplateId,
@RequestParam(value = "updateExistingDossierTemplate", required = false, defaultValue = "false") boolean updateExistingDossierTemplate);

View File

@ -101,7 +101,12 @@ public class DossierTemplateImportService {
public String importDossierTemplate(ImportDossierTemplateRequest request) {
ImportTemplateResult archiveResult = readDossierTemplateImportArchive(request);
ImportTemplateResult archiveResult;
try {
archiveResult = readDossierTemplateImportArchive(request);
} catch (Exception e) {
throw new BadRequestException("The import process failed in step: 0 - while reading the archive content with error: " + e.getMessage());
}
return importDossierTemplate(archiveResult).getDossierTemplateId();
}
@ -121,11 +126,13 @@ public class DossierTemplateImportService {
return dossierTemplateArchiveReader.buildResult();
}
@Observed(name = "DossierTemplateImportService", contextualName = "import-template")
public TemplateImportInfo importDossierTemplate(ImportTemplateResult request) {
long start = System.currentTimeMillis();
String dossierTemplateId;
int importStep = 1;
var dossierTemplateMeta = request.getDossierTemplate();
TemplateImportInfo templateImportInfo = TemplateImportInfo.builder().build();
@ -136,6 +143,8 @@ public class DossierTemplateImportService {
existingDossierTemplate = dossierTemplateOptional.orElse(null);
}
try {
if (existingDossierTemplate != null) {
dossierTemplateId = existingDossierTemplate.getId();
@ -143,14 +152,16 @@ public class DossierTemplateImportService {
updateDossierTemplateMeta(existingDossierTemplate, dossierTemplateMeta, request.getUserId());
dossierTemplateRepository.save(existingDossierTemplate);
existingDossierTemplate.setDossierTemplateStatus(DossierTemplateStatus.valueOf(dossierTemplatePersistenceService.computeDossierTemplateStatus(existingDossierTemplate)
.name()));
existingDossierTemplate.setDossierTemplateStatus(DossierTemplateStatus.valueOf(dossierTemplatePersistenceService.computeDossierTemplateStatus(
existingDossierTemplate).name()));
// set colors
importStep = 2;
this.setColors(dossierTemplateId, request.getColors());
// set watermarks
if (CollectionUtils.isNotEmpty(request.getWatermarks())) {
importStep = 3;
Set<String> toSetWatermarks = request.getWatermarks()
.stream()
.map(WatermarkModel::getName)
@ -181,6 +192,7 @@ public class DossierTemplateImportService {
}
// dossier status
importStep = 4;
if (CollectionUtils.isNotEmpty(request.getDossierStatusInfos())) {
this.updateDossierStates(request, dossierTemplateId);
} else { // no states to add, delete current states
@ -189,6 +201,7 @@ public class DossierTemplateImportService {
}
// update dossier attributes
importStep = 5;
if (CollectionUtils.isNotEmpty(request.getDossierAttributesConfigs())) {
this.updateDossierAttributes(request, dossierTemplateId, templateImportInfo);
} else { // no dossier attributes to add, but delete existing ones
@ -197,6 +210,7 @@ public class DossierTemplateImportService {
}
//update file attributes
importStep = 6;
if (CollectionUtils.isNotEmpty(request.getFileAttributesConfigs())) {
this.updateFileAttributes(request, dossierTemplateId, templateImportInfo);
} else { // no file attributes to add, but delete existing
@ -204,16 +218,8 @@ public class DossierTemplateImportService {
currentConfigs.forEach(fa -> fileAttributeConfigPersistenceService.deleteFileAttribute(fa.getId()));
}
entityTypeImportService.updateTypes(dossierTemplateId, null, request.getEntityTypeImportModel());
if (CollectionUtils.isNotEmpty(request.getComponentDefinitions())) {
this.updateComponents(request, dossierTemplateId);
} else { // no components to add, but remove existing ones
List<ComponentDefinitionEntity> currentComponents = componentDefinitionPersistenceService.findComponentsByDossierTemplateId(dossierTemplateId);
this.deleteComponents(currentComponents);
}
//set report templates
importStep = 7;
var existingReports = reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplateId);
List<String> reportsUpdated = new ArrayList<>();
@ -236,13 +242,39 @@ public class DossierTemplateImportService {
});
// set legal basis
importStep = 8;
if (CollectionUtils.isNotEmpty(request.getLegalBases())) {
legalBasisMappingPersistenceService.setLegalBasisMapping(dossierTemplateId, request.getLegalBases());
} else { // delete existing
legalBasisMappingPersistenceService.deleteLegalBasis(dossierTemplateId);
}
// file attribute general configuration
if (request.getFileAttributesGeneralConfiguration() != null) {
importStep = 9;
fileAttributeConfigPersistenceService.setFileAttributesGeneralConfig(dossierTemplateId,
convert(request.getFileAttributesGeneralConfiguration(),
FileAttributesGeneralConfigurationEntity.class));
}
// component definitions
importStep = 10;
if (CollectionUtils.isNotEmpty(request.getComponentDefinitions())) {
this.updateComponents(request, dossierTemplateId);
} else { // no components to add, but remove existing ones
List<ComponentDefinitionEntity> currentComponents = componentDefinitionPersistenceService.findComponentsByDossierTemplateId(dossierTemplateId);
this.deleteComponents(currentComponents);
}
//set component mappings
importStep = 11;
setComponentMappings(dossierTemplateId, request.getComponentMappings());
importStep = 12;
entityTypeImportService.updateTypes(dossierTemplateId, null, request.getEntityTypeImportModel());
} else {
// creates new dossier template
if (StringUtils.isEmpty(dossierTemplateMeta.getName())) {
throw new ConflictException("DossierTemplate name must be set");
@ -256,17 +288,19 @@ public class DossierTemplateImportService {
dossierTemplateEntity.setId(UUID.randomUUID().toString());
dossierTemplateEntity.setDateAdded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
dossierTemplateEntity.setCreatedBy(request.getUserId());
//set rules
var loadedDossierTemplate = dossierTemplateRepository.save(dossierTemplateEntity);
loadedDossierTemplate.setDossierTemplateStatus(dossierTemplatePersistenceService.computeDossierTemplateStatus(loadedDossierTemplate));
dossierTemplateId = loadedDossierTemplate.getId();
// set colors
importStep = 2;
this.setColors(dossierTemplateId, request.getColors());
// set watermarks
if (CollectionUtils.isNotEmpty(request.getWatermarks())) {
importStep = 3;
request.getWatermarks()
.forEach(watermark -> {
Long initialId = watermark.getId();
@ -279,6 +313,7 @@ public class DossierTemplateImportService {
// dossier status
if (CollectionUtils.isNotEmpty(request.getDossierStatusInfos())) {
importStep = 4;
request.getDossierStatusInfos()
.forEach(state -> {
state.setId(null);
@ -288,6 +323,7 @@ public class DossierTemplateImportService {
//set dossier attributes
if (CollectionUtils.isNotEmpty(request.getDossierAttributesConfigs())) {
importStep = 5;
request.getDossierAttributesConfigs()
.forEach(da -> {
String initialId = da.getId();
@ -299,6 +335,7 @@ public class DossierTemplateImportService {
//set file attributes
if (CollectionUtils.isNotEmpty(request.getFileAttributesConfigs())) {
importStep = 6;
request.getFileAttributesConfigs()
.forEach(fa -> {
String initialId = fa.getId();
@ -308,11 +345,32 @@ public class DossierTemplateImportService {
});
}
//set types
entityTypeImportService.importEntityTypes(dossierTemplateId, null, request.getEntityTypeImportModel());
//set report templates
if (CollectionUtils.isNotEmpty(request.getReportTemplateUploadRequests())) {
importStep = 7;
request.getReportTemplateUploadRequests()
.forEach(reportRequest -> {
reportRequest.setDossierTemplateId(dossierTemplateId);
reportTemplateService.uploadTemplate(reportRequest);
});
}
// set legal basis
if (CollectionUtils.isNotEmpty(request.getLegalBases())) {
importStep = 8;
legalBasisMappingPersistenceService.setLegalBasisMapping(dossierTemplateId, request.getLegalBases());
}
// file attribute general configuration
if (request.getFileAttributesGeneralConfiguration() != null) {
importStep = 9;
fileAttributeConfigPersistenceService.setFileAttributesGeneralConfig(dossierTemplateId,
convert(request.getFileAttributesGeneralConfiguration(),
FileAttributesGeneralConfigurationEntity.class));
}
// set components
if (CollectionUtils.isNotEmpty(request.getComponentDefinitions())) {
importStep = 10;
for (ComponentDefinition componentDefinition : request.getComponentDefinitions()) {
ComponentDefinitionAddRequest componentDefinitionAddRequest = ComponentDefinitionAddRequest.builder()
.displayName(componentDefinition.getDisplayName())
@ -323,30 +381,23 @@ public class DossierTemplateImportService {
}
}
//set report templates
if (CollectionUtils.isNotEmpty(request.getReportTemplateUploadRequests())) {
request.getReportTemplateUploadRequests()
.forEach(reportRequest -> {
reportRequest.setDossierTemplateId(dossierTemplateId);
reportTemplateService.uploadTemplate(reportRequest);
});
}
// set legal basis
if (CollectionUtils.isNotEmpty(request.getLegalBases())) {
legalBasisMappingPersistenceService.setLegalBasisMapping(dossierTemplateId, request.getLegalBases());
}
}
// file attribute general configuration
if (request.getFileAttributesGeneralConfiguration() != null) {
fileAttributeConfigPersistenceService.setFileAttributesGeneralConfig(dossierTemplateId,
convert(request.getFileAttributesGeneralConfiguration(),
FileAttributesGeneralConfigurationEntity.class));
}
setRulesWhenCompiled(request, dossierTemplateId);
//set component mappings
importStep = 11;
setComponentMappings(dossierTemplateId, request.getComponentMappings());
//set types
importStep = 12;
entityTypeImportService.importEntityTypes(dossierTemplateId, null, request.getEntityTypeImportModel());
}
importStep = 13;
setRulesWhenCompiled(request, dossierTemplateId);
} catch (Exception e) {
throw new BadRequestException("The import process failed in step: " + importStep + " with error: " + e.getMessage());
}
templateImportInfo.setDossierTemplateId(dossierTemplateId);
long elapsedTime = System.currentTimeMillis() - start;
@ -512,7 +563,7 @@ public class DossierTemplateImportService {
request.getFileAttributesConfigs()
.forEach(fa -> {
String initialId = fa.getId();
//check by id or by dossierTemplate and label and set the corresponding Id if found
//check by id or by dossierTemplate and label and set the corresponding id if found
fa.setId(fileAttributeConfigPersistenceService.getFileAttributeByIdOrName(dossierTemplateId, fa.getId(), fa.getLabel()));
FileAttributeConfigEntity fileAttributeAdded = fileAttributeConfigPersistenceService.addOrUpdateFileAttribute(dossierTemplateId,
convert(fa, FileAttributeConfigEntity.class));
@ -542,9 +593,7 @@ public class DossierTemplateImportService {
private void deleteComponents(List<ComponentDefinitionEntity> componentDefinitionEntities) {
componentDefinitionEntities.forEach(componentDefinition -> {
componentDefinitionPersistenceService.delete(componentDefinition.getId());
});
componentDefinitionEntities.forEach(componentDefinition -> componentDefinitionPersistenceService.delete(componentDefinition.getId()));
}

View File

@ -153,6 +153,7 @@ public class DossierTemplateImportTest extends AbstractPersistenceServerServiceT
var e = assertThrows(BadRequestException.class,
() -> dossierTemplateManagementService.importDossierTemplate(request));
assertThat(e.getMessage().contains("The import process failed in step: 13")).isTrue();
var reportTemplates = reportTemplateRepository.findAll();
assertThat(reportTemplates).hasSize(2);
var alldossierTemplates = dossierTemplateManagementService.getAllDossierTemplates();