package eu.eudat.service.dashborad; 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.*; import eu.eudat.commons.enums.ReferenceType; import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.types.dashborad.RecentActivityItemEntity; import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.event.EventBroker; import eu.eudat.model.*; import eu.eudat.model.builder.RecentActivityItemBuilder; 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.QueryFactory; import gr.cite.tools.fieldset.BaseFieldSet; 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.context.MessageSource; import org.springframework.stereotype.Service; import javax.management.InvalidApplicationException; import java.util.*; import static eu.eudat.authorization.AuthorizationFlags.Owner; 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; private final DashboardStatisticsCacheService dashboardStatisticsCacheService; @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, DashboardStatisticsCacheService dashboardStatisticsCacheService) { 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; this.dashboardStatisticsCacheService = dashboardStatisticsCacheService; } @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); 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); } @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(ReferenceQuery.class).isActive(IsActive.Active).types(ReferenceType.Organizations).authorize(EnumSet.of(Public)) .dmpReferenceSubQuery(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active) .dmpSubQuery(dmpQuery)).count()); statistics.setGrantCount(this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).types(ReferenceType.Grants).authorize(EnumSet.of(Public)) .dmpReferenceSubQuery(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active) .dmpSubQuery(dmpQuery)).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); DashboardStatistics statistics = new DashboardStatistics(); statistics.setDmpCount(dmpQuery.authorize(EnumSet.of(AuthorizationFlags.DmpAssociated)).count()); statistics.setDescriptionCount(this.queryFactory.query(DescriptionQuery.class).isActive(IsActive.Active).dmpSubQuery(dmpQuery).statuses(DescriptionStatus.Finalized).authorize(EnumSet.of(AuthorizationFlags.DmpAssociated)).count()); statistics.setOrganizationCount(this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).types(ReferenceType.Organizations).authorize(EnumSet.of(Owner)) .dmpReferenceSubQuery(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active) .dmpSubQuery(dmpQuery)).count()); statistics.setGrantCount(this.queryFactory.query(ReferenceQuery.class).isActive(IsActive.Active).types(ReferenceType.Grants).authorize(EnumSet.of(Owner)) .dmpReferenceSubQuery(this.queryFactory.query(DmpReferenceQuery.class).isActives(IsActive.Active) .dmpSubQuery(dmpQuery)).count()); cacheValue = new DashboardStatisticsCacheService.DashboardStatisticsCacheValue(this.userScope.getUserId()); cacheValue.setPublic(false); cacheValue.setDashboardStatistics(statistics); this.dashboardStatisticsCacheService.put(cacheValue); } return cacheValue.getDashboardStatistics(); } }