From fbed3072ee2ce24618db9eacf2b3f0dd96650877 Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Fri, 12 Jun 2020 23:53:40 +0200 Subject: [PATCH 01/15] GroupMessages get processed the right way now --- src/main/java/envoy/server/Startup.java | 11 +++++++- .../processors/GroupMessageProcessor.java | 25 ++++++++++++++----- .../server/processors/MessageProcessor.java | 4 +++ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/main/java/envoy/server/Startup.java b/src/main/java/envoy/server/Startup.java index 63415aa..a8be82f 100755 --- a/src/main/java/envoy/server/Startup.java +++ b/src/main/java/envoy/server/Startup.java @@ -14,7 +14,15 @@ import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectMessageProcessor; import envoy.server.net.ObjectMessageReader; -import envoy.server.processors.*; +import envoy.server.processors.ContactOperationProcessor; +import envoy.server.processors.ContactSearchProcessor; +import envoy.server.processors.GroupCreationProcessor; +import envoy.server.processors.GroupMessageProcessor; +import envoy.server.processors.IDGeneratorRequestProcessor; +import envoy.server.processors.LoginCredentialProcessor; +import envoy.server.processors.MessageProcessor; +import envoy.server.processors.MessageStatusChangeProcessor; +import envoy.server.processors.UserStatusChangeProcessor; import envoy.util.EnvoyLog; /** @@ -61,6 +69,7 @@ public class Startup { Server server = new Server(8080, ObjectMessageReader::new, new ObjectMessageProcessor(Set.of(new LoginCredentialProcessor(), new MessageProcessor(), + new GroupMessageProcessor(), new GroupCreationProcessor(), new MessageStatusChangeProcessor(), new UserStatusChangeProcessor(), diff --git a/src/main/java/envoy/server/processors/GroupMessageProcessor.java b/src/main/java/envoy/server/processors/GroupMessageProcessor.java index 087e2c0..a356c6e 100644 --- a/src/main/java/envoy/server/processors/GroupMessageProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageProcessor.java @@ -8,6 +8,7 @@ import javax.persistence.EntityExistsException; import envoy.data.GroupMessage; import envoy.data.Message.MessageStatus; +import envoy.event.MessageStatusChangeEvent; import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectWriteProxy; @@ -31,16 +32,28 @@ public class GroupMessageProcessor implements ObjectProcessor { ConnectionManager connectionManager = ConnectionManager.getInstance(); final var members = PersistenceManager.getInstance().getGroupByID(groupMessage.getRecipientID()).getContacts(); - for (long i = 0; i < groupMessage.getMemberStatuses().size(); i++) { - groupMessage.getMemberStatuses().replace(i, MessageStatus.SENT); - } + members.forEach(user -> groupMessage.getMemberStatuses().replace(user.getID(), MessageStatus.SENT)); members.forEach(user -> { setMemberStatus(connectionManager, groupMessage, user.getID()); }); + // Setting memberStatus of sender to READ + groupMessage.getMemberStatuses() + .replace(members.stream().filter(sender -> groupMessage.getSenderID() == sender.getID()).findAny().get().getID(), MessageStatus.READ); // Checks if all memberMessageStatuses are RECEIVED and if so sets the - // groupMessage Status to RECEIVED. - if (!groupMessage.getMemberStatuses().containsValue(MessageStatus.SENT)) groupMessage.setStatus(MessageStatus.RECEIVED); + // groupMessage Status to RECEIVED and sends a MessageStatusChangeEvent to the + // sender, if he is still online. + if (!groupMessage.getMemberStatuses().containsValue(MessageStatus.SENT)) { + groupMessage.setStatus(MessageStatus.RECEIVED); + if (connectionManager.isOnline(connectionManager.getUserIdBySocketId(socketID))) try { + writeProxy.write(socketID, new MessageStatusChangeEvent(groupMessage)); + } catch (IOException e) { + logger.warning("Sender of the groupMessage online. Failed to send MessageStatusChangeEvent"); + e.printStackTrace(); + } + } - members.forEach(user -> { sendToMember(connectionManager, groupMessage, user.getID(), writeProxy); }); + members.stream() + .filter(m -> groupMessage.getSenderID() != m.getID()) + .forEach(user -> { sendToMember(connectionManager, groupMessage, user.getID(), writeProxy); }); try { PersistenceManager.getInstance().addMessage(new envoy.server.data.GroupMessage(groupMessage, new Date())); diff --git a/src/main/java/envoy/server/processors/MessageProcessor.java b/src/main/java/envoy/server/processors/MessageProcessor.java index a326d8c..5a36b8f 100755 --- a/src/main/java/envoy/server/processors/MessageProcessor.java +++ b/src/main/java/envoy/server/processors/MessageProcessor.java @@ -31,6 +31,10 @@ public class MessageProcessor implements ObjectProcessor { @Override public void process(Message message, long socketID, ObjectWriteProxy writeProxy) { + // Makes sure, that there are no groupMessages processed here, because + // groupMessage is a subclass of message. + if (message.getClass().equals(envoy.data.GroupMessage.class)) return; + message.nextStatus(); ConnectionManager connectionManager = ConnectionManager.getInstance(); From a34e90adb817d72e67a3de8f140fc057d0e75cdf Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Sat, 27 Jun 2020 21:58:53 +0200 Subject: [PATCH 02/15] Implemented functionality regarding pending groupMessages (unfinished) (This was implemented some weeks ago but never pushed (made some revision)) --- .../java/envoy/server/data/GroupMessage.java | 13 ++++++++- .../envoy/server/data/PersistenceManager.java | 16 +++++++++++ .../processors/GroupMessageProcessor.java | 13 +++++---- .../processors/LoginCredentialProcessor.java | 27 ++++++++++++++++++- .../server/processors/MessageProcessor.java | 5 ++-- 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java index 13dcc49..13c1d08 100644 --- a/src/main/java/envoy/server/data/GroupMessage.java +++ b/src/main/java/envoy/server/data/GroupMessage.java @@ -3,7 +3,12 @@ package envoy.server.data; import java.util.Date; import java.util.Map; -import javax.persistence.*; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.NamedQuery; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; import envoy.data.MessageBuilder; @@ -16,8 +21,14 @@ import envoy.data.MessageBuilder; * @since Envoy Server Standalone v0.1-beta */ @Entity +@NamedQuery( + name = GroupMessage.getPendingGroupMsg, + query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE (KEY(s) = :userId) AND (m.creationDate > :lastSeen)" +) public class GroupMessage extends Message { + public static final String getPendingGroupMsg = "GroupMessage.getPendingGroupMsg"; + @ElementCollection private Map memberMessageStatus; diff --git a/src/main/java/envoy/server/data/PersistenceManager.java b/src/main/java/envoy/server/data/PersistenceManager.java index 1e99978..3432846 100755 --- a/src/main/java/envoy/server/data/PersistenceManager.java +++ b/src/main/java/envoy/server/data/PersistenceManager.java @@ -194,6 +194,22 @@ public class PersistenceManager { .getResultList(); } + /** + * Returns all groupMessages received while being offline or the ones that have + * changed. + * + * @param user the user who wants to receive his unread groupMessages + * @return all groupMessages that the client does not yet have (unread + * groupMessages) + * @since Envoy Server Standalone v0.1-alpha + */ + public List getPendingGroupMessages(User user) { + return entityManager.createNamedQuery(GroupMessage.getPendingGroupMsg) + .setParameter("userId", user.getID()) + .setParameter("lastSeen", user.getLastSeen()) + .getResultList(); + } + /** * Searches for users matching a search phrase. Contacts of the attached user * and the attached user is ignored. diff --git a/src/main/java/envoy/server/processors/GroupMessageProcessor.java b/src/main/java/envoy/server/processors/GroupMessageProcessor.java index 725004e..f62054e 100644 --- a/src/main/java/envoy/server/processors/GroupMessageProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageProcessor.java @@ -8,7 +8,6 @@ import javax.persistence.EntityExistsException; import envoy.data.GroupMessage; import envoy.data.Message.MessageStatus; -import envoy.event.MessageStatusChange; import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectWriteProxy; @@ -43,12 +42,12 @@ public class GroupMessageProcessor implements ObjectProcessor { // sender, if he is still online. if (!groupMessage.getMemberStatuses().containsValue(MessageStatus.SENT)) { groupMessage.setStatus(MessageStatus.RECEIVED); - if (connectionManager.isOnline(connectionManager.getUserIdBySocketID(socketID))) try { - writeProxy.write(socketID, new MessageStatusChange(groupMessage)); - } catch (IOException e) { - logger.warning("Sender of the groupMessage online. Failed to send MessageStatusChange"); - e.printStackTrace(); - } +// if (connectionManager.isOnline(connectionManager.getUserIdBySocketID(socketID))) try { +// writeProxy.write(socketID, new MessageStatusChange(groupMessage)); +// } catch (IOException e) { +// logger.warning("Sender of the groupMessage online. Failed to send MessageStatusChange"); +// e.printStackTrace(); +// } } members.stream() diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index 0a248c9..d0010a4 100755 --- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -1,12 +1,16 @@ package envoy.server.processors; import static envoy.data.User.UserStatus.ONLINE; -import static envoy.event.HandshakeRejection.*; +import static envoy.event.HandshakeRejection.INTERNAL_ERROR; +import static envoy.event.HandshakeRejection.USERNAME_TAKEN; +import static envoy.event.HandshakeRejection.WRONG_PASSWORD_OR_USER; +import static envoy.event.HandshakeRejection.WRONG_VERSION; import java.io.IOException; import java.time.LocalDateTime; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.logging.Logger; import javax.persistence.NoResultException; @@ -16,6 +20,7 @@ import envoy.data.LoginCredentials; import envoy.data.Message.MessageStatus; import envoy.event.HandshakeRejection; import envoy.event.MessageStatusChange; +import envoy.server.data.GroupMessage; import envoy.server.data.PersistenceManager; import envoy.server.data.User; import envoy.server.net.ConnectionManager; @@ -117,6 +122,9 @@ public final class LoginCredentialProcessor implements ObjectProcessor pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user); + logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "..."); + for (var msg : pendingMessages) { final var msgCommon = msg.toCommon(); if (msg.getStatus() == MessageStatus.SENT) { @@ -133,6 +141,23 @@ public final class LoginCredentialProcessor implements ObjectProcessor { public void process(Message message, long socketID, ObjectWriteProxy writeProxy) { // Makes sure, that there are no groupMessages processed here, because // groupMessage is a subclass of message. - if (message.getClass().equals(envoy.data.GroupMessage.class)) return; - + if (message.getClass().equals(envoy.data.GroupMessage.class)) { + return; + } message.nextStatus(); // Convert to server message From 5d0cc7e84cd88e9e49712b6c56f6271ab5fbdbd0 Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Sun, 28 Jun 2020 10:33:06 +0200 Subject: [PATCH 03/15] Fixed error regarding notSerializable exception --- src/main/java/envoy/server/data/GroupMessage.java | 3 ++- .../envoy/server/processors/LoginCredentialProcessor.java | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java index 13c1d08..176c82e 100644 --- a/src/main/java/envoy/server/data/GroupMessage.java +++ b/src/main/java/envoy/server/data/GroupMessage.java @@ -1,6 +1,7 @@ package envoy.server.data; import java.util.Date; +import java.util.HashMap; import java.util.Map; import javax.persistence.Column; @@ -73,7 +74,7 @@ public class GroupMessage extends Message { .setForwarded(forwarded) .setStatus(status) .setText(text) - .buildGroupMessage((envoy.data.Group) recipient.toCommon(), memberMessageStatus); + .buildGroupMessage((envoy.data.Group) recipient.toCommon(), new HashMap<>(memberMessageStatus)); groupMessage.setReceivedDate(receivedDate); groupMessage.setReadDate(readDate); return groupMessage; diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index d0010a4..f0da20f 100755 --- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -145,9 +145,10 @@ public final class LoginCredentialProcessor implements ObjectProcessor Date: Sun, 28 Jun 2020 16:11:47 +0200 Subject: [PATCH 04/15] Implemented PendingGroupMessageStatusChanges for RECEIVED --- src/main/java/envoy/server/data/GroupMessage.java | 3 ++- .../processors/LoginCredentialProcessor.java | 15 +++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java index 176c82e..9f9a72a 100644 --- a/src/main/java/envoy/server/data/GroupMessage.java +++ b/src/main/java/envoy/server/data/GroupMessage.java @@ -24,7 +24,8 @@ import envoy.data.MessageBuilder; @Entity @NamedQuery( name = GroupMessage.getPendingGroupMsg, - query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE (KEY(s) = :userId) AND (m.creationDate > :lastSeen)" + query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE (KEY(s) = :userId) AND ((m.creationDate > :lastSeen)" + + "OR ((m.status = envoy.data.Message$MessageStatus.RECEIVED) AND (m.receivedDate > :lastSeen)))" ) public class GroupMessage extends Message { diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index f0da20f..86ccdfb 100755 --- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -11,6 +11,7 @@ import java.time.LocalDateTime; import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.logging.Logger; import javax.persistence.NoResultException; @@ -120,6 +121,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor m instanceof GroupMessage); logger.fine("Sending " + pendingMessages.size() + " pending messages to " + user + "..."); List pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user); @@ -146,17 +148,22 @@ public final class LoginCredentialProcessor implements ObjectProcessor entry : gmsg.getMemberMessageStatus().entrySet()) { + if (entry.getKey() == connectionManager.getUserIdBySocketID(socketID)) continue; + if (connectionManager.isOnline(entry.getKey())) { + writeProxy.write(connectionManager.getSocketID(entry.getKey()), new MessageStatusChange(gmsg.toCommon())); + } + } } PersistenceManager.getInstance().updateMessage(gmsg); } else { // Sending memberStatusEvents and MessageStatusChange Events + writeProxy.write(socketID, new MessageStatusChange(gmsg.toCommon())); } } } From 3c8a5c7abbf4ada74397064e50c1637e53d14641 Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Fri, 3 Jul 2020 16:25:49 +0200 Subject: [PATCH 05/15] Implemented GroupMessageStatusChange handling (not with pending yet) --- src/main/java/envoy/server/Startup.java | 2 + .../GroupMessageStatusChangeProcessor.java | 69 +++++++++++++++++++ .../MessageStatusChangeProcessor.java | 3 + 3 files changed, 74 insertions(+) create mode 100644 src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java diff --git a/src/main/java/envoy/server/Startup.java b/src/main/java/envoy/server/Startup.java index 3aaaf64..8991667 100755 --- a/src/main/java/envoy/server/Startup.java +++ b/src/main/java/envoy/server/Startup.java @@ -18,6 +18,7 @@ import envoy.server.processors.ContactOperationProcessor; import envoy.server.processors.ContactSearchProcessor; import envoy.server.processors.GroupCreationProcessor; import envoy.server.processors.GroupMessageProcessor; +import envoy.server.processors.GroupMessageStatusChangeProcessor; import envoy.server.processors.IDGeneratorRequestProcessor; import envoy.server.processors.LoginCredentialProcessor; import envoy.server.processors.MessageProcessor; @@ -72,6 +73,7 @@ public class Startup { new GroupMessageProcessor(), new GroupCreationProcessor(), new MessageStatusChangeProcessor(), + new GroupMessageStatusChangeProcessor(), new UserStatusChangeProcessor(), new IDGeneratorRequestProcessor(), new ContactSearchProcessor(), diff --git a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java new file mode 100644 index 0000000..1dc37eb --- /dev/null +++ b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java @@ -0,0 +1,69 @@ +package envoy.server.processors; + +import java.io.IOException; + +import envoy.data.Message.MessageStatus; +import envoy.event.GroupMessageStatusChange; +import envoy.event.MessageStatusChange; +import envoy.exception.EnvoyException; +import envoy.server.data.GroupMessage; +import envoy.server.data.PersistenceManager; +import envoy.server.net.ConnectionManager; +import envoy.server.net.ObjectWriteProxy; + +/** + * Project: envoy-server-standalone
+ * File: GroupMessageStatusChangeProcessor.java
+ * Created: 03.07.2020
+ * + * @author Maximilian Käfer + * @since Envoy Server Standalone v0.1-beta + */ +public class GroupMessageStatusChangeProcessor implements ObjectProcessor { + + private final PersistenceManager persistenceManager = PersistenceManager.getInstance(); + private final ConnectionManager connectionManager = ConnectionManager.getInstance(); + + @Override + public void process(GroupMessageStatusChange input, long socketID, ObjectWriteProxy writeProxy) throws IOException { + GroupMessage gmsg = (GroupMessage) persistenceManager.getMessageByID(input.getID()); + if (gmsg.getStatus() == input.get()) + throw new IOException(new EnvoyException("The groupMessage already has the status " + input.get())); + + gmsg.getMemberMessageStatus().replace(input.getMemberID(), input.get()); + + // Notifying the other members about memberStatusChange + gmsg.getMemberMessageStatus().keySet().stream().filter(k -> connectionManager.getUserIdBySocketID(socketID) != k).forEach(k -> { + if(connectionManager.isOnline(k)) { + try { + writeProxy.write(connectionManager.getSocketID(k), input); + } catch (IOException e) { + // TODO Maybe Try Catch block is not necessarily needed but if so write proper + // logger statement here. + e.printStackTrace(); + } + } + }); + + if (!gmsg.getMemberMessageStatus().containsValue(MessageStatus.SENT) + && !gmsg.getMemberMessageStatus().containsValue(MessageStatus.RECEIVED)) { + gmsg.read(); + // Notifying the other members about messageStatusChange + gmsg.getMemberMessageStatus().keySet().forEach(k -> { + if (connectionManager.isOnline(k)) { + try { + writeProxy.write(connectionManager.getSocketID(k), new MessageStatusChange(input.getID(), input.get(), input.getDate())); + } catch (IOException e) { + // TODO Maybe Try Catch block is not necessarily needed but if so write proper + // logger statement here. + e.printStackTrace(); + } + } + }); + } + persistenceManager.updateMessage(gmsg); + } + + @Override + public Class getInputClass() { return GroupMessageStatusChange.class; } +} diff --git a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java index 8801d54..f4e2312 100755 --- a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java @@ -3,6 +3,7 @@ package envoy.server.processors; import java.io.IOException; import envoy.data.Message.MessageStatus; +import envoy.event.GroupMessageStatusChange; import envoy.event.MessageStatusChange; import envoy.exception.EnvoyException; import envoy.server.data.PersistenceManager; @@ -24,6 +25,8 @@ public class MessageStatusChangeProcessor implements ObjectProcessor Date: Fri, 3 Jul 2020 17:46:37 +0200 Subject: [PATCH 06/15] Implemented sending RECEIVED GroupMessageStatusChanges If a member logs in and receives pending groupMessages, there are now groupMessageStatusChanges sent to all other members, that are online and have already received the groupMessage. --- .../processors/LoginCredentialProcessor.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index 86ccdfb..b562950 100755 --- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -19,6 +19,7 @@ import javax.persistence.NoResultException; import enovy.server.util.VersionUtils; import envoy.data.LoginCredentials; import envoy.data.Message.MessageStatus; +import envoy.event.GroupMessageStatusChange; import envoy.event.HandshakeRejection; import envoy.event.MessageStatusChange; import envoy.server.data.GroupMessage; @@ -149,7 +150,22 @@ public final class LoginCredentialProcessor implements ObjectProcessor (gmsg.getMemberMessageStatus().get(k) == MessageStatus.RECEIVED + || gmsg.getMemberMessageStatus().get(k) == MessageStatus.READ) && connectionManager.getUserIdBySocketID(socketID) != k) + .forEach(k -> { + if (connectionManager.isOnline(k)) try { + writeProxy.write(connectionManager.getSocketID(k), + (new GroupMessageStatusChange(gmsg.getID(), MessageStatus.RECEIVED, LocalDateTime.now(), + connectionManager.getUserIdBySocketID(socketID)))); + } catch (IOException e) { + // TODO Maybe Try Catch block is not necessarily needed but if so write proper + // logger statement here. + e.printStackTrace(); + } + }); if (!gmsg.getMemberMessageStatus().containsValue(MessageStatus.SENT)) { gmsg.received(); // Sending MessageStatusChangeEvent to all other members From 8f71edc7cf863a081d9ee3adfd1974db1509d405 Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Sat, 4 Jul 2020 09:31:15 +0200 Subject: [PATCH 07/15] Implemented Date name change --- src/main/java/envoy/server/data/GroupMessage.java | 2 +- src/main/java/envoy/server/data/Message.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java index 9f9a72a..7c61390 100644 --- a/src/main/java/envoy/server/data/GroupMessage.java +++ b/src/main/java/envoy/server/data/GroupMessage.java @@ -71,7 +71,7 @@ public class GroupMessage extends Message { @Override public envoy.data.GroupMessage toCommon() { // TODO: Attachment - envoy.data.GroupMessage groupMessage = new MessageBuilder(sender.getID(), recipient.getID(), id).setDate(creationDate) + envoy.data.GroupMessage groupMessage = new MessageBuilder(sender.getID(), recipient.getID(), id).setCreationDate(creationDate) .setForwarded(forwarded) .setStatus(status) .setText(text) diff --git a/src/main/java/envoy/server/data/Message.java b/src/main/java/envoy/server/data/Message.java index 5b81e7d..7127832 100755 --- a/src/main/java/envoy/server/data/Message.java +++ b/src/main/java/envoy/server/data/Message.java @@ -104,7 +104,7 @@ public class Message { public envoy.data.Message toCommon() { // TODO: Attachment envoy.data.Message message = new MessageBuilder(sender.getID(), recipient.getID(), id).setText(text) - .setDate(creationDate) + .setCreationDate(creationDate) .setStatus(status) .setForwarded(forwarded) .build(); From 4f7eff74e3cfb888bb5050801b829fde4b5ad2ee Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Sat, 4 Jul 2020 15:59:48 +0200 Subject: [PATCH 08/15] Added pending MessageStatusChanges READ to Query --- src/main/java/envoy/server/data/GroupMessage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java index 7c61390..0cba412 100644 --- a/src/main/java/envoy/server/data/GroupMessage.java +++ b/src/main/java/envoy/server/data/GroupMessage.java @@ -25,7 +25,8 @@ import envoy.data.MessageBuilder; @NamedQuery( name = GroupMessage.getPendingGroupMsg, query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE (KEY(s) = :userId) AND ((m.creationDate > :lastSeen)" - + "OR ((m.status = envoy.data.Message$MessageStatus.RECEIVED) AND (m.receivedDate > :lastSeen)))" + + "OR ((m.status = envoy.data.Message$MessageStatus.RECEIVED) AND (m.receivedDate > :lastSeen))" + + "OR ((m.status = envoy.data.Message$MessageStatus.READ) AND (m.readDate > :lastSeen)))" ) public class GroupMessage extends Message { From 450714608b6f3ce7612e26dcfce96bfcf00b7c0f Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Sun, 5 Jul 2020 13:28:48 +0200 Subject: [PATCH 09/15] Reimplemented RECEIVED update sending to sender --- .../server/processors/GroupMessageProcessor.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/envoy/server/processors/GroupMessageProcessor.java b/src/main/java/envoy/server/processors/GroupMessageProcessor.java index f62054e..725004e 100644 --- a/src/main/java/envoy/server/processors/GroupMessageProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageProcessor.java @@ -8,6 +8,7 @@ import javax.persistence.EntityExistsException; import envoy.data.GroupMessage; import envoy.data.Message.MessageStatus; +import envoy.event.MessageStatusChange; import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectWriteProxy; @@ -42,12 +43,12 @@ public class GroupMessageProcessor implements ObjectProcessor { // sender, if he is still online. if (!groupMessage.getMemberStatuses().containsValue(MessageStatus.SENT)) { groupMessage.setStatus(MessageStatus.RECEIVED); -// if (connectionManager.isOnline(connectionManager.getUserIdBySocketID(socketID))) try { -// writeProxy.write(socketID, new MessageStatusChange(groupMessage)); -// } catch (IOException e) { -// logger.warning("Sender of the groupMessage online. Failed to send MessageStatusChange"); -// e.printStackTrace(); -// } + if (connectionManager.isOnline(connectionManager.getUserIdBySocketID(socketID))) try { + writeProxy.write(socketID, new MessageStatusChange(groupMessage)); + } catch (IOException e) { + logger.warning("Sender of the groupMessage online. Failed to send MessageStatusChange"); + e.printStackTrace(); + } } members.stream() From ead5673d6d92631a90d9b7d255fb4c978656779f Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Sun, 5 Jul 2020 16:53:27 +0200 Subject: [PATCH 10/15] Apply suggestions from code review (not everything) Co-authored-by: CyB3RC0nN0R --- src/main/java/envoy/server/Startup.java | 11 +---------- src/main/java/envoy/server/data/GroupMessage.java | 7 +------ .../processors/GroupMessageStatusChangeProcessor.java | 5 +++-- .../server/processors/LoginCredentialProcessor.java | 11 +++-------- .../envoy/server/processors/MessageProcessor.java | 2 +- .../processors/MessageStatusChangeProcessor.java | 2 +- 6 files changed, 10 insertions(+), 28 deletions(-) diff --git a/src/main/java/envoy/server/Startup.java b/src/main/java/envoy/server/Startup.java index 0edcfed..5128d15 100755 --- a/src/main/java/envoy/server/Startup.java +++ b/src/main/java/envoy/server/Startup.java @@ -14,16 +14,7 @@ import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectMessageProcessor; import envoy.server.net.ObjectMessageReader; -import envoy.server.processors.ContactOperationProcessor; -import envoy.server.processors.ContactSearchProcessor; -import envoy.server.processors.GroupCreationProcessor; -import envoy.server.processors.GroupMessageProcessor; -import envoy.server.processors.GroupMessageStatusChangeProcessor; -import envoy.server.processors.IDGeneratorRequestProcessor; -import envoy.server.processors.LoginCredentialProcessor; -import envoy.server.processors.MessageProcessor; -import envoy.server.processors.MessageStatusChangeProcessor; -import envoy.server.processors.UserStatusChangeProcessor; +import envoy.server.processors.*; import envoy.util.EnvoyLog; /** diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java index 28965ec..3dfe94a 100644 --- a/src/main/java/envoy/server/data/GroupMessage.java +++ b/src/main/java/envoy/server/data/GroupMessage.java @@ -4,12 +4,7 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; -import javax.persistence.Column; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.NamedQuery; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import javax.persistence.*; import envoy.data.Group; diff --git a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java index 1dc37eb..20a25f7 100644 --- a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java @@ -21,8 +21,9 @@ import envoy.server.net.ObjectWriteProxy; */ public class GroupMessageStatusChangeProcessor implements ObjectProcessor { - private final PersistenceManager persistenceManager = PersistenceManager.getInstance(); - private final ConnectionManager connectionManager = ConnectionManager.getInstance(); + private static final PersistenceManager persistenceManager = PersistenceManager.getInstance(); + private static final ConnectionManager connectionManager = ConnectionManager.getInstance(); + @Override public void process(GroupMessageStatusChange input, long socketID, ObjectWriteProxy writeProxy) throws IOException { diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index fc43207..f54498b 100755 --- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -1,10 +1,7 @@ package envoy.server.processors; import static envoy.data.User.UserStatus.ONLINE; -import static envoy.event.HandshakeRejection.INTERNAL_ERROR; -import static envoy.event.HandshakeRejection.USERNAME_TAKEN; -import static envoy.event.HandshakeRejection.WRONG_PASSWORD_OR_USER; -import static envoy.event.HandshakeRejection.WRONG_VERSION; +import static envoy.event.HandshakeRejection.*; import java.io.IOException; import java.time.LocalDateTime; @@ -122,7 +119,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor m instanceof GroupMessage); + pendingMessages.removeIf(GroupMessage.class::isInstance); logger.fine("Sending " + pendingMessages.size() + " pending messages to " + user + "..."); List pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user); @@ -161,9 +158,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor { public void process(Message message, long socketID, ObjectWriteProxy writeProxy) { // Makes sure, that there are no groupMessages processed here, because // groupMessage is a subclass of message. - if (message.getClass().equals(envoy.data.GroupMessage.class)) { + if (message instanceof envoy.data.GroupMessage)) { return; } message.nextStatus(); diff --git a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java index f4e2312..0d57be0 100755 --- a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java @@ -26,7 +26,7 @@ public class MessageStatusChangeProcessor implements ObjectProcessor Date: Mon, 6 Jul 2020 11:40:13 +0200 Subject: [PATCH 11/15] Active Code Review --- .../java/envoy/server/data/GroupMessage.java | 22 +++-- .../envoy/server/net/ConnectionManager.java | 4 +- .../envoy/server/net/ObjectWriteProxy.java | 50 ++++++++-- .../processors/ContactOperationProcessor.java | 7 +- .../processors/ContactSearchProcessor.java | 2 +- .../processors/GroupCreationProcessor.java | 15 +-- .../processors/GroupMessageProcessor.java | 68 +++++-------- .../GroupMessageStatusChangeProcessor.java | 73 +++++++------- .../processors/GroupResizeProcessor.java | 12 +-- .../processors/LoginCredentialProcessor.java | 98 +++++++++---------- .../server/processors/MessageProcessor.java | 8 +- .../MessageStatusChangeProcessor.java | 15 ++- .../processors/NameChangeProcessor.java | 16 +-- .../processors/UserStatusChangeProcessor.java | 35 ++----- 14 files changed, 195 insertions(+), 230 deletions(-) diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java index 3dfe94a..a9623a0 100644 --- a/src/main/java/envoy/server/data/GroupMessage.java +++ b/src/main/java/envoy/server/data/GroupMessage.java @@ -1,6 +1,6 @@ package envoy.server.data; -import java.util.Date; +import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; @@ -25,14 +25,20 @@ import envoy.data.Group; ) public class GroupMessage extends Message { + /** + * Named query retrieving pending group messages sent to a group containing a + * specific user (parameter {@code userId}) that were sent after a certain time + * stamp (parameter {@code :lastSeen}). + * + * @since Envoy Server Standalone v0.1-beta + */ public static final String getPendingGroupMsg = "GroupMessage.getPendingGroupMsg"; @ElementCollection private Map memberMessageStatus; @Column(name = "last_status_change_date") - @Temporal(TemporalType.TIMESTAMP) - protected Date lastStatusChangeDate; + protected LocalDateTime lastStatusChangeDate; /** * The constructor for a database object. @@ -47,12 +53,12 @@ public class GroupMessage extends Message { * @param groupMessage the {@link envoy.data.GroupMessage} to convert * into a * database {@link GroupMessage} - * @param lastStatusChangeDate the {@link Date} to set + * @param lastStatusChangeDate the time stamp to set * @since Envoy Server Standalone v0.1-beta */ - public GroupMessage(envoy.data.GroupMessage groupMessage, Date lastStatusChangeDate) { + public GroupMessage(envoy.data.GroupMessage groupMessage, LocalDateTime lastStatusChangeDate) { super(groupMessage); - memberMessageStatus = groupMessage.getMemberStatuses(); + memberMessageStatus = groupMessage.getMemberStatuses(); this.lastStatusChangeDate = lastStatusChangeDate; } @@ -87,11 +93,11 @@ public class GroupMessage extends Message { * @return the date at which one of the member statuses changed last * @since Envoy Server Standalone v0.1-beta */ - public Date getLastStatusChangeDate() { return lastStatusChangeDate; } + public LocalDateTime getLastStatusChangeDate() { return lastStatusChangeDate; } /** * @param date the date to set * @since Envoy Server Standalone v0.1-beta */ - public void setLastStatusChangeDate(Date date) { lastStatusChangeDate = date; } + public void setLastStatusChangeDate(LocalDateTime date) { lastStatusChangeDate = date; } } diff --git a/src/main/java/envoy/server/net/ConnectionManager.java b/src/main/java/envoy/server/net/ConnectionManager.java index cb2d818..e0ce7ed 100755 --- a/src/main/java/envoy/server/net/ConnectionManager.java +++ b/src/main/java/envoy/server/net/ConnectionManager.java @@ -50,7 +50,7 @@ public class ConnectionManager implements ISocketIdListener { public void socketCancelled(long socketID) { if (!pendingSockets.remove(socketID)) { // Notify contacts of this users offline-going - envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIdBySocketID(socketID)); + envoy.server.data.User user = PersistenceManager.getInstance().getUserByID(getUserIDBySocketID(socketID)); user.setStatus(UserStatus.OFFLINE); user.setLastSeen(LocalDateTime.now()); UserStatusChangeProcessor.updateUserStatus(user); @@ -87,7 +87,7 @@ public class ConnectionManager implements ISocketIdListener { * @return the userId associated with this socketId * @since Envoy Server Standalone v0.1-alpha */ - public long getUserIdBySocketID(long socketID) { + public long getUserIDBySocketID(long socketID) { return sockets.entrySet().stream().filter(entry -> entry.getValue().equals(socketID)).findFirst().get().getKey(); } diff --git a/src/main/java/envoy/server/net/ObjectWriteProxy.java b/src/main/java/envoy/server/net/ObjectWriteProxy.java index 1e1c76b..68c82bb 100755 --- a/src/main/java/envoy/server/net/ObjectWriteProxy.java +++ b/src/main/java/envoy/server/net/ObjectWriteProxy.java @@ -1,11 +1,14 @@ package envoy.server.net; import java.io.IOException; +import java.util.Set; import java.util.logging.Logger; +import java.util.stream.Stream; import com.jenkov.nioserver.Message; import com.jenkov.nioserver.WriteProxy; +import envoy.server.data.Contact; import envoy.util.EnvoyLog; import envoy.util.SerializationUtils; @@ -23,7 +26,8 @@ public class ObjectWriteProxy { private final WriteProxy writeProxy; - private static final Logger logger = EnvoyLog.getLogger(ObjectWriteProxy.class); + private static final ConnectionManager connectionManager = ConnectionManager.getInstance(); + private static final Logger logger = EnvoyLog.getLogger(ObjectWriteProxy.class); /** * Creates an instance of {@link ObjectWriteProxy}. @@ -36,23 +40,49 @@ public class ObjectWriteProxy { /** * @param recipientSocketID the socket id of the recipient * @param obj the object to return to the client - * @throws IOException if the serialization of the object failed + * @throws RuntimeException if the serialization of the object failed (this is + * highly unlikely) * @since Envoy Server Standalone v0.1-alpha */ - public void write(long recipientSocketID, Object obj) throws IOException { + public void write(long recipientSocketID, Object obj) { // Create message targeted at the client final Message response = writeProxy.getMessage(); response.socketId = recipientSocketID; logger.fine("Sending " + obj); - // Serialize object to byte array - final byte[] objBytes = SerializationUtils.writeToByteArray(obj); + try { - // Acquire object length in bytes - final byte[] objLen = SerializationUtils.intToBytes(objBytes.length); + // Serialize object to byte array + final byte[] objBytes = SerializationUtils.writeToByteArray(obj); - response.writeToMessage(objLen); - response.writeToMessage(objBytes); - writeProxy.enqueue(response); + // Acquire object length in bytes + final byte[] objLen = SerializationUtils.intToBytes(objBytes.length); + + response.writeToMessage(objLen); + response.writeToMessage(objBytes); + writeProxy.enqueue(response); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Sends an object to all contact in a set that are online. + * + * @param contacts the contacts to send the object to + * @param message the object to send + * @since Envoy Server Standalone v0.1-beta + */ + public void writeToOnlineContacts(Set contacts, Object message) { writeToOnlineContacts(contacts.stream(), message); } + + /** + * Sends an object to all contact in a set that are online. + * + * @param contacts the contacts to send the object to + * @param message the object to send + * @since Envoy Server Standalone v0.1-beta + */ + public void writeToOnlineContacts(Stream contacts, Object message) { + contacts.map(Contact::getID).filter(connectionManager::isOnline).map(connectionManager::getSocketID).forEach(id -> write(id, message)); } } diff --git a/src/main/java/envoy/server/processors/ContactOperationProcessor.java b/src/main/java/envoy/server/processors/ContactOperationProcessor.java index febd409..4363f60 100755 --- a/src/main/java/envoy/server/processors/ContactOperationProcessor.java +++ b/src/main/java/envoy/server/processors/ContactOperationProcessor.java @@ -1,6 +1,5 @@ package envoy.server.processors; -import java.io.IOException; import java.util.logging.Logger; import envoy.event.ElementOperation; @@ -24,10 +23,10 @@ public class ContactOperationProcessor implements ObjectProcessor { private final ConnectionManager connectionManager = ConnectionManager.getInstance(); @Override - public void process(GroupCreation groupCreation, long socketID, ObjectWriteProxy writeProxy) throws IOException { + public void process(GroupCreation groupCreation, long socketID, ObjectWriteProxy writeProxy) { envoy.server.data.Group group = new envoy.server.data.Group(); group.setName(groupCreation.get()); group.setContacts(new HashSet<>()); groupCreation.getInitialMemberIDs().stream().map(persistenceManager::getUserByID).forEach(group.getContacts()::add); - group.getContacts().add(persistenceManager.getContactByID(connectionManager.getUserIdBySocketID(socketID))); + group.getContacts().add(persistenceManager.getContactByID(connectionManager.getUserIDBySocketID(socketID))); group.getContacts().forEach(c -> c.getContacts().add(group)); - group.getContacts().add(persistenceManager.getUserByID(connectionManager.getUserIdBySocketID(socketID))); + group.getContacts().add(persistenceManager.getUserByID(connectionManager.getUserIDBySocketID(socketID))); persistenceManager.addContact(group); group.getContacts() .stream() .map(Contact::getID) .filter(connectionManager::isOnline) .map(connectionManager::getSocketID) - .forEach(memberSocketID -> { - try { - writeProxy.write(memberSocketID, new ContactOperation(group.toCommon(), ElementOperation.ADD)); - } catch (IOException e) { - e.printStackTrace(); - } - }); + .forEach(memberSocketID -> writeProxy.write(memberSocketID, new ContactOperation(group.toCommon(), ElementOperation.ADD))); } @Override diff --git a/src/main/java/envoy/server/processors/GroupMessageProcessor.java b/src/main/java/envoy/server/processors/GroupMessageProcessor.java index 725004e..54594e3 100644 --- a/src/main/java/envoy/server/processors/GroupMessageProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageProcessor.java @@ -1,13 +1,14 @@ package envoy.server.processors; -import java.io.IOException; -import java.util.Date; +import static envoy.data.Message.MessageStatus.*; + +import java.time.LocalDateTime; +import java.util.Collections; import java.util.logging.Logger; import javax.persistence.EntityExistsException; import envoy.data.GroupMessage; -import envoy.data.Message.MessageStatus; import envoy.event.MessageStatusChange; import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; @@ -24,60 +25,43 @@ import envoy.util.EnvoyLog; */ public class GroupMessageProcessor implements ObjectProcessor { - private static final Logger logger = EnvoyLog.getLogger(GroupCreationProcessor.class); + private static final ConnectionManager connectionManager = ConnectionManager.getInstance(); + private static final PersistenceManager persistenceManager = PersistenceManager.getInstance(); + private static final Logger logger = EnvoyLog.getLogger(GroupCreationProcessor.class); @Override public void process(GroupMessage groupMessage, long socketID, ObjectWriteProxy writeProxy) { groupMessage.nextStatus(); - ConnectionManager connectionManager = ConnectionManager.getInstance(); - final var members = PersistenceManager.getInstance().getGroupByID(groupMessage.getRecipientID()).getContacts(); - members.forEach(user -> groupMessage.getMemberStatuses().replace(user.getID(), MessageStatus.SENT)); - members.forEach(user -> { setMemberStatus(connectionManager, groupMessage, user.getID()); }); - // Setting memberStatus of sender to READ - groupMessage.getMemberStatuses() - .replace(members.stream().filter(sender -> groupMessage.getSenderID() == sender.getID()).findAny().get().getID(), MessageStatus.READ); + // Update statuses to SENT / RECEIVED depending on online status + groupMessage.getMemberStatuses().replaceAll((memberID, status) -> connectionManager.isOnline(memberID) ? RECEIVED : SENT); - // Checks if all memberMessageStatuses are RECEIVED and if so sets the - // groupMessage Status to RECEIVED and sends a MessageStatusChange to the - // sender, if he is still online. - if (!groupMessage.getMemberStatuses().containsValue(MessageStatus.SENT)) { - groupMessage.setStatus(MessageStatus.RECEIVED); - if (connectionManager.isOnline(connectionManager.getUserIdBySocketID(socketID))) try { - writeProxy.write(socketID, new MessageStatusChange(groupMessage)); - } catch (IOException e) { - logger.warning("Sender of the groupMessage online. Failed to send MessageStatusChange"); - e.printStackTrace(); - } + // Set status for sender to READ + groupMessage.getMemberStatuses().replace(groupMessage.getSenderID(), READ); + + // Increment the overall status to RECEIVED if necessary + if (Collections.min(groupMessage.getMemberStatuses().values()) == RECEIVED) { + groupMessage.nextStatus(); + + // Notify the sender of the status change + writeProxy.write(socketID, new MessageStatusChange(groupMessage)); } - members.stream() - .filter(m -> groupMessage.getSenderID() != m.getID()) - .forEach(user -> { sendToMember(connectionManager, groupMessage, user.getID(), writeProxy); }); + // Deliver the message to the recipients that are online + writeProxy.writeToOnlineContacts( + persistenceManager.getGroupByID(groupMessage.getRecipientID()) + .getContacts() + .stream() + .filter(c -> c.getID() != groupMessage.getSenderID()), + groupMessage); try { - PersistenceManager.getInstance().addMessage(new envoy.server.data.GroupMessage(groupMessage, new Date())); + PersistenceManager.getInstance().addMessage(new envoy.server.data.GroupMessage(groupMessage, LocalDateTime.now())); } catch (EntityExistsException e) { logger.warning("Received a groupMessage with an ID that already exists"); } } - private void sendToMember(ConnectionManager connectionManager, GroupMessage groupMessage, long memberID, ObjectWriteProxy writeProxy) { - if (connectionManager.isOnline(memberID)) try { - // If recipient is online, send the groupMessage directly - writeProxy.write(connectionManager.getSocketID(memberID), groupMessage); - } catch (IOException e) { - logger.warning("Recipient online. Failed to send message" + groupMessage.getID()); - e.printStackTrace(); - } - } - - private void setMemberStatus(ConnectionManager connectionManager, GroupMessage groupMessage, long memberID) { - if (connectionManager.isOnline(memberID)) - // Update the message status of the member to RECEIVED - groupMessage.getMemberStatuses().replace(memberID, MessageStatus.RECEIVED); - } - @Override public Class getInputClass() { return GroupMessage.class; } } diff --git a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java index 20a25f7..9337540 100644 --- a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java @@ -1,15 +1,20 @@ package envoy.server.processors; -import java.io.IOException; +import static envoy.data.Message.MessageStatus.READ; + +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.logging.Level; +import java.util.logging.Logger; import envoy.data.Message.MessageStatus; import envoy.event.GroupMessageStatusChange; import envoy.event.MessageStatusChange; -import envoy.exception.EnvoyException; import envoy.server.data.GroupMessage; import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectWriteProxy; +import envoy.util.EnvoyLog; /** * Project: envoy-server-standalone
@@ -21,46 +26,38 @@ import envoy.server.net.ObjectWriteProxy; */ public class GroupMessageStatusChangeProcessor implements ObjectProcessor { - private static final PersistenceManager persistenceManager = PersistenceManager.getInstance(); - private static final ConnectionManager connectionManager = ConnectionManager.getInstance(); - + private final ConnectionManager connectionManager = ConnectionManager.getInstance(); + private final PersistenceManager persistenceManager = PersistenceManager.getInstance(); + private final Logger logger = EnvoyLog.getLogger(MessageStatusChangeProcessor.class); @Override - public void process(GroupMessageStatusChange input, long socketID, ObjectWriteProxy writeProxy) throws IOException { - GroupMessage gmsg = (GroupMessage) persistenceManager.getMessageByID(input.getID()); - if (gmsg.getStatus() == input.get()) - throw new IOException(new EnvoyException("The groupMessage already has the status " + input.get())); + public void process(GroupMessageStatusChange statusChange, long socketID, ObjectWriteProxy writeProxy) { + GroupMessage gmsg = (GroupMessage) persistenceManager.getMessageByID(statusChange.getID()); - gmsg.getMemberMessageStatus().replace(input.getMemberID(), input.get()); - - // Notifying the other members about memberStatusChange - gmsg.getMemberMessageStatus().keySet().stream().filter(k -> connectionManager.getUserIdBySocketID(socketID) != k).forEach(k -> { - if(connectionManager.isOnline(k)) { - try { - writeProxy.write(connectionManager.getSocketID(k), input); - } catch (IOException e) { - // TODO Maybe Try Catch block is not necessarily needed but if so write proper - // logger statement here. - e.printStackTrace(); - } - } - }); - - if (!gmsg.getMemberMessageStatus().containsValue(MessageStatus.SENT) - && !gmsg.getMemberMessageStatus().containsValue(MessageStatus.RECEIVED)) { + // Any other status than READ is not supposed to be sent to the server + if (statusChange.get() != MessageStatus.READ) { + logger.log(Level.WARNING, "Invalid " + statusChange); + return; + } + + // Apply the status change + gmsg.getMemberMessageStatus().replace(statusChange.getMemberID(), statusChange.get()); + + // Notifying the other members about the status change + gmsg.getMemberMessageStatus() + .keySet() + .stream() + .filter(k -> connectionManager.getUserIDBySocketID(socketID) != k) + .filter(connectionManager::isOnline) + .forEach(k -> writeProxy.write(connectionManager.getSocketID(k), statusChange)); + + // Increment overall status to READ if necessary + if (Collections.min(gmsg.getMemberMessageStatus().values()) == READ) { gmsg.read(); - // Notifying the other members about messageStatusChange - gmsg.getMemberMessageStatus().keySet().forEach(k -> { - if (connectionManager.isOnline(k)) { - try { - writeProxy.write(connectionManager.getSocketID(k), new MessageStatusChange(input.getID(), input.get(), input.getDate())); - } catch (IOException e) { - // TODO Maybe Try Catch block is not necessarily needed but if so write proper - // logger statement here. - e.printStackTrace(); - } - } - }); + + // Notify online members about the status change + writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(), + new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), LocalDateTime.now())); } persistenceManager.updateMessage(gmsg); } diff --git a/src/main/java/envoy/server/processors/GroupResizeProcessor.java b/src/main/java/envoy/server/processors/GroupResizeProcessor.java index e90b56f..a571811 100644 --- a/src/main/java/envoy/server/processors/GroupResizeProcessor.java +++ b/src/main/java/envoy/server/processors/GroupResizeProcessor.java @@ -1,7 +1,5 @@ package envoy.server.processors; -import java.io.IOException; - import envoy.event.GroupResize; import envoy.server.data.Contact; import envoy.server.data.PersistenceManager; @@ -22,7 +20,7 @@ public class GroupResizeProcessor implements ObjectProcessor { private static final ConnectionManager connectionManager = ConnectionManager.getInstance(); @Override - public void process(GroupResize groupResize, long socketID, ObjectWriteProxy writeProxy) throws IOException { + public void process(GroupResize groupResize, long socketID, ObjectWriteProxy writeProxy) { // Acquire the group to resize from the database var group = persistenceManager.getGroupByID(groupResize.getGroupID()); @@ -47,13 +45,7 @@ public class GroupResizeProcessor implements ObjectProcessor { .map(Contact::getID) .filter(connectionManager::isOnline) .map(connectionManager::getSocketID) - .forEach(memberSocketID -> { - try { - writeProxy.write(memberSocketID, commonGroup); - } catch (IOException e) { - e.printStackTrace(); - } - }); + .forEach(memberSocketID -> writeProxy.write(memberSocketID, commonGroup)); } @Override diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index f54498b..418a30c 100755 --- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -3,12 +3,8 @@ package envoy.server.processors; import static envoy.data.User.UserStatus.ONLINE; import static envoy.event.HandshakeRejection.*; -import java.io.IOException; import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.logging.Logger; import javax.persistence.NoResultException; @@ -46,7 +42,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor()); - persistenceManager.addContact(user); - logger.info("Registered new " + user); - } + // This code only gets executed if this user already exists + logger.info("The requested user already exists."); + writeProxy.write(socketID, new HandshakeRejection(USERNAME_TAKEN)); + return; + } catch (NoResultException e) { + // Creation of a new user + user = new User(); + user.setName(credentials.getIdentifier()); + user.setLastSeen(LocalDateTime.now()); + user.setStatus(ONLINE); + user.setPasswordHash(credentials.getPasswordHash()); + user.setContacts(new HashSet<>()); + persistenceManager.addContact(user); + logger.info("Registered new " + user); + } } logger.info(user + " successfully authenticated."); @@ -122,9 +118,6 @@ public final class LoginCredentialProcessor implements ObjectProcessor pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user); - logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "..."); - for (var msg : pendingMessages) { final var msgCommon = msg.toCommon(); if (msg.getStatus() == MessageStatus.SENT) { @@ -142,39 +135,36 @@ public final class LoginCredentialProcessor implements ObjectProcessor pendingGroupMessages = PersistenceManager.getInstance().getPendingGroupMessages(user); + logger.fine("Sending " + pendingGroupMessages.size() + " pending group messages to " + user + "..."); + + for (var gmsg : pendingGroupMessages) { + final var gmsgCommon = gmsg.toCommon(); + + // Deliver the message to the user if he hasn't received it yet if (gmsg.getMemberMessageStatus().get(user.getID()) == MessageStatus.SENT) { gmsg.getMemberMessageStatus().replace(user.getID(), MessageStatus.RECEIVED); - envoy.data.GroupMessage groupMessage = gmsg.toCommon(); - writeProxy.write(socketID, groupMessage); - // Sending GroupMessageStatusChanges to all members, that already received the - // groupMessage. - gmsg.getMemberMessageStatus().keySet().stream() - .filter(k -> (gmsg.getMemberMessageStatus().get(k) == MessageStatus.RECEIVED - || gmsg.getMemberMessageStatus().get(k) == MessageStatus.READ) && connectionManager.getUserIdBySocketID(socketID) != k) - .forEach(k -> { - if (connectionManager.isOnline(k)) try { - writeProxy.write(connectionManager.getSocketID(k), - (new GroupMessageStatusChange(gmsg.getID(), MessageStatus.RECEIVED, LocalDateTime.now(), - connectionManager.getUserIdBySocketID(socketID)))); - } catch (IOException e) { - logger.log(Level.WARNING, "Could not deliver group message status changes", e); - } - }); - if (!gmsg.getMemberMessageStatus().containsValue(MessageStatus.SENT)) { + writeProxy.write(socketID, gmsgCommon); + + // Notify all online group members about the status change + writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(), + new GroupMessageStatusChange(gmsg.getID(), MessageStatus.RECEIVED, LocalDateTime.now(), + connectionManager.getUserIDBySocketID(socketID))); + + if (Collections.min(gmsg.getMemberMessageStatus().values()) == MessageStatus.RECEIVED) { gmsg.received(); - // Sending MessageStatusChangeEvent to all other members - for (Map.Entry entry : gmsg.getMemberMessageStatus().entrySet()) { - if (entry.getKey() == connectionManager.getUserIdBySocketID(socketID)) continue; - if (connectionManager.isOnline(entry.getKey())) { - writeProxy.write(connectionManager.getSocketID(entry.getKey()), new MessageStatusChange(gmsg.toCommon())); - } - } + + // Notify online members about the status change + writeProxy.writeToOnlineContacts(gmsg.getRecipient().getContacts(), + new MessageStatusChange(gmsg.getID(), gmsg.getStatus(), LocalDateTime.now())); } + PersistenceManager.getInstance().updateMessage(gmsg); } else { - // Sending memberStatusEvents and MessageStatusChange Events - writeProxy.write(socketID, new MessageStatusChange(gmsg.toCommon())); + + // Deliver just a status change instead of the whole message + // TODO: Notify group members about the status change + writeProxy.write(socketID, new MessageStatusChange(gmsgCommon)); } } } diff --git a/src/main/java/envoy/server/processors/MessageProcessor.java b/src/main/java/envoy/server/processors/MessageProcessor.java index 1f34c5a..71352b0 100755 --- a/src/main/java/envoy/server/processors/MessageProcessor.java +++ b/src/main/java/envoy/server/processors/MessageProcessor.java @@ -1,6 +1,5 @@ package envoy.server.processors; -import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; @@ -34,9 +33,8 @@ public class MessageProcessor implements ObjectProcessor { public void process(Message message, long socketID, ObjectWriteProxy writeProxy) { // Makes sure, that there are no groupMessages processed here, because // groupMessage is a subclass of message. - if (message instanceof envoy.data.GroupMessage)) { - return; - } + if (message instanceof envoy.data.GroupMessage) return; + message.nextStatus(); // Convert to server message @@ -62,8 +60,6 @@ public class MessageProcessor implements ObjectProcessor { } } catch (EntityExistsException e) { logger.log(Level.WARNING, "Received " + message + " with an ID that already exists!"); - } catch (IOException e) { - logger.log(Level.WARNING, "Failed to deliver " + message + ":", e); } } diff --git a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java index 0d57be0..354e9f8 100755 --- a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java @@ -1,14 +1,16 @@ package envoy.server.processors; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; import envoy.data.Message.MessageStatus; import envoy.event.GroupMessageStatusChange; import envoy.event.MessageStatusChange; -import envoy.exception.EnvoyException; import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectWriteProxy; +import envoy.util.EnvoyLog; /** * Project: envoy-server-standalone
@@ -20,15 +22,20 @@ import envoy.server.net.ObjectWriteProxy; */ public class MessageStatusChangeProcessor implements ObjectProcessor { - private final PersistenceManager persistenceManager = PersistenceManager.getInstance(); private final ConnectionManager connectionManager = ConnectionManager.getInstance(); + private final PersistenceManager persistenceManager = PersistenceManager.getInstance(); + private final Logger logger = EnvoyLog.getLogger(MessageStatusChangeProcessor.class); @Override public void process(MessageStatusChange statusChange, long socketID, ObjectWriteProxy writeProxy) throws IOException { // Filtering out subclass objects, which should not be processed here. - if (statusChange instanceof GroupMessageStatusChange)) return; + if (statusChange instanceof GroupMessageStatusChange) return; + // Any other status than READ is not supposed to be sent to the server - if (statusChange.get() != MessageStatus.READ) throw new IOException(new EnvoyException(statusChange + " has an invalid status")); + if (statusChange.get() != MessageStatus.READ) { + logger.log(Level.WARNING, "Invalid " + statusChange); + return; + } final var msg = persistenceManager.getMessageByID(statusChange.getID()); msg.read(); diff --git a/src/main/java/envoy/server/processors/NameChangeProcessor.java b/src/main/java/envoy/server/processors/NameChangeProcessor.java index 4400c04..75f713c 100644 --- a/src/main/java/envoy/server/processors/NameChangeProcessor.java +++ b/src/main/java/envoy/server/processors/NameChangeProcessor.java @@ -5,8 +5,6 @@ import java.io.IOException; import envoy.event.NameChange; import envoy.server.data.Contact; import envoy.server.data.PersistenceManager; -import envoy.server.data.User; -import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectWriteProxy; /** @@ -19,22 +17,16 @@ import envoy.server.net.ObjectWriteProxy; */ public class NameChangeProcessor implements ObjectProcessor { + private static final PersistenceManager persistenceManager = PersistenceManager.getInstance(); + @Override public void process(NameChange nameChange, long socketID, ObjectWriteProxy writeProxy) throws IOException { - PersistenceManager persistenceManager = PersistenceManager.getInstance(); - ConnectionManager connectionManager = ConnectionManager.getInstance(); - Contact toUpdate = persistenceManager.getContactByID(nameChange.getID()); + Contact toUpdate = persistenceManager.getContactByID(nameChange.getID()); toUpdate.setName(nameChange.get()); persistenceManager.updateContact(toUpdate); // Notify online contacts of the name change - toUpdate.getContacts().stream().filter(User.class::isInstance).map(Contact::getID).filter(connectionManager::isOnline).forEach(userID -> { - try { - writeProxy.write(userID, nameChange); - } catch (IOException e) { - e.printStackTrace(); - } - }); + writeProxy.writeToOnlineContacts(toUpdate.getContacts(), nameChange); } @Override diff --git a/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java b/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java index f090f42..87dd179 100755 --- a/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/UserStatusChangeProcessor.java @@ -1,19 +1,17 @@ package envoy.server.processors; -import java.io.IOException; import java.util.logging.Logger; import envoy.data.User.UserStatus; import envoy.event.UserStatusChange; import envoy.server.data.PersistenceManager; import envoy.server.data.User; -import envoy.server.net.ConnectionManager; import envoy.server.net.ObjectWriteProxy; import envoy.util.EnvoyLog; /** - * This processor handles incoming {@link UserStatusChange}.
- *
+ * This processor handles incoming {@link UserStatusChange}. + *

* Project: envoy-server-standalone
* File: UserStatusChangeProcessor.java
* Created: 1 Feb 2020
@@ -23,16 +21,16 @@ import envoy.util.EnvoyLog; */ public class UserStatusChangeProcessor implements ObjectProcessor { - private static ObjectWriteProxy writeProxy; - private static PersistenceManager persistenceManager = PersistenceManager.getInstance(); + private static ObjectWriteProxy writeProxy; - private static final Logger logger = EnvoyLog.getLogger(UserStatusChangeProcessor.class); + private static final PersistenceManager persistenceManager = PersistenceManager.getInstance(); + private static final Logger logger = EnvoyLog.getLogger(UserStatusChangeProcessor.class); @Override public Class getInputClass() { return UserStatusChange.class; } @Override - public void process(UserStatusChange input, long socketID, ObjectWriteProxy writeProxy) throws IOException { + public void process(UserStatusChange input, long socketID, ObjectWriteProxy writeProxy) { // new status should not equal old status if (input.get().equals(persistenceManager.getUserByID(input.getID()).getStatus())) { logger.warning("Received an unnecessary UserStatusChange"); @@ -55,7 +53,7 @@ public class UserStatusChangeProcessor implements ObjectProcessor Date: Mon, 6 Jul 2020 12:34:13 +0200 Subject: [PATCH 12/15] Filter out subclasses in ObjectMessageProcessor --- .../envoy/server/net/ObjectMessageProcessor.java | 5 +++-- .../server/processors/LoginCredentialProcessor.java | 13 +++++++------ .../envoy/server/processors/MessageProcessor.java | 4 ---- .../processors/MessageStatusChangeProcessor.java | 3 --- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/main/java/envoy/server/net/ObjectMessageProcessor.java b/src/main/java/envoy/server/net/ObjectMessageProcessor.java index 8fb120d..ec8488a 100755 --- a/src/main/java/envoy/server/net/ObjectMessageProcessor.java +++ b/src/main/java/envoy/server/net/ObjectMessageProcessor.java @@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.util.Set; +import java.util.logging.Level; import java.util.logging.Logger; import com.jenkov.nioserver.IMessageProcessor; @@ -50,11 +51,11 @@ public class ObjectMessageProcessor implements IMessageProcessor { logger.fine("Received " + obj); // Process object - processors.stream().filter(p -> p.getInputClass().isInstance(obj)).forEach((@SuppressWarnings("rawtypes") ObjectProcessor p) -> { + processors.stream().filter(p -> p.getInputClass().equals(obj.getClass())).forEach((@SuppressWarnings("rawtypes") ObjectProcessor p) -> { try { p.process(p.getInputClass().cast(obj), message.socketId, new ObjectWriteProxy(writeProxy)); } catch (IOException e) { - e.printStackTrace(); + logger.log(Level.SEVERE, "Exception during processor execution: ", e); } }); } catch (IOException | ClassNotFoundException e) { diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index 418a30c..9f20800 100755 --- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -1,5 +1,6 @@ package envoy.server.processors; +import static envoy.data.Message.MessageStatus.*; import static envoy.data.User.UserStatus.ONLINE; import static envoy.event.HandshakeRejection.*; @@ -10,7 +11,6 @@ import java.util.logging.Logger; import javax.persistence.NoResultException; import envoy.data.LoginCredentials; -import envoy.data.Message.MessageStatus; import envoy.event.GroupMessageStatusChange; import envoy.event.HandshakeRejection; import envoy.event.MessageStatusChange; @@ -120,7 +120,7 @@ public final class LoginCredentialProcessor implements ObjectProcessor { @Override public void process(Message message, long socketID, ObjectWriteProxy writeProxy) { - // Makes sure, that there are no groupMessages processed here, because - // groupMessage is a subclass of message. - if (message instanceof envoy.data.GroupMessage) return; - message.nextStatus(); // Convert to server message diff --git a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java index 354e9f8..1c76f77 100755 --- a/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/MessageStatusChangeProcessor.java @@ -5,7 +5,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import envoy.data.Message.MessageStatus; -import envoy.event.GroupMessageStatusChange; import envoy.event.MessageStatusChange; import envoy.server.data.PersistenceManager; import envoy.server.net.ConnectionManager; @@ -28,8 +27,6 @@ public class MessageStatusChangeProcessor implements ObjectProcessor Date: Mon, 6 Jul 2020 16:14:14 +0200 Subject: [PATCH 13/15] Fix some inconsistencies --- .../processors/GroupMessageStatusChangeProcessor.java | 6 +++--- .../envoy/server/processors/LoginCredentialProcessor.java | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java index 9337540..4720961 100644 --- a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java @@ -26,9 +26,9 @@ import envoy.util.EnvoyLog; */ public class GroupMessageStatusChangeProcessor implements ObjectProcessor { - private final ConnectionManager connectionManager = ConnectionManager.getInstance(); - private final PersistenceManager persistenceManager = PersistenceManager.getInstance(); - private final Logger logger = EnvoyLog.getLogger(MessageStatusChangeProcessor.class); + private static final ConnectionManager connectionManager = ConnectionManager.getInstance(); + private static final PersistenceManager persistenceManager = PersistenceManager.getInstance(); + private static final Logger logger = EnvoyLog.getLogger(MessageStatusChangeProcessor.class); @Override public void process(GroupMessageStatusChange statusChange, long socketID, ObjectWriteProxy writeProxy) { diff --git a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java index 9f20800..2fe4953 100755 --- a/src/main/java/envoy/server/processors/LoginCredentialProcessor.java +++ b/src/main/java/envoy/server/processors/LoginCredentialProcessor.java @@ -164,7 +164,6 @@ public final class LoginCredentialProcessor implements ObjectProcessor Date: Wed, 8 Jul 2020 13:53:10 +0200 Subject: [PATCH 14/15] Adjusted Query and implemented pending groupMessageStatusChange proc*ing --- src/main/java/envoy/server/data/GroupMessage.java | 3 ++- .../GroupMessageStatusChangeProcessor.java | 1 + .../processors/LoginCredentialProcessor.java | 14 +++++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/envoy/server/data/GroupMessage.java b/src/main/java/envoy/server/data/GroupMessage.java index a9623a0..90ad823 100644 --- a/src/main/java/envoy/server/data/GroupMessage.java +++ b/src/main/java/envoy/server/data/GroupMessage.java @@ -21,7 +21,8 @@ import envoy.data.Group; name = GroupMessage.getPendingGroupMsg, query = "SELECT m FROM GroupMessage m JOIN m.memberMessageStatus s WHERE (KEY(s) = :userId) AND ((m.creationDate > :lastSeen)" + "OR ((m.status = envoy.data.Message$MessageStatus.RECEIVED) AND (m.receivedDate > :lastSeen))" - + "OR ((m.status = envoy.data.Message$MessageStatus.READ) AND (m.readDate > :lastSeen)))" + + "OR ((m.status = envoy.data.Message$MessageStatus.READ) AND (m.readDate > :lastSeen))" + + "OR ((m.lastStatusChangeDate > :lastSeen)))" ) public class GroupMessage extends Message { diff --git a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java index 4720961..cc86e0c 100644 --- a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java @@ -42,6 +42,7 @@ public class GroupMessageStatusChangeProcessor implements ObjectProcessor + writeProxy.write(socketID, new GroupMessageStatusChange(gmsg.getID(), memberStatus, gmsg.getLastStatusChangeDate(), memberID))); + } + // Deliver just a status change instead of the whole message - writeProxy.write(socketID, new MessageStatusChange(gmsgCommon)); + if (gmsg.getStatus() == SENT && user.getLastSeen().isBefore(gmsg.getCreationDate()) + || gmsg.getStatus() == RECEIVED && user.getLastSeen().isBefore(gmsg.getReceivedDate())) + writeProxy.write(socketID, new MessageStatusChange(gmsgCommon)); } } } From 4a7ad7e1fd0d94b3887b2c9352b689ffa5bac4a6 Mon Sep 17 00:00:00 2001 From: DieGurke <55625494+DieGurke@users.noreply.github.com> Date: Wed, 8 Jul 2020 13:55:19 +0200 Subject: [PATCH 15/15] Extracted into local variable Co-authored-by: delvh --- .../server/processors/GroupMessageStatusChangeProcessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java index cc86e0c..fa3bcb2 100644 --- a/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java +++ b/src/main/java/envoy/server/processors/GroupMessageStatusChangeProcessor.java @@ -45,10 +45,11 @@ public class GroupMessageStatusChangeProcessor implements ObjectProcessor connectionManager.getUserIDBySocketID(socketID) != k) + .filter(k -> userID != k) .filter(connectionManager::isOnline) .forEach(k -> writeProxy.write(connectionManager.getSocketID(k), statusChange));