From ea58ed2e44c8cc13b145ca06910f726335e970f3 Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 7 Nov 2023 11:09:54 +0200 Subject: [PATCH 1/3] Fix on entity doi entity id, removed reference on Dmps, fix on dmp reference query --- .../java/eu/eudat/data/EntityDoiEntity.java | 9 ++++----- .../eudat/model/builder/EntityDoiBuilder.java | 2 +- .../eu/eudat/query/DmpReferenceQuery.java | 4 ++-- .../java/eu/eudat/query/EntityDoiQuery.java | 19 ++++++++++--------- .../deposit/RepositoryDepositService.java | 2 +- .../entitydoi/EntityDoiServiceImpl.java | 4 +--- .../managers/DataManagementPlanManager.java | 2 +- 7 files changed, 20 insertions(+), 22 deletions(-) diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/EntityDoiEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/EntityDoiEntity.java index 761e043a5..3637bee88 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/EntityDoiEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/EntityDoiEntity.java @@ -53,9 +53,8 @@ public class EntityDoiEntity { public static final String _isActive = "isActive"; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "entity_id", nullable = false) - private DMP entityId; + @Column(name = "entity_id", nullable = false) + private UUID entityId; public static final String _entityId = "entityId"; @@ -115,11 +114,11 @@ public class EntityDoiEntity { this.isActive = isActive; } - public DMP getEntityId() { + public UUID getEntityId() { return entityId; } - public void setEntityId(DMP entityId) { + public void setEntityId(UUID entityId) { this.entityId = entityId; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/EntityDoiBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/EntityDoiBuilder.java index 0dbe42042..a4cff8bd7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/EntityDoiBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/EntityDoiBuilder.java @@ -48,7 +48,7 @@ public class EntityDoiBuilder extends BaseBuilder { if (fields.hasField(this.asIndexer(EntityDoi._doi))) m.setDoi(d.getDoi()); if (fields.hasField(this.asIndexer(EntityDoi._entityId))) - m.setEntityId(d.getEntityId().getId()); + m.setEntityId(d.getEntityId()); if (fields.hasField(this.asIndexer(EntityDoi._entityType))) m.setEntityType(d.getEntityType()); if (fields.hasField(this.asIndexer(EntityDoi._repositoryId))) diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpReferenceQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpReferenceQuery.java index 72c837fe3..497a2c350 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DmpReferenceQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpReferenceQuery.java @@ -120,7 +120,7 @@ public class DmpReferenceQuery extends QueryBase { } if (this.referenceIds != null) { CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpReferenceEntity._referenceId)); - for (UUID item : this.ids) + for (UUID item : this.referenceIds) inClause.value(item); predicates.add(inClause); } @@ -136,7 +136,7 @@ public class DmpReferenceQuery extends QueryBase { protected DmpReferenceEntity convert(Tuple tuple, Set columns) { DmpReferenceEntity item = new DmpReferenceEntity(); item.setId(QueryBase.convertSafe(tuple, columns, DmpReferenceEntity._id, UUID.class)); - item.setReferenceId(QueryBase.convertSafe(tuple, columns, DmpReferenceEntity._dmpId, UUID.class)); + item.setDmpId(QueryBase.convertSafe(tuple, columns, DmpReferenceEntity._dmpId, UUID.class)); item.setReferenceId(QueryBase.convertSafe(tuple, columns, DmpReferenceEntity._referenceId, UUID.class)); item.setData(QueryBase.convertSafe(tuple, columns, DmpReferenceEntity._data, String.class)); item.setCreatedAt(QueryBase.convertSafe(tuple, columns, DmpReferenceEntity._createdAt, Instant.class)); diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/EntityDoiQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/EntityDoiQuery.java index b03ca28cc..46541a002 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/EntityDoiQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/EntityDoiQuery.java @@ -6,6 +6,7 @@ import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.scope.user.UserScope; import eu.eudat.data.EntityDoiEntity; import eu.eudat.data.old.DMP; +import eu.eudat.model.EntityDoi; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; @@ -211,7 +212,7 @@ public class EntityDoiQuery extends QueryBase { item.setId(QueryBase.convertSafe(tuple, columns, EntityDoiEntity._id, UUID.class)); item.setDoi(QueryBase.convertSafe(tuple, columns, EntityDoiEntity._doi, String.class)); item.setRepositoryId(QueryBase.convertSafe(tuple, columns, EntityDoiEntity._repositoryId, String.class)); - item.setEntityId(QueryBase.convertSafe(tuple, columns, EntityDoiEntity._entityId, DMP.class)); + item.setEntityId(QueryBase.convertSafe(tuple, columns, EntityDoiEntity._entityId, UUID.class)); item.setEntityType(QueryBase.convertSafe(tuple, columns, EntityDoiEntity._entityType, EntityType.class)); item.setCreatedAt(QueryBase.convertSafe(tuple, columns, EntityDoiEntity._createdAt, Instant.class)); item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, EntityDoiEntity._updatedAt, Instant.class)); @@ -221,21 +222,21 @@ public class EntityDoiQuery extends QueryBase { @Override protected String fieldNameOf(FieldResolver item) { - if (item.match(EntityDoiEntity._id)) + if (item.match(EntityDoi._id)) return EntityDoiEntity._id; - else if (item.match(EntityDoiEntity._doi)) + else if (item.match(EntityDoi._doi)) return EntityDoiEntity._doi; - else if (item.match(EntityDoiEntity._repositoryId)) + else if (item.match(EntityDoi._repositoryId)) return EntityDoiEntity._repositoryId; - else if (item.match(EntityDoiEntity._entityId)) + else if (item.match(EntityDoi._entityId)) return EntityDoiEntity._entityId; - else if (item.match(EntityDoiEntity._entityType)) + else if (item.match(EntityDoi._entityType)) return EntityDoiEntity._entityType; - else if (item.match(EntityDoiEntity._createdAt)) + else if (item.match(EntityDoi._createdAt)) return EntityDoiEntity._createdAt; - else if (item.match(EntityDoiEntity._updatedAt)) + else if (item.match(EntityDoi._updatedAt)) return EntityDoiEntity._updatedAt; - else if (item.match(EntityDoiEntity._isActive)) + else if (item.match(EntityDoi._isActive)) return EntityDoiEntity._isActive; else return null; diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java index d66581e7b..7014175eb 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java @@ -203,7 +203,7 @@ public class RepositoryDepositService { if (uuid.equals(currentId)) continue; doiEntity = dois.stream() - .filter(entityDoiEntity -> entityDoiEntity.getEntityId().getId().equals(uuid)).findFirst().orElse(null); + .filter(entityDoiEntity -> entityDoiEntity.getEntityId().equals(uuid)).findFirst().orElse(null); if (doiEntity != null) break; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/entitydoi/EntityDoiServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/entitydoi/EntityDoiServiceImpl.java index d17a2f439..149b36064 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/entitydoi/EntityDoiServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/entitydoi/EntityDoiServiceImpl.java @@ -100,9 +100,7 @@ public class EntityDoiServiceImpl implements EntityDoiService { } data.setEntityType(EntityType.DMP); - DMP dmp = new DMP(); - dmp.setId(model.getEntityId()); - data.setEntityId(dmp); + data.setEntityId(model.getEntityId()); data.setRepositoryId(model.getRepositoryId()); data.setDoi(model.getDoi()); data.setUpdatedAt(Instant.now()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 276770177..22137afbf 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -2556,7 +2556,7 @@ public class DataManagementPlanManager { doiEntity.setRepositoryId(depositRequest.getRepositoryId()); doiEntity.setCreatedAt(Instant.now()); doiEntity.setUpdatedAt(Instant.now()); - doiEntity.setEntityId(dmp); + doiEntity.setEntityId(dmp.getId()); //TODO: Save doi // apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().createOrUpdate(doiEntity); From ee68224f5838e92eb719082864617e203ca0361f Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 7 Nov 2023 12:12:14 +0200 Subject: [PATCH 2/3] Added DmpUser table and stack --- .../eu/eudat/commons/enums/DmpUserRole.java | 30 +++ .../java/eu/eudat/data/DmpUserEntity.java | 108 +++++++++++ .../enums/DmpUserRoleConverter.java | 14 ++ .../src/main/java/eu/eudat/model/DmpUser.java | 103 ++++++++++ .../eudat/model/builder/DmpUserBuilder.java | 143 ++++++++++++++ .../eudat/model/deleter/DmpUserDeleter.java | 76 ++++++++ .../java/eu/eudat/query/DmpUserQuery.java | 182 ++++++++++++++++++ ...012_Add_Dmp_description_template_table.sql | 2 +- .../updates/00.01.013_Add_Dmp_User_table.sql | 25 +++ 9 files changed, 682 insertions(+), 1 deletion(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/enums/DmpUserRole.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/data/DmpUserEntity.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DmpUserRoleConverter.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/DmpUser.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpUserBuilder.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpUserDeleter.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java create mode 100644 dmp-db-scema/updates/00.01.013_Add_Dmp_User_table.sql diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/DmpUserRole.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/DmpUserRole.java new file mode 100644 index 000000000..c7e4721e3 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/DmpUserRole.java @@ -0,0 +1,30 @@ +package eu.eudat.commons.enums; + +import com.fasterxml.jackson.annotation.JsonValue; +import eu.eudat.data.converters.enums.DatabaseEnum; + +import java.util.Map; + +public enum DmpUserRole implements DatabaseEnum { + + Owner((short) 0), User((short) 1); + + private final Short value; + + DmpUserRole(Short value) { + this.value = value; + } + + @Override + @JsonValue + public Short getValue() { + return value; + } + + private static final Map map = EnumUtils.getEnumValueMap(DmpUserRole.class); + + public static DmpUserRole of(Short i) { + return map.get(i); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/DmpUserEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/DmpUserEntity.java new file mode 100644 index 000000000..45037d81a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/DmpUserEntity.java @@ -0,0 +1,108 @@ +package eu.eudat.data; + +import eu.eudat.commons.enums.DmpUserRole; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.converters.enums.IsActiveConverter; +import jakarta.persistence.*; + +import java.time.Instant; +import java.util.UUID; + +@Table(name = "\"DmpUser\"") +public class DmpUserEntity { + + @Id + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + public static final String _id = "id"; + + @Column(name = "dmp", columnDefinition = "uuid", nullable = false) + private UUID dmp; + + public static final String _dmp = "dmp"; + + @Column(name = "user", columnDefinition = "uuid", nullable = false) + private UUID user; + + public static final String _user = "user"; + + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false) + private DmpUserRole role; + + public static final String _role = "role"; + + @Column(name = "created_at", nullable = false) + private Instant createdAt; + + public static final String _createdAt = "createdAt"; + + @Column(name = "updated_at", nullable = false) + private Instant updatedAt; + + public static final String _updatedAt = "updatedAt"; + + @Column(name = "is_active", nullable = false) + @Convert(converter = IsActiveConverter.class) + private IsActive isActive; + + public static final String _isActive = "isActive"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getDmp() { + return dmp; + } + + public void setDmp(UUID dmp) { + this.dmp = dmp; + } + + public UUID getUser() { + return user; + } + + public void setUser(UUID user) { + this.user = user; + } + + public DmpUserRole getRole() { + return role; + } + + public void setRole(DmpUserRole role) { + this.role = role; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DmpUserRoleConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DmpUserRoleConverter.java new file mode 100644 index 000000000..9fe2878f6 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DmpUserRoleConverter.java @@ -0,0 +1,14 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.DmpUserRole; +import jakarta.persistence.Converter; + +@Converter +public class DmpUserRoleConverter extends DatabaseEnumConverter { + + @Override + protected DmpUserRole of(Short i) { + return DmpUserRole.of(i); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/DmpUser.java b/dmp-backend/core/src/main/java/eu/eudat/model/DmpUser.java new file mode 100644 index 000000000..d2d22b2ca --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/DmpUser.java @@ -0,0 +1,103 @@ +package eu.eudat.model; + +import eu.eudat.commons.enums.DmpUserRole; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.converters.enums.IsActiveConverter; +import eu.eudat.data.old.UserInfo; +import jakarta.persistence.*; + +import java.time.Instant; +import java.util.UUID; + +public class DmpUser { + + private UUID id; + + public static final String _id = "id"; + + private Dmp dmp; + + public static final String _dmp = "dmp"; + + @Column(name = "user", columnDefinition = "uuid", nullable = false) + private UserInfo user; + + public static final String _user = "user"; + + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false) + private DmpUserRole role; + + public static final String _role = "role"; + + @Column(name = "created_at", nullable = false) + private Instant createdAt; + + public static final String _createdAt = "createdAt"; + + @Column(name = "updated_at", nullable = false) + private Instant updatedAt; + + public static final String _updatedAt = "updatedAt"; + + @Column(name = "is_active", nullable = false) + @Convert(converter = IsActiveConverter.class) + private IsActive isActive; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public Dmp getDmp() { + return dmp; + } + + public void setDmp(Dmp dmp) { + this.dmp = dmp; + } + + public UserInfo getUser() { + return user; + } + + public void setUser(UserInfo user) { + this.user = user; + } + + public DmpUserRole getRole() { + return role; + } + + public void setRole(DmpUserRole role) { + this.role = role; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpUserBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpUserBuilder.java new file mode 100644 index 000000000..a0d34b4c5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpUserBuilder.java @@ -0,0 +1,143 @@ +package eu.eudat.model.builder; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DmpUserEntity; +import eu.eudat.data.old.UserInfo; +import eu.eudat.model.Dmp; +import eu.eudat.model.DmpUser; +import eu.eudat.model.Reference; +import eu.eudat.query.DmpQuery; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.fieldset.BaseFieldSet; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DmpUserBuilder extends BaseBuilder{ + + private final BuilderFactory builderFactory; + + private final QueryFactory queryFactory; + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public DmpUserBuilder( + ConventionService conventionService, + BuilderFactory builderFactory, QueryFactory queryFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(DmpUserBuilder.class))); + this.builderFactory = builderFactory; + this.queryFactory = queryFactory; + } + + public DmpUserBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + + @Override + public List build(FieldSet fields, List data) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || data == null || fields.isEmpty()) + return new ArrayList<>(); + + FieldSet userFields = fields.extractPrefixed(this.asPrefix(DmpUser._user)); + Map userItemsMap = this.collectUsers(userFields, data); + + FieldSet dmpFields = fields.extractPrefixed(this.asPrefix(DmpUser._dmp)); + Map dmpItemsMap = this.collectDmps(dmpFields, data); + + List models = new ArrayList<>(); + for (DmpUserEntity d : data) { + DmpUser m = new DmpUser(); + if (fields.hasField(this.asIndexer(DmpUser._id))) + m.setId(d.getId()); + if (fields.hasField(this.asIndexer(DmpUser._role))) + m.setRole(d.getRole()); + if (fields.hasField(this.asIndexer(DmpUser._createdAt))) + m.setCreatedAt(d.getCreatedAt()); + if (fields.hasField(this.asIndexer(DmpUser._updatedAt))) + m.setUpdatedAt(d.getUpdatedAt()); + if (!userFields.isEmpty() && userItemsMap != null && userItemsMap.containsKey(d.getUser())) { + m.setUser(userItemsMap.get(d.getUser())); + } + if (!dmpFields.isEmpty() && dmpItemsMap != null && dmpItemsMap.containsKey(d.getDmp())) { + m.setDmp(dmpItemsMap.get(d.getDmp())); + } + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + + //TODO: Hookup user info when refactored + private Map collectUsers(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) + return null; + this.logger.debug("checking related - {}", UserInfo.class.getSimpleName()); + + Map itemMap; + if (!fields.hasOtherField(this.asIndexer("id"))) { + itemMap = this.asEmpty( + data.stream().map(DmpUserEntity::getUser).distinct().collect(Collectors.toList()), + x -> { + UserInfo item = new UserInfo(); + item.setId(x); + return item; + }, + UserInfo::getId); + } else { + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure("id"); +// ReferenceQuery q = this.queryFactory.query(ReferenceQuery.class).authorize(this.authorize).ids(data.stream().map(DmpReferenceEntity::getReferenceId).distinct().collect(Collectors.toList())); +// itemMap = this.builderFactory.builder(ReferenceBuilder.class).authorize(this.authorize).asForeignKey(q, clone, Reference::getId); + } + if (!fields.hasField(Reference._id)) { +// itemMap.values().stream().filter(Objects::nonNull).peek(x -> x.setId(null)).collect(Collectors.toList()); + } + +// return itemMap; + return new HashMap<>(); + } + + private Map collectDmps(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) + return null; + this.logger.debug("checking related - {}", Dmp.class.getSimpleName()); + + Map itemMap; + if (!fields.hasOtherField(this.asIndexer(Dmp._id))) { + itemMap = this.asEmpty( + data.stream().map(DmpUserEntity::getDmp).distinct().collect(Collectors.toList()), + x -> { + Dmp item = new Dmp(); + item.setId(x); + return item; + }, + Dmp::getId); + } else { + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(Dmp._id); + DmpQuery q = this.queryFactory.query(DmpQuery.class).authorize(this.authorize).ids(data.stream().map(DmpUserEntity::getDmp).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(DmpBuilder.class).authorize(this.authorize).asForeignKey(q, clone, Dmp::getId); + } + if (!fields.hasField(Dmp._id)) { + itemMap.values().stream().filter(Objects::nonNull).peek(x -> x.setId(null)).collect(Collectors.toList()); + } + + return itemMap; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpUserDeleter.java b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpUserDeleter.java new file mode 100644 index 000000000..c1771a37a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpUserDeleter.java @@ -0,0 +1,76 @@ +package eu.eudat.model.deleter; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.DmpUserEntity; +import eu.eudat.query.DmpUserQuery; +import gr.cite.tools.data.deleter.Deleter; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DmpUserDeleter implements Deleter { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpUserDeleter.class)); + private final EntityManager entityManager; + + protected final QueryFactory queryFactory; + + protected final DeleterFactory deleterFactory; + + @Autowired + public DmpUserDeleter( + EntityManager entityManager, + QueryFactory queryFactory, + DeleterFactory deleterFactory + ) { + this.entityManager = entityManager; + this.queryFactory = queryFactory; + this.deleterFactory = deleterFactory; + } + + public void deleteAndSaveByIds(List ids) throws InvalidApplicationException { + logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids)); + List data = this.queryFactory.query(DmpUserQuery.class).ids(ids).collect(); + logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.deleteAndSave(data); + } + + public void deleteAndSave(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.delete(data); + logger.trace("saving changes"); + this.entityManager.flush(); + logger.trace("changes saved"); + } + + public void delete(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + if (data == null || data.isEmpty()) + return; + + for (DmpUserEntity item : data) { + logger.trace("deleting item {}", item.getId()); + logger.trace("updating item"); + item.setUpdatedAt(Instant.now()); + item.setIsActive(IsActive.Inactive); + this.entityManager.merge(item); + logger.trace("updated item"); + } + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java new file mode 100644 index 000000000..262b7480b --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java @@ -0,0 +1,182 @@ +package eu.eudat.query; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.DmpUserRole; +import eu.eudat.commons.scope.user.UserScope; +import eu.eudat.data.DmpUserEntity; +import eu.eudat.model.DmpUser; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryBase; +import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.Tuple; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Predicate; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DmpUserQuery extends QueryBase { + + private Collection ids; + + private Collection dmpIds; + + private Collection userIds; + + private Collection userRoles; + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + + public DmpUserQuery ids(UUID value) { + this.ids = List.of(value); + return this; + } + + public DmpUserQuery ids(UUID... value) { + this.ids = Arrays.asList(value); + return this; + } + + public DmpUserQuery ids(Collection values) { + this.ids = values; + return this; + } + + public DmpUserQuery dmpIds(UUID value) { + this.dmpIds = List.of(value); + return this; + } + + public DmpUserQuery dmpIds(UUID... value) { + this.dmpIds = Arrays.asList(value); + return this; + } + + public DmpUserQuery dmpIds(Collection values) { + this.dmpIds = values; + return this; + } + + public DmpUserQuery userRoles(DmpUserRole value) { + this.userRoles = List.of(value); + return this; + } + + public DmpUserQuery userRoles(DmpUserRole... value) { + this.userRoles = Arrays.asList(value); + return this; + } + + public DmpUserQuery userRoles(Collection values) { + this.userRoles = values; + return this; + } + + public DmpUserQuery userIds(UUID value) { + this.userIds = List.of(value); + return this; + } + + public DmpUserQuery userIds(UUID... value) { + this.userIds = Arrays.asList(value); + return this; + } + + public DmpUserQuery userIds(Collection values) { + this.userIds = values; + return this; + } + + public DmpUserQuery authorize(EnumSet values) { + this.authorize = values; + return this; + } + + private final UserScope userScope; + + private final AuthorizationService authService; + + public DmpUserQuery( + UserScope userScope, + AuthorizationService authService + ) { + this.userScope = userScope; + this.authService = authService; + } + + @Override + protected Class entityClass() { + return DmpUserEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return this.isEmpty(this.ids) || this.isEmpty(this.dmpIds) || this.isEmpty(this.userIds); + } + + @Override + protected Predicate applyFilters(QueryContext queryContext) { + List predicates = new ArrayList<>(); + if (this.ids != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpUserEntity._id)); + for (UUID item : this.ids) + inClause.value(item); + predicates.add(inClause); + } + if (this.dmpIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpUserEntity._dmp)); + for (UUID item : this.dmpIds) + inClause.value(item); + predicates.add(inClause); + } + if (this.userIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpUserEntity._user)); + for (UUID item : this.userIds) + inClause.value(item); + predicates.add(inClause); + } + if (this.userRoles != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpUserEntity._role)); + for (DmpUserRole item : this.userRoles) + inClause.value(item); + predicates.add(inClause); + } + if (!predicates.isEmpty()) { + Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); + return queryContext.CriteriaBuilder.and(predicatesArray); + } else { + return null; + } + } + + @Override + protected DmpUserEntity convert(Tuple tuple, Set columns) { + DmpUserEntity item = new DmpUserEntity(); + item.setId(QueryBase.convertSafe(tuple, columns, DmpUserEntity._id, UUID.class)); + item.setDmp(QueryBase.convertSafe(tuple, columns, DmpUserEntity._dmp, UUID.class)); + item.setUser(QueryBase.convertSafe(tuple, columns, DmpUserEntity._user, UUID.class)); + item.setRole(QueryBase.convertSafe(tuple, columns, DmpUserEntity._role, DmpUserRole.class)); + item.setCreatedAt(QueryBase.convertSafe(tuple, columns, DmpUserEntity._createdAt, Instant.class)); + item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, DmpUserEntity._updatedAt, Instant.class)); + return item; + } + + @Override + protected String fieldNameOf(FieldResolver item) { + if (item.match(DmpUser._id)) return DmpUserEntity._id; + else if (item.prefix(DmpUser._dmp)) return DmpUserEntity._dmp; + else if (item.prefix(DmpUser._user)) return DmpUserEntity._user; + else if (item.match(DmpUser._role)) return DmpUserEntity._role; + else if (item.match(DmpUser._createdAt)) return DmpUserEntity._createdAt; + else if (item.match(DmpUser._updatedAt)) return DmpUserEntity._updatedAt; + else return null; + } + +} diff --git a/dmp-db-scema/updates/00.01.012_Add_Dmp_description_template_table.sql b/dmp-db-scema/updates/00.01.012_Add_Dmp_description_template_table.sql index 2a5f6e5b6..21ff5a190 100644 --- a/dmp-db-scema/updates/00.01.012_Add_Dmp_description_template_table.sql +++ b/dmp-db-scema/updates/00.01.012_Add_Dmp_description_template_table.sql @@ -13,7 +13,7 @@ CREATE TABLE IF NOT EXISTS public."DmpDescriptionTemplate" "created_at" timestamp without time zone NOT NULL DEFAULT now(), "updated_at" timestamp without time zone NOT NULL DEFAULT now(), "is_active" smallint NOT NULL DEFAULT 1, - CONSTRAINT id PRIMARY KEY (id), + CONSTRAINT "DmpDescriptionTemplate_pkey" PRIMARY KEY (id), CONSTRAINT "DmpDescriptionTemplate_dmp_fkey" FOREIGN KEY (dmp) REFERENCES public."Dmp" (id), CONSTRAINT "DmpDescriptionTemplate_description_template_fkey" FOREIGN KEY (description_template) diff --git a/dmp-db-scema/updates/00.01.013_Add_Dmp_User_table.sql b/dmp-db-scema/updates/00.01.013_Add_Dmp_User_table.sql new file mode 100644 index 000000000..be1f00b64 --- /dev/null +++ b/dmp-db-scema/updates/00.01.013_Add_Dmp_User_table.sql @@ -0,0 +1,25 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.01.013'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +CREATE TABLE IF NOT EXISTS public."DmpUser" +( + "id" uuid NOT NULL, + "dmp" uuid NOT NULL, + "user" uuid NOT NULL, + "role" smallint NOT NULL DEFAULT 0, + "created_at" timestamp without time zone NOT NULL DEFAULT now(), + "updated_at" timestamp without time zone NOT NULL DEFAULT now(), + "is_active" smallint NOT NULL DEFAULT 1, + CONSTRAINT "DmpUser_pkey" PRIMARY KEY (id), + CONSTRAINT "DmpUser_dmp_fkey" FOREIGN KEY ("dmp") + REFERENCES public."Dmp" (id), + CONSTRAINT "DmpUser_user_fkey" FOREIGN KEY ("user") + REFERENCES public."UserInfo" (id) +) + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.013', '2023-11-07 12:00:00.000000+02', now(), 'Add Dmp User table (former UserDMP).'); + +END$$; \ No newline at end of file From f87860160901972d835359d18256f4c2f09c1827 Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 7 Nov 2023 12:28:40 +0200 Subject: [PATCH 3/3] Added missing converter annotations on entity enums --- dmp-backend/core/src/main/java/eu/eudat/data/DmpEntity.java | 3 ++- .../core/src/main/java/eu/eudat/data/DmpUserEntity.java | 3 ++- .../core/src/main/java/eu/eudat/data/EntityDoiEntity.java | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/DmpEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/DmpEntity.java index bb26c7b87..27bd32e3e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/DmpEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/DmpEntity.java @@ -4,6 +4,7 @@ import eu.eudat.commons.enums.DmpAccessType; import eu.eudat.commons.enums.DmpStatus; import eu.eudat.commons.enums.IsActive; import eu.eudat.data.converters.DateToUTCConverter; +import eu.eudat.data.converters.enums.DmpStatusConverter; import eu.eudat.data.converters.enums.IsActiveConverter; import jakarta.persistence.*; @@ -30,8 +31,8 @@ public class DmpEntity { public static final String _version = "version"; - @Enumerated(EnumType.STRING) @Column(name = "status", nullable = false) + @Convert(converter = DmpStatusConverter.class) private DmpStatus status; public static final String _status = "status"; diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/DmpUserEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/DmpUserEntity.java index 45037d81a..39c0dc146 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/DmpUserEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/DmpUserEntity.java @@ -2,6 +2,7 @@ package eu.eudat.data; import eu.eudat.commons.enums.DmpUserRole; import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.converters.enums.DmpUserRoleConverter; import eu.eudat.data.converters.enums.IsActiveConverter; import jakarta.persistence.*; @@ -27,8 +28,8 @@ public class DmpUserEntity { public static final String _user = "user"; - @Enumerated(EnumType.STRING) @Column(name = "status", nullable = false) + @Convert(converter = DmpUserRoleConverter.class) private DmpUserRole role; public static final String _role = "role"; diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/EntityDoiEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/EntityDoiEntity.java index 3637bee88..2fd0edb7a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/EntityDoiEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/EntityDoiEntity.java @@ -3,6 +3,7 @@ package eu.eudat.data; import eu.eudat.commons.enums.EntityType; import eu.eudat.commons.enums.IsActive; import eu.eudat.data.converters.DateToUTCConverter; +import eu.eudat.data.converters.enums.EntityTypeConverter; import eu.eudat.data.converters.enums.IsActiveConverter; import eu.eudat.data.old.DMP; import jakarta.persistence.*; @@ -21,8 +22,8 @@ public class EntityDoiEntity { public static final String _id = "id"; - @Enumerated(EnumType.STRING) @Column(name = "entity_type", nullable = false) + @Convert(converter = EntityTypeConverter.class) private EntityType entityType; public static final String _entityType = "entityType";