From 2fb99d2fe7673a1507830d1330a97ad51be3d3af Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Tue, 5 Dec 2023 16:05:37 +0200 Subject: [PATCH] add getMyRecentActivityItems --- .../java/eu/eudat/audit/AuditableAction.java | 2 + .../commons/enums/RecentActivityItemType.java | 31 ++++ .../commons/enums/RecentActivityOrder.java | 31 ++++ .../dashborad/RecentActivityItemEntity.java | 62 +++++++ .../java/eu/eudat/data/DmpUserEntity.java | 12 +- .../elasticbuilder/DmpElasticBuilder.java | 4 +- .../nested/NestedDmpElasticBuilder.java | 4 +- .../query/DescriptionElasticQuery.java | 2 +- .../query/NestedCollaboratorElasticQuery.java | 26 ++- .../eu/eudat/model/RecentActivityItem.java | 46 +++++ .../eudat/model/RecentActivityItemLookup.java | 135 ++++++++++++++ .../eudat/model/builder/DmpUserBuilder.java | 7 +- .../model/builder/PublicDmpUserBuilder.java | 7 +- .../builder/RecentActivityItemBuilder.java | 132 ++++++++++++++ .../censorship/RecentActivityItemCensor.java | 45 +++++ .../java/eu/eudat/query/DescriptionQuery.java | 2 +- .../main/java/eu/eudat/query/DmpQuery.java | 17 +- .../java/eu/eudat/query/DmpUserQuery.java | 8 +- .../java/eu/eudat/query/lookup/DmpLookup.java | 12 ++ .../eu/eudat/query/lookup/DmpUserLookup.java | 87 +++++++++ .../query/utils/QueryUtilsServiceImpl.java | 2 +- .../service/dashborad/DashboardService.java | 11 ++ .../dashborad/DashboardServiceImpl.java | 167 ++++++++++++++++++ .../eu/eudat/service/dmp/DmpServiceImpl.java | 12 +- .../ElasticQueryHelperServiceImpl.java | 2 +- .../controllers/v2/DashboardController.java | 92 ++++++++++ .../managers/DataManagementPlanManager.java | 4 +- .../logic/managers/QuickWizardManager.java | 2 +- 28 files changed, 924 insertions(+), 40 deletions(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/enums/RecentActivityItemType.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/enums/RecentActivityOrder.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/types/dashborad/RecentActivityItemEntity.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/RecentActivityItem.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/RecentActivityItemLookup.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/builder/RecentActivityItemBuilder.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/censorship/RecentActivityItemCensor.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpUserLookup.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardService.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardServiceImpl.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DashboardController.java 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 b6c83a378..b7dbf52ef 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 @@ -93,5 +93,7 @@ public class AuditableAction { public static final EventId StorageFile_Download = new EventId(14000, "StorageFile_Download"); public static final EventId StorageFile_Upload = new EventId(14001, "StorageFile_Upload"); + public static final EventId Dashboard_MyRecentActivityItems = new EventId(15000, "Dashboard_MyRecentActivityItems"); + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/RecentActivityItemType.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/RecentActivityItemType.java new file mode 100644 index 000000000..c969946bf --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/RecentActivityItemType.java @@ -0,0 +1,31 @@ +package eu.eudat.commons.enums; + +import com.fasterxml.jackson.annotation.JsonValue; +import eu.eudat.data.converters.enums.DatabaseEnum; + +import java.util.Map; + +public enum RecentActivityItemType implements DatabaseEnum { + + Dmp((short) 0), + Description((short) 1); + + private final Short value; + + RecentActivityItemType(Short value) { + this.value = value; + } + + @Override + @JsonValue + public Short getValue() { + return value; + } + + private static final Map map = EnumUtils.getEnumValueMap(RecentActivityItemType.class); + + public static RecentActivityItemType of(Short i) { + return map.get(i); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/RecentActivityOrder.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/RecentActivityOrder.java new file mode 100644 index 000000000..0e4b27603 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/RecentActivityOrder.java @@ -0,0 +1,31 @@ +package eu.eudat.commons.enums; + +import com.fasterxml.jackson.annotation.JsonValue; +import eu.eudat.data.converters.enums.DatabaseEnum; + +import java.util.Map; + +public enum RecentActivityOrder implements DatabaseEnum { + UpdatedAt((short) 0), + Label((short) 1), + Status((short) 2); + + private final Short value; + + RecentActivityOrder(Short value) { + this.value = value; + } + + @Override + @JsonValue + public Short getValue() { + return value; + } + + private static final Map map = EnumUtils.getEnumValueMap(RecentActivityOrder.class); + + public static RecentActivityOrder of(Short i) { + return map.get(i); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/dashborad/RecentActivityItemEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/dashborad/RecentActivityItemEntity.java new file mode 100644 index 000000000..f6b23a5c4 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/dashborad/RecentActivityItemEntity.java @@ -0,0 +1,62 @@ +package eu.eudat.commons.types.dashborad; + +import eu.eudat.commons.enums.RecentActivityItemType; + +import java.time.Instant; +import java.util.UUID; + +public class RecentActivityItemEntity { + private RecentActivityItemType type; + private UUID id; + private Instant updatedAt; + private String label; + private Short statusValue; + + public RecentActivityItemEntity(RecentActivityItemType type, UUID id, Instant updatedAt, String label, Short statusValue) { + this.type = type; + this.id = id; + this.updatedAt = updatedAt; + this.label = label; + this.statusValue = statusValue; + } + + public RecentActivityItemType getType() { + return type; + } + + public void setType(RecentActivityItemType type) { + this.type = type; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public Short getStatusValue() { + return statusValue; + } + + public void setStatusValue(Short statusValue) { + this.statusValue = statusValue; + } +} 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 232470c21..56d7dbb2d 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 @@ -20,9 +20,9 @@ public class DmpUserEntity { public static final String _id = "id"; @Column(name = "dmp", columnDefinition = "uuid", nullable = false) - private UUID dmp; + private UUID dmpId; - public static final String _dmp = "dmp"; + public static final String _dmpId = "dmpId"; @Column(name = "\"user\"", columnDefinition = "uuid", nullable = false) private UUID userId; @@ -59,12 +59,12 @@ public class DmpUserEntity { this.id = id; } - public UUID getDmp() { - return dmp; + public UUID getDmpId() { + return dmpId; } - public void setDmp(UUID dmp) { - this.dmp = dmp; + public void setDmpId(UUID dmpId) { + this.dmpId = dmpId; } public UUID getUserId() { diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DmpElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DmpElasticBuilder.java index ee37e23ad..15588a0f3 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DmpElasticBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/DmpElasticBuilder.java @@ -136,9 +136,9 @@ public class DmpElasticBuilder extends BaseElasticBuilder> itemMap = new HashMap<>(); for (DmpUserEntity associationEntity : associationEntities){ - if (!itemMap.containsKey(associationEntity.getId())) itemMap.put(associationEntity.getDmp(), new ArrayList<>()); + if (!itemMap.containsKey(associationEntity.getId())) itemMap.put(associationEntity.getDmpId(), new ArrayList<>()); NestedCollaboratorElasticEntity item = itemMapById.getOrDefault(associationEntity.getId(), null); - if (item != null) itemMap.get(associationEntity.getDmp()).add(item); + if (item != null) itemMap.get(associationEntity.getDmpId()).add(item); } return itemMap; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDmpElasticBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDmpElasticBuilder.java index 55f63fd58..83e3151eb 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDmpElasticBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/elasticbuilder/nested/NestedDmpElasticBuilder.java @@ -106,9 +106,9 @@ public class NestedDmpElasticBuilder extends BaseElasticBuilder> itemMap = new HashMap<>(); for (DmpUserEntity associationEntity : associationEntities){ - if (!itemMap.containsKey(associationEntity.getId())) itemMap.put(associationEntity.getDmp(), new ArrayList<>()); + if (!itemMap.containsKey(associationEntity.getId())) itemMap.put(associationEntity.getDmpId(), new ArrayList<>()); NestedCollaboratorElasticEntity item = itemMapById.getOrDefault(associationEntity.getId(), null); - if (item != null) itemMap.get(associationEntity.getDmp()).add(item); + if (item != null) itemMap.get(associationEntity.getDmpId()).add(item); } return itemMap; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DescriptionElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DescriptionElasticQuery.java index 50fa03fb1..d2c50d363 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DescriptionElasticQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/DescriptionElasticQuery.java @@ -207,7 +207,7 @@ public class DescriptionElasticQuery extends ElasticQuery x.getValue()).collect(Collectors.toList()).toArray(new Short[statuses.size()]))._toQuery()); + predicates.add(this.contains(this.elasticFieldOf(DescriptionElasticEntity._status), statuses.stream().map(DescriptionStatus::getValue).toList().toArray(new Short[statuses.size()]))._toQuery()); } if (this.finalizedAfter != null) { predicates.add(this.dateGreaterThanQuery(this.elasticFieldOf(DescriptionElasticEntity._finalizedAt), this.finalizedAfter)._toQuery()); diff --git a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedCollaboratorElasticQuery.java b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedCollaboratorElasticQuery.java index 05b41f4fa..0a4e52f50 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedCollaboratorElasticQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/elastic/query/NestedCollaboratorElasticQuery.java @@ -1,7 +1,9 @@ package eu.eudat.elastic.query; import co.elastic.clients.elasticsearch._types.query_dsl.Query; +import eu.eudat.commons.enums.DescriptionStatus; import eu.eudat.commons.enums.DmpUserRole; +import eu.eudat.elastic.data.DescriptionElasticEntity; import eu.eudat.elastic.data.DmpElasticEntity; import eu.eudat.elastic.data.nested.NestedCollaboratorElasticEntity; import gr.cite.tools.data.query.FieldResolver; @@ -21,6 +23,9 @@ import java.util.stream.Collectors; @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class NestedCollaboratorElasticQuery extends ElasticNestedQuery { private Collection ids; + + + private Collection userRoles; public NestedCollaboratorElasticQuery ids(UUID value) { this.ids = List.of(value); @@ -36,6 +41,21 @@ public class NestedCollaboratorElasticQuery extends ElasticNestedQuery values) { + this.userRoles = values; + return this; + } private String nestedPath; @Override @@ -59,7 +79,7 @@ public class NestedCollaboratorElasticQuery extends ElasticNestedQuery userIds; + private Paging page; + private BaseFieldSet project; + private RecentActivityOrder orderField; + + public String getLike() { + return like; + } + + public void setLike(String like) { + this.like = like; + } + + public Boolean getOnlyDraft() { + return onlyDraft; + } + + public void setOnlyDraft(Boolean onlyDraft) { + this.onlyDraft = onlyDraft; + } + + public List getUserIds() { + return userIds; + } + + public void setUserIds(List userIds) { + this.userIds = userIds; + } + + public Paging getPage() { + return page; + } + + public void setPage(Paging page) { + this.page = page; + } + + public BaseFieldSet getProject() { + return project; + } + + public void setProject(BaseFieldSet project) { + this.project = project; + } + + public RecentActivityOrder getOrderField() { + return orderField; + } + + public void setOrderField(RecentActivityOrder orderField) { + this.orderField = orderField; + } + + + public DescriptionLookup asDescriptionLookup() { + DescriptionLookup lookup = new DescriptionLookup(); + lookup.setIsActive(List.of(IsActive.Active)); + if (this.like != null) lookup.setLike(this.like); + if (this.onlyDraft != null) lookup.setStatuses(List.of(DescriptionStatus.Draft)); + if (this.userIds != null) { + DmpLookup dmpLookup = new DmpLookup(); + DmpUserLookup dmpUserLookup = new DmpUserLookup(); + dmpUserLookup.setUserIds(this.userIds); + dmpUserLookup.setIsActive(List.of(IsActive.Active)); + dmpLookup.setDmpUserSubQuery(dmpUserLookup); + dmpLookup.setIsActive(List.of(IsActive.Active)); + lookup.setDmpSubQuery(dmpLookup); + } + if (this.page != null) lookup.setPage(new Paging(this.page.getOffset(), this.page.getSize())); + Ordering ordering = new Ordering(); + if (this.orderField != null) { + switch (this.orderField){ + case Label -> ordering.addDescending(Description._label).addDescending(Description._updatedAt); + case UpdatedAt -> ordering.addDescending(Description._updatedAt); + case Status -> ordering.addDescending(Description._status).addDescending(Description._updatedAt); + default -> throw new IllegalArgumentException("Type not found" + this.orderField) ; + } + } else { + ordering.addDescending(Description._updatedAt); + } + lookup.setOrder(ordering); + if (this.project !=null) lookup.setProject((BaseFieldSet) this.project.extractPrefixed(RecentActivityItem._description)); + return lookup; + } + + public DmpLookup asDmpLookup() { + DmpLookup lookup = new DmpLookup(); + lookup.setIsActive(List.of(IsActive.Active)); + if (this.like != null) lookup.setLike(this.like); + if (this.onlyDraft != null) lookup.setStatuses(List.of(DmpStatus.Draft)); + if (this.userIds != null) { + DmpUserLookup dmpUserLookup = new DmpUserLookup(); + dmpUserLookup.setUserIds(this.userIds); + dmpUserLookup.setIsActive(List.of(IsActive.Active)); + lookup.setDmpUserSubQuery(dmpUserLookup); + } + if (this.page != null) lookup.setPage(new Paging(this.page.getOffset(), this.page.getSize())); + Ordering ordering = new Ordering(); + if (this.orderField != null) { + switch (this.orderField){ + case Label -> ordering.addDescending(Dmp._label); + case UpdatedAt -> ordering.addDescending(Dmp._updatedAt); + case Status -> ordering.addDescending(Dmp._status).addDescending(Dmp._updatedAt); + default -> throw new IllegalArgumentException("Type not found" + this.orderField) ; + } + } else { + ordering.addDescending(Dmp._updatedAt); + } + lookup.setOrder(ordering); + if (this.project !=null)lookup.setProject((BaseFieldSet) this.project.extractPrefixed(RecentActivityItem._dmp)); + return lookup; + } + +} 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 index 33fc490a0..d4a396e87 100644 --- 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 @@ -2,7 +2,6 @@ package eu.eudat.model.builder; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.convention.ConventionService; -import eu.eudat.data.DescriptionEntity; import eu.eudat.data.DmpUserEntity; import eu.eudat.model.*; import eu.eudat.query.DmpQuery; @@ -69,7 +68,7 @@ public class DmpUserBuilder extends BaseBuilder{ if (fields.hasField(this.asIndexer(DmpUser._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); if (fields.hasField(this.asIndexer(DmpReference._hash))) m.setHash(this.hashValue(d.getUpdatedAt())); if (!userFields.isEmpty() && userItemsMap != null && userItemsMap.containsKey(d.getUserId())) m.setUser(userItemsMap.get(d.getUserId())); - if (!dmpFields.isEmpty() && dmpItemsMap != null && dmpItemsMap.containsKey(d.getDmp())) m.setDmp(dmpItemsMap.get(d.getDmp())); + if (!dmpFields.isEmpty() && dmpItemsMap != null && dmpItemsMap.containsKey(d.getDmpId())) m.setDmp(dmpItemsMap.get(d.getDmpId())); if (!userFields.isEmpty() && userItemsMap != null && userItemsMap.containsKey(d.getUserId())) m.setUser(userItemsMap.get(d.getUserId())); models.add(m); } @@ -115,7 +114,7 @@ public class DmpUserBuilder extends BaseBuilder{ Map itemMap; if (!fields.hasOtherField(this.asIndexer(Dmp._id))) { itemMap = this.asEmpty( - data.stream().map(DmpUserEntity::getDmp).distinct().collect(Collectors.toList()), + data.stream().map(DmpUserEntity::getDmpId).distinct().collect(Collectors.toList()), x -> { Dmp item = new Dmp(); item.setId(x); @@ -124,7 +123,7 @@ public class DmpUserBuilder extends BaseBuilder{ 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())); + DmpQuery q = this.queryFactory.query(DmpQuery.class).authorize(this.authorize).ids(data.stream().map(DmpUserEntity::getDmpId).distinct().collect(Collectors.toList())); itemMap = this.builderFactory.builder(DmpBuilder.class).authorize(this.authorize).asForeignKey(q, clone, Dmp::getId); } if (!fields.hasField(Dmp._id)) { diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpUserBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpUserBuilder.java index 2f6029118..b788b468d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpUserBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpUserBuilder.java @@ -3,7 +3,6 @@ package eu.eudat.model.builder; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.convention.ConventionService; import eu.eudat.data.DmpUserEntity; -import eu.eudat.data.UserRoleEntity; import eu.eudat.model.PublicDmp; import eu.eudat.model.PublicDmpUser; import eu.eudat.model.PublicUser; @@ -69,7 +68,7 @@ public class PublicDmpUserBuilder extends BaseBuilder itemMap; if (!fields.hasOtherField(this.asIndexer(PublicDmp._id))) { itemMap = this.asEmpty( - data.stream().map(DmpUserEntity::getDmp).distinct().collect(Collectors.toList()), + data.stream().map(DmpUserEntity::getDmpId).distinct().collect(Collectors.toList()), x -> { PublicDmp item = new PublicDmp(); item.setId(x); @@ -123,7 +122,7 @@ public class PublicDmpUserBuilder extends BaseBuilder { + + private final BuilderFactory builderFactory; + + private final QueryFactory queryFactory; + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public RecentActivityItemBuilder( + ConventionService conventionService, + BuilderFactory builderFactory, QueryFactory queryFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(RecentActivityItemBuilder.class))); + this.builderFactory = builderFactory; + this.queryFactory = queryFactory; + } + + public RecentActivityItemBuilder 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 descriptionFields = fields.extractPrefixed(this.asPrefix(RecentActivityItem._description)); + Map descriptionItemsMap = this.collectDescriptions(descriptionFields, data); + + FieldSet dmpFields = fields.extractPrefixed(this.asPrefix(RecentActivityItem._dmp)); + Map dmpItemsMap = this.collectDmps(dmpFields, data); + + List models = new ArrayList<>(); + for (RecentActivityItemEntity d : data) { + RecentActivityItem m = new RecentActivityItem(); + if (fields.hasField(this.asIndexer(RecentActivityItem._type))) m.setType(d.getType()); + if (!descriptionFields.isEmpty() && descriptionItemsMap != null && descriptionItemsMap.containsKey(d.getId())) m.setDescription(descriptionItemsMap.get(d.getId())); + if (!dmpFields.isEmpty() && dmpItemsMap != null && dmpItemsMap.containsKey(d.getId())) m.setDmp(dmpItemsMap.get(d.getId())); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + + + 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().filter(x-> x.getType().equals(RecentActivityItemType.Dmp)).map(RecentActivityItemEntity::getId).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().filter(x-> x.getType().equals(RecentActivityItemType.Dmp)).map(RecentActivityItemEntity::getId).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; + } + + private Map collectDescriptions(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) + return null; + this.logger.debug("checking related - {}", Description.class.getSimpleName()); + + Map itemMap; + if (!fields.hasOtherField(this.asIndexer(Description._id))) { + itemMap = this.asEmpty( + data.stream().filter(x-> x.getType().equals(RecentActivityItemType.Description)).map(RecentActivityItemEntity::getId).distinct().collect(Collectors.toList()), + x -> { + Description item = new Description(); + item.setId(x); + return item; + }, + Description::getId); + } else { + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(Description._id); + DescriptionQuery q = this.queryFactory.query(DescriptionQuery.class).authorize(this.authorize).ids(data.stream().filter(x-> x.getType().equals(RecentActivityItemType.Description)).map(RecentActivityItemEntity::getId).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(DescriptionBuilder.class).authorize(this.authorize).asForeignKey(q, clone, Description::getId); + } + if (!fields.hasField(Description._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/censorship/RecentActivityItemCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/RecentActivityItemCensor.java new file mode 100644 index 000000000..45e2ecabd --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/RecentActivityItemCensor.java @@ -0,0 +1,45 @@ +package eu.eudat.model.censorship; + +import eu.eudat.convention.ConventionService; +import eu.eudat.model.RecentActivityItem; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.censor.CensorFactory; +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.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class RecentActivityItemCensor extends BaseCensor { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(RecentActivityItemCensor.class)); + + protected final AuthorizationService authService; + + protected final CensorFactory censorFactory; + + public RecentActivityItemCensor(ConventionService conventionService, AuthorizationService authService, CensorFactory censorFactory) { + super(conventionService); + this.authService = authService; + this.censorFactory = censorFactory; + } + + public void censor(FieldSet fields, UUID userId) { + logger.debug(new DataLogEntry("censoring fields", fields)); + if (fields == null || fields.isEmpty()) + return; + + FieldSet dmpFields = fields.extractPrefixed(this.asIndexerPrefix(RecentActivityItem._dmp)); + this.censorFactory.censor(DmpCensor.class).censor(dmpFields, userId); + + FieldSet descriptionFields = fields.extractPrefixed(this.asIndexerPrefix(RecentActivityItem._description)); + this.censorFactory.censor(DescriptionCensor.class).censor(descriptionFields, userId); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionQuery.java index bcc4e193c..e366d5c85 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionQuery.java @@ -195,7 +195,7 @@ public class DescriptionQuery extends QueryBase { List predicates = new ArrayList<>(); if (userId != null || usePublic ) { - predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._dmpDescriptionTemplateId)).value(queryUtilsService.buildDmpAuthZSubQuery(queryContext.Query, queryContext.CriteriaBuilder, userId, usePublic))); + predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._dmpId)).value(queryUtilsService.buildDmpAuthZSubQuery(queryContext.Query, queryContext.CriteriaBuilder, userId, usePublic))); } if (!predicates.isEmpty()) { Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java index c093035fb..22dc650b6 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java @@ -7,11 +7,10 @@ import eu.eudat.commons.enums.DmpStatus; import eu.eudat.commons.enums.DmpVersionStatus; import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.scope.user.UserScope; -import eu.eudat.data.DescriptionEntity; import eu.eudat.data.DmpDescriptionTemplateEntity; import eu.eudat.data.DmpEntity; +import eu.eudat.data.DmpUserEntity; import eu.eudat.model.Dmp; -import eu.eudat.model.DmpDescriptionTemplate; import eu.eudat.model.PublicDmp; import eu.eudat.query.utils.QueryUtilsService; import gr.cite.commons.web.authz.service.AuthorizationService; @@ -24,7 +23,6 @@ import org.springframework.stereotype.Component; import java.time.Instant; import java.util.*; -import java.util.function.Function; @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) @@ -45,6 +43,7 @@ public class DmpQuery extends QueryBase { private Collection versions; private Collection groupIds; + private DmpUserQuery dmpUserQuery; private DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery; @@ -190,6 +189,11 @@ public class DmpQuery extends QueryBase { return this; } + public DmpQuery dmpUserSubQuery(DmpUserQuery subQuery) { + this.dmpUserQuery = subQuery; + return this; + } + public DmpQuery authorize(EnumSet values) { this.authorize = values; return this; @@ -197,7 +201,7 @@ public class DmpQuery extends QueryBase { @Override protected Boolean isFalseQuery() { - return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.versionStatuses) || this.isEmpty(this.excludedIds) || this.isEmpty(this.accessTypes)|| this.isEmpty(this.statuses)|| this.isFalseQuery(this.dmpDescriptionTemplateQuery); + return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.versionStatuses) || this.isEmpty(this.excludedIds) || this.isEmpty(this.accessTypes)|| this.isEmpty(this.statuses)|| this.isFalseQuery(this.dmpDescriptionTemplateQuery)|| this.isFalseQuery(this.dmpUserQuery); } @Override @@ -287,6 +291,11 @@ public class DmpQuery extends QueryBase { predicates.add(inClause); } + if (this.dmpUserQuery != null) { + QueryContext subQuery = this.applySubQuery(this.dmpUserQuery, queryContext, UUID.class, root -> root.get(DmpUserEntity._dmpId)); + predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id)).value(subQuery.Query)); + } + if (this.dmpDescriptionTemplateQuery != null) { QueryContext subQuery = this.applySubQuery(this.dmpDescriptionTemplateQuery, queryContext, UUID.class, dmpDescriptionTemplateEntityRoot -> dmpDescriptionTemplateEntityRoot.get(DmpDescriptionTemplateEntity._dmpId)); predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id)).value(subQuery.Query)); 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 index a28f0ecdc..82fd74239 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java @@ -155,7 +155,7 @@ public class DmpUserQuery extends QueryBase { List predicates = new ArrayList<>(); if (userId != null || usePublic ) { predicates.add(queryContext.CriteriaBuilder.or( - usePublic ? queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpUserEntity._dmp)).value(queryUtilsService.buildPublicDmpAuthZSubQuery(queryContext.Query, queryContext.CriteriaBuilder, usePublic)) : queryContext.CriteriaBuilder.or(), //Creates a false query + usePublic ? queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpUserEntity._dmpId)).value(queryUtilsService.buildPublicDmpAuthZSubQuery(queryContext.Query, queryContext.CriteriaBuilder, usePublic)) : queryContext.CriteriaBuilder.or(), //Creates a false query userId != null ? queryContext.CriteriaBuilder.equal(queryContext.Root.get(DmpUserEntity._userId), userId) : queryContext.CriteriaBuilder.or() //Creates a false query )); } @@ -183,7 +183,7 @@ public class DmpUserQuery extends QueryBase { predicates.add(inClause); } if (this.dmpIds != null) { - CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpUserEntity._dmp)); + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpUserEntity._dmpId)); for (UUID item : this.dmpIds) inClause.value(item); predicates.add(inClause); @@ -212,7 +212,7 @@ public class DmpUserQuery extends QueryBase { 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.setDmpId(QueryBase.convertSafe(tuple, columns, DmpUserEntity._dmpId, UUID.class)); item.setUserId(QueryBase.convertSafe(tuple, columns, DmpUserEntity._userId, UUID.class)); item.setRole(QueryBase.convertSafe(tuple, columns, DmpUserEntity._role, DmpUserRole.class)); item.setCreatedAt(QueryBase.convertSafe(tuple, columns, DmpUserEntity._createdAt, Instant.class)); @@ -223,7 +223,7 @@ public class DmpUserQuery extends QueryBase { @Override protected String fieldNameOf(FieldResolver item) { if (item.match(DmpUser._id) || item.match(PublicDmpUser._id)) return DmpUserEntity._id; - else if (item.prefix(DmpUser._dmp) || item.prefix(PublicDmpUser._dmp)) return DmpUserEntity._dmp; + else if (item.prefix(DmpUser._dmp) || item.prefix(PublicDmpUser._dmp)) return DmpUserEntity._dmpId; else if (item.prefix(DmpUser._user) || item.prefix(PublicDmpUser._user)) return DmpUserEntity._userId; else if (item.match(DmpUser._role) || item.match(PublicDmpUser._role)) return DmpUserEntity._role; else if (item.match(DmpUser._createdAt)) return DmpUserEntity._createdAt; diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpLookup.java b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpLookup.java index ba6e4ed6b..b3c6bfc10 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpLookup.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpLookup.java @@ -32,6 +32,7 @@ public class DmpLookup extends Lookup { private List versions; private DmpDescriptionTemplateLookup dmpDescriptionTemplateSubQuery; + private DmpUserLookup dmpUserSubQuery; public String getLike() { return like; @@ -113,6 +114,14 @@ public class DmpLookup extends Lookup { this.groupIds = groupIds; } + public DmpUserLookup getDmpUserSubQuery() { + return dmpUserSubQuery; + } + + public void setDmpUserSubQuery(DmpUserLookup dmpUserSubQuery) { + this.dmpUserSubQuery = dmpUserSubQuery; + } + public DmpQuery enrich(QueryFactory queryFactory) { DmpQuery query = queryFactory.query(DmpQuery.class); if (this.like != null) query.like(this.like); @@ -125,6 +134,7 @@ public class DmpLookup extends Lookup { if (this.versions != null) query.versions(this.versions); if (this.versionStatuses != null) query.versionStatuses(this.versionStatuses); if (this.dmpDescriptionTemplateSubQuery != null) query.dmpDescriptionTemplateSubQuery(this.dmpDescriptionTemplateSubQuery.enrich(queryFactory)); + if (this.dmpUserSubQuery != null) query.dmpUserSubQuery(this.dmpUserSubQuery.enrich(queryFactory)); this.enrichCommon(query); @@ -142,6 +152,7 @@ public class DmpLookup extends Lookup { if (this.versions != null) query.versions(this.versions); if (this.versionStatuses != null) query.versionStatuses(this.versionStatuses); if (this.dmpDescriptionTemplateSubQuery != null) throw new UnsupportedOperationException(""); + if (this.dmpUserSubQuery != null) throw new UnsupportedOperationException(""); this.enrichCommon(query); @@ -159,6 +170,7 @@ public class DmpLookup extends Lookup { if (this.versions != null) query.versions(this.versions); if (this.versionStatuses != null) query.versionStatuses(this.versionStatuses); if (this.dmpDescriptionTemplateSubQuery != null) throw new UnsupportedOperationException(""); + if (this.dmpUserSubQuery != null) throw new UnsupportedOperationException(""); return query; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpUserLookup.java b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpUserLookup.java new file mode 100644 index 000000000..4b999e1af --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DmpUserLookup.java @@ -0,0 +1,87 @@ +package eu.eudat.query.lookup; + +import eu.eudat.commons.enums.*; +import eu.eudat.elastic.query.DmpElasticQuery; +import eu.eudat.elastic.query.InnerObjectDmpElasticQuery; +import eu.eudat.elastic.query.NestedCollaboratorElasticQuery; +import eu.eudat.query.DmpUserQuery; +import gr.cite.tools.data.query.Lookup; +import gr.cite.tools.data.query.QueryFactory; + +import java.util.List; +import java.util.UUID; + +public class DmpUserLookup extends Lookup { + + + private List ids; + + private List dmpIds; + private List userIds; + + private List isActive; + private List userRoles; + + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } + + public List getDmpIds() { + return dmpIds; + } + + public void setDmpIds(List dmpIds) { + this.dmpIds = dmpIds; + } + + public List getUserIds() { + return userIds; + } + + public void setUserIds(List userIds) { + this.userIds = userIds; + } + + public List getIsActive() { + return isActive; + } + + public void setIsActive(List isActive) { + this.isActive = isActive; + } + + public List getUserRoles() { + return userRoles; + } + + public void setUserRoles(List userRoles) { + this.userRoles = userRoles; + } + + public DmpUserQuery enrich(QueryFactory queryFactory) { + DmpUserQuery query = queryFactory.query(DmpUserQuery.class); + if (this.ids != null) query.ids(this.ids); + if (this.dmpIds != null) query.dmpIds(this.dmpIds); + if (this.userIds != null) query.userIds(this.userIds); + if (this.userRoles != null) query.userRoles(this.userRoles); + if (this.isActive != null) query.isActives(this.isActive); + + this.enrichCommon(query); + + return query; + } + + public NestedCollaboratorElasticQuery enrichElastic(QueryFactory queryFactory) { + NestedCollaboratorElasticQuery query = queryFactory.query(NestedCollaboratorElasticQuery.class); + if (this.ids != null) query.ids(this.ids); + if (this.userRoles != null) query.userRoles(this.userRoles); + + this.enrichCommon(query); + + return query; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/utils/QueryUtilsServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/query/utils/QueryUtilsServiceImpl.java index 9666cbe70..1be4d94e3 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/utils/QueryUtilsServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/utils/QueryUtilsServiceImpl.java @@ -63,7 +63,7 @@ public class QueryUtilsServiceImpl implements QueryUtilsService { return this.buildSubQuery(new BuildSubQueryInput<>(new BuildSubQueryInput.Builder<>(DmpUserEntity.class, UUID.class) .query(query) .criteriaBuilder(criteriaBuilder) - .keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpUserEntity._dmp)) + .keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpUserEntity._dmpId)) .filterFunc((subQueryRoot, cb) -> userId != null ? cb.and( cb.equal(subQueryRoot.get(DmpUserEntity._userId), userId), diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardService.java b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardService.java new file mode 100644 index 000000000..abff4c07e --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardService.java @@ -0,0 +1,11 @@ +package eu.eudat.service.dashborad; + +import eu.eudat.model.RecentActivityItem; +import eu.eudat.model.RecentActivityItemLookup; + +import javax.management.InvalidApplicationException; +import java.util.List; + +public interface DashboardService { + List getMyRecentActivityItems(RecentActivityItemLookup model) throws InvalidApplicationException; +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardServiceImpl.java new file mode 100644 index 000000000..d03e01c99 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardServiceImpl.java @@ -0,0 +1,167 @@ +package eu.eudat.service.dashborad; + +import com.fasterxml.jackson.core.JsonProcessingException; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.authorization.Permission; +import eu.eudat.commons.JsonHandlingService; +import eu.eudat.commons.XmlHandlingService; +import eu.eudat.commons.enums.DescriptionStatus; +import eu.eudat.commons.enums.DmpStatus; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.enums.RecentActivityItemType; +import eu.eudat.commons.scope.user.UserScope; +import eu.eudat.commons.types.dashborad.RecentActivityItemEntity; +import eu.eudat.commons.types.description.FieldEntity; +import eu.eudat.commons.types.description.PropertyDefinitionEntity; +import eu.eudat.commons.types.reference.DefinitionEntity; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.*; +import eu.eudat.errorcode.ErrorThesaurusProperties; +import eu.eudat.event.DescriptionTouchedEvent; +import eu.eudat.event.EventBroker; +import eu.eudat.model.*; +import eu.eudat.model.builder.DescriptionBuilder; +import eu.eudat.model.builder.RecentActivityItemBuilder; +import eu.eudat.model.deleter.DescriptionDeleter; +import eu.eudat.model.deleter.DescriptionReferenceDeleter; +import eu.eudat.model.deleter.DescriptionTagDeleter; +import eu.eudat.model.persist.DescriptionPersist; +import eu.eudat.model.persist.DescriptionReferencePersist; +import eu.eudat.model.persist.DescriptionStatusPersist; +import eu.eudat.model.persist.ReferencePersist; +import eu.eudat.model.persist.descriptionproperties.FieldPersist; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionPersist; +import eu.eudat.model.persist.referencedefinition.DefinitionPersist; +import eu.eudat.model.referencetypedefinition.ReferenceTypeSourceBaseConfiguration; +import eu.eudat.model.result.QueryResult; +import eu.eudat.query.*; +import eu.eudat.query.lookup.DescriptionLookup; +import eu.eudat.query.lookup.DmpLookup; +import eu.eudat.service.elastic.ElasticQueryHelperService; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.Ordering; +import gr.cite.tools.data.query.QueryFactory; +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.BaseFieldSet; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.jetbrains.annotations.NotNull; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Service; + +import javax.management.InvalidApplicationException; +import java.io.IOException; +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; + +import static eu.eudat.authorization.AuthorizationFlags.Public; + +@Service +public class DashboardServiceImpl implements DashboardService { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DashboardServiceImpl.class)); + + private final EntityManager entityManager; + + private final AuthorizationService authorizationService; + + private final DeleterFactory deleterFactory; + + private final BuilderFactory builderFactory; + + private final ConventionService conventionService; + + private final ErrorThesaurusProperties errors; + + private final MessageSource messageSource; + + private final EventBroker eventBroker; + + private final QueryFactory queryFactory; + + private final JsonHandlingService jsonHandlingService; + + private final UserScope userScope; + private final XmlHandlingService xmlHandlingService; + + private final ElasticQueryHelperService elasticQueryHelperService; + + @Autowired + public DashboardServiceImpl( + EntityManager entityManager, + AuthorizationService authorizationService, + DeleterFactory deleterFactory, + BuilderFactory builderFactory, + ConventionService conventionService, + ErrorThesaurusProperties errors, + MessageSource messageSource, + EventBroker eventBroker, + QueryFactory queryFactory, + JsonHandlingService jsonHandlingService, + UserScope userScope, + XmlHandlingService xmlHandlingService, ElasticQueryHelperService elasticQueryHelperService) { + this.entityManager = entityManager; + this.authorizationService = authorizationService; + this.deleterFactory = deleterFactory; + this.builderFactory = builderFactory; + this.conventionService = conventionService; + this.errors = errors; + this.messageSource = messageSource; + this.eventBroker = eventBroker; + this.queryFactory = queryFactory; + this.jsonHandlingService = jsonHandlingService; + this.userScope = userScope; + this.xmlHandlingService = xmlHandlingService; + this.elasticQueryHelperService = elasticQueryHelperService; + } + + @Override + public List getMyRecentActivityItems(RecentActivityItemLookup model) throws InvalidApplicationException { + logger.debug(new MapLogEntry("collecting recent activity").And("model", model)); + model.setUserIds(List.of(this.userScope.getUserId())); + + List recentActivityItemEntities = new ArrayList<>(); + DescriptionLookup descriptionLookup = model.asDescriptionLookup(); + descriptionLookup.getPage().setOffset(0); + QueryResult descriptions = this.elasticQueryHelperService.collect(descriptionLookup, AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic, new BaseFieldSet().ensure(Description._id).ensure(Description._updatedAt).ensure(Description._status).ensure(Description._label)); + if (!this.conventionService.isListNullOrEmpty(descriptions.getItems())) { + for (Description description : descriptions.getItems()) recentActivityItemEntities.add(new RecentActivityItemEntity(RecentActivityItemType.Description, description.getId(), description.getUpdatedAt(), description.getLabel(), description.getStatus().getValue())); + } + + DmpLookup dmpLookup = model.asDmpLookup(); + dmpLookup.getPage().setOffset(0); + QueryResult dmps = this.elasticQueryHelperService.collect(dmpLookup, AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic, new BaseFieldSet().ensure(Dmp._id).ensure(Dmp._updatedAt).ensure(Dmp._label).ensure(Dmp._status)); + if (!this.conventionService.isListNullOrEmpty(dmps.getItems())) { + for (Dmp dmp : dmps.getItems()) recentActivityItemEntities.add(new RecentActivityItemEntity(RecentActivityItemType.Dmp, dmp.getId(), dmp.getUpdatedAt(), dmp.getLabel(), dmp.getStatus().getValue())); + } + Comparator comparator = Comparator.comparing(RecentActivityItemEntity::getUpdatedAt); + + Ordering ordering = new Ordering(); + if (model.getOrderField() != null) { + switch (model.getOrderField()){ + case Label -> comparator = Comparator.comparing(RecentActivityItemEntity::getLabel).thenComparing(RecentActivityItemEntity::getUpdatedAt); + case UpdatedAt -> comparator = Comparator.comparing(RecentActivityItemEntity::getUpdatedAt); + case Status -> comparator = Comparator.comparing(RecentActivityItemEntity::getStatusValue).thenComparing(RecentActivityItemEntity::getUpdatedAt); + default -> throw new IllegalArgumentException("Type not found" + model.getOrderField()) ; + } + } + recentActivityItemEntities = recentActivityItemEntities.stream().sorted(comparator).toList().reversed(); + + if (model.getPage() != null){ + recentActivityItemEntities = recentActivityItemEntities.stream().skip(model.getPage().getOffset()).limit(model.getPage().getSize()).toList(); + } + return this.builderFactory.builder(RecentActivityItemBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(model.getProject()), recentActivityItemEntities); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java index 2f8d86628..7585c4cde 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java @@ -190,7 +190,7 @@ public class DmpServiceImpl implements DmpService { for (DmpUserEntity dmpUser : dmpUsers) { DmpUserEntity newUser = new DmpUserEntity(); newUser.setId(UUID.randomUUID()); - newUser.setDmp(newDmp.getId()); + newUser.setDmpId(newDmp.getId()); newUser.setUserId(dmpUser.getUserId()); newUser.setRole(dmpUser.getRole()); newUser.setCreatedAt(Instant.now()); @@ -278,7 +278,7 @@ public class DmpServiceImpl implements DmpService { for (DmpUserEntity dmpUser : dmpUsers) { DmpUserEntity newUser = new DmpUserEntity(); newUser.setId(UUID.randomUUID()); - newUser.setDmp(newDmp.getId()); + newUser.setDmpId(newDmp.getId()); newUser.setUserId(dmpUser.getUserId()); newUser.setRole(dmpUser.getRole()); newUser.setCreatedAt(Instant.now()); @@ -331,11 +331,11 @@ public class DmpServiceImpl implements DmpService { List updatedCreatedIds = new ArrayList<>(); for (DmpUserPersist dmpUser : model) { - DmpUserEntity dmpUserEntity = existingUsers.stream().filter(x-> x.getDmp().equals(dmp) && x.getUserId().equals(dmpUser.getUser()) && x.getRole().equals(dmpUser.getRole())).findFirst().orElse(null); + DmpUserEntity dmpUserEntity = existingUsers.stream().filter(x-> x.getDmpId().equals(dmp) && x.getUserId().equals(dmpUser.getUser()) && x.getRole().equals(dmpUser.getRole())).findFirst().orElse(null); if (dmpUserEntity == null){ dmpUserEntity = new DmpUserEntity(); dmpUserEntity.setId(UUID.randomUUID()); - dmpUserEntity.setDmp(dmp); + dmpUserEntity.setDmpId(dmp); dmpUserEntity.setUserId(dmpUser.getUser()); dmpUserEntity.setRole(dmpUser.getRole()); dmpUserEntity.setCreatedAt(Instant.now()); @@ -422,7 +422,7 @@ public class DmpServiceImpl implements DmpService { data.setCreatedAt(Instant.now()); dmpUserEntity.setId(UUID.randomUUID()); - dmpUserEntity.setDmp(data.getId()); + dmpUserEntity.setDmpId(data.getId()); dmpUserEntity.setUserId(userScope.getUserId()); dmpUserEntity.setRole(DmpUserRole.Owner); dmpUserEntity.setCreatedAt(Instant.now()); @@ -604,7 +604,7 @@ public class DmpServiceImpl implements DmpService { private DmpUserEntity checkUserRoleIfExists(List dmpUserEntities, UUID dmp, UUID user, DmpUserRole role) { for (DmpUserEntity dmpUser : dmpUserEntities) { - if (dmpUser.getDmp().equals(dmp) && dmpUser.getUserId().equals(user) && dmpUser.getRole() == role) { + if (dmpUser.getDmpId().equals(dmp) && dmpUser.getUserId().equals(user) && dmpUser.getRole() == role) { return dmpUser; }; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticQueryHelperServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticQueryHelperServiceImpl.java index 63cb512c2..e43ef4226 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticQueryHelperServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/elastic/ElasticQueryHelperServiceImpl.java @@ -34,7 +34,6 @@ public class ElasticQueryHelperServiceImpl implements ElasticQueryHelperService private final QueryFactory queryFactory; private final BuilderFactory builderFactory; private final ElasticService elasticService; - public ElasticQueryHelperServiceImpl(QueryFactory queryFactory, BuilderFactory builderFactory, ElasticService elasticService) { this.queryFactory = queryFactory; this.builderFactory = builderFactory; @@ -86,6 +85,7 @@ public class ElasticQueryHelperServiceImpl implements ElasticQueryHelperService EnumSet flags = authorizationFlags == null ? EnumSet.of(AuthorizationFlags.None) : authorizationFlags; return this.collect(lookup, (d) -> this.builderFactory.builder(DescriptionBuilder.class).authorize(flags).build(fieldSet != null ? fieldSet : lookup.getProject(), d), flags); } + @Override public QueryResult collectPublic(DescriptionLookup lookup, EnumSet authorizationFlags, FieldSet fieldSet) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DashboardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DashboardController.java new file mode 100644 index 000000000..ba69b39da --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DashboardController.java @@ -0,0 +1,92 @@ +package eu.eudat.controllers.v2; + +import com.fasterxml.jackson.core.JsonProcessingException; +import eu.eudat.audit.AuditableAction; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.DmpAccessType; +import eu.eudat.commons.enums.DmpStatus; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.scope.user.UserScope; +import eu.eudat.model.*; +import eu.eudat.model.builder.DescriptionBuilder; +import eu.eudat.model.builder.UserBuilder; +import eu.eudat.model.censorship.DescriptionCensor; +import eu.eudat.model.censorship.PublicDescriptionCensor; +import eu.eudat.model.censorship.RecentActivityItemCensor; +import eu.eudat.model.persist.DescriptionPersist; +import eu.eudat.model.persist.DescriptionStatusPersist; +import eu.eudat.model.result.QueryResult; +import eu.eudat.query.DescriptionQuery; +import eu.eudat.query.DmpQuery; +import eu.eudat.query.UserQuery; +import eu.eudat.query.lookup.DescriptionLookup; +import eu.eudat.service.dashborad.DashboardService; +import eu.eudat.service.description.DescriptionService; +import eu.eudat.service.elastic.ElasticQueryHelperService; +import gr.cite.tools.auditing.AuditService; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.censor.CensorFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import gr.cite.tools.validation.MyValidate; +import org.slf4j.LoggerFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import javax.management.InvalidApplicationException; +import java.io.IOException; +import java.util.*; + +import static eu.eudat.authorization.AuthorizationFlags.Public; + +@RestController +@RequestMapping(path = "api/dashboard") +public class DashboardController { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DashboardController.class)); + + private final AuditService auditService; + + private final DashboardService dashboardService; + + private final CensorFactory censorFactory; + + private final UserScope userScope; + public DashboardController( + AuditService auditService, + DashboardService dashboardService, + CensorFactory censorFactory, + UserScope userScope) { + this.auditService = auditService; + this.dashboardService = dashboardService; + this.censorFactory = censorFactory; + this.userScope = userScope; + } + + + + @PostMapping("recent-activity/mine") + public List getMyRecentActivityItems(@RequestBody RecentActivityItemLookup lookup) throws InvalidApplicationException { + logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("lookup", lookup)); + + this.censorFactory.censor(RecentActivityItemCensor.class).censor(lookup.getProject(), this.userScope.getUserId()); + + lookup.setUserIds(List.of(this.userScope.getUserId())); + List models = this.dashboardService.getMyRecentActivityItems(lookup); + + this.auditService.track(AuditableAction.Dashboard_MyRecentActivityItems, Map.ofEntries( + new AbstractMap.SimpleEntry("lookup", lookup) + )); + //this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action); + + return models; + } + +} 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 4cb87126d..d720bea7f 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 @@ -784,7 +784,7 @@ public class DataManagementPlanManager { DmpUserEntity temp = new DmpUserEntity(); temp.setUserId(userDMP.getUserId()); temp.setRole(userDMP.getRole()); - temp.setDmp(newDmp.getId()); + temp.setDmpId(newDmp.getId()); // apiContext.getOperationsContext().getDatabaseRepository().getUserDmpDao().createOrUpdate(temp); }); @@ -2403,7 +2403,7 @@ public class DataManagementPlanManager { private void assignUser(DmpEntity dmp, UserEntity userInfo, DmpUserRole role) { DmpUserEntity userDMP = new DmpUserEntity(); - userDMP.setDmp(dmp.getId()); + userDMP.setDmpId(dmp.getId()); userDMP.setUserId(userInfo.getId()); userDMP.setRole(role); // databaseRepository.getUserDmpDao().createOrUpdate(userDMP); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/QuickWizardManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/QuickWizardManager.java index afc5d6a3f..4398b6951 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/QuickWizardManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/QuickWizardManager.java @@ -90,7 +90,7 @@ public class QuickWizardManager { private void assignUser(DmpEntity dmp, UserEntity userInfo, ApiContext apiContext) { DmpUserEntity userDMP = new DmpUserEntity(); - userDMP.setDmp(dmp.getId()); + userDMP.setDmpId(dmp.getId()); userDMP.setUserId(userInfo.getId()); userDMP.setRole(DmpUserRole.User); //apiContext.getOperationsContext().getDatabaseRepository().getUserDmpDao().createOrUpdate(userDMP);