Created method to extract all currently online members of a group

additionally, refactored every ".Id" to ".ID"
This commit is contained in:
delvh 2020-03-26 20:14:09 +01:00
parent f91b193d59
commit 0057c66d99
11 changed files with 79 additions and 66 deletions

View File

@ -1,15 +1,14 @@
package envoy.server.net;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import com.jenkov.nioserver.ISocketIdListener;
import envoy.data.User.UserStatus;
import envoy.server.data.Group;
import envoy.server.data.PersistenceManager;
import envoy.server.data.User;
import envoy.server.processors.UserStatusChangeProcessor;
/**
@ -48,60 +47,74 @@ public class ConnectionManager implements ISocketIdListener {
public static ConnectionManager getInstance() { return connectionManager; }
@Override
public void socketCancelled(long socketId) {
if (!pendingSockets.remove(socketId)) {
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(new Date());
UserStatusChangeProcessor.updateUserStatus(user);
// Remove the socket
sockets.entrySet().removeIf(e -> e.getValue() == socketId);
sockets.entrySet().removeIf(e -> e.getValue() == socketID);
}
}
@Override
public void socketRegistered(long socketId) { pendingSockets.add(socketId); }
public void socketRegistered(long socketID) { pendingSockets.add(socketID); }
/**
* Associates a socket ID with a user ID.
*
* @param userId the user ID
* @param socketId the socket ID
* @param userID the user ID
* @param socketID the socket ID
* @since Envoy Server Standalone v0.1-alpha
*/
public void registerUser(long userId, long socketId) {
sockets.put(userId, socketId);
pendingSockets.remove(socketId);
public void registerUser(long userID, long socketID) {
sockets.put(userID, socketID);
pendingSockets.remove(socketID);
}
/**
* @param userId the ID of the user registered at a socket
* @param userID the ID of the user registered at a socket
* @return the ID of the socket
* @since Envoy Server Standalone v0.1-alpha
*/
public long getSocketId(long userId) { return sockets.get(userId); }
public long getSocketId(long userID) { return sockets.get(userID); }
/**
* @param socketId the id of the socket whose User is needed
* @param socketID the id of the socket whose User is needed
* @return the userId associated with this socketId
* @since Envoy Server Standalone v0.1-alpha
*/
public long getUserIdBySocketId(long socketId) {
return sockets.entrySet().stream().filter(entry -> entry.getValue().equals(socketId)).findFirst().get().getKey();
public long getUserIdBySocketId(long socketID) {
return sockets.entrySet().stream().filter(entry -> entry.getValue().equals(socketID)).findFirst().get().getKey();
}
/**
* @param userId the ID of the user to check for
* @param userID the ID of the user to check for
* @return {@code true} if the user is online
* @since Envoy Server Standalone v0.1-alpha
*/
public boolean isOnline(long userId) { return sockets.containsKey(userId); }
public boolean isOnline(long userID) { return sockets.containsKey(userID); }
/**
* @return the userId of all users who are currently online
* @return the userIDs of all users who are currently online
* @since Envoy Server Standalone v0.1-alpha
*/
public Set<Long> getOnlineUsers() { return sockets.keySet(); }
/**
* Returns all members of a group who are currently online.
*
* @param group the group to search for
* @return a set of all IDs of currently active members in this group
* @since Envoy Server Standalone v0.1-beta
*/
public Set<Long> getOnlineUsersOfGroup(Group group) {
Set<Long> onlineMembers = new HashSet<>();
Set<Long> members = group.getMembers().stream().map(User::getID).collect(Collectors.toSet());
members.forEach(userID -> { if (isOnline(userID)) onlineMembers.add(userID); });
return onlineMembers;
}
}

View File

@ -30,15 +30,15 @@ public class ObjectWriteProxy {
public ObjectWriteProxy(WriteProxy writeProxy) { this.writeProxy = writeProxy; }
/**
* @param recipientSocketId the socket id of the recipient
* @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
* @since Envoy Server Standalone v0.1-alpha
*/
public void write(long recipientSocketId, Object obj) throws IOException {
public void write(long recipientSocketID, Object obj) throws IOException {
// Create message targeted at the client
Message response = writeProxy.getMessage();
response.socketId = recipientSocketId;
response.socketId = recipientSocketID;
// Serialize object to byte array
byte[] objBytes = SerializationUtils.writeToByteArray(obj);

View File

@ -25,15 +25,15 @@ public class ContactOperationProcessor implements ObjectProcessor<ContactOperati
public void process(ContactOperationEvent evt, long socketId, ObjectWriteProxy writeProxy) throws IOException {
switch (evt.getOperationType()) {
case ADD:
final long userId = ConnectionManager.getInstance().getUserIdBySocketId(socketId);
final long userID = ConnectionManager.getInstance().getUserIdBySocketId(socketId);
final long contactId = evt.get().getID();
System.out.printf("Adding user %s to the contact list of user %d.%n", evt.get(), userId);
PersistenceManager.getInstance().addUserContact(userId, contactId);
System.out.printf("Adding user %s to the contact list of user %d.%n", evt.get(), userID);
PersistenceManager.getInstance().addUserContact(userID, contactId);
// Notify the contact if online
if (ConnectionManager.getInstance().isOnline(contactId)) writeProxy.write(connectionManager.getSocketId(contactId),
new Contacts(Arrays.asList(PersistenceManager.getInstance().getUserById(userId).toCommon())));
new Contacts(Arrays.asList(PersistenceManager.getInstance().getUserById(userID).toCommon())));
break;
default:
System.err.printf("Received %s with an unsupported operation.%n", evt);

View File

@ -30,10 +30,10 @@ public class ContactsRequestEventProcessor implements ObjectProcessor<ContactSea
* @since Envoy Server Standalone v0.1-alpha
*/
@Override
public void process(ContactSearchRequest request, long socketId, ObjectWriteProxy writeProxy) throws IOException {
writeProxy.write(socketId,
public void process(ContactSearchRequest request, long socketID, ObjectWriteProxy writeProxy) throws IOException {
writeProxy.write(socketID,
new ContactSearchResult(PersistenceManager.getInstance()
.searchUsers(request.get(), ConnectionManager.getInstance().getUserIdBySocketId(socketId))
.searchUsers(request.get(), ConnectionManager.getInstance().getUserIdBySocketId(socketID))
.stream()
.map(User::toCommon)
.collect(Collectors.toList())));

View File

@ -19,13 +19,13 @@ public class GroupCreationProcessor implements ObjectProcessor<GroupCreationEven
private final PersistenceManager persistenceManager = PersistenceManager.getInstance();
@Override
public void process(GroupCreationEvent input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
public void process(GroupCreationEvent input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
envoy.server.data.Group group = new envoy.server.data.Group();
group.setName(input.get());
// TODO adjust event, so it sends a members list as well, which can be initially
// set here
persistenceManager.addContact(group);
writeProxy.write(socketId, group); // TODO Prepare the client to receive the group object after sending the
writeProxy.write(socketID, group); // TODO Prepare the client to receive the group object after sending the
// groupCreationEvent to the server.
}

View File

@ -25,11 +25,11 @@ public class IDGeneratorRequestProcessor implements ObjectProcessor<IDGeneratorR
public Class<IDGeneratorRequest> getInputClass() { return IDGeneratorRequest.class; }
@Override
public void process(IDGeneratorRequest input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
public void process(IDGeneratorRequest input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
System.out.println("Received id generation request.");
var generator = createIDGenerator();
System.out.println("Sending new id generator " + generator);
writeProxy.write(socketId, generator);
writeProxy.write(socketID, generator);
}
/**
@ -44,10 +44,10 @@ public class IDGeneratorRequestProcessor implements ObjectProcessor<IDGeneratorR
* @since Envoy Server Standalone v0.1-beta
*/
public static IDGenerator createIDGenerator(long range) {
ConfigItem currentId = PersistenceManager.getInstance().getConfigItemById("currentMessageId");
IDGenerator generator = new IDGenerator(Integer.parseInt(currentId.getValue()), range);
currentId.setValue(String.valueOf(Integer.parseInt(currentId.getValue()) + range));
PersistenceManager.getInstance().updateConfigItem(currentId);
ConfigItem currentID = PersistenceManager.getInstance().getConfigItemById("currentMessageId");
IDGenerator generator = new IDGenerator(Integer.parseInt(currentID.getValue()), range);
currentID.setValue(String.valueOf(Integer.parseInt(currentID.getValue()) + range));
PersistenceManager.getInstance().updateConfigItem(currentID);
return generator;
}
}

View File

@ -38,18 +38,18 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential
private final ConnectionManager connectionManager = ConnectionManager.getInstance();
@Override
public void process(LoginCredentials input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
public void process(LoginCredentials input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
UserStatusChangeProcessor.setWriteProxy(writeProxy);
System.out.println(String.format("Received login credentials %s from socket ID %d", input, socketId));
System.out.println(String.format("Received login credentials %s from socket ID %d", input, socketID));
envoy.server.data.User user = getUser(input, socketId, writeProxy);
envoy.server.data.User user = getUser(input, socketID, writeProxy);
// Not logged in successfully
if (user == null) {
System.out.println("Rejecting handshake on socket " + socketId);
System.out.println("Rejecting handshake on socket " + socketID);
return;
}
connectionManager.registerUser(user.getID(), socketId);
connectionManager.registerUser(user.getID(), socketID);
// Notifies contacts of this users online-going and updates his status in the
// database
@ -62,14 +62,14 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential
// Complete handshake
System.out.println("Sending user...");
writeProxy.write(socketId, user.toCommon());
writeProxy.write(socketID, user.toCommon());
System.out.println("Sending contacts...");
writeProxy.write(socketId, contacts);
writeProxy.write(socketID, contacts);
System.out.println("Acquiring pending messages for the client...");
List<Message> pendingMessages = PersistenceManager.getInstance().getUnreadMessages(user);
for (Message msg : pendingMessages) {
System.out.println("Sending message " + msg.toCommonMessage());
writeProxy.write(socketId, msg.toCommonMessage());
writeProxy.write(socketID, msg.toCommonMessage());
msg.setReceivedDate(new Date());
msg.setStatus(MessageStatus.RECEIVED);
PersistenceManager.getInstance().updateMessage(msg);
@ -79,13 +79,13 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential
@Override
public Class<LoginCredentials> getInputClass() { return LoginCredentials.class; }
private envoy.server.data.User getUser(LoginCredentials credentials, long socketId, ObjectWriteProxy writeProxy) throws IOException {
return credentials.isRegistration() ? newUser(credentials, socketId, writeProxy) : checkForExistingUser(credentials, socketId, writeProxy);
private envoy.server.data.User getUser(LoginCredentials credentials, long socketID, ObjectWriteProxy writeProxy) throws IOException {
return credentials.isRegistration() ? newUser(credentials, socketID, writeProxy) : checkForExistingUser(credentials, socketID, writeProxy);
}
/**
* @param credentials the input to evaluate
* @param socketId the socket ID at which the client performing the handshake
* @param socketID the socket ID at which the client performing the handshake
* is connected
* @param writeProxy the {@link ObjectWriteProxy} to use if login was not
* successful
@ -93,34 +93,34 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential
* @throws IOException if sending the failed login back to the client failed
* @since Envoy Server Standalone v0.1-alpha
*/
private envoy.server.data.User checkForExistingUser(LoginCredentials credentials, long socketId, ObjectWriteProxy writeProxy) throws IOException {
private envoy.server.data.User checkForExistingUser(LoginCredentials credentials, long socketID, ObjectWriteProxy writeProxy) throws IOException {
try {
envoy.server.data.User user = persistenceManager.getUserByName(credentials.getIdentifier());
// Checking if user is already online
if (connectionManager.isOnline(user.getID())) {
writeProxy.write(socketId, new HandshakeRejectionEvent(HandshakeRejectionEvent.ALREADY_ONLINE));
writeProxy.write(socketID, new HandshakeRejectionEvent(HandshakeRejectionEvent.ALREADY_ONLINE));
return null;
}
// Evaluating the correctness of the password hash
if (!Arrays.equals(credentials.getPasswordHash(), user.getPasswordHash())) {
writeProxy.write(socketId, new HandshakeRejectionEvent(HandshakeRejectionEvent.WRONG_PASSWORD));
writeProxy.write(socketID, new HandshakeRejectionEvent(HandshakeRejectionEvent.WRONG_PASSWORD));
return null;
}
return user;
} catch (NoResultException e) {
// Checking if user exists
writeProxy.write(socketId, new HandshakeRejectionEvent(HandshakeRejectionEvent.USER_DOES_NOT_EXIST));
writeProxy.write(socketID, new HandshakeRejectionEvent(HandshakeRejectionEvent.USER_DOES_NOT_EXIST));
} catch (InputMismatchException e) {
// Checking if the given password hash is correct
writeProxy.write(socketId, new HandshakeRejectionEvent(HandshakeRejectionEvent.WRONG_PASSWORD));
writeProxy.write(socketID, new HandshakeRejectionEvent(HandshakeRejectionEvent.WRONG_PASSWORD));
}
return null;
}
/**
* @param credentials the credentials upon which to create the new {@link User}
* @param socketId the socketID at which the client performing the handshake
* @param socketID the socketID at which the client performing the handshake
* is connected
* @param writeProxy the write proxy used to notify the client about handshake
* rejection
@ -128,12 +128,12 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential
* @throws IOException if sending the failed login back to the client failed
* @since Envoy Server Standalone v0.1-alpha
*/
private envoy.server.data.User newUser(LoginCredentials credentials, long socketId, ObjectWriteProxy writeProxy) throws IOException {
private envoy.server.data.User newUser(LoginCredentials credentials, long socketID, ObjectWriteProxy writeProxy) throws IOException {
try {
// Checking that no user already has this identifier
PersistenceManager.getInstance().getUserByName(credentials.getIdentifier());
// this code only gets executed if this user already exists
writeProxy.write(socketId, new HandshakeRejectionEvent(HandshakeRejectionEvent.USER_EXISTS_ALREADY));
writeProxy.write(socketID, new HandshakeRejectionEvent(HandshakeRejectionEvent.USER_EXISTS_ALREADY));
return null;
} catch (NoResultException e) {
// Creation of a new user

View File

@ -26,7 +26,7 @@ import envoy.server.net.ObjectWriteProxy;
public class MessageProcessor implements ObjectProcessor<Message> {
@Override
public void process(Message message, long socketId, ObjectWriteProxy writeProxy) {
public void process(Message message, long socketID, ObjectWriteProxy writeProxy) {
message.nextStatus();
ConnectionManager connectionManager = ConnectionManager.getInstance();
Contact recipient = PersistenceManager.getInstance().getContactById(message.getID());
@ -36,7 +36,7 @@ public class MessageProcessor implements ObjectProcessor<Message> {
sendToUser(connectionManager, message, writeProxy);
// Sending a messageStatusChangeEvent to the sender
try {
writeProxy.write(socketId, new MessageStatusChangeEvent(message));
writeProxy.write(socketID, new MessageStatusChangeEvent(message));
} catch (IOException e) {
System.err.println("Could not send messageStatusChangeEvent to the sender of this message with ID: " + message.getID());
e.printStackTrace();

View File

@ -23,7 +23,7 @@ public class MessageStatusChangeProcessor implements ObjectProcessor<MessageStat
private final ConnectionManager connectionManager = ConnectionManager.getInstance();
@Override
public void process(MessageStatusChangeEvent input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
public void process(MessageStatusChangeEvent input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
// Any other status than READ is not supposed to be sent to the server
if (input.get() != MessageStatus.READ) throw new IOException(new EnvoyException("Message " + input + " has an invalid status"));

View File

@ -26,10 +26,10 @@ public interface ObjectProcessor<T> {
/**
* @param input the request object
* @param socketId the ID of the socket from which the object was received
* @param socketID the ID of the socket from which the object was received
* @param writeProxy the object that allows writing to a client
* @throws IOException if something went wrong during processing
* @since Envoy Server Standalone v0.1-alpha
*/
void process(T input, long socketId, ObjectWriteProxy writeProxy) throws IOException;
void process(T input, long socketID, ObjectWriteProxy writeProxy) throws IOException;
}

View File

@ -28,7 +28,7 @@ public class UserStatusChangeProcessor implements ObjectProcessor<UserStatusChan
public Class<UserStatusChangeEvent> getInputClass() { return UserStatusChangeEvent.class; }
@Override
public void process(UserStatusChangeEvent input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
public void process(UserStatusChangeEvent input, long socketID, ObjectWriteProxy writeProxy) throws IOException {
// new status should not equal old status
if (input.get().equals(persistenceManager.getUserById(input.getID()).getStatus())) {
System.out.println("Received an unnecessary UserStatusChangeEvent");