Switched to persistent storage of active users. This solves the issue of tracking active user with multiple sessions

This commit is contained in:
Rohan Sircar 2019-11-16 14:15:30 +05:30
parent d1a2d58411
commit 2564fdca35
5 changed files with 96 additions and 24 deletions

View File

@ -1,7 +1,5 @@
package org.ros.chatto.dto; package org.ros.chatto.dto;
import java.time.Instant;
import lombok.Data; import lombok.Data;
@Data @Data

View File

@ -7,5 +7,6 @@ import lombok.Data;
@Data @Data
public class ActiveUser { public class ActiveUser {
private String userName; private String userName;
private Instant lastActive; // private Instant lastActive;
private int numSessions = 0;
} }

View File

@ -2,6 +2,7 @@ package org.ros.chatto.logged;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.Optional;
import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener; 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.model.UserSession;
import org.ros.chatto.repository.UserSessionRepository; import org.ros.chatto.repository.UserSessionRepository;
import org.ros.chatto.service.UserService; import org.ros.chatto.service.UserService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.context.support.WebApplicationContextUtils;
@ -47,25 +49,31 @@ public class LoggedUser implements HttpSessionBindingListener {
} }
Instant instant = Instant.now(); Instant instant = Instant.now();
boolean found = activeUsers.stream().anyMatch(au -> au.getUserName().equals(user.getUsername())); // Optional<ActiveUser> activeUserOptional = activeUsers.stream()
if (!found) { // .filter(au -> au.getUserName().equals(user.getUsername()))
System.out.println("Test found "); // .findFirst();
ActiveUser activeUser = new ActiveUser(); // ActiveUser activeUser2 = activeUserOptional.get();
activeUser.setUserName(user.getUsername()); // activeUser2.setNumSessions(activeUser2.getNumSessions() + 1);
activeUser.setLastActive(instant); // boolean found = activeUsers.stream().anyMatch(au -> au.getUserName().equals(user.getUsername()));
activeUsers.add(activeUser); // 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()); ChatUser chatUser = userService.findByUserName(user.getUsername());
UserSession userSession = userSessionRepository.findByUserName(user.getUsername()); UserSession userSession = userSessionRepository.findByUserName(user.getUsername());
if(userSession == null) if (userSession == null) {
{
userSession = new UserSession(); userSession = new UserSession();
} }
userSession.setUser(chatUser); userSession.setUser(chatUser);
userSession.setTimeStamp(instant); userSession.setTimeStamp(instant);
userSession.setOnline(true);
userSession.setNumSessions(userSession.getNumSessions() + 1);
userSessionRepository.save(userSession); userSessionRepository.save(userSession);
} }
@ -75,11 +83,45 @@ public class LoggedUser implements HttpSessionBindingListener {
LoggedUser user = (LoggedUser) event.getValue(); LoggedUser user = (LoggedUser) event.getValue();
List<ActiveUser> activeUsers = activeUserStore.getActiveUsers(); List<ActiveUser> activeUsers = activeUserStore.getActiveUsers();
UserService userService = getUserService(event);
UserSessionRepository userSessionRepository = getUserSessionRepository(event);
Instant instant = Instant.now();
if (users.contains(user.getUsername())) { if (users.contains(user.getUsername())) {
users.remove(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) { private UserService getUserService(HttpSessionEvent se) {

View File

@ -25,6 +25,10 @@ public class UserSession {
@OneToOne @OneToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id")
private ChatUser user; private ChatUser user;
private boolean online;
private int numSessions;
// private Boolean loggedIn; // private Boolean loggedIn;
private Instant timeStamp; private Instant timeStamp;
} }

View File

@ -90,19 +90,38 @@ public class UserServiceImpl implements UserService {
public List<ActiveUserDTO> getOtherActiveUsers(String userName) { public List<ActiveUserDTO> getOtherActiveUsers(String userName) {
List<String> userList = findAllOtherUsers(userName); List<String> userList = findAllOtherUsers(userName);
List<String> onlineUsers = activeUserStore.getUsers(); // List<String> onlineUsers = activeUserStore.getUsers();
List<UserSession> userSessionsList = userSessionRepository.findAll();
Map<String, UserSession> 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<ActiveUserDTO> activeUserDTOs = new ArrayList<ActiveUserDTO>(); List<ActiveUserDTO> activeUserDTOs = new ArrayList<ActiveUserDTO>();
Map<String, Instant> lastActiveMap = convertToMap(userSessionRepository.findAll());
userList.forEach(u -> { userList.forEach(u -> {
ActiveUserDTO activeUserDTO = new ActiveUserDTO(); ActiveUserDTO activeUserDTO = new ActiveUserDTO();
UserSession us = lastActiveMap.get(u);
activeUserDTO.setUserName(u); activeUserDTO.setUserName(u);
activeUserDTO.setOnline(false); activeUserDTO.setOnline(false);
activeUserDTO.setLastActive(toLastActiveString(lastActiveMap.get(u))); activeUserDTO.setLastActive(null);
if (onlineUsers.contains(u)) { if(us != null)
activeUserDTO.setOnline(true); {
activeUserDTO.setOnline(us.isOnline());
activeUserDTO.setLastActive(toLastActiveString(lastActiveMap.get(u).getTimeStamp()));
} }
activeUserDTOs.add(activeUserDTO); activeUserDTOs.add(activeUserDTO);
}); });
return activeUserDTOs; return activeUserDTOs;
} }
@ -112,10 +131,18 @@ public class UserServiceImpl implements UserService {
return userRepository.findByUserName(userName); return userRepository.findByUserName(userName);
} }
private Map<String, Instant> convertToMap(List<UserSession> userSessionList) { // private Map<String, Instant> convertToMap(List<UserSession> userSessionList) {
Map<String, Instant> userMap = new HashMap<>(); // Map<String, Instant> userMap = new HashMap<>();
// userSessionList.forEach(us -> {
// userMap.put(us.getUser().getUserName(), us.getTimeStamp());
// });
// return userMap;
// }
private Map<String, UserSession> convertToMap(List<UserSession> userSessionList) {
Map<String, UserSession> userMap = new HashMap<>();
userSessionList.forEach(us -> { userSessionList.forEach(us -> {
userMap.put(us.getUser().getUserName(), us.getTimeStamp()); userMap.put(us.getUser().getUserName(), us);
}); });
return userMap; return userMap;
} }