Skip to content

Commit

Permalink
Issue 3015: Show notifications in GUI - pagination + read all (#3042)
Browse files Browse the repository at this point in the history
* Issue 3015: Show notifications in GUI - pagination + read all

* Issue 3015: Show notifications in GUI - pagination + read all

* Issue 3015: Show notifications in GUI - on/off ui notifications

* Issue #3015 User notifications: add env var to enable UI notifications

---------

Co-authored-by: mzueva <mariia_zueva@epam.com>
  • Loading branch information
okolesn and mzueva authored Feb 6, 2023
1 parent 623e928 commit 86d802f
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.epam.pipeline.acl.notification;

import com.epam.pipeline.controller.PagedResult;
import com.epam.pipeline.entity.notification.UserNotification;
import com.epam.pipeline.manager.notification.UserNotificationManager;
import lombok.RequiredArgsConstructor;
Expand All @@ -36,12 +37,19 @@ public UserNotification save(final UserNotification notification) {
}

@PreAuthorize("hasRole('ADMIN') OR @notificationPermissionManager.hasPermissionByUserId(#userId)")
public List<UserNotification> findByUserId(final Long userId) {
return notificationManager.findByUserId(userId);
public PagedResult<List<UserNotification>> findByUserId(final Long userId,
final Boolean isRead,
final int pageNum,
final int pageSize) {
return notificationManager.findByUserId(userId, isRead, pageNum, pageSize);
}

public List<UserNotification> findMy() {
return notificationManager.findMy();
public PagedResult<List<UserNotification>> findMy(final Boolean isRead, final int pageNum, final int pageSize) {
return notificationManager.findMy(isRead, pageNum, pageSize);
}

public void readAll() {
notificationManager.readAll();
}

@PreAuthorize("hasRole('ADMIN') OR @notificationPermissionManager.hasPermission(#notificationId)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.epam.pipeline.acl.notification.UserNotificationApiService;
import com.epam.pipeline.controller.AbstractRestController;
import com.epam.pipeline.controller.PagedResult;
import com.epam.pipeline.controller.Result;
import com.epam.pipeline.entity.notification.UserNotification;
import io.swagger.annotations.ApiOperation;
Expand All @@ -29,8 +30,10 @@
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
Expand All @@ -55,6 +58,19 @@ public Result<UserNotification> create(@RequestBody final UserNotification userN
return Result.success(notificationApiService.save(userNotification));
}

@PutMapping("/message/readAll")
@ApiOperation(
value = "Mark all user notifications as read.",
notes = "Mark all user notifications as read.",
produces = MediaType.APPLICATION_JSON_VALUE)
@ApiResponses(
value = {@ApiResponse(code = HTTP_STATUS_OK, message = API_STATUS_DESCRIPTION)}
)
public Result<Boolean> readAll() {
notificationApiService.readAll();
return Result.success();
}

@GetMapping("/message/{userId}")
@ApiOperation(
value = "Gets user notifications.",
Expand All @@ -63,8 +79,11 @@ public Result<UserNotification> create(@RequestBody final UserNotification userN
@ApiResponses(
value = {@ApiResponse(code = HTTP_STATUS_OK, message = API_STATUS_DESCRIPTION)}
)
public Result<List<UserNotification>> findByUserId(@PathVariable final Long userId) {
return Result.success(notificationApiService.findByUserId(userId));
public Result<PagedResult<List<UserNotification>>> findByUserId(@PathVariable final Long userId,
@RequestParam final Boolean isRead,
@RequestParam final int pageNum,
@RequestParam final int pageSize) {
return Result.success(notificationApiService.findByUserId(userId, isRead, pageNum, pageSize));
}

@GetMapping("/message/my")
Expand All @@ -75,8 +94,10 @@ public Result<List<UserNotification>> findByUserId(@PathVariable final Long user
@ApiResponses(
value = {@ApiResponse(code = HTTP_STATUS_OK, message = API_STATUS_DESCRIPTION)}
)
public Result<List<UserNotification>> findMy() {
return Result.success(notificationApiService.findMy());
public Result<PagedResult<List<UserNotification>>> findMy(@RequestParam final Boolean isRead,
@RequestParam final int pageNum,
@RequestParam final int pageSize) {
return Result.success(notificationApiService.findMy(isRead, pageNum, pageSize));
}

@DeleteMapping("/message/{messageId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.epam.pipeline.common.MessageConstants;
import com.epam.pipeline.common.MessageHelper;
import com.epam.pipeline.controller.PagedResult;
import com.epam.pipeline.entity.notification.UserNotification;
import com.epam.pipeline.entity.user.PipelineUser;
import com.epam.pipeline.manager.preference.PreferenceManager;
Expand All @@ -26,6 +27,9 @@
import com.epam.pipeline.manager.user.UserManager;
import com.epam.pipeline.repository.notification.UserNotificationRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
Expand All @@ -34,8 +38,6 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -73,17 +75,24 @@ public void cleanUp(final LocalDateTime date) {
userNotificationRepository.deleteByCreatedDateLessThan(date);
}

public List<UserNotification> findByUserId(final Long userId) {
return StreamSupport.stream(userNotificationRepository
.findByUserIdOrderByCreatedDateDesc(userId).spliterator(), false)
.collect(Collectors.toList());
public PagedResult<List<UserNotification>> findByUserId(final Long userId,
final Boolean isRead,
final int pageNum,
final int pageSize) {
final Pageable pageable = new PageRequest(Math.max(pageNum, 0), pageSize > 0 ? pageSize : 10);
final Page<UserNotification> notifications = isRead == null ?
userNotificationRepository.findByUserIdOrderByCreatedDateDesc(userId, pageable) :
userNotificationRepository.findByUserIdAndIsReadOrderByCreatedDateDesc(userId, isRead, pageable);
return new PagedResult<>(notifications.getContent(), (int) notifications.getTotalElements());
}

public List<UserNotification> findMy() {
final String currentUser = authManager.getAuthorizedUser();
final PipelineUser user = userManager.loadUserByName(currentUser);
Assert.notNull(user, messageHelper.getMessage(MessageConstants.ERROR_USER_NAME_NOT_FOUND, user));
return findByUserId(user.getId());
public PagedResult<List<UserNotification>> findMy(final Boolean isRead, final int pageNum, final int pageSize) {
return findByUserId(getPipelineUserId(), isRead, pageNum, pageSize);
}

@Transactional(propagation = Propagation.REQUIRED)
public void readAll() {
userNotificationRepository.readAll(getPipelineUserId(), LocalDateTime.now());
}

@Scheduled(fixedDelayString = "${scheduled.notifications.cleanup.sec:86400}")
Expand All @@ -98,4 +107,11 @@ private void setUp(final UserNotification notification) {
notification.setIsRead(false);
}
}

private Long getPipelineUserId() {
final String currentUser = authManager.getAuthorizedUser();
final PipelineUser user = userManager.loadUserByName(currentUser);
Assert.notNull(user, messageHelper.getMessage(MessageConstants.ERROR_USER_NAME_NOT_FOUND, user));
return user.getId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,21 @@
package com.epam.pipeline.repository.notification;

import com.epam.pipeline.entity.notification.UserNotification;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;

import java.time.LocalDateTime;

public interface UserNotificationRepository extends CrudRepository<UserNotification, Long> {
Iterable<UserNotification> findByUserIdOrderByCreatedDateDesc(Long userId);
public interface UserNotificationRepository extends PagingAndSortingRepository<UserNotification, Long> {
Page<UserNotification> findByUserIdAndIsReadOrderByCreatedDateDesc(Long userId, boolean isRead, Pageable pageable);
Page<UserNotification> findByUserIdOrderByCreatedDateDesc(Long userId, Pageable pageable);
void deleteByCreatedDateLessThan(LocalDateTime date);
void deleteByUserId(Long userId);

@Modifying
@Query("update UserNotification set isRead = true, readDate = ?2 where userId = ?1")
void readAll(Long userId, LocalDateTime readDate);
}
3 changes: 2 additions & 1 deletion deploy/docker/cp-notifier/config/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ spring.datasource.hikari.maximumPoolSize=${CP_NOTIFIER_DB_POOL_SIZE:1}

#in ms
notification.scheduler.delay=30000
notification.enable.smtp=true
notification.enable.smtp=${CP_NOTIFIER_SMTP_ENABLE:true}
notification.enable.ui=${CP_NOTIFIER_UI_ENABLE:false}

submit.threads=2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.ListUtils;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Value;

import javax.transaction.Transactional;
import java.time.LocalDateTime;
Expand All @@ -34,12 +35,18 @@
@RequiredArgsConstructor
public class UserNotificationManager implements NotificationManager {

@Value(value = "${notification.enable.ui}")
private boolean isEnabled;

private final UserNotificationRepository notificationRepository;
private final TemplateService templateService;

@Override
@Transactional
public void notifySubscribers(final NotificationMessage message) {
if (!isEnabled) {
return;
}
notificationRepository.save(toUserNotifications(message));
}

Expand Down
2 changes: 2 additions & 0 deletions notifier/smtp/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ spring.datasource.hikari.maximumPoolSize=1
notification.scheduler.delay=30000

notification.enable.smtp=true
notification.enable.ui=false

submit.threads=2

email.smtp.server.host.name=
Expand Down

0 comments on commit 86d802f

Please sign in to comment.