From 2564fdca3526c72e26845b8f3faa9f0e3212a726 Mon Sep 17 00:00:00 2001 From: Rohan Sircar Date: Sat, 16 Nov 2019 14:15:30 +0530 Subject: [PATCH] Switched to persistent storage of active users. This solves the issue of tracking active user with multiple sessions --- .../org/ros/chatto/dto/ActiveUserDTO.java | 2 - .../org/ros/chatto/logged/ActiveUser.java | 3 +- .../org/ros/chatto/logged/LoggedUser.java | 68 +++++++++++++++---- .../org/ros/chatto/model/UserSession.java | 4 ++ .../ros/chatto/service/UserServiceImpl.java | 43 +++++++++--- 5 files changed, 96 insertions(+), 24 deletions(-) diff --git a/chatto/src/main/java/org/ros/chatto/dto/ActiveUserDTO.java b/chatto/src/main/java/org/ros/chatto/dto/ActiveUserDTO.java index 72e16d9..781837d 100644 --- a/chatto/src/main/java/org/ros/chatto/dto/ActiveUserDTO.java +++ b/chatto/src/main/java/org/ros/chatto/dto/ActiveUserDTO.java @@ -1,7 +1,5 @@ package org.ros.chatto.dto; -import java.time.Instant; - import lombok.Data; @Data diff --git a/chatto/src/main/java/org/ros/chatto/logged/ActiveUser.java b/chatto/src/main/java/org/ros/chatto/logged/ActiveUser.java index b45f132..588b103 100644 --- a/chatto/src/main/java/org/ros/chatto/logged/ActiveUser.java +++ b/chatto/src/main/java/org/ros/chatto/logged/ActiveUser.java @@ -7,5 +7,6 @@ import lombok.Data; @Data public class ActiveUser { private String userName; - private Instant lastActive; +// private Instant lastActive; + private int numSessions = 0; } diff --git a/chatto/src/main/java/org/ros/chatto/logged/LoggedUser.java b/chatto/src/main/java/org/ros/chatto/logged/LoggedUser.java index ee442f6..163a212 100644 --- a/chatto/src/main/java/org/ros/chatto/logged/LoggedUser.java +++ b/chatto/src/main/java/org/ros/chatto/logged/LoggedUser.java @@ -2,6 +2,7 @@ package org.ros.chatto.logged; import java.time.Instant; import java.util.List; +import java.util.Optional; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; @@ -11,6 +12,7 @@ import org.ros.chatto.model.ChatUser; import org.ros.chatto.model.UserSession; import org.ros.chatto.repository.UserSessionRepository; import org.ros.chatto.service.UserService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; @@ -47,25 +49,31 @@ public class LoggedUser implements HttpSessionBindingListener { } Instant instant = Instant.now(); - boolean found = activeUsers.stream().anyMatch(au -> au.getUserName().equals(user.getUsername())); - if (!found) { - System.out.println("Test found "); - ActiveUser activeUser = new ActiveUser(); - activeUser.setUserName(user.getUsername()); - activeUser.setLastActive(instant); - activeUsers.add(activeUser); - } +// Optional activeUserOptional = activeUsers.stream() +// .filter(au -> au.getUserName().equals(user.getUsername())) +// .findFirst(); +// ActiveUser activeUser2 = activeUserOptional.get(); +// activeUser2.setNumSessions(activeUser2.getNumSessions() + 1); +// boolean found = activeUsers.stream().anyMatch(au -> au.getUserName().equals(user.getUsername())); +// if (!found) { +// System.out.println("Test found "); +// ActiveUser activeUser = new ActiveUser(); +// activeUser.setUserName(user.getUsername()); +//// activeUser.setLastActive(instant); +// activeUsers.add(activeUser); +// } ChatUser chatUser = userService.findByUserName(user.getUsername()); UserSession userSession = userSessionRepository.findByUserName(user.getUsername()); - - if(userSession == null) - { + + if (userSession == null) { userSession = new UserSession(); } - + userSession.setUser(chatUser); userSession.setTimeStamp(instant); + userSession.setOnline(true); + userSession.setNumSessions(userSession.getNumSessions() + 1); userSessionRepository.save(userSession); } @@ -74,12 +82,46 @@ public class LoggedUser implements HttpSessionBindingListener { List users = activeUserStore.getUsers(); LoggedUser user = (LoggedUser) event.getValue(); List activeUsers = activeUserStore.getActiveUsers(); + + UserService userService = getUserService(event); + UserSessionRepository userSessionRepository = getUserSessionRepository(event); + Instant instant = Instant.now(); if (users.contains(user.getUsername())) { users.remove(user.getUsername()); } - activeUsers.removeIf(au -> au.getUserName().equals(user.getUsername())); + activeUsers.removeIf(au -> { + int numSessions = au.getNumSessions(); + if (au.getUserName().equals(user.getUsername()) && --numSessions == 0) { + au.setNumSessions(numSessions); + return true; + } + + return false; + }); + + + ChatUser chatUser = userService.findByUserName(user.getUsername()); + + UserSession userSession = userSessionRepository.findByUserName(user.getUsername()); + + if (userSession == null) { +// userSession = new UserSession(); + throw new UsernameNotFoundException("User session not found"); + } + + int numSessions = userSession.getNumSessions(); + + if(--numSessions == 0) + { + userSession.setOnline(false); + } + + userSession.setUser(chatUser); + userSession.setTimeStamp(instant); + userSession.setNumSessions(numSessions); + userSessionRepository.save(userSession); } private UserService getUserService(HttpSessionEvent se) { diff --git a/chatto/src/main/java/org/ros/chatto/model/UserSession.java b/chatto/src/main/java/org/ros/chatto/model/UserSession.java index 262a2b5..286fb3a 100644 --- a/chatto/src/main/java/org/ros/chatto/model/UserSession.java +++ b/chatto/src/main/java/org/ros/chatto/model/UserSession.java @@ -25,6 +25,10 @@ public class UserSession { @OneToOne @JoinColumn(name = "user_id") private ChatUser user; + + private boolean online; + + private int numSessions; // private Boolean loggedIn; private Instant timeStamp; } diff --git a/chatto/src/main/java/org/ros/chatto/service/UserServiceImpl.java b/chatto/src/main/java/org/ros/chatto/service/UserServiceImpl.java index e24ea39..282fc8a 100644 --- a/chatto/src/main/java/org/ros/chatto/service/UserServiceImpl.java +++ b/chatto/src/main/java/org/ros/chatto/service/UserServiceImpl.java @@ -90,19 +90,38 @@ public class UserServiceImpl implements UserService { public List getOtherActiveUsers(String userName) { List userList = findAllOtherUsers(userName); - List onlineUsers = activeUserStore.getUsers(); +// List onlineUsers = activeUserStore.getUsers(); + + List userSessionsList = userSessionRepository.findAll(); + Map lastActiveMap = convertToMap(userSessionsList); +// userList.forEach(u -> { +// ActiveUserDTO activeUserDTO = new ActiveUserDTO(); +// activeUserDTO.setUserName(u); +// activeUserDTO.setOnline(false); +// activeUserDTO.setLastActive(toLastActiveString(lastActiveMap.get(u))); +// if (onlineUsers.contains(u)) { +// activeUserDTO.setOnline(true); +// } +// activeUserDTOs.add(activeUserDTO); +// }); + List activeUserDTOs = new ArrayList(); - Map lastActiveMap = convertToMap(userSessionRepository.findAll()); userList.forEach(u -> { ActiveUserDTO activeUserDTO = new ActiveUserDTO(); + UserSession us = lastActiveMap.get(u); + activeUserDTO.setUserName(u); activeUserDTO.setOnline(false); - activeUserDTO.setLastActive(toLastActiveString(lastActiveMap.get(u))); - if (onlineUsers.contains(u)) { - activeUserDTO.setOnline(true); + activeUserDTO.setLastActive(null); + if(us != null) + { + activeUserDTO.setOnline(us.isOnline()); + activeUserDTO.setLastActive(toLastActiveString(lastActiveMap.get(u).getTimeStamp())); } + activeUserDTOs.add(activeUserDTO); }); + return activeUserDTOs; } @@ -112,10 +131,18 @@ public class UserServiceImpl implements UserService { return userRepository.findByUserName(userName); } - private Map convertToMap(List userSessionList) { - Map userMap = new HashMap<>(); +// private Map convertToMap(List userSessionList) { +// Map userMap = new HashMap<>(); +// userSessionList.forEach(us -> { +// userMap.put(us.getUser().getUserName(), us.getTimeStamp()); +// }); +// return userMap; +// } + + private Map convertToMap(List userSessionList) { + Map userMap = new HashMap<>(); userSessionList.forEach(us -> { - userMap.put(us.getUser().getUserName(), us.getTimeStamp()); + userMap.put(us.getUser().getUserName(), us); }); return userMap; }