From fc5932f56a05ba4958cebebc329ac6ed1778f40c Mon Sep 17 00:00:00 2001 From: amentis Date: Mon, 15 Apr 2024 15:11:35 +0300 Subject: [PATCH] main app notify event changes --- .../service/deposit/DepositServiceImpl.java | 68 ++++++++++++++++++- .../description/DescriptionServiceImpl.java | 9 ++- .../DescriptionTemplateServiceImpl.java | 15 ++-- .../eu/eudat/service/dmp/DmpServiceImpl.java | 28 ++++---- .../eudat/service/user/UserServiceImpl.java | 2 - .../inapp-notification-editor.component.ts | 6 +- 6 files changed, 98 insertions(+), 30 deletions(-) diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java index 6f16bd3ad..50362a9a6 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java @@ -5,13 +5,24 @@ import eu.eudat.authorization.Permission; import eu.eudat.authorization.authorizationcontentresolver.AuthorizationContentResolver; import eu.eudat.commonmodels.models.FileEnvelopeModel; import eu.eudat.commonmodels.models.dmp.DmpModel; +import eu.eudat.commons.JsonHandlingService; +import eu.eudat.commons.enums.ContactInfoType; +import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.StorageType; +import eu.eudat.commons.notification.NotificationProperties; import eu.eudat.commons.scope.user.UserScope; +import eu.eudat.commons.types.notification.*; +import eu.eudat.convention.ConventionService; import eu.eudat.data.DmpEntity; +import eu.eudat.data.DmpUserEntity; +import eu.eudat.data.UserEntity; import eu.eudat.depositinterface.repository.DepositClient; import eu.eudat.depositinterface.repository.DepositConfiguration; +import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEvent; +import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEventHandler; import eu.eudat.model.EntityDoi; import eu.eudat.model.StorageFile; +import eu.eudat.model.UserContactInfo; import eu.eudat.model.builder.commonmodels.DepositConfigurationBuilder; import eu.eudat.model.builder.commonmodels.dmp.DmpCommonModelBuilder; import eu.eudat.model.persist.StorageFilePersist; @@ -19,6 +30,9 @@ import eu.eudat.model.persist.deposit.DepositAuthenticateRequest; import eu.eudat.model.persist.deposit.DepositRequest; import eu.eudat.model.persist.EntityDoiPersist; import eu.eudat.query.DmpQuery; +import eu.eudat.query.DmpUserQuery; +import eu.eudat.query.UserContactInfoQuery; +import eu.eudat.query.UserQuery; import eu.eudat.service.entitydoi.EntityDoiService; import eu.eudat.service.storage.StorageFileProperties; import eu.eudat.service.storage.StorageFileService; @@ -28,6 +42,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeModel; import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.fieldset.BaseFieldSet; @@ -42,11 +57,13 @@ import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; +import javax.management.InvalidApplicationException; import java.io.IOException; import java.net.URI; import java.net.URLConnection; import java.time.Duration; import java.util.*; +import java.util.stream.Collectors; @Service public class DepositServiceImpl implements DepositService { @@ -67,6 +84,10 @@ public class DepositServiceImpl implements DepositService { private final ValidatorFactory validatorFactory; private final StorageFileProperties storageFileProperties; private final AuthorizationContentResolver authorizationContentResolver; + private final ConventionService conventionService; + private final JsonHandlingService jsonHandlingService; + private final NotificationProperties notificationProperties; + private final NotifyIntegrationEventHandler eventHandler; @Autowired public DepositServiceImpl(DepositProperties depositProperties, TokenExchangeCacheService tokenExchangeCacheService, @@ -74,7 +95,7 @@ public class DepositServiceImpl implements DepositService { EntityDoiService doiService, QueryFactory queryFactory, MessageSource messageSource, - BuilderFactory builderFactory, DepositConfigurationCacheService depositConfigurationCacheService, FileTransformerService fileTransformerService, StorageFileService storageFileService, UserScope userScope, ValidatorFactory validatorFactory, StorageFileProperties storageFileProperties, AuthorizationContentResolver authorizationContentResolver) { + BuilderFactory builderFactory, DepositConfigurationCacheService depositConfigurationCacheService, FileTransformerService fileTransformerService, StorageFileService storageFileService, UserScope userScope, ValidatorFactory validatorFactory, StorageFileProperties storageFileProperties, AuthorizationContentResolver authorizationContentResolver, ConventionService conventionService, JsonHandlingService jsonHandlingService, NotificationProperties notificationProperties, NotifyIntegrationEventHandler eventHandler) { this.depositProperties = depositProperties; this.tokenExchangeCacheService = tokenExchangeCacheService; this.authorizationService = authorizationService; @@ -89,7 +110,11 @@ public class DepositServiceImpl implements DepositService { this.validatorFactory = validatorFactory; this.storageFileProperties = storageFileProperties; this.authorizationContentResolver = authorizationContentResolver; - this.clients = new HashMap<>(); + this.conventionService = conventionService; + this.jsonHandlingService = jsonHandlingService; + this.notificationProperties = notificationProperties; + this.eventHandler = eventHandler; + this.clients = new HashMap<>(); } private DepositClient getDepositClient(String repositoryId) { @@ -181,8 +206,47 @@ public class DepositServiceImpl implements DepositService { doiPersist.setRepositoryId(dmpDepositModel.getRepositoryId()); doiPersist.setDoi(doi); doiPersist.setEntityId(dmpEntity.getId()); + this.sendNotification(dmpEntity); return doiService.persist(doiPersist, dmpDepositModel.getProject()); } + + private void sendNotification(DmpEntity dmpEntity) throws InvalidApplicationException { + List dmpUsers = this.queryFactory.query(DmpUserQuery.class).ids(dmpEntity.getId()).isActives(IsActive.Active).collect(); + if (this.conventionService.isListNullOrEmpty(dmpUsers)){ + throw new MyNotFoundException("Dmp does not have Users"); + } + + List users = this.queryFactory.query(UserQuery.class).ids(dmpUsers.stream().map(x -> x.getUserId()).collect(Collectors.toList())).isActive(IsActive.Active).collect(); + + for (UserEntity user: users) { + if (!user.getId().equals(this.userScope.getUserIdSafe()) && !this.conventionService.isListNullOrEmpty(dmpUsers.stream().filter(x -> x.getUserId().equals(user.getId())).collect(Collectors.toList()))){ + this.createDmpDepositNotificationEvent(dmpEntity, user); + } + } + } + + private void createDmpDepositNotificationEvent(DmpEntity dmp, UserEntity user) throws InvalidApplicationException { + NotifyIntegrationEvent event = new NotifyIntegrationEvent(); + event.setUserId(user.getId()); + UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).userIds(user.getId()); + query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); + + List contactPairs = new ArrayList<>(); + contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue())); + NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); + event.setContactHint(jsonHandlingService.toJsonSafe(contactData)); + event.setNotificationType(notificationProperties.getDmpDepositType()); + NotificationFieldData data = new NotificationFieldData(); + List fieldInfoList = new ArrayList<>(); + fieldInfoList.add(new FieldInfo("{recipient}", DataType.String, user.getName())); + fieldInfoList.add(new FieldInfo("{reasonName}", DataType.String, this.queryFactory.query(UserQuery.class).ids(this.userScope.getUserId()).first().getName())); + fieldInfoList.add(new FieldInfo("{name}", DataType.String, dmp.getLabel())); + fieldInfoList.add(new FieldInfo("{id}", DataType.String, dmp.getId().toString())); + data.setFields(fieldInfoList); + event.setData(jsonHandlingService.toJsonSafe(data)); + + eventHandler.handle(event); + } private String addFileToSharedStorage(eu.eudat.model.file.FileEnvelope file) throws IOException { StorageFilePersist storageFilePersist = new StorageFilePersist(); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java index f0890cedf..636f26c5f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/description/DescriptionServiceImpl.java @@ -302,8 +302,7 @@ public class DescriptionServiceImpl implements DescriptionService { if (!dmpUser.getUserId().equals(this.userScope.getUserIdSafe())){ UserEntity user = this.queryFactory.query(UserQuery.class).ids(dmpUser.getUserId()).first(); if (user != null){ - this.createDescriptionNotificationEvent(description, user, NotificationContactType.EMAIL); - this.createDescriptionNotificationEvent(description, user, NotificationContactType.IN_APP); + this.createDescriptionNotificationEvent(description, user); } } } @@ -353,9 +352,9 @@ public class DescriptionServiceImpl implements DescriptionService { return cleanData; } - private void createDescriptionNotificationEvent(DescriptionEntity description, UserEntity user, NotificationContactType type) throws InvalidApplicationException { + private void createDescriptionNotificationEvent(DescriptionEntity description, UserEntity user) throws InvalidApplicationException { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); - event.setUserId(this.userScope.getUserId()); + event.setUserId(user.getId()); UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).userIds(user.getId()); query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); @@ -364,7 +363,6 @@ public class DescriptionServiceImpl implements DescriptionService { contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue())); NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); event.setContactHint(jsonHandlingService.toJsonSafe(contactData)); - event.setContactTypeHint(type); event = this.applyNotificationType(description.getStatus(), event); NotificationFieldData data = new NotificationFieldData(); @@ -421,6 +419,7 @@ public class DescriptionServiceImpl implements DescriptionService { this.eventBroker.emit(new DescriptionTouchedEvent(data.getId())); this.annotationEntityTouchedIntegrationEventHandler.handleDescription(data.getId()); + if (data.getStatus().equals(DescriptionStatus.Finalized)) this.sendNotification(data); } return this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, Description._id), data); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java index e0fb45be1..9f448b9e2 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java @@ -245,8 +245,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic data.setRole(user.getRole()); this.entityManager.persist(data); if (!this.userScope.getUserId().equals(user.getUserId())) { - this.sendDescriptionTemplateInvitationEvent(data, NotificationContactType.EMAIL); - this.sendDescriptionTemplateInvitationEvent(data, NotificationContactType.IN_APP); + this.sendDescriptionTemplateInvitationEvent(data); } } updatedCreatedIds.add(data.getUserId()); @@ -256,13 +255,18 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic this.deleterFactory.deleter(UserDescriptionTemplateDeleter.class).delete(toDelete); } - private void sendDescriptionTemplateInvitationEvent(UserDescriptionTemplateEntity userDescriptionTemplate, NotificationContactType type) throws InvalidApplicationException { + private void sendDescriptionTemplateInvitationEvent(UserDescriptionTemplateEntity userDescriptionTemplate) throws InvalidApplicationException { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); - event.setUserId(userScope.getUserIdSafe()); UserEntity user = this.entityManager.find(UserEntity.class, userDescriptionTemplate.getUserId()); + if (user == null){ + throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{userDescriptionTemplate.getUserId(), User.class.getSimpleName()}, LocaleContextHolder.getLocale())); + } DescriptionTemplateEntity descriptionTemplate = this.queryFactory.query(DescriptionTemplateQuery.class).isActive(IsActive.Active).ids(userDescriptionTemplate.getDescriptionTemplateId()).first(); - + if (descriptionTemplate == null){ + throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{userDescriptionTemplate.getDescriptionTemplateId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale())); + } + event.setUserId(user.getId()); UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).userIds(user.getId()); query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); @@ -270,7 +274,6 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue())); NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); event.setContactHint(jsonHandlingService.toJsonSafe(contactData)); - event.setContactTypeHint(type); event.setNotificationType(notificationProperties.getDescriptionTemplateInvitationType()); NotificationFieldData data = new NotificationFieldData(); List fieldInfoList = new ArrayList<>(); 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 39f34de96..d1c24ba50 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 @@ -258,16 +258,15 @@ public class DmpServiceImpl implements DmpService { if (!dmpUser.getUserId().equals(this.userScope.getUserIdSafe())){ UserEntity user = this.queryFactory.query(UserQuery.class).ids(dmpUser.getUserId()).first(); if (user != null){ - this.createDmpNotificationEvent(dmp, user, NotificationContactType.EMAIL); - this.createDmpNotificationEvent(dmp, user, NotificationContactType.IN_APP); + this.createDmpNotificationEvent(dmp, user); } } } } - private void createDmpNotificationEvent(DmpEntity dmp, UserEntity user, NotificationContactType type) throws InvalidApplicationException { + private void createDmpNotificationEvent(DmpEntity dmp, UserEntity user) throws InvalidApplicationException { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); - event.setUserId(this.userScope.getUserId()); + event.setUserId(user.getId()); UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).userIds(user.getId()); query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); @@ -275,7 +274,6 @@ public class DmpServiceImpl implements DmpService { contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue())); NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); event.setContactHint(jsonHandlingService.toJsonSafe(contactData)); - event.setContactTypeHint(type); this.applyNotificationType(dmp.getStatus(), event); NotificationFieldData data = new NotificationFieldData(); @@ -1186,6 +1184,15 @@ public class DmpServiceImpl implements DmpService { throw new InvalidApplicationException("Dmp does not exist!"); } + List existingUsers = this.queryFactory.query(DmpUserQuery.class) + .dmpIds(dmp.getId()) + .isActives(IsActive.Active) + .collect(); + + if (this.conventionService.isListNullOrEmpty(existingUsers)){ + throw new InvalidApplicationException("Dmp does not have users!"); + } + List usersToAssign = new ArrayList<>(); for (DmpUserPersist user :users) { UUID userId = null; @@ -1200,7 +1207,7 @@ public class DmpServiceImpl implements DmpService { if (userId != null){ user.setUser(userId); usersToAssign.add(user); - if (this.userScope.getUserId() != userId){ + if (this.userScope.getUserId() != userId && !existingUsers.stream().map(x -> x.getUserId()).collect(Collectors.toList()).contains(userId)){ this.sendDmpInvitationExistingUser(user.getUser(), dmp, user.getRole()); } }else if (user.getEmail() != null) { @@ -1215,20 +1222,18 @@ public class DmpServiceImpl implements DmpService { private void sendDmpInvitationExistingUser(UUID userId, DmpEntity dmp, DmpUserRole role) throws InvalidApplicationException { UserEntity recipient = this.queryFactory.query(UserQuery.class).ids(userId).isActive(IsActive.Active).first(); String email = this.queryFactory.query(UserContactInfoQuery.class).userIds(recipient.getId()).first().getValue(); - this.createDmpInvitationExistingUserEvent(recipient, dmp, role, email, NotificationContactType.EMAIL); - this.createDmpInvitationExistingUserEvent(recipient, dmp, role, email, NotificationContactType.IN_APP); + this.createDmpInvitationExistingUserEvent(recipient, dmp, role, email); } - private void createDmpInvitationExistingUserEvent(UserEntity recipient, DmpEntity dmp, DmpUserRole role, String email, NotificationContactType type) throws InvalidApplicationException { + private void createDmpInvitationExistingUserEvent(UserEntity recipient, DmpEntity dmp, DmpUserRole role, String email) throws InvalidApplicationException { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); - event.setUserId(this.userScope.getUserIdSafe()); + event.setUserId(recipient.getId()); List contactPairs = new ArrayList<>(); contactPairs.add(new ContactPair(ContactInfoType.Email, email)); NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); event.setContactHint(jsonHandlingService.toJsonSafe(contactData)); - event.setContactTypeHint(type); event.setNotificationType(notificationProperties.getDmpInvitationExistingUserType()); NotificationFieldData data = new NotificationFieldData(); List fieldInfoList = new ArrayList<>(); @@ -1246,7 +1251,6 @@ public class DmpServiceImpl implements DmpService { String token = this.createActionConfirmation(email, dmp, role); NotifyIntegrationEvent event = new NotifyIntegrationEvent(); - event.setUserId(this.userScope.getUserIdSafe()); List contactPairs = new ArrayList<>(); contactPairs.add(new ContactPair(ContactInfoType.Email, email)); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/user/UserServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/user/UserServiceImpl.java index c4e8d3c72..4706d42c4 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/user/UserServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/user/UserServiceImpl.java @@ -375,7 +375,6 @@ public class UserServiceImpl implements UserService { String token = this.createMergeAccountConfirmation(model.getEmail()); createMergeNotificationEvent(token, user, model.getEmail(), NotificationContactType.EMAIL); - createMergeNotificationEvent(token, user, model.getEmail(), NotificationContactType.IN_APP); } private void createMergeNotificationEvent(String token, UserEntity user, String email, NotificationContactType type) throws InvalidApplicationException { @@ -405,7 +404,6 @@ public class UserServiceImpl implements UserService { String token = this.createRemoveConfirmation(data.getId()); this.createRemoveCredentialNotificationEvent(token, data.getUserId(), NotificationContactType.EMAIL); - this.createRemoveCredentialNotificationEvent(token, data.getUserId(), NotificationContactType.IN_APP); } private void createRemoveCredentialNotificationEvent(String token, UUID userId, NotificationContactType type) throws InvalidApplicationException { diff --git a/dmp-frontend/src/notification-service/ui/inapp-notification/editor/inapp-notification-editor.component.ts b/dmp-frontend/src/notification-service/ui/inapp-notification/editor/inapp-notification-editor.component.ts index a76cce850..881751746 100644 --- a/dmp-frontend/src/notification-service/ui/inapp-notification/editor/inapp-notification-editor.component.ts +++ b/dmp-frontend/src/notification-service/ui/inapp-notification/editor/inapp-notification-editor.component.ts @@ -99,9 +99,9 @@ export class InAppNotificationEditorComponent extends BaseComponent implements O maxWidth: '300px', restoreFocus: false, data: { - message: this.language.instant('COMMONS.CONFIRMATION-DIALOG.DELETE-ITEM'), - confirmButton: this.language.instant('COMMONS.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), - cancelButton: this.language.instant('COMMONS.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') } }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {