Added notifications system

This commit is contained in:
redtea committed 2022-08-31 22:22:15 +03:00
1 parent 5e5871b78c
commit ff67f31cf3
14 files changed
+178 -2

No files matched your search

@@ -1,11 +1,13 @@
package site.easystartup.web.config;
import org.modelmapper.ModelMapper;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Configuration
@ComponentScan(basePackages = {"site.easystartup.web"})
@@ -1,4 +1,4 @@
package site.easystartup.web.chat.config;
package site.easystartup.web.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Configuration;
@@ -19,7 +19,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker( "/user");
config.enableSimpleBroker( "/user", "/queue");
config.setApplicationDestinationPrefixes("/app");
config.setUserDestinationPrefix("/user");
}
@@ -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.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,10 @@
package site.easystartup.web.notification.domian;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Notification {
private String text;
}
@@ -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,22 @@
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.service.NotificationService;
import site.easystartup.web.post.domain.event.RepostEvent;
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class RealTimeListener implements NotificationListener {
private final NotificationService notificationService;
//Обрабатывает все ивенты
@EventHandler
public void onEvent(NotificationEvent event) {
notificationService.sendNotification(
new Notification(event.getMessage()));
}
}
@@ -0,0 +1,17 @@
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.notification.domian.Notification;
@Component
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class NotificationService {
private final SimpMessagingTemplate messagingTemplate;
public void sendNotification(Notification notification) {
messagingTemplate.convertAndSendToUser("server", "queue/notification", notification);
}
}
@@ -0,0 +1,27 @@
package site.easystartup.web.post.domain.event;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import site.easystartup.web.notification.event.NotificationEvent;
import site.easystartup.web.notification.event.NotificationEventManager;
@RequiredArgsConstructor
public class RepostEvent implements NotificationEvent {
@Autowired
private NotificationEventManager notificationEventManager;
@Getter
private final String recipient;
@Getter
private final String reportedUser;
@Getter
private final String message;
@Override
public void invoke() {
notificationEventManager.notifyListeners(getClass());
}
}
@@ -3,6 +3,7 @@ package site.easystartup.web.post.service;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import site.easystartup.web.post.domain.event.RepostEvent;
import site.easystartup.web.post.domain.exception.AlreadyLikedException;
import site.easystartup.web.post.domain.exception.PostNotFoundException;
import site.easystartup.web.post.domain.model.Post;
@@ -61,6 +62,9 @@ public class PostService {
List<Long> answers = answered.getAnswers() != null ? answered.getAnswers() : new ArrayList<>();
answers.add(post.getId());
answered.setAnswers(answers);
new RepostEvent(answered.getSender(),
post.getSender(),
String.format("Пользователь %s ответил на вашу запись!", answered.getSender())).invoke();
postRepo.save(answered);
}
}