aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2019-09-24 11:54:21 +0300
committerGravatar Vitaly Takmazov2019-09-24 11:54:21 +0300
commit2f2e9aab6194037259625200091949d8648e3409 (patch)
tree4669e3bf5389bf68581094ab01dee4155a91e24f
parent289afd5a0b510e4501cf421dd9a05bb53bc424c3 (diff)
Use single event model for all application events
-rw-r--r--src/main/java/com/juick/server/ActivityPubManager.java43
-rw-r--r--src/main/java/com/juick/server/CommandsManager.java39
-rw-r--r--src/main/java/com/juick/server/EmailManager.java33
-rw-r--r--src/main/java/com/juick/server/ServerManager.java71
-rw-r--r--src/main/java/com/juick/server/TelegramBotManager.java50
-rw-r--r--src/main/java/com/juick/server/TopManager.java23
-rw-r--r--src/main/java/com/juick/server/TwitterManager.java44
-rw-r--r--src/main/java/com/juick/server/XMPPManager.java39
-rw-r--r--src/main/java/com/juick/server/api/Messages.java6
-rw-r--r--src/main/java/com/juick/server/api/PM.java6
-rw-r--r--src/main/java/com/juick/server/api/SystemActivity.java88
-rw-r--r--src/main/java/com/juick/service/component/LikeEvent.java36
-rw-r--r--src/main/java/com/juick/service/component/MessageEvent.java31
-rw-r--r--src/main/java/com/juick/service/component/MessageReadEvent.java30
-rw-r--r--src/main/java/com/juick/service/component/NotificationListener.java14
-rw-r--r--src/main/java/com/juick/service/component/SubscribeEvent.java27
-rw-r--r--src/main/java/com/juick/service/component/SystemEvent.java26
-rw-r--r--src/main/java/com/juick/service/component/TopEvent.java21
-rw-r--r--src/test/java/com/juick/server/MockNotificationListener.java6
-rw-r--r--src/test/java/com/juick/server/tests/ServerTests.java24
20 files changed, 303 insertions, 354 deletions
diff --git a/src/main/java/com/juick/server/ActivityPubManager.java b/src/main/java/com/juick/server/ActivityPubManager.java
index c40bbb5c..2fa663eb 100644
--- a/src/main/java/com/juick/server/ActivityPubManager.java
+++ b/src/main/java/com/juick/server/ActivityPubManager.java
@@ -4,6 +4,7 @@ import com.juick.Message;
import com.juick.Reaction;
import com.juick.User;
import com.juick.formatters.PlainTextFormatter;
+import com.juick.server.api.SystemActivity.ActivityType;
import com.juick.server.api.activity.model.Context;
import com.juick.server.api.activity.model.activities.Accept;
import com.juick.server.api.activity.model.activities.Announce;
@@ -142,10 +143,10 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
List<String> segments = uriComponents.getPathSegments();
if (segments.get(0).equals("n")) {
String[] ids = segments.get(1).split("-", 2);
- if (ids.length == 2 && Integer.valueOf(ids[1]) == 0) {
+ if (ids.length == 2 && Integer.parseInt(ids[1]) == 0) {
// only messages
logger.info("{} recommends {}", event.getActorUri(), Integer.valueOf(ids[0]));
- messagesService.likeMessage(Integer.valueOf(ids[0]), 0, Reaction.LIKE, event.getActorUri());
+ messagesService.likeMessage(Integer.parseInt(ids[0]), 0, Reaction.LIKE, event.getActorUri());
}
}
}
@@ -156,18 +157,27 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
List<String> segments = uriComponents.getPathSegments();
if (segments.get(0).equals("n")) {
String[] ids = segments.get(1).split("-", 2);
- if (ids.length == 2 && Integer.valueOf(ids[1]) == 0) {
+ if (ids.length == 2 && Integer.parseInt(ids[1]) == 0) {
// only messages
logger.info("{} stop recommending {}", event.getActorUri(), Integer.valueOf(ids[0]));
- messagesService.likeMessage(Integer.valueOf(ids[0]), 0, null, event.getActorUri());
+ messagesService.likeMessage(Integer.parseInt(ids[0]), 0, null, event.getActorUri());
}
}
}
@Override
- public void processMessageEvent(MessageEvent messageEvent) {
- Message msg = messageEvent.getMessage();
- if (MessageUtils.isPM(msg)) {
+ public void processSystemEvent(SystemEvent systemEvent) {
+ ActivityType type = systemEvent.getActivity().getType();
+ if (type.equals(ActivityType.message)) {
+ processMessage(systemEvent.getActivity().getMessage());
+ } else if (type.equals(ActivityType.like)) {
+ if (systemEvent.getActivity().getFrom().equals(serviceUser)) {
+ processTop(systemEvent.getActivity().getMessage());
+ }
+ }
+ }
+ private void processMessage(Message msg) {
+ if (MessageUtils.isPM(msg) || msg.isService()) {
return;
}
User user = msg.getUser();
@@ -323,28 +333,11 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
}
@Override
- public void processSubscribeEvent(SubscribeEvent subscribeEvent) {
-
- }
-
- @Override
- public void processLikeEvent(LikeEvent likeEvent) {
-
- }
-
- @Override
public void processPingEvent(PingEvent pingEvent) {
}
- @Override
- public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
-
- }
-
- @Override
- public void processTopEvent(TopEvent topEvent) {
- Message message = topEvent.getMessage();
+ private void processTop(Message message) {
Note note = makeNote(message);
Announce announce = new Announce();
announce.setId(note.getId() + "#top");
diff --git a/src/main/java/com/juick/server/CommandsManager.java b/src/main/java/com/juick/server/CommandsManager.java
index b21ff81c..6fd88f07 100644
--- a/src/main/java/com/juick/server/CommandsManager.java
+++ b/src/main/java/com/juick/server/CommandsManager.java
@@ -23,6 +23,7 @@ import com.juick.User;
import com.juick.formatters.PlainTextFormatter;
import com.juick.model.CommandResult;
import com.juick.model.TagStats;
+import com.juick.server.api.SystemActivity;
import com.juick.server.helpers.annotation.UserCommand;
import com.juick.server.util.HttpUtils;
import com.juick.server.www.WebApp;
@@ -141,9 +142,12 @@ public class CommandsManager {
msg.getUser().setAvatar(webApp.getAvatarUrl(msg.getUser()));
subscriptionService.subscribeMessage(msg, user);
- applicationEventPublisher.publishEvent(new MessageReadEvent(this, user, msg));
- applicationEventPublisher.publishEvent(new MessageEvent(this, msg, subscriptionService.getSubscribedUsers(msg.getUser().getUid(), msg)));
- return CommandResult.build(msg, "New message posted.\n#" + msg.getMid() + " https://juick.com/m/" + msg.getMid(), String.format("[New message](%s) posted", PlainTextFormatter.formatUrl(msg)));
+ applicationEventPublisher.publishEvent(new SystemEvent(this, SystemActivity.read(user, msg)));
+ applicationEventPublisher.publishEvent(new SystemEvent(this,
+ SystemActivity.message(user, msg, subscriptionService.getSubscribedUsers(msg.getUser().getUid(), msg))));
+ return CommandResult.build(msg,
+ "New message posted.\n#" + msg.getMid() + " https://juick.com/m/" + msg.getMid(),
+ String.format("[New message](%s) posted", PlainTextFormatter.formatUrl(msg)));
}
@UserCommand(pattern = "^ping$", patternFlags = Pattern.CASE_INSENSITIVE,
@@ -180,7 +184,8 @@ public class CommandsManager {
jmsg.setUser(user_from);
jmsg.setTo(user_to);
jmsg.setText(body);
- applicationEventPublisher.publishEvent(new MessageEvent(this, jmsg, Collections.singletonList(user_to)));
+ applicationEventPublisher.publishEvent(new SystemEvent(this,
+ SystemActivity.message(user_from, jmsg, Collections.singletonList(user_to))));
return CommandResult.fromString("Private message sent");
}
}
@@ -314,9 +319,9 @@ public class CommandsManager {
MessagesService.RecommendStatus status = messagesService.recommendMessage(mid, user.getUid(), user.getUri().toASCIIString());
switch (status) {
case Added:
- applicationEventPublisher.publishEvent(new LikeEvent(this, user, msg.get(),
+ applicationEventPublisher.publishEvent(new SystemEvent(this, SystemActivity.like(user, msg.get(),
subscriptionService.getUsersSubscribedToUserRecommendations(
- user.getUid(), msg.get())));
+ user.getUid(), msg.get()))));
return CommandResult.fromString("Message is added to your recommendations");
case Deleted:
return CommandResult.fromString("Message deleted from your recommendations.");
@@ -338,7 +343,8 @@ public class CommandsManager {
if (subscribe) {
if (subscriptionService.subscribeUser(user, toUser)) {
// TODO: already subscribed case
- applicationEventPublisher.publishEvent(new SubscribeEvent(this, user, toUser));
+ applicationEventPublisher.publishEvent(new SystemEvent(this,
+ SystemActivity.follow(user, Collections.singletonList(toUser))));
return CommandResult.fromString("Subscribed to @" + toUser.getName());
}
} else {
@@ -376,7 +382,7 @@ public class CommandsManager {
if (subscribe) {
if (subscriptionService.subscribeMessage(msg.get(), user)) {
applicationEventPublisher.publishEvent(
- new MessageReadEvent(this, user, msg.get()));
+ new SystemEvent(this, SystemActivity.read(user, msg.get())));
return CommandResult.fromString("Subscribed");
}
} else {
@@ -429,10 +435,10 @@ public class CommandsManager {
if (showReplies) {
List<com.juick.Message> replies = messagesService.getReplies(user, mid);
applicationEventPublisher.publishEvent(
- new MessageReadEvent(this, user, msg.get()));
+ new SystemEvent(this, SystemActivity.read(user, msg.get())));
replies.add(0, msg.get());
- return CommandResult.fromString(String.join("\n",
- replies.stream().map(PlainTextFormatter::formatPostSummary).collect(Collectors.toList())));
+ return CommandResult.fromString(replies.stream()
+ .map(PlainTextFormatter::formatPostSummary).collect(Collectors.joining("\n")));
}
return CommandResult.fromString(PlainTextFormatter.formatPost(msg.get()));
}
@@ -474,8 +480,8 @@ public class CommandsManager {
}
@UserCommand(pattern = "^D #(\\d+)(\\.|\\-|\\/)(\\d+)$", help = "D #1234/5 - Delete comment", patternFlags = Pattern.CASE_INSENSITIVE)
public CommandResult commandDeleteReply(User user, URI attachment, String... args) {
- int mid = Integer.valueOf(args[0]);
- int rid = Integer.valueOf(args[2]);
+ int mid = Integer.parseInt(args[0]);
+ int rid = Integer.parseInt(args[2]);
if (messagesService.deleteReply(user.getUid(), mid, rid)) {
return CommandResult.fromString("Reply deleted");
} else {
@@ -556,12 +562,15 @@ public class CommandsManager {
imagesService.saveImageWithPreviews(attachmentFName, fname);
}
applicationEventPublisher.publishEvent(
- new MessageReadEvent(this, user, msg.get()));
+ new SystemEvent(this, SystemActivity.read(user, msg.get())));
Message original = messagesService.getMessage(mid).orElseThrow(IllegalStateException::new);
subscriptionService.subscribeMessage(original, user);
Message reply = messagesService.getReply(mid, newrid);
reply.getUser().setAvatar(webApp.getAvatarUrl(reply.getUser()));
- applicationEventPublisher.publishEvent(new MessageEvent(this, reply, subscriptionService.getUsersSubscribedToComments(original, reply)));
+ applicationEventPublisher.publishEvent(
+ new SystemEvent(this,
+ SystemActivity.message(reply.getUser(), reply,
+ subscriptionService.getUsersSubscribedToComments(original, reply))));
return CommandResult.build(reply, "Reply posted.\n#" + mid + "/" + newrid + " "
+ "https://juick.com/m/" + mid + "#" + newrid,
String.format("[Reply](%s) posted", PlainTextFormatter.formatUrl(reply)));
diff --git a/src/main/java/com/juick/server/EmailManager.java b/src/main/java/com/juick/server/EmailManager.java
index bd77d8d6..edff7b70 100644
--- a/src/main/java/com/juick/server/EmailManager.java
+++ b/src/main/java/com/juick/server/EmailManager.java
@@ -2,6 +2,7 @@ package com.juick.server;
import com.juick.Message;
import com.juick.User;
+import com.juick.server.api.SystemActivity;
import com.juick.service.EmailService;
import com.juick.service.MessagesService;
import com.juick.service.UserService;
@@ -52,9 +53,15 @@ public class EmailManager implements NotificationListener {
private PebbleEngine pebbleEngine;
@Override
- public void processMessageEvent(@Nonnull MessageEvent event) {
- Message msg = event.getMessage();
- List<User> subscribedUsers = event.getUsers();
+ public void processSystemEvent(@Nonnull SystemEvent systemEvent) {
+ var activity = systemEvent.getActivity();
+ var msg = activity.getMessage();
+ var subscribers = activity.getTo();
+ if (activity.getType().equals(SystemActivity.ActivityType.message)) {
+ processMessage(msg, subscribers);
+ }
+ }
+ private void processMessage(com.juick.Message msg, List<User> subscribedUsers) {
if (msg.isService()) {
return;
}
@@ -78,30 +85,10 @@ public class EmailManager implements NotificationListener {
}
@Override
- public void processSubscribeEvent(SubscribeEvent subscribeEvent) {
-
- }
-
- @Override
- public void processLikeEvent(LikeEvent likeEvent) {
-
- }
-
- @Override
public void processPingEvent(PingEvent pingEvent) {
}
- @Override
- public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
-
- }
-
- @Override
- public void processTopEvent(TopEvent topEvent) {
-
- }
-
private void emailNotify(String email, String subject, Message msg) {
Map<String, String> headers = new HashMap<>();
if (!MessageUtils.isPM(msg)) {
diff --git a/src/main/java/com/juick/server/ServerManager.java b/src/main/java/com/juick/server/ServerManager.java
index 5b859125..ca69f7d8 100644
--- a/src/main/java/com/juick/server/ServerManager.java
+++ b/src/main/java/com/juick/server/ServerManager.java
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.juick.Message;
import com.juick.User;
import com.juick.model.AnonymousUser;
+import com.juick.server.api.SystemActivity;
import com.juick.service.MessagesService;
import com.juick.service.SubscriptionService;
import com.juick.service.UserService;
@@ -34,6 +35,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.ArrayList;
@@ -91,10 +93,30 @@ public class ServerManager implements NotificationListener {
}
@Override
- public void processMessageEvent(MessageEvent event) {
- com.juick.Message jmsg = event.getMessage();
- List<User> subscribedUsers = ListUtils.union(event.getUsers(), Collections.singletonList(jmsg.getUser()));
+ public void processSystemEvent(@Nonnull SystemEvent systemEvent) {
+ var activity = systemEvent.getActivity();
+ var from = activity.getFrom();
+ var message = activity.getMessage();
+ var subscribers = activity.getTo();
+ if (activity.getType().equals(SystemActivity.ActivityType.message)) {
+ processMessage(from, message, subscribers);
+ } else if (activity.getType().equals(SystemActivity.ActivityType.like)) {
+ if (from.equals(serviceUser)) {
+ processTop(message);
+ }
+ }
+ try {
+ var eventHeader = Collections.singletonMap("X-Event-Version", "1.0");
+ emailManager.sendEmail("noreply@juick.com", serviceEmail, "New system event",
+ jsonMapper.writeValueAsString(systemEvent), null, eventHeader);
+ } catch (JsonProcessingException e) {
+ logger.warn("JSON exception", e);
+ }
+ }
+ private void processMessage(User from, com.juick.Message jmsg, List<User> subscribers) {
+ List<User> subscribedUsers = ListUtils.union(subscribers, Collections.singletonList(jmsg.getUser()));
if (jmsg.isService()) {
+ logger.info("Message read event from {} for {}", from.getUid(), jmsg.getMid());
readEvent(jmsg, Collections.singletonList(serviceUser));
return;
}
@@ -111,21 +133,6 @@ public class ServerManager implements NotificationListener {
onJuickMessageReply(jmsg, subscribedUsers);
}
messageEvent(jmsg, Collections.singletonList(serviceUser));
- try {
- emailManager.sendEmail("noreply@juick.com", serviceEmail, "New message", jsonMapper.writeValueAsString(jmsg), null, Collections.emptyMap());
- } catch (JsonProcessingException e) {
- logger.warn("JSON exception", e);
- }
- }
-
- @Override
- public void processSubscribeEvent(SubscribeEvent subscribeEvent) {
-
- }
-
- @Override
- public void processLikeEvent(LikeEvent likeEvent) {
-
}
@Override
@@ -133,35 +140,19 @@ public class ServerManager implements NotificationListener {
}
- @Override
- public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
- User user = messageReadEvent.getUser();
- Message source = messageReadEvent.getMessage();
-
- logger.info("Message read event from {} for {}", user.getUid(), source.getMid());
- Message serviceMessage = new Message();
- serviceMessage.setService(true);
- serviceMessage.setUser(user);
- serviceMessage.setMid(source.getMid());
- serviceMessage.setUnread(false);
- readEvent(serviceMessage, Arrays.asList(serviceUser, user));
- }
-
- @Override
- public void processTopEvent(TopEvent topEvent) {
- User topUser = topEvent.getMessage().getUser();
- topEvent(topEvent.getMessage(), Arrays.asList(topUser, serviceUser));
+ private void processTop(Message msg) {
+ User topUser = msg.getUser();
+ topEvent(msg, Arrays.asList(topUser, serviceUser));
}
-
- public void topEvent(Message msg, List<User> subscribers){
+ private void topEvent(Message msg, List<User> subscribers){
sendSseEvent(msg, "top", subscribers);
}
- public void readEvent(Message msg, List<User> subscribers){
+ private void readEvent(Message msg, List<User> subscribers){
sendSseEvent(msg, "read", subscribers);
}
- public void messageEvent(Message msg, List<User> subscribers) {
+ private void messageEvent(Message msg, List<User> subscribers) {
sendSseEvent(msg, "msg", subscribers);
}
diff --git a/src/main/java/com/juick/server/TelegramBotManager.java b/src/main/java/com/juick/server/TelegramBotManager.java
index 9e53fbe1..7ca9e347 100644
--- a/src/main/java/com/juick/server/TelegramBotManager.java
+++ b/src/main/java/com/juick/server/TelegramBotManager.java
@@ -20,17 +20,14 @@ package com.juick.server;
import com.juick.User;
import com.juick.model.AnonymousUser;
import com.juick.model.CommandResult;
+import com.juick.server.api.SystemActivity;
import com.juick.server.util.HttpUtils;
import com.juick.service.MessagesService;
import com.juick.service.TelegramService;
import com.juick.service.UserService;
-import com.juick.service.component.LikeEvent;
-import com.juick.service.component.MessageEvent;
-import com.juick.service.component.MessageReadEvent;
+import com.juick.service.component.SystemEvent;
import com.juick.service.component.NotificationListener;
import com.juick.service.component.PingEvent;
-import com.juick.service.component.SubscribeEvent;
-import com.juick.service.component.TopEvent;
import com.juick.util.MessageUtils;
import com.pengrad.telegrambot.Callback;
import com.pengrad.telegrambot.TelegramBot;
@@ -370,7 +367,7 @@ public class TelegramBotManager implements NotificationListener {
User user = userService.getUserByUID(userId).orElseThrow(IllegalStateException::new);
userService.updateLastSeen(user);
applicationEventPublisher.publishEvent(
- new MessageReadEvent(this, user, source));
+ new SystemEvent(this, SystemActivity.read(user, source)));
}
}
}
@@ -394,9 +391,22 @@ public class TelegramBotManager implements NotificationListener {
}
@Override
- public void processMessageEvent(MessageEvent messageEvent) {
- com.juick.Message jmsg = messageEvent.getMessage();
- List<User> subscribedUsers = messageEvent.getUsers();
+ public void processSystemEvent(SystemEvent systemEvent) {
+ var activity = systemEvent.getActivity();
+ var type = activity.getType();
+ if (type.equals(SystemActivity.ActivityType.message)) {
+ processMessage(activity.getMessage(), activity.getTo());
+ } else if (type.equals(SystemActivity.ActivityType.like)) {
+ if (systemEvent.getActivity().getFrom().getName().equals(serviceUser)) {
+ processTop(systemEvent.getActivity().getMessage());
+ } else {
+ processLike(activity.getFrom(), activity.getMessage(), activity.getTo());
+ }
+ } else if (type.equals(SystemActivity.ActivityType.follow)) {
+ processFollow(activity.getFrom(), activity.getTo());
+ }
+ }
+ private void processMessage(com.juick.Message jmsg, List<User> subscribedUsers) {
if (jmsg.isService()) {
return;
}
@@ -422,12 +432,8 @@ public class TelegramBotManager implements NotificationListener {
}
}
- @Override
- public void processLikeEvent(LikeEvent likeEvent) {
- User liker = likeEvent.getUser();
+ private void processLike(User liker, com.juick.Message message, List<User> subscribers) {
if (!liker.getName().equals(serviceUser)) {
- com.juick.Message message = likeEvent.getMessage();
- List<User> subscribers = likeEvent.getSubscribers();
logger.info("Like received in tg listener");
if (!userService.isInBLAny(message.getUser().getUid(), liker.getUid())) {
telegramService.getTelegramIdentifiers(Collections.singletonList(message.getUser()))
@@ -445,24 +451,14 @@ public class TelegramBotManager implements NotificationListener {
}
- @Override
- public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
-
- }
-
- @Override
- public void processTopEvent(TopEvent topEvent) {
- com.juick.Message message = topEvent.getMessage();
+ private void processTop(com.juick.Message message) {
telegramService.getTelegramIdentifiers(Collections.singletonList(message.getUser()))
.forEach(c -> telegramNotify(c, String.format("Your [post](%s) became popular!",
formatUrl(message)), new com.juick.Message()));
}
- @Override
- public void processSubscribeEvent(SubscribeEvent subscribeEvent) {
- User subscriber = subscribeEvent.getUser();
- User target = subscribeEvent.getToUser();
- telegramService.getTelegramIdentifiers(Collections.singletonList(target))
+ private void processFollow(User subscriber, List<User> target) {
+ telegramService.getTelegramIdentifiers(target)
.forEach(c -> telegramNotify(c, String.format("%s subscribed to your blog",
MessageUtils.getMarkdownUser(subscriber)), new com.juick.Message()));
}
diff --git a/src/main/java/com/juick/server/TopManager.java b/src/main/java/com/juick/server/TopManager.java
index fe3d605d..ff7ae9fd 100644
--- a/src/main/java/com/juick/server/TopManager.java
+++ b/src/main/java/com/juick/server/TopManager.java
@@ -19,15 +19,21 @@ package com.juick.server;
import com.juick.Message;
import com.juick.Tag;
+import com.juick.User;
+import com.juick.server.api.SystemActivity;
import com.juick.service.MessagesService;
-import com.juick.service.component.TopEvent;
+import com.juick.service.UserService;
+import com.juick.service.component.SystemEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
+import javax.annotation.PostConstruct;
import javax.inject.Inject;
+import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -37,8 +43,20 @@ public class TopManager {
@Inject
private MessagesService messagesService;
@Inject
+ private UserService userService;
+ @Inject
private ApplicationEventPublisher applicationEventPublisher;
+ @Value("${service_user:juick}")
+ private String serviceUsername;
+
+ private User serviceUser;
+
+ @PostConstruct
+ public void init() {
+ serviceUser = userService.getUserByName(serviceUsername);
+ }
+
@Scheduled(fixedRate = 3600000)
public void updateTop() {
messagesService.getPopularCandidates().forEach(m -> {
@@ -47,7 +65,8 @@ public class TopManager {
messagesService.setMessagePopular(m, 1);
List<String> tags = jmsg.getTags().stream().map(Tag::getName).map(String::toLowerCase).collect(Collectors.toList());
if (!tags.contains("juick")) {
- applicationEventPublisher.publishEvent(new TopEvent(this, jmsg));
+ applicationEventPublisher.publishEvent(new SystemEvent(this,
+ SystemActivity.like(serviceUser, jmsg, Collections.emptyList())));
}
});
}
diff --git a/src/main/java/com/juick/server/TwitterManager.java b/src/main/java/com/juick/server/TwitterManager.java
index d799bb17..0cb247fe 100644
--- a/src/main/java/com/juick/server/TwitterManager.java
+++ b/src/main/java/com/juick/server/TwitterManager.java
@@ -18,6 +18,7 @@ package com.juick.server;
import com.juick.Message;
import com.juick.User;
+import com.juick.server.api.SystemActivity;
import com.juick.service.UserService;
import com.juick.service.component.*;
import com.juick.service.CrosspostService;
@@ -85,41 +86,32 @@ public class TwitterManager implements NotificationListener {
}
@Override
- public void processMessageEvent(MessageEvent messageEvent) {
- Message msg = messageEvent.getMessage();
- if (MessageUtils.isPM(msg) || MessageUtils.isReply(msg) || msg.isService()) {
- return;
- }
- if (StringUtils.isNotEmpty(crosspostService.getTwitterName(msg.getUser().getUid()))) {
- if (msg.getTags().stream().noneMatch(t -> t.getName().equals("notwitter"))) {
- twitterPost(msg);
+ public void processSystemEvent(SystemEvent systemEvent) {
+ var activity = systemEvent.getActivity();
+ var msg = activity.getMessage();
+ if (activity.getType().equals(SystemActivity.ActivityType.message)) {
+ if (MessageUtils.isPM(msg) || MessageUtils.isReply(msg) || msg.isService()) {
+ return;
+ }
+ if (StringUtils.isNotEmpty(crosspostService.getTwitterName(msg.getUser().getUid()))) {
+ if (msg.getTags().stream().noneMatch(t -> t.getName().equals("notwitter"))) {
+ twitterPost(msg);
+ }
+ }
+ } else if (activity.getType().equals(SystemActivity.ActivityType.like)) {
+ if (activity.getFrom().getName().equals(serviceUsername)) {
+ processTop(msg);
}
}
}
@Override
- public void processSubscribeEvent(SubscribeEvent subscribeEvent) {
-
- }
-
- @Override
- public void processLikeEvent(LikeEvent likeEvent) {
-
- }
-
- @Override
public void processPingEvent(PingEvent pingEvent) {
}
- @Override
- public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
-
- }
-
- @Override
- public void processTopEvent(TopEvent topEvent) {
- Message jmsg = SerializationUtils.clone(topEvent.getMessage());
+ private void processTop(com.juick.Message message) {
+ Message jmsg = SerializationUtils.clone(message);
jmsg.setUser(serviceUser);
twitterPost(jmsg);
}
diff --git a/src/main/java/com/juick/server/XMPPManager.java b/src/main/java/com/juick/server/XMPPManager.java
index a41e6053..a0390507 100644
--- a/src/main/java/com/juick/server/XMPPManager.java
+++ b/src/main/java/com/juick/server/XMPPManager.java
@@ -20,6 +20,7 @@ package com.juick.server;
import com.juick.User;
import com.juick.formatters.PlainTextFormatter;
import com.juick.model.CommandResult;
+import com.juick.server.api.SystemActivity;
import com.juick.server.www.WebApp;
import com.juick.server.xmpp.iq.MessageQuery;
import com.juick.service.MessagesService;
@@ -337,9 +338,20 @@ public class XMPPManager implements NotificationListener {
}
@Override
- public void processMessageEvent(MessageEvent event) {
- com.juick.Message msg = event.getMessage();
- List<User> subscribers = event.getUsers();
+ public void processSystemEvent(SystemEvent systemEvent) {
+ var activity = systemEvent.getActivity();
+ var type = activity.getType();
+ if (type.equals(SystemActivity.ActivityType.message)) {
+ processMessage(activity.getMessage(), activity.getTo());
+ } else if (type.equals(SystemActivity.ActivityType.like)) {
+ if (systemEvent.getActivity().getFrom().equals(serviceUser)) {
+ processTop(systemEvent.getActivity().getMessage());
+ } else {
+ processLike(activity.getFrom(), activity.getMessage(), activity.getTo());
+ }
+ }
+ }
+ private void processMessage(com.juick.Message msg, List<User> subscribers) {
if (msg.isService()) {
return;
}
@@ -376,17 +388,7 @@ public class XMPPManager implements NotificationListener {
return ClientMessage.from(reply);
}
- @Override
- public void processSubscribeEvent(SubscribeEvent subscribeEvent) {
-
- }
-
- @Override
- public void processLikeEvent(LikeEvent likeEvent) {
- List<User> users = likeEvent.getSubscribers();
- com.juick.Message jmsg = likeEvent.getMessage();
- User liker = likeEvent.getUser();
-
+ public void processLike(User liker, com.juick.Message jmsg, List<User> users) {
if (!userService.isInBLAny(jmsg.getUser().getUid(), liker.getUid())) {
userService.getJIDsbyUID(jmsg.getUser().getUid()).forEach(authorJid -> {
Message xmppMessage = new Message();
@@ -454,14 +456,7 @@ public class XMPPManager implements NotificationListener {
});
}
- @Override
- public void processMessageReadEvent(MessageReadEvent messageReadEvent) {
-
- }
-
- @Override
- public void processTopEvent(TopEvent topEvent) {
- com.juick.Message message = topEvent.getMessage();
+ public void processTop(com.juick.Message message) {
try {
commandsManager.processCommand(serviceUser, String.format("! #%d", message.getMid()), URI.create(StringUtils.EMPTY));
} catch (Exception e) {
diff --git a/src/main/java/com/juick/server/api/Messages.java b/src/main/java/com/juick/server/api/Messages.java
index 3ac272f2..1c9e37ad 100644
--- a/src/main/java/com/juick/server/api/Messages.java
+++ b/src/main/java/com/juick/server/api/Messages.java
@@ -22,12 +22,12 @@ import com.juick.Tag;
import com.juick.User;
import com.juick.server.Utils;
import com.juick.server.www.WebApp;
-import com.juick.service.component.MessageReadEvent;
import com.juick.model.CommandResult;
import com.juick.server.util.HttpBadRequestException;
import com.juick.service.MessagesService;
import com.juick.service.TagService;
import com.juick.service.UserService;
+import com.juick.service.component.SystemEvent;
import com.juick.service.security.annotation.Visitor;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.tuple.Pair;
@@ -192,7 +192,7 @@ public class Messages {
if (!visitor.isAnonymous()) {
userService.updateLastSeen(visitor);
applicationEventPublisher.publishEvent(
- new MessageReadEvent(this, visitor, msg));
+ new SystemEvent(this, SystemActivity.read(visitor, msg)));
}
replies.add(0, msg);
return ResponseEntity.ok(replies);
@@ -209,7 +209,7 @@ public class Messages {
Message msg = messagesService.getMessage(mid).orElseThrow(IllegalStateException::new);
userService.updateLastSeen(visitor);
applicationEventPublisher.publishEvent(
- new MessageReadEvent(this, visitor, msg));
+ new SystemEvent(this, SystemActivity.read(visitor, msg)));
return IOUtils.toByteArray(invisiblePixel.getInputStream());
}
throw new HttpBadRequestException();
diff --git a/src/main/java/com/juick/server/api/PM.java b/src/main/java/com/juick/server/api/PM.java
index b65841c0..4a408dce 100644
--- a/src/main/java/com/juick/server/api/PM.java
+++ b/src/main/java/com/juick/server/api/PM.java
@@ -28,7 +28,7 @@ import com.juick.server.util.WebUtils;
import com.juick.server.www.WebApp;
import com.juick.service.PMQueriesService;
import com.juick.service.UserService;
-import com.juick.service.component.MessageEvent;
+import com.juick.service.component.SystemEvent;
import com.juick.service.security.annotation.Visitor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.MediaType;
@@ -97,7 +97,9 @@ public class PM {
jmsg.setText(body);
jmsg.setTo(userTo);
jmsg.getUser().setAvatar(webApp.getAvatarUrl(jmsg.getUser()));
- applicationEventPublisher.publishEvent(new MessageEvent(this, jmsg, Collections.singletonList(jmsg.getTo())));
+ applicationEventPublisher.publishEvent(
+ new SystemEvent(this,
+ SystemActivity.message(jmsg.getUser(), jmsg, Collections.singletonList(jmsg.getTo()))));
return jmsg;
}
diff --git a/src/main/java/com/juick/server/api/SystemActivity.java b/src/main/java/com/juick/server/api/SystemActivity.java
new file mode 100644
index 00000000..162374d1
--- /dev/null
+++ b/src/main/java/com/juick/server/api/SystemActivity.java
@@ -0,0 +1,88 @@
+package com.juick.server.api;
+
+import com.juick.Message;
+import com.juick.User;
+
+import java.util.List;
+
+public class SystemActivity {
+ public static SystemActivity like(User from, Message message, List<User> subscribers) {
+ var like = new SystemActivity();
+ like.setType(ActivityType.like);
+ like.setFrom(from);
+ like.setMessage(message);
+ like.setTo(subscribers);
+ return like;
+ }
+
+ public static SystemActivity message(User from, Message message, List<User> subscribers) {
+ var msg = new SystemActivity();
+ msg.setType(ActivityType.message);
+ msg.setFrom(from);
+ msg.setMessage(message);
+ msg.setTo(subscribers);
+ return msg;
+ }
+
+ public static SystemActivity read(User from, Message message) {
+ var read = new SystemActivity();
+ read.setType(ActivityType.message);
+ read.setFrom(from);
+ var msg = new Message();
+ msg.setMid(message.getMid());
+ msg.setService(true);
+ msg.setUnread(false);
+ read.setMessage(msg);
+ return read;
+ }
+
+ public static SystemActivity follow(User from, List<User> to) {
+ var follow = new SystemActivity();
+ follow.setFrom(from);
+ follow.setTo(to);
+ return follow;
+ }
+
+ public enum ActivityType {
+ message,
+ like,
+ follow
+ }
+
+ private ActivityType type;
+ private User from;
+ private List<User> to;
+ private Message message;
+
+ public ActivityType getType() {
+ return type;
+ }
+
+ public void setType(ActivityType type) {
+ this.type = type;
+ }
+
+ public User getFrom() {
+ return from;
+ }
+
+ public void setFrom(User from) {
+ this.from = from;
+ }
+
+ public List<User> getTo() {
+ return to;
+ }
+
+ public void setTo(List<User> to) {
+ this.to = to;
+ }
+
+ public Message getMessage() {
+ return message;
+ }
+
+ public void setMessage(Message message) {
+ this.message = message;
+ }
+}
diff --git a/src/main/java/com/juick/service/component/LikeEvent.java b/src/main/java/com/juick/service/component/LikeEvent.java
deleted file mode 100644
index 0d4df70c..00000000
--- a/src/main/java/com/juick/service/component/LikeEvent.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.juick.service.component;
-
-import com.juick.Message;
-import com.juick.User;
-import org.springframework.context.ApplicationEvent;
-
-import java.util.List;
-
-public class LikeEvent extends ApplicationEvent {
- private User user;
- private Message message;
- private List<User> subscribers;
- /**
- * Create a new ApplicationEvent.
- *
- * @param source the object on which the event initially occurred (never {@code null})
- */
- public LikeEvent(Object source, User user, Message message, List<User> subscribers) {
- super(source);
- this.message = message;
- this.user = user;
- this.subscribers = subscribers;
- }
-
- public User getUser() {
- return user;
- }
-
- public Message getMessage() {
- return message;
- }
-
- public List<User> getSubscribers() {
- return subscribers;
- }
-}
diff --git a/src/main/java/com/juick/service/component/MessageEvent.java b/src/main/java/com/juick/service/component/MessageEvent.java
deleted file mode 100644
index 82911a58..00000000
--- a/src/main/java/com/juick/service/component/MessageEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.juick.service.component;
-
-import com.juick.Message;
-import com.juick.User;
-import org.springframework.context.ApplicationEvent;
-
-import java.util.List;
-
-public class MessageEvent extends ApplicationEvent {
- private Message message;
- private List<User> users;
- /**
- * Create a new ApplicationEvent.
- *
- * @param source the object on which the event initially occurred (never {@code null})
- * @param message app message
- * @param interestedUsers users interested in notification
- */
- public MessageEvent(Object source, Message message, List<User> interestedUsers) {
- super(source);
- this.message = message;
- this.users = interestedUsers;
- }
-
- public Message getMessage() {
- return message;
- }
- public List<User> getUsers() {
- return users;
- }
-}
diff --git a/src/main/java/com/juick/service/component/MessageReadEvent.java b/src/main/java/com/juick/service/component/MessageReadEvent.java
deleted file mode 100644
index b2af4a08..00000000
--- a/src/main/java/com/juick/service/component/MessageReadEvent.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.juick.service.component;
-
-import com.juick.Message;
-import com.juick.User;
-import org.springframework.context.ApplicationEvent;
-
-import javax.annotation.Nonnull;
-
-public class MessageReadEvent extends ApplicationEvent {
- private User user;
- private Message message;
- /**
- * Create a new ApplicationEvent.
- *
- * @param source the object on which the event initially occurred (never {@code null})
- */
- public MessageReadEvent(Object source, @Nonnull User user, Message message) {
- super(source);
- this.user = user;
- this.message = message;
- }
-
- public User getUser() {
- return user;
- }
-
- public Message getMessage() {
- return message;
- }
-}
diff --git a/src/main/java/com/juick/service/component/NotificationListener.java b/src/main/java/com/juick/service/component/NotificationListener.java
index 38d0490a..7ca88de8 100644
--- a/src/main/java/com/juick/service/component/NotificationListener.java
+++ b/src/main/java/com/juick/service/component/NotificationListener.java
@@ -6,20 +6,8 @@ import org.springframework.scheduling.annotation.Async;
public interface NotificationListener {
@Async
@EventListener
- void processMessageEvent(MessageEvent messageEvent);
- @Async
- @EventListener
- void processSubscribeEvent(SubscribeEvent subscribeEvent);
- @Async
- @EventListener
- void processLikeEvent(LikeEvent likeEvent);
+ void processSystemEvent(SystemEvent systemEvent);
@Async
@EventListener
void processPingEvent(PingEvent pingEvent);
- @Async
- @EventListener
- void processMessageReadEvent(MessageReadEvent messageReadEvent);
- @Async
- @EventListener
- void processTopEvent(TopEvent topEvent);
}
diff --git a/src/main/java/com/juick/service/component/SubscribeEvent.java b/src/main/java/com/juick/service/component/SubscribeEvent.java
deleted file mode 100644
index 9b644f2f..00000000
--- a/src/main/java/com/juick/service/component/SubscribeEvent.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.juick.service.component;
-
-import com.juick.User;
-import org.springframework.context.ApplicationEvent;
-
-public class SubscribeEvent extends ApplicationEvent {
- private User user;
- private User toUser;
- /**
- * Create a new ApplicationEvent.
- *
- * @param source the object on which the event initially occurred (never {@code null})
- */
- public SubscribeEvent(Object source, User user, User toUser) {
- super(source);
- this.user = user;
- this.toUser = toUser;
- }
-
- public User getUser() {
- return user;
- }
-
- public User getToUser() {
- return toUser;
- }
-}
diff --git a/src/main/java/com/juick/service/component/SystemEvent.java b/src/main/java/com/juick/service/component/SystemEvent.java
new file mode 100644
index 00000000..11a10860
--- /dev/null
+++ b/src/main/java/com/juick/service/component/SystemEvent.java
@@ -0,0 +1,26 @@
+package com.juick.service.component;
+
+import com.juick.Message;
+import com.juick.User;
+import com.juick.server.api.SystemActivity;
+import org.springframework.context.ApplicationEvent;
+
+import java.util.List;
+
+public class SystemEvent extends ApplicationEvent {
+ private SystemActivity activity;
+ /**
+ * Create a new ApplicationEvent.
+ *
+ * @param source the object on which the event initially occurred (never {@code null})
+ * @param activity system activity
+ */
+ public SystemEvent(Object source, SystemActivity activity) {
+ super(source);
+ this.activity = activity;
+ }
+
+ public SystemActivity getActivity() {
+ return activity;
+ }
+}
diff --git a/src/main/java/com/juick/service/component/TopEvent.java b/src/main/java/com/juick/service/component/TopEvent.java
deleted file mode 100644
index b7e24957..00000000
--- a/src/main/java/com/juick/service/component/TopEvent.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.juick.service.component;
-
-import com.juick.Message;
-import org.springframework.context.ApplicationEvent;
-
-public class TopEvent extends ApplicationEvent {
- private Message message;
- /**
- * Create a new ApplicationEvent.
- *
- * @param source the object on which the event initially occurred (never {@code null})
- */
- public TopEvent(Object source, Message message) {
- super(source);
- this.message = message;
- }
-
- public Message getMessage() {
- return message;
- }
-}
diff --git a/src/test/java/com/juick/server/MockNotificationListener.java b/src/test/java/com/juick/server/MockNotificationListener.java
index 4fc9a1d9..c3a929fd 100644
--- a/src/test/java/com/juick/server/MockNotificationListener.java
+++ b/src/test/java/com/juick/server/MockNotificationListener.java
@@ -1,13 +1,13 @@
package com.juick.server;
-import com.juick.service.component.TopEvent;
+import com.juick.service.component.SystemEvent;
import org.springframework.context.ApplicationListener;
import javax.annotation.Nonnull;
-public class MockNotificationListener implements ApplicationListener<TopEvent> {
+public class MockNotificationListener implements ApplicationListener<SystemEvent> {
@Override
- public void onApplicationEvent(@Nonnull TopEvent event) {
+ public void onApplicationEvent(@Nonnull SystemEvent event) {
}
}
diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java
index 901d1501..e5d39743 100644
--- a/src/test/java/com/juick/server/tests/ServerTests.java
+++ b/src/test/java/com/juick/server/tests/ServerTests.java
@@ -18,6 +18,7 @@
package com.juick.server.tests;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -34,6 +35,7 @@ import com.juick.model.CommandResult;
import com.juick.model.PrivateChats;
import com.juick.model.TagStats;
import com.juick.server.*;
+import com.juick.server.api.SystemActivity;
import com.juick.server.api.Users;
import com.juick.server.api.activity.Profile;
import com.juick.server.api.activity.model.Context;
@@ -46,8 +48,7 @@ import com.juick.server.util.HttpUtils;
import com.juick.server.util.ImageUtils;
import com.juick.server.www.WebApp;
import com.juick.service.*;
-import com.juick.service.component.MessageEvent;
-import com.juick.service.component.TopEvent;
+import com.juick.service.component.SystemEvent;
import com.juick.test.util.MockUtils;
import com.juick.util.DateFormattersHolder;
import com.juick.util.MessageUtils;
@@ -1011,8 +1012,8 @@ public class ServerTests {
assertThat(lastRead.apply(ugnich, mid), is(freefdrid));
privacyQueriesService.blacklistUser(ugnich, freefd);
int newfreefdrid = messagesService.createReply(mid, 0, freefd, "from ban", null);
- serverManager.processMessageEvent(new MessageEvent(this, messagesService.getReply(mid, newfreefdrid),
- Collections.emptyList()));
+ serverManager.processSystemEvent(new SystemEvent(this, SystemActivity.message(juick, messagesService.getReply(mid, newfreefdrid),
+ Collections.emptyList())));
assertThat(userService.isReplyToBL(ugnich, messagesService.getReply(mid, newfreefdrid)), is(true));
// TODO: test event listeners correctly
Thread.sleep(2000L);
@@ -2159,16 +2160,16 @@ public class ServerTests {
@MockBean
private MockNotificationListener notificationListener;
@Captor
- protected ArgumentCaptor<TopEvent> topEventCaptor;
+ protected ArgumentCaptor<SystemEvent> topEventCaptor;
@Test
public void topEventShouldNotLossUser() {
Message topMessage = MockUtils.mockMessage(1000, ugnich, "top message");
topMessage.setTo(AnonymousUser.INSTANCE);
- TopEvent event = new TopEvent(this, topMessage);
+ SystemEvent event = new SystemEvent(this, SystemActivity.like(juick, topMessage, Collections.emptyList()));
applicationEventPublisher.publishEvent(event);
Mockito.verify(notificationListener, Mockito.times(1)).onApplicationEvent(topEventCaptor.capture());
- TopEvent receivedEvent = topEventCaptor.getValue();
- assertThat(receivedEvent.getMessage().getUser(), is(ugnich));
+ SystemEvent receivedEvent = topEventCaptor.getValue();
+ assertThat(receivedEvent.getActivity().getMessage().getUser(), is(ugnich));
}
@Test
public void tagStatsSpec() throws Exception {
@@ -2221,4 +2222,11 @@ public class ServerTests {
var authorResult = commandsManager.processCommand(ugnich, String.format("#%d PEOPLE", mid), emptyUri);
assertThat(authorResult.getNewMessage().isPresent(), is(true));
}
+ @Test
+ public void activitySerializationTest() throws JsonProcessingException {
+ var freefd = MockUtils.mockUser(10, "freefd", "secret");
+ var like = SystemActivity.like(MockUtils.mockUser(1, "ugnich", "secret"),
+ MockUtils.mockMessage(1, freefd, "txt"), Collections.singletonList(freefd));
+ var likeStr = jsonMapper.writeValueAsString(like);
+ }
}