Added Post system. Notification system

This commit is contained in:
redtea committed 2022-09-01 17:04:25 +03:00
1 parent cc068fc3a8
commit 3ac444931c
29 files changed
+639 -86

No files matched your search

@@ -0,0 +1,28 @@
package site.easystartup.web.notification.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import site.easystartup.web.notification.domian.Notification;
import java.security.Principal;
import java.util.logging.Logger;
@Controller
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class NotificationController {
private final SimpMessagingTemplate messagingTemplate;
Logger logger = Logger.getGlobal();
@GetMapping("/notify")
public void notification(Principal principal, @Payload Notification notification) {
logger.info("Web socket sent notification to " + principal.getName());
messagingTemplate.convertAndSendToUser(principal.getName(), "queue/notification", notification);
}
}
@@ -0,0 +1,32 @@
package site.easystartup.web.notification.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import site.easystartup.web.notification.domian.Notification;
import site.easystartup.web.notification.repo.NotificationRepo;
import site.easystartup.web.notification.service.NotificationService;
import java.security.Principal;
import java.util.List;
@RestController
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class NotificationRestController {
private final NotificationService notificationService;
@GetMapping("/notifications/{username}")
public ResponseEntity<List<Notification>> notification(@PathVariable String username, Principal principal) {
return ResponseEntity.ok().body(notificationService.getNotificationByRecipient(username, principal));
}
@DeleteMapping("/notifications/{id}/delete")
public void delete(@PathVariable long id,
Principal principal) {
notificationService.delete(id, principal);
}
}
@@ -0,0 +1,17 @@
package site.easystartup.web.notification.domian;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.Id;
@Getter
@Setter
@ToString
@Entity
public class Notification {
@Id
private long id;
private String text;
private String recipient;
}
@@ -0,0 +1,12 @@
package site.easystartup.web.notification.event;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EventHandler {
}
@@ -0,0 +1,9 @@
package site.easystartup.web.notification.event;
public interface NotificationEvent {
void invoke();
String getRecipient();
String getMessage();
}
@@ -0,0 +1,36 @@
package site.easystartup.web.notification.event;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Component
@Scope("singleton")
public class NotificationEventManager {
private List<NotificationListener> listeners = new ArrayList<>();
public void registerListener(NotificationListener listener) {
listeners.add(listener);
}
public void removeListener(NotificationListener listener) {
listeners.remove(listener);
}
public void notifyListeners(Class<? extends NotificationEvent> event) {
listeners.forEach(listener -> Arrays.stream(listener.getClass().getMethods()).
filter(m -> m.isAnnotationPresent(EventHandler.class)).forEach(method -> {
if (method.getParameterTypes()[0].equals(event.getClass())) {
try {
method.invoke(listener, event);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}));
}
}
@@ -0,0 +1,4 @@
package site.easystartup.web.notification.event;
public interface NotificationListener {
}
@@ -0,0 +1,26 @@
package site.easystartup.web.notification.event.realtime;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import site.easystartup.web.notification.domian.Notification;
import site.easystartup.web.notification.event.EventHandler;
import site.easystartup.web.notification.event.NotificationEvent;
import site.easystartup.web.notification.event.NotificationListener;
import site.easystartup.web.notification.repo.NotificationRepo;
import site.easystartup.web.notification.service.NotificationService;
import site.easystartup.web.post.domain.event.RepostEvent;
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class RealTimeListener implements NotificationListener {
private final NotificationService notificationService;
private final NotificationRepo repo;
@EventHandler
public void onEvent(NotificationEvent event) {
Notification notification = new Notification();
notification.setText(event.getMessage());
notification.setRecipient(event.getRecipient());
notificationService.sendNotification(repo.save(notification));
}
}
@@ -0,0 +1,7 @@
package site.easystartup.web.notification.repo;
import org.springframework.data.jpa.repository.JpaRepository;
import site.easystartup.web.notification.domian.Notification;
public interface NotificationRepo extends JpaRepository<Notification, Long> {
}
@@ -0,0 +1,43 @@
package site.easystartup.web.notification.service;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;
import site.easystartup.web.exception.NoPermissionException;
import site.easystartup.web.notification.domian.Notification;
import site.easystartup.web.notification.repo.NotificationRepo;
import site.easystartup.web.service.UserService;
import java.security.Principal;
import java.util.List;
@Component
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class NotificationService {
private final SimpMessagingTemplate messagingTemplate;
private final NotificationRepo repo;
private final UserService userService;
public void sendNotification(Notification notification) {
messagingTemplate.convertAndSendToUser(notification.getRecipient(), "queue/notification", notification);
}
public List<Notification> getNotificationByRecipient(String recipient, Principal principal) {
if(!recipient.equals(principal.getName()) && !userService.getUserByPrincipal(principal).isAdmin())
throw new NoPermissionException(String.format("User %s dont have access to see notifications of user %s",
principal.getName(), recipient));
return repo.findAll().stream()
.filter(notification -> notification.getRecipient().equals(recipient)).toList();
}
public void delete(long id, Principal principal) {
Notification notification = repo.findById(id).orElseThrow();
if(!notification.getRecipient().equals(principal.getName()) && !userService.getUserByPrincipal(principal).isAdmin())
throw new NoPermissionException(String.format("User %s dont have access to delete notifications of user %s",
principal.getName(), notification.getRecipient()));
repo.delete(notification);
}
}