From e73565aa71104fff07f21dccc1be5957d539154c Mon Sep 17 00:00:00 2001 From: Timo Bejan Date: Wed, 15 Sep 2021 11:55:39 +0300 Subject: [PATCH] integrated notificaiton and audit --- .../persistence-service-api-v1/pom.xml | 12 +++ .../data/audit/AddNotificationRequest.java | 24 ++++++ .../v1/api/model/data/audit/AuditModel.java | 41 +++++++++ .../v1/api/model/data/audit/AuditRequest.java | 27 ++++++ .../model/data/audit/AuditSearchRequest.java | 21 +++++ .../api/model/data/audit/CategoryModel.java | 8 ++ .../model/data/notification/Notification.java | 53 ++++++++++++ .../v1/api/resources/AuditResource.java | 37 ++++++++ .../api/resources/NotificationResource.java | 50 +++++++++++ .../service/v1/api/utils/JSONConverter.java | 27 ++++++ ...sistenceServiceProcessorConfiguration.java | 4 +- .../persistence/AuditPersistenceService.java | 85 +++++++++++++++++++ .../NotificationPersistenceService.java | 72 ++++++++++++++++ .../repository/AuditRepository.java | 19 +++++ .../repository/NotificationRepository.java | 21 +++++ .../v1/server/controller/AuditController.java | 38 +++++++++ .../controller/NotificationController.java | 70 +++++++++++++++ 17 files changed, 608 insertions(+), 1 deletion(-) create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AddNotificationRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditModel.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditSearchRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/CategoryModel.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/notification/Notification.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/AuditResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/NotificationResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/utils/JSONConverter.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/AuditPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/AuditRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/NotificationRepository.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/AuditController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/NotificationController.java diff --git a/persistence-service-v1/persistence-service-api-v1/pom.xml b/persistence-service-v1/persistence-service-api-v1/pom.xml index d4a7bc4fb..fb329153b 100644 --- a/persistence-service-v1/persistence-service-api-v1/pom.xml +++ b/persistence-service-v1/persistence-service-api-v1/pom.xml @@ -50,6 +50,18 @@ com.iqser.red.commons jackson-commons + + org.hibernate + hibernate-core + 5.4.28.Final + compile + + + org.springframework.data + spring-data-commons + 2.4.5 + compile + diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AddNotificationRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AddNotificationRequest.java new file mode 100644 index 000000000..287781c63 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AddNotificationRequest.java @@ -0,0 +1,24 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.audit; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AddNotificationRequest { + + private String userId; + private String issuerId; + private String notificationType; + + @Builder.Default + private Map target = new HashMap<>(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditModel.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditModel.java new file mode 100644 index 000000000..233103a1f --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditModel.java @@ -0,0 +1,41 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.audit; + +import com.iqser.red.service.persistence.service.v1.api.utils.JSONConverter; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.time.OffsetDateTime; +import java.util.Map; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name="audit") +public class AuditModel { + + @Id + @GeneratedValue + private long recordId; + + @Column + private OffsetDateTime recordDate; + + @Column + private String objectId; + @Column + private String category; + @Column + private String userId; + @Column + private String message; + + @Convert(converter = JSONConverter.class) + @Column(columnDefinition = "json") + private Map details; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditRequest.java new file mode 100644 index 000000000..16b6318df --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditRequest.java @@ -0,0 +1,27 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.audit; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.HashMap; +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AuditRequest { + + private String objectId; + private String category; + private String userId; + + private String message; + + @Builder.Default + private Map details = new HashMap<>(); + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditSearchRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditSearchRequest.java new file mode 100644 index 000000000..c6d637247 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/AuditSearchRequest.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.audit; + +import lombok.Data; + +import java.time.OffsetDateTime; + +@Data +public class AuditSearchRequest { + + private String category; + private String userId; + private String objectId; + private String requestingUserId; + + private OffsetDateTime from; + private OffsetDateTime to; + + private int page; + private int pageSize; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/CategoryModel.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/CategoryModel.java new file mode 100644 index 000000000..3d23a2d63 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/audit/CategoryModel.java @@ -0,0 +1,8 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.audit; + +public interface CategoryModel { + + String getCategory(); + + long getRecordCount(); +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/notification/Notification.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/notification/Notification.java new file mode 100644 index 000000000..e977c6c62 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/notification/Notification.java @@ -0,0 +1,53 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.notification; + +import com.iqser.red.service.persistence.service.v1.api.utils.JSONConverter; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; + +import javax.persistence.*; +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.Map; + +@Data +@NoArgsConstructor +@Entity +@Table(name = "notification") +public class Notification { + + @Id + @GeneratedValue + private long id; + + @Column + private String userId; + + @Column + private String notificationType; + + @Column + private String issuerId; + + @Column + private OffsetDateTime creationDate; + + @Column + private OffsetDateTime seenDate; + + @Column + private OffsetDateTime readDate; + + @Column + private OffsetDateTime softDeleted; + + @Column + private String notificationDetails; + + @Convert(converter = JSONConverter.class) + @Column(columnDefinition = "json") + private Map target = new HashMap<>(); +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/AuditResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/AuditResource.java new file mode 100644 index 000000000..5f09829f4 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/AuditResource.java @@ -0,0 +1,37 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditModel; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditSearchRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.CategoryModel; +import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +public interface AuditResource { + + String PATH = "/audit"; + + /** + * @param auditRequest - details to audit + * @throws org.springframework.web.server.ResponseStatusException - 404 - Not Found in case the object doesn't exist + */ + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = PATH, consumes = MediaType.APPLICATION_JSON_VALUE) + void audit(@RequestBody AuditRequest auditRequest); + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = PATH + "/search", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + Page search(@RequestBody AuditSearchRequest auditSearchRequest); + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = PATH + "/categories", produces = MediaType.APPLICATION_JSON_VALUE) + List getCategories(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/NotificationResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/NotificationResource.java new file mode 100644 index 000000000..883760d2f --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/NotificationResource.java @@ -0,0 +1,50 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AddNotificationRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.notification.Notification; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@ResponseStatus(value = HttpStatus.OK) +public interface NotificationResource { + + String NOTIFICATION_PATH = "/notification"; + String TOGGLE_SEEN_PATH = "/toggle-seen"; + String TOGGLE_READ_PATH = "/toggle-read"; + + String USER_ID_PARAM = "userId"; + String USER_ID_PATH_PARAM = "/{" + USER_ID_PARAM + "}"; + + String INCLUDE_SEEN_PARAM = "includeSeen"; + String SET_SEEN_PARAM = "setSeen"; + String SET_READ_PARAM = "setRead"; + + + @PostMapping(value = NOTIFICATION_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) + void addNotification(@RequestBody AddNotificationRequest addNotificationRequest); + + + @PostMapping(value = NOTIFICATION_PATH + TOGGLE_SEEN_PATH + USER_ID_PATH_PARAM, consumes = MediaType.APPLICATION_JSON_VALUE) + void toggleSeen(@PathVariable(USER_ID_PARAM) String userId, @RequestBody List notificationIds, + @RequestParam(SET_SEEN_PARAM) boolean setSeen); + + + @PostMapping(value = NOTIFICATION_PATH + TOGGLE_READ_PATH + USER_ID_PATH_PARAM, consumes = MediaType.APPLICATION_JSON_VALUE) + void toggleRead(@PathVariable(USER_ID_PARAM) String userId, @RequestBody List notificationIds, + @RequestParam(SET_READ_PARAM) boolean setRead); + + + @DeleteMapping(value = NOTIFICATION_PATH + USER_ID_PATH_PARAM, consumes = MediaType.APPLICATION_JSON_VALUE) + void softDelete(@PathVariable(USER_ID_PARAM) String userId, @RequestBody List notificationIds); + + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = NOTIFICATION_PATH + USER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) + List getNotifications(@PathVariable(USER_ID_PARAM) String userId, + @RequestParam(INCLUDE_SEEN_PARAM) boolean includeSeen); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/utils/JSONConverter.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/utils/JSONConverter.java new file mode 100644 index 000000000..ebc4c6c37 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/utils/JSONConverter.java @@ -0,0 +1,27 @@ +package com.iqser.red.service.persistence.service.v1.api.utils; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import java.util.Map; + +@Converter(autoApply = true) +public class JSONConverter implements AttributeConverter, String> { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + + @SneakyThrows + @Override + public String convertToDatabaseColumn(Map map) { + return objectMapper.writeValueAsString(map); + } + + @SneakyThrows + @Override + public Map convertToEntityAttribute(String data) { + return objectMapper.readValue(data, Map.class); + } +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java index 159548407..d0e2e7103 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java @@ -3,9 +3,11 @@ package com.iqser.red.service.persistence.management.v1.processor; import com.iqser.red.service.persistence.management.v1.processor.client.PDFTronRedactionClient; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ColorsRepository; import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.Comment; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditModel; import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Colors; import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.notification.Notification; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; @@ -14,7 +16,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @Configuration @ComponentScan -@EntityScan(basePackageClasses = {Comment.class, Colors.class, Dossier.class, DownloadStatus.class}) +@EntityScan(basePackageClasses = {Comment.class, AuditModel.class, Notification.class, Colors.class, Dossier.class, DownloadStatus.class}) @EnableJpaRepositories(basePackageClasses = ColorsRepository.class) @EnableFeignClients(basePackageClasses = {PDFTronRedactionClient.class}) public class PersistenceServiceProcessorConfiguration { diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/AuditPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/AuditPersistenceService.java new file mode 100644 index 000000000..1340607ce --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/AuditPersistenceService.java @@ -0,0 +1,85 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.AuditRepository; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditModel; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditSearchRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.CategoryModel; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.springframework.beans.BeanUtils; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +@Service +@RequiredArgsConstructor +public class AuditPersistenceService { + + private final static String AUDIT_LOG_CATEGORY = "AUDIT_LOG"; + + private final AuditRepository auditRepository; + + @SneakyThrows + public void insertRecord(AuditRequest auditRequest) { + + + var auditModel = new AuditModel(); + BeanUtils.copyProperties(auditRequest, auditModel); + auditModel.setRecordDate(OffsetDateTime.now()); + + auditRepository.save(auditModel); + + } + + public List getCategories() { + return auditRepository.findCategories(); + + } + + public Page search(AuditSearchRequest auditRequest) { + + + AuditModel example = new AuditModel(); + example.setCategory(auditRequest.getCategory()); + example.setUserId(auditRequest.getUserId()); + example.setObjectId(auditRequest.getObjectId()); + + var result = auditRepository.findAll(Example.of(example), PageRequest.of(auditRequest.getPage(), auditRequest.getPageSize())); + + // after search, insert a record logging the search + this.insertRecord(AuditRequest.builder() + .category(AUDIT_LOG_CATEGORY) + .message("Audit Log Accessed") + .userId(auditRequest.getRequestingUserId()) + .details(searchRequestToMap(auditRequest)) + .build()); + return result; + } + + + private Map searchRequestToMap(AuditSearchRequest auditSearchRequest) { + + var map = new HashMap(); + + map.put("userId", auditSearchRequest.getUserId()); + map.put("category", auditSearchRequest.getCategory()); + map.put("objectId", auditSearchRequest.getObjectId()); + map.put("from", auditSearchRequest.getFrom()); + map.put("to", auditSearchRequest.getTo()); + map.put("page", auditSearchRequest.getPage()); + map.put("pageSize", auditSearchRequest.getPageSize()); + + return map; + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java new file mode 100644 index 000000000..cf8ffd38f --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java @@ -0,0 +1,72 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.NotificationRepository; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AddNotificationRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.notification.Notification; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class NotificationPersistenceService { + + + private final NotificationRepository notificationRepository; + + + @SneakyThrows + public void insertNotification(AddNotificationRequest addNotificationRequest) { + + var notification = new Notification(); + BeanUtils.copyProperties(addNotificationRequest, notification); + notification.setCreationDate(OffsetDateTime.now()); + + notificationRepository.save(notification); + } + + + public void setSeenDate(String userId, long notificationId, OffsetDateTime seenDate) { + + notificationRepository.findByIdAndUserId(notificationId, userId).ifPresentOrElse(notification -> notification.setSeenDate(seenDate), () -> { + throw new NotFoundException("Notification not found"); + }); + } + + + public void setReadDate(String userId, long notificationId, OffsetDateTime readDate) { + notificationRepository.findByIdAndUserId(notificationId, userId).ifPresentOrElse(notification -> notification.setReadDate(readDate), () -> { + throw new NotFoundException("Notification not found"); + }); + } + + + public void softDelete(String userId, long notificationId) { + notificationRepository.findByIdAndUserId(notificationId, userId).ifPresentOrElse(notification -> notification.setSoftDeleted(OffsetDateTime.now()), () -> { + throw new NotFoundException("Notification not found"); + }); + } + + + public void hardDelete(long notificationId) { + notificationRepository.deleteById(notificationId); + } + + + public List getNotifications(String userId, boolean includeSeen) { + + if (includeSeen) { + return notificationRepository.findForUser(userId); + } else { + return notificationRepository.findNotSeenForUser(userId); + } + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/AuditRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/AuditRepository.java new file mode 100644 index 000000000..0217ffcc9 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/AuditRepository.java @@ -0,0 +1,19 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditModel; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.CategoryModel; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface AuditRepository extends JpaRepository { + + @Query("SELECT a.category, count(a) as recordCount FROM AuditModel a GROUP BY a.category") + List findCategories(); + + + Page findAllByObjectId(double price, Pageable pageable); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/NotificationRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/NotificationRepository.java new file mode 100644 index 000000000..8301c36f4 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/NotificationRepository.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.notification.Notification; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Optional; + +public interface NotificationRepository extends JpaRepository { + + List findByUserIdOrderByCreationDateDesc(String userId); + + @Query("Select n from Notification n where n.softDeleted is null and n.userId = :userId order by n.creationDate desc") + List findForUser(String userId); + + @Query("Select n from Notification n where n.seenDate is null and n.softDeleted is null and n.userId = :userId order by n.creationDate desc") + List findNotSeenForUser(String userId); + + Optional findByIdAndUserId(long notificationId, String userId); +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/AuditController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/AuditController.java new file mode 100644 index 000000000..836294b65 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/AuditController.java @@ -0,0 +1,38 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditModel; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AuditSearchRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.CategoryModel; +import com.iqser.red.service.persistence.service.v1.api.resources.AuditResource; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class AuditController implements AuditResource { + + private final AuditPersistenceService auditPersistenceService; + + @Override + public void audit(@RequestBody AuditRequest auditRequest) { + auditPersistenceService.insertRecord(auditRequest); + } + + @Override + public Page search(@RequestBody AuditSearchRequest auditSearchRequest) { + return auditPersistenceService.search(auditSearchRequest); + } + + @Override + public List getCategories() { + return auditPersistenceService.getCategories(); + } + + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/NotificationController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/NotificationController.java new file mode 100644 index 000000000..661f56ce5 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/NotificationController.java @@ -0,0 +1,70 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.audit.AddNotificationRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.notification.Notification; +import com.iqser.red.service.persistence.service.v1.api.resources.NotificationResource; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.time.OffsetDateTime; +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class NotificationController implements NotificationResource { + + private final NotificationPersistenceService notificationPersistenceService; + + + public void addNotification(@RequestBody AddNotificationRequest addNotificationRequest) { + + notificationPersistenceService.insertNotification(addNotificationRequest); + } + + + public void toggleSeen(@PathVariable(USER_ID_PARAM) String userId, @RequestBody List notificationIds, + @RequestParam(SET_SEEN_PARAM) boolean setSeen) { + + notificationIds.forEach(notificationId -> { + if (setSeen) { + notificationPersistenceService.setSeenDate(userId, notificationId, OffsetDateTime.now()); + } else { + notificationPersistenceService.setSeenDate(userId, notificationId, null); + } + }); + } + + + public void toggleRead(@PathVariable(USER_ID_PARAM) String userId, @RequestBody List notificationIds, + @RequestParam(SET_READ_PARAM) boolean setRead) { + + notificationIds.forEach(notificationId -> { + if (setRead) { + notificationPersistenceService.setReadDate(userId, notificationId, OffsetDateTime.now()); + } else { + notificationPersistenceService.setReadDate(userId, notificationId, null); + } + }); + + } + + + public void softDelete(@PathVariable(USER_ID_PARAM) String userId, @RequestBody List notificationIds) { + + notificationIds.forEach(notificationId -> { + notificationPersistenceService.softDelete(userId, notificationId); + }); + } + + + public List getNotifications(@PathVariable(USER_ID_PARAM) String userId, + @RequestParam(INCLUDE_SEEN_PARAM) boolean includeSeen) { + + return notificationPersistenceService.getNotifications(userId,includeSeen); + } + +}