diff --git a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java index 39e172336..5c887e269 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java +++ b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java @@ -57,6 +57,7 @@ public class AuditableAction { public static final EventId Description_GetFieldFile = new EventId(6008, "Description_GetFieldFile"); public static final EventId Description_Validate = new EventId(6009, "Description_Validate"); public static final EventId Description_GetDescriptionSectionPermissions = new EventId(6010, "Description_GetDescriptionSectionPermissions"); + public static final EventId Description_UpdateDescriptionTemplate = new EventId(6011, "Description_UpdateDescriptionTemplate"); public static final EventId Reference_Query = new EventId(7000, "Reference_Query"); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java index 1b8153f3d..43071c959 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionService.java @@ -4,16 +4,14 @@ import eu.eudat.data.StorageFileEntity; import eu.eudat.model.Description; import eu.eudat.model.DescriptionValidationResult; import eu.eudat.model.StorageFile; -import eu.eudat.model.persist.DescriptionFieldFilePersist; -import eu.eudat.model.persist.DescriptionPersist; -import eu.eudat.model.persist.DescriptionSectionPermissionResolver; -import eu.eudat.model.persist.DescriptionStatusPersist; +import eu.eudat.model.persist.*; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyValidationException; import gr.cite.tools.fieldset.FieldSet; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.multipart.MultipartFile; import javax.management.InvalidApplicationException; @@ -39,4 +37,5 @@ public interface DescriptionService { StorageFile uploadFieldFile(DescriptionFieldFilePersist model, MultipartFile file, FieldSet fields) throws IOException; StorageFileEntity getFieldFile(UUID descriptionId, UUID storageFileId); + void updateDescriptionTemplate(UpdateDescriptionTemplatePersist model) throws InvalidApplicationException, IOException; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java index c4435b141..94faf9248 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java @@ -235,6 +235,54 @@ public class DescriptionServiceImpl implements DescriptionService { this.elasticService.persistDescription(data); return this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, Description._id), data); } + @Override + public void updateDescriptionTemplate(UpdateDescriptionTemplatePersist model) throws InvalidApplicationException, IOException { + logger.debug(new MapLogEntry("update description template").And("model", model)); + + this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.descriptionAffiliation(model.getId())), Permission.EditDescription); + + DescriptionEntity data = this.entityManager.find(DescriptionEntity.class, model.getId()); + if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); + + DescriptionTemplateEntity oldDescriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, data.getDescriptionTemplateId()); + if (oldDescriptionTemplateEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{data.getDescriptionTemplateId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + DmpDescriptionTemplateEntity dmpDescriptionTemplateEntity = this.entityManager.find(DmpDescriptionTemplateEntity.class, data.getDmpDescriptionTemplateId()); + if (dmpDescriptionTemplateEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{data.getDmpDescriptionTemplateId(), DmpDescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + + List latestVersionDescriptionTemplates = this.queryFactory.query(DescriptionTemplateQuery.class) + .versionStatuses(DescriptionTemplateVersionStatus.Current) + .isActive(IsActive.Active) + .groupIds(oldDescriptionTemplateEntity.getGroupId()) + .collect(); + if (latestVersionDescriptionTemplates.isEmpty()) + throw new MyValidationException("New version not found"); + if (latestVersionDescriptionTemplates.size() > 1) + throw new MyValidationException("Multiple template found"); + if (!latestVersionDescriptionTemplates.getFirst().getVersion().equals(oldDescriptionTemplateEntity.getVersion())) + throw new MyValidationException(this.errors.getDescriptionTemplateNewVersionConflict().getCode(), this.errors.getDescriptionTemplateNewVersionConflict().getMessage()); + + data.setDescriptionTemplateId(latestVersionDescriptionTemplates.getFirst().getId()); + + eu.eudat.commons.types.descriptiontemplate.DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(eu.eudat.commons.types.descriptiontemplate.DefinitionEntity.class, latestVersionDescriptionTemplates.getFirst().getDefinition()); + PropertyDefinitionEntity propertyDefinition = this.xmlHandlingService.fromXmlSafe(PropertyDefinitionEntity.class, data.getProperties()); + + data.setUpdatedAt(Instant.now()); + this.entityManager.merge(data); + + this.entityManager.flush(); + + + this.sendNotification(data); + + this.eventBroker.emit(new DescriptionTouchedEvent(data.getId())); + + this.annotationEntityTouchedIntegrationEventHandler.handleDescription(data.getId()); + + this.elasticService.persistDescription(data); + } private void sendNotification(DescriptionEntity description) throws InvalidApplicationException { List existingUsers = this.queryFactory.query(DmpUserQuery.class) @@ -807,6 +855,7 @@ public class DescriptionServiceImpl implements DescriptionService { return storageFile; } + //region build persist private @NotNull DescriptionPersist buildDescriptionPersist(DescriptionEntity data) throws InvalidApplicationException { diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java index bd0e03269..7b15b0ea9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java @@ -270,12 +270,15 @@ public class DescriptionController { } @PostMapping("update-description-template") -// @Transactional + @Transactional @ValidationFilterAnnotation(validator = UpdateDescriptionTemplatePersist.UpdateDescriptionTemplatePersistValidator.ValidatorName, argumentName = "model") public Boolean updateDescriptionTemplate(@RequestBody UpdateDescriptionTemplatePersist model) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, IOException { - logger.debug(new MapLogEntry("persisting" + Description.class.getSimpleName()).And("model", model)); + logger.debug(new MapLogEntry("update description template" + Description.class.getSimpleName()).And("model", model)); + this.descriptionService.updateDescriptionTemplate(model); - // TODO + this.auditService.track(AuditableAction.Description_UpdateDescriptionTemplate, Map.ofEntries( + new AbstractMap.SimpleEntry("model", model) + )); return true; }