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 b7dbf52ef..eb57acfcc 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 @@ -92,8 +92,10 @@ 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"); + public static final EventId Dashboard_MyDashboardStatistics = new EventId(15001, "Dashboard_MyDashboardStatistics"); + public static final EventId Dashboard_PublicDashboardStatistics = new EventId(15002, "Dashboard_PublicDashboardStatistics"); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java b/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java index 25b24e205..ac7fe2b4f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java +++ b/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java @@ -21,9 +21,12 @@ public final class Permission { public static String PublicBrowseDmpUser = "PublicBrowseDmpUser"; public static String PublicBrowseReference = "PublicBrowseReference"; public static String PublicBrowseUser = "PublicBrowseUser"; + public static String PublicBrowseDashboardStatistics = "PublicBrowseDashboardStatistics"; //Elastic public static String ManageElastic = "ManageElastic"; + + //Language public static String BrowseLanguage = "BrowseLanguage"; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/DashboardStatistics.java b/dmp-backend/core/src/main/java/eu/eudat/model/DashboardStatistics.java new file mode 100644 index 000000000..a288a7944 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/DashboardStatistics.java @@ -0,0 +1,52 @@ +package eu.eudat.model; + +public class DashboardStatistics { + + private long dmpCount; + + public static final String _dmpCount = "dmpCount"; + + private long descriptionCount; + + public static final String _descriptionCount = "descriptionCount"; + + private long organizationCount; + + public static final String _organizationCount = "organizationCount"; + + private long grantCount; + + public static final String _grantCount = "grantCount"; + + public long getDmpCount() { + return dmpCount; + } + + public void setDmpCount(long dmpCount) { + this.dmpCount = dmpCount; + } + + public long getDescriptionCount() { + return descriptionCount; + } + + public void setDescriptionCount(long descriptionCount) { + this.descriptionCount = descriptionCount; + } + + public long getOrganizationCount() { + return organizationCount; + } + + public void setOrganizationCount(long organizationCount) { + this.organizationCount = organizationCount; + } + + public long getGrantCount() { + return grantCount; + } + + public void setGrantCount(long grantCount) { + this.grantCount = grantCount; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/MyDashboardStatisticsCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/MyDashboardStatisticsCensor.java new file mode 100644 index 000000000..6c35cdc41 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/MyDashboardStatisticsCensor.java @@ -0,0 +1,33 @@ +package eu.eudat.model.censorship; + +import eu.eudat.authorization.OwnedResource; +import eu.eudat.convention.ConventionService; +import gr.cite.commons.web.authz.service.AuthorizationService; +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.List; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class MyDashboardStatisticsCensor extends BaseCensor { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(MyDashboardStatisticsCensor.class)); + + protected final AuthorizationService authService; + + + public MyDashboardStatisticsCensor(ConventionService conventionService, AuthorizationService authService) { + super(conventionService); + this.authService = authService; + } + + public void censor(UUID userId) { + this.authService.authorizeAtLeastOneForce(userId != null ? List.of(new OwnedResource(userId)) : null); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/PublicDashboardStatisticsCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/PublicDashboardStatisticsCensor.java new file mode 100644 index 000000000..62f64e27a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/PublicDashboardStatisticsCensor.java @@ -0,0 +1,34 @@ +package eu.eudat.model.censorship; + +import eu.eudat.authorization.Permission; +import eu.eudat.convention.ConventionService; +import gr.cite.commons.web.authz.service.AuthorizationService; +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 PublicDashboardStatisticsCensor extends BaseCensor { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(PublicDashboardStatisticsCensor.class)); + + protected final AuthorizationService authService; + + + public PublicDashboardStatisticsCensor(ConventionService conventionService, AuthorizationService authService) { + super(conventionService); + this.authService = authService; + } + + public void censor(UUID userId) { + this.authService.authorizeForce(Permission.PublicBrowseDashboardStatistics); + } + +} 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 3ed7e2c14..771e5c6fa 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 @@ -5,11 +5,11 @@ import eu.eudat.authorization.Permission; import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.scope.user.UserScope; import eu.eudat.data.DescriptionEntity; -import eu.eudat.data.DescriptionReferenceEntity; +import eu.eudat.data.DmpEntity; import eu.eudat.data.DmpReferenceEntity; +import eu.eudat.data.ReferenceEntity; import eu.eudat.model.DmpReference; import eu.eudat.model.PublicDmpReference; -import eu.eudat.query.utils.BuildSubQueryInput; import eu.eudat.query.utils.QueryUtilsService; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; @@ -18,7 +18,6 @@ import gr.cite.tools.data.query.QueryContext; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Subquery; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -37,6 +36,8 @@ public class DmpReferenceQuery extends QueryBase { private Collection dmpIds; private Collection referenceIds; + private DmpQuery dmpQuery; + private ReferenceQuery referenceQuery; private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); @@ -101,6 +102,16 @@ public class DmpReferenceQuery extends QueryBase { return this; } + public DmpReferenceQuery dmpSubQuery(DmpQuery value) { + this.dmpQuery = value; + return this; + } + + public DmpReferenceQuery referenceSubQuery(ReferenceQuery value) { + this.referenceQuery = value; + return this; + } + public DmpReferenceQuery authorize(EnumSet values) { this.authorize = values; return this; @@ -127,7 +138,7 @@ public class DmpReferenceQuery extends QueryBase { @Override protected Boolean isFalseQuery() { - return this.isEmpty(this.ids) || this.isEmpty(this.dmpIds) || this.isEmpty(this.referenceIds); + return this.isEmpty(this.ids) || this.isEmpty(this.dmpIds) || this.isEmpty(this.referenceIds) || this.isFalseQuery(this.dmpQuery) || this.isFalseQuery(this.referenceQuery); } @Override @@ -178,6 +189,14 @@ public class DmpReferenceQuery extends QueryBase { inClause.value(item); predicates.add(inClause); } + if (this.dmpQuery != null) { + QueryContext subQuery = this.applySubQuery(this.dmpQuery, queryContext, UUID.class, dmpEntityRoot -> dmpEntityRoot.get(DmpEntity._id)); + predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpReferenceEntity._dmpId)).value(subQuery.Query)); + } + if (this.referenceQuery != null) { + QueryContext subQuery = this.applySubQuery(this.referenceQuery, queryContext, UUID.class, root -> root.get(ReferenceEntity._id)); + predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpReferenceEntity._referenceId)).value(subQuery.Query)); + } if (!predicates.isEmpty()) { Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); return queryContext.CriteriaBuilder.and(predicatesArray); 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 index abff4c07e..d1fece2c1 100644 --- 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 @@ -1,5 +1,6 @@ package eu.eudat.service.dashborad; +import eu.eudat.model.DashboardStatistics; import eu.eudat.model.RecentActivityItem; import eu.eudat.model.RecentActivityItemLookup; @@ -8,4 +9,8 @@ import java.util.List; public interface DashboardService { List getMyRecentActivityItems(RecentActivityItemLookup model) throws InvalidApplicationException; + + DashboardStatistics getPublicDashboardStatistics(); + + DashboardStatistics getMyDashboardStatistics() 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 index d03e01c99..d7fae9df7 100644 --- 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 @@ -1,38 +1,19 @@ package eu.eudat.service.dashborad; -import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.authorization.OwnedResource; 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.enums.*; +import eu.eudat.commons.enums.ReferenceType; 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; @@ -41,30 +22,20 @@ 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.Owner; import static eu.eudat.authorization.AuthorizationFlags.Public; @Service @@ -97,6 +68,7 @@ public class DashboardServiceImpl implements DashboardService { private final ElasticQueryHelperService elasticQueryHelperService; + private final DashboardStatisticsCacheService dashboardStatisticsCacheService; @Autowired public DashboardServiceImpl( EntityManager entityManager, @@ -110,7 +82,7 @@ public class DashboardServiceImpl implements DashboardService { QueryFactory queryFactory, JsonHandlingService jsonHandlingService, UserScope userScope, - XmlHandlingService xmlHandlingService, ElasticQueryHelperService elasticQueryHelperService) { + XmlHandlingService xmlHandlingService, ElasticQueryHelperService elasticQueryHelperService, DashboardStatisticsCacheService dashboardStatisticsCacheService) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; @@ -124,6 +96,7 @@ public class DashboardServiceImpl implements DashboardService { this.userScope = userScope; this.xmlHandlingService = xmlHandlingService; this.elasticQueryHelperService = elasticQueryHelperService; + this.dashboardStatisticsCacheService = dashboardStatisticsCacheService; } @Override @@ -147,7 +120,6 @@ public class DashboardServiceImpl implements DashboardService { } 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); @@ -164,4 +136,49 @@ public class DashboardServiceImpl implements DashboardService { return this.builderFactory.builder(RecentActivityItemBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(model.getProject()), recentActivityItemEntities); } + @Override + public DashboardStatistics getPublicDashboardStatistics(){ + this.authorizationService.authorizeForce(Permission.PublicBrowseDashboardStatistics); + + DashboardStatisticsCacheService.DashboardStatisticsCacheValue cacheValue = this.dashboardStatisticsCacheService.lookup(this.dashboardStatisticsCacheService.buildKey(DashboardStatisticsCacheService.publicKey)); + if (cacheValue == null || cacheValue.getDashboardStatistics() == null) { + DmpQuery dmpQuery = this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).versionStatuses(DmpVersionStatus.Current).statuses(DmpStatus.Finalized).accessTypes(DmpAccessType.Public); + DashboardStatistics statistics = new DashboardStatistics(); + statistics.setDmpCount(dmpQuery.authorize(EnumSet.of(Public)).count()); + statistics.setDescriptionCount(this.queryFactory.query(DescriptionQuery.class).isActive(IsActive.Active).dmpSubQuery(dmpQuery).statuses(DescriptionStatus.Finalized).authorize(EnumSet.of(Public)).count()); + statistics.setOrganizationCount(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active).dmpSubQuery(dmpQuery).referenceSubQuery(this.queryFactory.query(ReferenceQuery.class).types(ReferenceType.Organizations).isActive(IsActive.Active)).authorize(EnumSet.of(Public)).count()); + statistics.setDmpCount(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active).dmpSubQuery(dmpQuery).referenceSubQuery(this.queryFactory.query(ReferenceQuery.class).types(ReferenceType.Grants).isActive(IsActive.Active)).authorize(EnumSet.of(Public)).count()); + cacheValue = new DashboardStatisticsCacheService.DashboardStatisticsCacheValue(); + cacheValue.setPublic(true); + cacheValue.setDashboardStatistics(statistics); + this.dashboardStatisticsCacheService.put(cacheValue); + } + return cacheValue.getDashboardStatistics(); + } + + @Override + public DashboardStatistics getMyDashboardStatistics() throws InvalidApplicationException { + this.authorizationService.authorizeAtLeastOneForce(this.userScope.getUserIdSafe() != null ? List.of(new OwnedResource(this.userScope.getUserIdSafe())) : null); + + DashboardStatisticsCacheService.DashboardStatisticsCacheValue cacheValue = this.dashboardStatisticsCacheService.lookup(this.dashboardStatisticsCacheService.buildKey(this.userScope.getUserId().toString().toLowerCase(Locale.ROOT))); + if (cacheValue == null || cacheValue.getDashboardStatistics() == null) { + DmpUserQuery dmpUserLookup = this.queryFactory.query(DmpUserQuery.class); + dmpUserLookup.userIds(this.userScope.getUserId()); + dmpUserLookup.isActives(IsActive.Active); + + DmpQuery dmpQuery = this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).dmpUserSubQuery(dmpUserLookup).versionStatuses(DmpVersionStatus.Current).statuses(DmpStatus.Finalized); + + DashboardStatistics statistics = new DashboardStatistics(); + statistics.setDmpCount(dmpQuery.authorize(EnumSet.of(Owner)).count()); + statistics.setDescriptionCount(this.queryFactory.query(DescriptionQuery.class).isActive(IsActive.Active).dmpSubQuery(dmpQuery).statuses(DescriptionStatus.Finalized).authorize(EnumSet.of(Owner)).count()); + statistics.setOrganizationCount(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active).dmpSubQuery(dmpQuery).referenceSubQuery(this.queryFactory.query(ReferenceQuery.class).types(ReferenceType.Organizations).isActive(IsActive.Active)).authorize(EnumSet.of(Owner)).count()); + statistics.setDmpCount(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active).dmpSubQuery(dmpQuery).referenceSubQuery(this.queryFactory.query(ReferenceQuery.class).types(ReferenceType.Grants).isActive(IsActive.Active)).authorize(EnumSet.of(Owner)).count()); + + cacheValue = new DashboardStatisticsCacheService.DashboardStatisticsCacheValue(this.userScope.getUserId()); + cacheValue.setPublic(false); + cacheValue.setDashboardStatistics(statistics); + this.dashboardStatisticsCacheService.put(cacheValue); + } + return cacheValue.getDashboardStatistics(); + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardStatisticsCacheOptions.java b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardStatisticsCacheOptions.java new file mode 100644 index 000000000..3b28fbd5a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardStatisticsCacheOptions.java @@ -0,0 +1,10 @@ +package eu.eudat.service.dashborad; + +import gr.cite.tools.cache.CacheOptions; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "cache.dashboard-statistics-by-user-id") +public class DashboardStatisticsCacheOptions extends CacheOptions { +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardStatisticsCacheService.java b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardStatisticsCacheService.java new file mode 100644 index 000000000..d700fb979 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dashborad/DashboardStatisticsCacheService.java @@ -0,0 +1,83 @@ +package eu.eudat.service.dashborad; + +import eu.eudat.model.DashboardStatistics; +import gr.cite.tools.cache.CacheService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Locale; +import java.util.UUID; + +@Service +public class DashboardStatisticsCacheService extends CacheService { + + public static final String publicKey = "Public"; + public static class DashboardStatisticsCacheValue { + + public DashboardStatisticsCacheValue() { + this.isPublic = true; + } + + public DashboardStatisticsCacheValue(UUID userId) { + this.userId = userId; + this.isPublic = false; + } + + private UUID userId; + private boolean isPublic; + + private DashboardStatistics dashboardStatistics; + + public UUID getUserId() { + return userId; + } + + public void setUserId(UUID userId) { + this.userId = userId; + } + + public DashboardStatistics getDashboardStatistics() { + return dashboardStatistics; + } + + public void setDashboardStatistics(DashboardStatistics dashboardStatistics) { + this.dashboardStatistics = dashboardStatistics; + } + + public boolean isPublic() { + return isPublic; + } + + public void setPublic(boolean aPublic) { + isPublic = aPublic; + } + } + + + @Autowired + public DashboardStatisticsCacheService(DashboardStatisticsCacheOptions options) { + super(options); + } + + @Override + protected Class valueClass() { + return DashboardStatisticsCacheValue.class; + } + + @Override + public String keyOf(DashboardStatisticsCacheValue value) { + if (value.userId == null){ + if (value.isPublic) return this.buildKey(publicKey); + else throw new IllegalArgumentException("Key not set"); + } else { + return this.buildKey(value.userId.toString().toLowerCase(Locale.ROOT)); + } + } + + public String buildKey(String key) { + HashMap keyParts = new HashMap<>(); + keyParts.put("$key$", key); + return this.generateKey(keyParts); + } +} 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 index ba69b39da..14b9bfdee 100644 --- 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 @@ -1,51 +1,23 @@ 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.model.censorship.*; 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 { @@ -72,7 +44,7 @@ public class DashboardController { - @PostMapping("recent-activity/mine") + @PostMapping("/mine/recent-activity") public List getMyRecentActivityItems(@RequestBody RecentActivityItemLookup lookup) throws InvalidApplicationException { logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("lookup", lookup)); @@ -89,4 +61,30 @@ public class DashboardController { return models; } + @GetMapping("mine/get-statistics") + public DashboardStatistics getMyDashboardStatistics() throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { + logger.debug(new MapLogEntry("retrieving public statistics")); + + this.censorFactory.censor(MyDashboardStatisticsCensor.class).censor(this.userScope.getUserIdSafe()); + + DashboardStatistics model = this.dashboardService.getMyDashboardStatistics(); + + this.auditService.track(AuditableAction.Dashboard_PublicDashboardStatistics); + + return model; + } + + @GetMapping("public/get-statistics") + public DashboardStatistics getPublicDashboardStatistics() throws MyApplicationException, MyForbiddenException, MyNotFoundException { + logger.debug(new MapLogEntry("retrieving public statistics")); + + this.censorFactory.censor(PublicDashboardStatisticsCensor.class).censor(null); + + DashboardStatistics model = this.dashboardService.getPublicDashboardStatistics(); + + this.auditService.track(AuditableAction.Dashboard_PublicDashboardStatistics); + + return model; + } + } diff --git a/dmp-backend/web/src/main/resources/config/cache.yml b/dmp-backend/web/src/main/resources/config/cache.yml index 7c3fd1dba..17ea03686 100644 --- a/dmp-backend/web/src/main/resources/config/cache.yml +++ b/dmp-backend/web/src/main/resources/config/cache.yml @@ -42,6 +42,14 @@ cache: expireAfterWriteMinutes: 10 expireAfterAccessMinutes: 10 refreshAfterWriteMinutes: 10 + - names: [ "dashboardStatisticsByUserId" ] + allowNullValues: true + initialCapacity: 100 + maximumSize: 500 + enableRecordStats: false + expireAfterWriteMinutes: 1 + expireAfterAccessMinutes: 1 + refreshAfterWriteMinutes: 1 mapCaches: apiKey: name: apikey @@ -55,6 +63,9 @@ cache: Reference: name: Reference keyPattern: reference_$type$_$criteria$:v0 + dashboardStatisticsByUserId: + name: dashboardStatisticsByUserId + keyPattern: dashboard_stats_by_usr_$key$:v0 deposit: name: deposit keyPattern: base:v0 \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/config/permissions.yml b/dmp-backend/web/src/main/resources/config/permissions.yml index 12fc511be..9e9c80a7f 100644 --- a/dmp-backend/web/src/main/resources/config/permissions.yml +++ b/dmp-backend/web/src/main/resources/config/permissions.yml @@ -80,7 +80,12 @@ permissions: clients: [ ] allowAnonymous: true allowAuthenticated: true - + PublicBrowseDashboardStatistics: + roles: [ ] + clients: [ ] + allowAnonymous: true + allowAuthenticated: true + # Elastic ManageElastic: roles: diff --git a/dmp-backend/web/src/main/resources/config/security.yml b/dmp-backend/web/src/main/resources/config/security.yml index 5fcc815b0..838fdbe5d 100644 --- a/dmp-backend/web/src/main/resources/config/security.yml +++ b/dmp-backend/web/src/main/resources/config/security.yml @@ -2,7 +2,7 @@ web: security: enabled: true authorized-endpoints: [ api ] - allowed-endpoints: [ api/public, api/description/public ] + allowed-endpoints: [ api/public, api/description/public, api/dashboard/public ] idp: api-key: enabled: true