diff --git a/src/main/java/de/thm/arsnova/FeedbackStorage.java b/src/main/java/de/thm/arsnova/FeedbackStorage.java deleted file mode 100644 index 3ac11f5535786d30535041c504873c4f4f908f9c..0000000000000000000000000000000000000000 --- a/src/main/java/de/thm/arsnova/FeedbackStorage.java +++ /dev/null @@ -1,128 +0,0 @@ -package de.thm.arsnova; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import de.thm.arsnova.dao.IDatabaseDao; -import de.thm.arsnova.entities.Feedback; -import de.thm.arsnova.entities.User; -import de.thm.arsnova.exceptions.NotFoundException; - -public class FeedbackStorage { - private static class FeedbackStorageObject { - private int value; - private Date timestamp; - private User user; - - public FeedbackStorageObject(int initValue, User u) { - this.value = initValue; - this.timestamp = new Date(); - this.user = u; - } - - public int getValue() { - return value; - } - public Date getTimestamp() { - return timestamp; - } - public boolean fromUser(User u) { - return u.getUsername().equals(user.getUsername()); - } - } - - private Map<String, Map<String, FeedbackStorageObject>> data; - - private IDatabaseDao dao; - - public FeedbackStorage(IDatabaseDao newDao) { - this.data = new HashMap<String, Map<String,FeedbackStorageObject>>(); - this.dao = newDao; - } - - public Feedback getFeedback(String keyword) { - int a = 0; - int b = 0; - int c = 0; - int d = 0; - - if (dao.getSession(keyword) == null) { - throw new NotFoundException(); - } - - if (data.get(keyword) == null) { - return new Feedback(0, 0, 0, 0); - } - - for (FeedbackStorageObject fso : data.get(keyword).values()) { - switch (fso.getValue()) { - case Feedback.FEEDBACK_FASTER: - a++; - break; - case Feedback.FEEDBACK_OK: - b++; - break; - case Feedback.FEEDBACK_SLOWER: - c++; - break; - case Feedback.FEEDBACK_AWAY: - d++; - break; - default: - break; - } - } - return new Feedback(a, b, c, d); - } - - public Integer getMyFeedback(String keyword, User u) { - if (data.get(keyword) == null) { - return null; - } - - for (FeedbackStorageObject fso : data.get(keyword).values()) { - if (fso.fromUser(u)) { - return fso.getValue(); - } - } - - return null; - } - - public boolean saveFeedback(String keyword, int value, User user) { - if (dao.getSession(keyword) == null) { - throw new NotFoundException(); - } - - if (data.get(keyword) == null) { - data.put(keyword, new HashMap<String, FeedbackStorageObject>()); - } - - System.out.println(user.getUsername()); - - data.get(keyword).put(user.getUsername(), new FeedbackStorageObject(value, user)); - return true; - } - - public void cleanFeedbackVotes(int cleanupFeedbackDelay) { - for (String keyword : data.keySet()) { - this.cleanSessionFeedbackVotes(keyword, cleanupFeedbackDelay); - } - } - - private void cleanSessionFeedbackVotes(String keyword, int cleanupFeedbackDelay) { - final long timelimitInMillis = 60000 * (long) cleanupFeedbackDelay; - final long maxAllowedTimeInMillis = System.currentTimeMillis() - timelimitInMillis; - - Map<String, FeedbackStorageObject> sessionFeedbacks = data.get(keyword); - - for (Map.Entry<String, FeedbackStorageObject> entry : sessionFeedbacks.entrySet()) { - if ( - entry.getValue().getTimestamp().getTime() < maxAllowedTimeInMillis - ) { - sessionFeedbacks.remove(entry.getKey()); - } - } - } -} diff --git a/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java b/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java index 5fd14a886a0852eec83e605043855f060860e974..1cc0eea7ada5747ccd0d0894e44a1bfa0edf25be 100644 --- a/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java +++ b/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java @@ -8,6 +8,7 @@ import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired; import de.thm.arsnova.entities.Session; +import de.thm.arsnova.events.Publisher; import de.thm.arsnova.services.IUserService; import de.thm.arsnova.services.UserSessionService; @@ -20,55 +21,38 @@ public class UserSessionAspect { @Autowired private IUserService userService; - /** Sets current user and ARSnova session in session scoped UserSessionService - * + @Autowired + private Publisher publisher; + + /** Sets current user and ARSnova session in session scoped UserSessionService + * * @param jp * @param keyword * @param session */ @AfterReturning( - pointcut = "execution(public * de.thm.arsnova.services.SessionService.joinSession(..)) && args(keyword)", - returning = "session" + pointcut="execution(public * de.thm.arsnova.services.SessionService.joinSession(..)) && args(keyword)", + returning="session" ) - public final void joinSessionAdvice( - final JoinPoint jp, - final String keyword, - final Session session - ) { + public final void joinSessionAdvice(final JoinPoint jp, final String keyword, final Session session) { userSessionService.setUser(userService.getCurrentUser()); userSessionService.setSession(session); } - /** Sets current user, ARSnova session and websocket session ID in session scoped UserSessionService - * + /** Sets current user, ARSnova session and websocket session ID in session scoped UserSessionService + * * @param jp * @param keyword * @param socketId * @param session */ @AfterReturning( - pointcut = "execution(public * de.thm.arsnova.services.SessionService.joinSession(..)) && args(keyword, socketId)", - returning = "session" + pointcut="execution(public * de.thm.arsnova.services.SessionService.joinSession(..)) && args(keyword, socketId)", + returning="session" ) - public final void joinSessionAdviceWithWebsocket( - final JoinPoint jp, - final String keyword, - final UUID socketId, - final Session session - ) { + public final void joinSessionAdviceWithWebsocket(final JoinPoint jp, final String keyword, final UUID socketId, final Session session) { userSessionService.setUser(userService.getCurrentUser()); userSessionService.setSession(session); userSessionService.setSocketId(socketId); } - - /** Sets current users activity to active and updates is last active timestamp - * - * @param keyword - */ - @AfterReturning( - pointcut = "execution(public * de.thm.arsnova.services.SessionService.*(..)) && args(keyword,..)" - ) - public final void userIsActive(final String keyword) { - userSessionService.keepalive(); - } } diff --git a/src/main/java/de/thm/arsnova/services/FeedbackService.java b/src/main/java/de/thm/arsnova/services/FeedbackService.java index db7bff304020fdb69d818c6af8156e2f233034c5..3523b64ce0a0fb07b2b59ca0cfeac624083079a8 100644 --- a/src/main/java/de/thm/arsnova/services/FeedbackService.java +++ b/src/main/java/de/thm/arsnova/services/FeedbackService.java @@ -19,18 +19,17 @@ package de.thm.arsnova.services; +import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import javax.annotation.PostConstruct; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import de.thm.arsnova.FeedbackStorage; import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.User; @@ -56,32 +55,25 @@ public class FeedbackService implements IFeedbackService { @Autowired private IUserService userService; - - private FeedbackStorage feedbackStorage; public final void setDatabaseDao(final IDatabaseDao newDatabaseDao) { this.databaseDao = newDatabaseDao; } - @PostConstruct - public void init() { - this.feedbackStorage = new FeedbackStorage(databaseDao); - } - @Override @Scheduled(fixedDelay = DEFAULT_SCHEDULER_DELAY) public final void cleanFeedbackVotes() { - feedbackStorage.cleanFeedbackVotes(cleanupFeedbackDelay); + databaseDao.cleanFeedbackVotes(cleanupFeedbackDelay); } @Override public final Feedback getFeedback(final String keyword) { - return feedbackStorage.getFeedback(keyword); + return databaseDao.getFeedback(keyword); } @Override public final int getFeedbackCount(final String keyword) { - Feedback feedback = feedbackStorage.getFeedback(keyword); + Feedback feedback = databaseDao.getFeedback(keyword); List<Integer> values = feedback.getValues(); return values.get(Feedback.FEEDBACK_FASTER) + values.get(Feedback.FEEDBACK_OK) + values.get(Feedback.FEEDBACK_SLOWER) + values.get(Feedback.FEEDBACK_AWAY); @@ -89,7 +81,7 @@ public class FeedbackService implements IFeedbackService { @Override public final double getAverageFeedback(final String sessionkey) { - Feedback feedback = feedbackStorage.getFeedback(sessionkey); + Feedback feedback = databaseDao.getFeedback(sessionkey); List<Integer> values = feedback.getValues(); double count = values.get(Feedback.FEEDBACK_FASTER) + values.get(Feedback.FEEDBACK_OK) + values.get(Feedback.FEEDBACK_SLOWER) + values.get(Feedback.FEEDBACK_AWAY); @@ -109,7 +101,7 @@ public class FeedbackService implements IFeedbackService { @Override public final boolean saveFeedback(final String keyword, final int value, final User user) { - boolean result = feedbackStorage.saveFeedback(keyword, value, user); + boolean result = databaseDao.saveFeedback(keyword, value, user); if (result) { this.server.reportUpdatedFeedbackForSession(keyword); } @@ -144,6 +136,91 @@ public class FeedbackService implements IFeedbackService { @Override public final Integer getMyFeedback(final String keyword, final User user) { - return this.feedbackStorage.getMyFeedback(keyword, user); + return this.databaseDao.getMyFeedback(keyword, user); + } + + private static class FeedbackStorageObject { + private int value; + private Date timestamp; + + public FeedbackStorageObject(int initValue) { + this.value = initValue; + this.timestamp = new Date(); + } + + public int getValue() { + return value; + } + public Date getTimestamp() { + return timestamp; + } + } + + private static class FeedbackStorage { + private Map<String, Map<String, FeedbackStorageObject>> data; + + public FeedbackStorage() { + this.data = new HashMap<String, Map<String,FeedbackStorageObject>>(); + } + + public Feedback getFeedback(String keyword) { + int a = 0; + int b = 0; + int c = 0; + int d = 0; + + if (data.get(keyword) == null) { + return new Feedback(0, 0, 0, 0); + } + + for (FeedbackStorageObject fso : data.get(keyword).values()) { + switch (fso.getValue()) { + case Feedback.FEEDBACK_FASTER: + a++; + break; + case Feedback.FEEDBACK_OK: + b++; + break; + case Feedback.FEEDBACK_SLOWER: + c++; + break; + case Feedback.FEEDBACK_AWAY: + d++; + break; + default: + break; + } + } + return new Feedback(a, b, c, d); + } + + public boolean saveFeedback(String keyword, int value, User user) { + if (data.get(keyword) == null) { + data.put(keyword, new HashMap<String, FeedbackStorageObject>()); + } + data.get(keyword).put(user.getUsername(), new FeedbackStorageObject(value)); + return true; + } + + public void cleanFeedbackVotes(int cleanupFeedbackDelay) { + for (String keyword : data.keySet()) { + this.cleanSessionFeedbackVotes(keyword, cleanupFeedbackDelay); + } + } + + private void cleanSessionFeedbackVotes(String keyword, int cleanupFeedbackDelay) { + final long timelimitInMillis = 60000 * (long) cleanupFeedbackDelay; + final long maxAllowedTimeInMillis = System.currentTimeMillis() - timelimitInMillis; + + Map<String, FeedbackStorageObject> sessionFeedbacks = data.get(keyword); + + for (Map.Entry<String, FeedbackStorageObject> entry : sessionFeedbacks.entrySet()) { + if ( + entry.getValue().getTimestamp().getTime() < maxAllowedTimeInMillis + ) { + sessionFeedbacks.remove(entry.getKey()); + } + } + } } } diff --git a/src/main/java/de/thm/arsnova/services/IUserService.java b/src/main/java/de/thm/arsnova/services/IUserService.java index 485a75c659cd99fd62b816d3645285968ab6d137..9016b6e5e55e6b03aada1aac8a031d02b265121c 100644 --- a/src/main/java/de/thm/arsnova/services/IUserService.java +++ b/src/main/java/de/thm/arsnova/services/IUserService.java @@ -19,7 +19,6 @@ package de.thm.arsnova.services; -import java.util.Date; import java.util.Map; import java.util.Set; import java.util.UUID; @@ -54,6 +53,4 @@ public interface IUserService { void removeUserFromMaps(User user); int loggedInUsers(); - - void setLastOnlineActivity(User user, Date date); } diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java index 25dd202125d6ca178389ce2008a7800239985dbe..34b2b3d20954ee8082eacdd1249650b467c0c47e 100644 --- a/src/main/java/de/thm/arsnova/services/SessionService.java +++ b/src/main/java/de/thm/arsnova/services/SessionService.java @@ -52,10 +52,7 @@ public class SessionService implements ISessionService { @Autowired private IUserService userService; - - @Autowired - private UserSessionService userSessionService; - + @Autowired private ARSnovaSocketIOServer socketIoServer; @@ -185,9 +182,8 @@ public class SessionService implements ISessionService { if (session.getCreator().equals(user.getUsername())) { databaseDao.updateSessionOwnerActivity(session); } - - return userSessionService.keepalive(); - //return databaseDao.registerAsOnlineUser(user, session); + + return databaseDao.registerAsOnlineUser(user, session); } @Override diff --git a/src/main/java/de/thm/arsnova/services/UserService.java b/src/main/java/de/thm/arsnova/services/UserService.java index 8adff15bb8191be5415afff3ce8842ff8fd57c7b..c76517ef5feae69b76087898edd442d78ca58e5f 100644 --- a/src/main/java/de/thm/arsnova/services/UserService.java +++ b/src/main/java/de/thm/arsnova/services/UserService.java @@ -1,7 +1,15 @@ package de.thm.arsnova.services; -import java.util.Date; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; import java.util.HashSet; +import java.util.Hashtable; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -13,6 +21,10 @@ import org.scribe.up.profile.google.Google2Profile; import org.scribe.up.profile.twitter.TwitterProfile; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.cas.authentication.CasAuthenticationToken; @@ -23,10 +35,14 @@ import org.springframework.transaction.annotation.Transactional; import com.github.leleuj.ss.oauth.client.authentication.OAuthAuthenticationToken; +import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.User; import de.thm.arsnova.exceptions.UnauthorizedException; +import de.thm.arsnova.socket.ARSnovaSocketIOServer; -public class UserService implements IUserService { +public class UserService implements IUserService, InitializingBean, DisposableBean { + + private static final int DEFAULT_SCHEDULER_DELAY_MS = 60000; private static final int MAX_USER_INACTIVE_SECONDS = 120; @@ -40,24 +56,34 @@ public class UserService implements IUserService { /* used for HTTP polling online check solution (legacy) */ private static final ConcurrentHashMap<User, String> user2sessionLegacy = new ConcurrentHashMap<User, String>(); - private static final ConcurrentHashMap<User, Date> lastOnline = new ConcurrentHashMap<User, Date>(); + @Autowired + private IDatabaseDao databaseDao; - @Override - public void setLastOnlineActivity(User user, Date date) { - lastOnline.put(user, date); - LOGGER.info("Updating active user {}", user.getUsername()); - - for (Entry<User,Date> e : lastOnline.entrySet()) { - LOGGER.info("User in Map {}", e.getKey().getUsername()); - if (e.getValue().getTime() < System.currentTimeMillis() - MAX_USER_INACTIVE_SECONDS * 1000) { - LOGGER.info("Removing inactive user {}", e.getKey()); - lastOnline.remove(e.getKey()); - this.removeUserFromMaps(e.getKey()); - LOGGER.info("Active user count: {}", this.loggedInUsers()); + @Autowired + private ARSnovaSocketIOServer socketIoServer; + + @Scheduled(fixedDelay = DEFAULT_SCHEDULER_DELAY_MS) + public final void removeInactiveUsersFromLegacyMap() { + List<String> usernames = databaseDao.getActiveUsers(MAX_USER_INACTIVE_SECONDS); + Set<String> affectedSessions = new HashSet<String>(); + + for (Entry<User, String> e : user2sessionLegacy.entrySet()) { + User key = e.getKey(); + if (usernames != null && !usernames.contains(key.getUsername())) { + if (null != e.getValue()) { + affectedSessions.add(e.getValue()); + } else { + LOGGER.warn("Session for user {} is null", key); + } + user2sessionLegacy.remove(e.getKey()); } } + + for (String sessionKeyword : affectedSessions) { + socketIoServer.reportActiveUserCountForSession(sessionKeyword); + } } - + @Override public User getCurrentUser() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -196,6 +222,57 @@ public class UserService implements IUserService { return null; } + @Override + public void afterPropertiesSet() { + try { + File tmpDir = new File(System.getProperty("java.io.tmpdir")); + File store = new File(tmpDir, "arsnova.bin"); + if (!store.exists()) { + return; + } + ObjectInputStream ois = new ObjectInputStream(new FileInputStream(store)); + Hashtable<String, Map<?, ?>> map = (Hashtable<String, Map<?, ?>>) ois.readObject(); + ois.close(); + Map<UUID, User> s2u = (Map<UUID, User>) map.get("socketid2user"); + Map<User, String> u2s = (Map<User, String>) map.get("user2session"); + + LOGGER.info("load from store: {}", map); + + socketid2user.putAll(s2u); + user2sessionLegacy.putAll(u2s); + + } catch (IOException e) { + LOGGER.error("IOException during restoring UserService", e); + } catch (ClassNotFoundException e) { + LOGGER.error("ClassNotFoundException during restoring UserService", e); + } + } + + @Override + public void destroy() { + Hashtable<String, Map<?, ?>> map = new Hashtable<String, Map<?, ?>>(); + map.put("socketid2user", socketid2user); + map.put("user2session", user2sessionLegacy); + + try { + File tmpDir = new File(System.getProperty("java.io.tmpdir")); + File store = new File(tmpDir, "arsnova.bin"); + if (!store.exists()) { + if (! store.createNewFile()) { + LOGGER.info("Could not create store file"); + } + } + OutputStream file = new FileOutputStream(store); + ObjectOutputStream objOut = new ObjectOutputStream(file); + objOut.writeObject(map); + objOut.close(); + file.close(); + LOGGER.info("saved to store: {}", map); + } catch (IOException e) { + LOGGER.error("IOException while saving UserService", e); + } + } + @Override public void removeUserFromMaps(User user) { if (user != null) { diff --git a/src/main/java/de/thm/arsnova/services/UserSessionService.java b/src/main/java/de/thm/arsnova/services/UserSessionService.java index c514a700ddd9de794fead6c7c359b7b70e1f85e9..84f2885033b88772db4c74d34c4f831b6530982d 100644 --- a/src/main/java/de/thm/arsnova/services/UserSessionService.java +++ b/src/main/java/de/thm/arsnova/services/UserSessionService.java @@ -2,7 +2,6 @@ package de.thm.arsnova.services; import java.util.UUID; -import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; import de.thm.arsnova.events.ARSnovaEvent; @@ -19,7 +18,5 @@ public interface UserSessionService { void setSocketId(UUID socketId); UUID getSocketId(); - LoggedIn keepalive(); - void sendEventViaWebSocket(ARSnovaSocketIOServer server, ARSnovaEvent event); } \ No newline at end of file diff --git a/src/main/java/de/thm/arsnova/services/UserSessionServiceImpl.java b/src/main/java/de/thm/arsnova/services/UserSessionServiceImpl.java index 57340a41f8717ae94118d3903b79f62ca7b544ea..e10a7b6c662d102775b72b729c23009cc72f7fd1 100644 --- a/src/main/java/de/thm/arsnova/services/UserSessionServiceImpl.java +++ b/src/main/java/de/thm/arsnova/services/UserSessionServiceImpl.java @@ -1,51 +1,31 @@ package de.thm.arsnova.services; import java.io.Serializable; -import java.util.Date; import java.util.UUID; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; -import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Session; import de.thm.arsnova.entities.User; import de.thm.arsnova.events.ARSnovaEvent; import de.thm.arsnova.events.ARSnovaEvent.Destination; -import de.thm.arsnova.events.Publisher; import de.thm.arsnova.socket.ARSnovaSocketIOServer; @Component @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public class UserSessionServiceImpl implements UserSessionService, Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = LoggerFactory.getLogger(UserSessionServiceImpl.class); - private static final int MAX_USER_INACTIVE_MILLIS = 120000; private User user; private Session session; private UUID socketId; - private Date lastActive; - - @Autowired - private IUserService userService; - @PreDestroy - public void tearDown() { - if ( socketId != null ) { - LOGGER.info("Removing websocket session {}", socketId); - userService.removeUser2SocketId(socketId); - } - LOGGER.info("TEAR DOWN SESSION"); - } - @Override public void setUser(User u) { this.user = u; @@ -76,21 +56,6 @@ public class UserSessionServiceImpl implements UserSessionService, Serializable return this.socketId; } - @Override - public LoggedIn keepalive() { - if (this.user != null) { - this.lastActive = new Date(); - userService.setLastOnlineActivity(this.user, this.lastActive); - - LoggedIn result = new LoggedIn(); - result.setUser(this.user.getUsername()); - result.setTimestamp(this.lastActive.getTime()); - return result; - } - - return new LoggedIn(); - } - private boolean hasConnectedWebSocket() { return getSocketId() != null; } diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java index b6b2044a6a4b9151027cffd95e5d47f7e2e34b7c..d4132f35652a9f0854a31865a6791b7a9c560514 100644 --- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java +++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java @@ -24,7 +24,6 @@ import com.corundumstudio.socketio.listener.DisconnectListener; import de.thm.arsnova.entities.User; import de.thm.arsnova.events.ARSnovaEvent; -import de.thm.arsnova.events.Publisher; import de.thm.arsnova.exceptions.NoContentException; import de.thm.arsnova.services.IFeedbackService; import de.thm.arsnova.services.IQuestionService; @@ -47,9 +46,6 @@ public class ARSnovaSocketIOServer { @Autowired private ISessionService sessionService; - @Autowired - private Publisher publisher; - private static final Logger LOGGER = LoggerFactory.getLogger(ARSnovaSocketIOServer.class); private int portNumber; @@ -235,15 +231,12 @@ public class ARSnovaSocketIOServer { public void reportUpdatedFeedbackForSession(String sessionKey) { de.thm.arsnova.entities.Feedback fb = feedbackService.getFeedback(sessionKey); - publisher.publish(new ARSnovaEvent(this, sessionKey, "feedbackData", fb.getValues())); - //broadcastInSession(sessionKey, "feedbackData", fb.getValues()); + broadcastInSession(sessionKey, "feedbackData", fb.getValues()); try { long averageFeedback = feedbackService.getAverageFeedbackRounded(sessionKey); - publisher.publish(new ARSnovaEvent(this, sessionKey, "feedbackDataRoundedAverage", averageFeedback)); - //broadcastInSession(sessionKey, "feedbackDataRoundedAverage", averageFeedback); + broadcastInSession(sessionKey, "feedbackDataRoundedAverage", averageFeedback); } catch (NoContentException e) { - publisher.publish(new ARSnovaEvent(this, sessionKey, "feedbackDataRoundedAverage", null)); - //broadcastInSession(sessionKey, "feedbackDataRoundedAverage", null); + broadcastInSession(sessionKey, "feedbackDataRoundedAverage", null); } } @@ -260,15 +253,12 @@ public class ARSnovaSocketIOServer { return; } - publisher.publish(new ARSnovaEvent(this, user, "feedbackData", fb.getValues())); - publisher.publish(new ARSnovaEvent(this, user, "feedbackDataRoundedAverage", averageFeedback)); - - /*for (SocketIOClient client : server.getAllClients()) { + for (SocketIOClient client : server.getAllClients()) { if (connectionIds.contains(client.getSessionId())) { client.sendEvent("feedbackData", fb.getValues()); client.sendEvent("feedbackDataRoundedAverage", averageFeedback); } - }*/ + } } public void reportActiveUserCountForSession(String sessionKey) { @@ -278,26 +268,22 @@ public class ARSnovaSocketIOServer { return; } lastActiveUserCount = count; - - publisher.publish(new ARSnovaEvent(this, sessionKey, "activeUserCountData", count)); - //broadcastInSession(sessionKey, "activeUserCountData", count); + + broadcastInSession(sessionKey, "activeUserCountData", count); } public void reportAnswersToLecturerQuestionAvailable(String sessionKey, String lecturerQuestionId) { - publisher.publish(new ARSnovaEvent(this, sessionKey, "answersToLecQuestionAvail", lecturerQuestionId)); - //broadcastInSession(sessionKey, "answersToLecQuestionAvail", lecturerQuestionId); + broadcastInSession(sessionKey, "answersToLecQuestionAvail", lecturerQuestionId); } public void reportAudienceQuestionAvailable(String sessionKey, String audienceQuestionId) { /* TODO role handling implementation, send this only to users with role lecturer */ - publisher.publish(new ARSnovaEvent(this, sessionKey, "audQuestionAvail", audienceQuestionId)); - //broadcastInSession(sessionKey, "audQuestionAvail", audienceQuestionId); + broadcastInSession(sessionKey, "audQuestionAvail", audienceQuestionId); } public void reportLecturerQuestionAvailable(String sessionKey, String lecturerQuestionId) { /* TODO role handling implementation, send this only to users with role audience */ - publisher.publish(new ARSnovaEvent(this, sessionKey, "lecQuestionAvail", lecturerQuestionId)); - //broadcastInSession(sessionKey, "lecQuestionAvail", lecturerQuestionId); + broadcastInSession(sessionKey, "lecQuestionAvail", lecturerQuestionId); } /** Sends event to a websocket connection identified by UUID @@ -308,10 +294,25 @@ public class ARSnovaSocketIOServer { public void sendToClient(UUID sessionId, ARSnovaEvent event) { for (SocketIOClient c : server.getAllClients()) { if (c.getSessionId().equals(sessionId)) { - LOGGER.info("Send Event {}", event.getEventName()); - c.sendEvent(event.getEventName(), event.getData()); + System.out.println(sessionId); break; } } } + + public void broadcastInSession(String sessionKey, String eventName, Object data) { + /** + * collect a list of users which are in the current session iterate over + * all connected clients and if send feedback, if user is in current + * session + */ + Set<User> users = userService.getUsersInSession(sessionKey); + + for (SocketIOClient c : server.getAllClients()) { + User u = userService.getUser2SocketId(c.getSessionId()); + if (u != null && users.contains(u)) { + c.sendEvent(eventName, data); + } + } + } } diff --git a/src/test/java/de/thm/arsnova/controller/FeedbackControllerTest.java b/src/test/java/de/thm/arsnova/controller/FeedbackControllerTest.java index 75e3d0b90f8a5946d92cf8b84eb3f243c8eaf8fa..d0b8997bcac3b8d60fad34d7d06f6c214073eb3f 100644 --- a/src/test/java/de/thm/arsnova/controller/FeedbackControllerTest.java +++ b/src/test/java/de/thm/arsnova/controller/FeedbackControllerTest.java @@ -20,7 +20,6 @@ import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; -import de.thm.arsnova.FeedbackStorage; import de.thm.arsnova.dao.StubDatabaseDao; import de.thm.arsnova.exceptions.NoContentException; import de.thm.arsnova.exceptions.NotFoundException; @@ -48,8 +47,6 @@ public class FeedbackControllerTest { @Autowired private StubDatabaseDao databaseDao; - - private FeedbackStorage feedbackStorage; @After public final void cleanup() { @@ -61,7 +58,6 @@ public class FeedbackControllerTest { this.request = new MockHttpServletRequest(); this.response = new MockHttpServletResponse(); handlerAdapter = applicationContext.getBean(AnnotationMethodHandlerAdapter.class); - this.feedbackStorage = new FeedbackStorage(databaseDao); } @Test(expected = NotFoundException.class) @@ -109,6 +105,6 @@ public class FeedbackControllerTest { handlerAdapter.handle(request, response, feedbackController); assertTrue(response.getStatus() == 200); - //assertEquals("{\"values\":[0,0,0,0]}", response.getContentAsString()); + assertEquals("{\"values\":[2,3,5,7]}", response.getContentAsString()); } } diff --git a/src/test/java/de/thm/arsnova/controller/StatisticsControllerTest.java b/src/test/java/de/thm/arsnova/controller/StatisticsControllerTest.java index 63fcbcd0bc271b89c926688f3bbc8fc09b7a0fb9..2882e4b3c1e223a399daf8ca9e57ff9a47180631 100644 --- a/src/test/java/de/thm/arsnova/controller/StatisticsControllerTest.java +++ b/src/test/java/de/thm/arsnova/controller/StatisticsControllerTest.java @@ -55,7 +55,7 @@ public class StatisticsControllerTest { request.setRequestURI("/statistics/sessioncount"); handlerAdapter.handle(request, response, statisticsController); - assertEquals("3", response.getContentAsString()); + assertEquals("2", response.getContentAsString()); } @Test @@ -64,7 +64,7 @@ public class StatisticsControllerTest { request.setRequestURI("/statistics/"); handlerAdapter.handle(request, response, statisticsController); - String expected = "{\"answers\":0,\"questions\":0,\"openSessions\":3,\"closedSessions\":0,\"activeUsers\":0}"; + String expected = "{\"answers\":0,\"questions\":0,\"openSessions\":2,\"closedSessions\":0,\"activeUsers\":0}"; assertEquals(expected, response.getContentAsString()); } } diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index b1d6447fb29cae486d52b6dce606f42a7d83e2c5..37750ff80cbf436768c341d0ff483e2a30e2e9ec 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -87,15 +87,6 @@ public class StubDatabaseDao implements IDatabaseDao { session.setShortName("TS2"); stubSessions.put("87654321", session); - - session = new Session(); - session.setActive(true); - session.setCreator("ptsr00"); - session.setKeyword("18273645"); - session.setName("TestSession2"); - session.setShortName("TS3"); - - stubSessions.put("18273645", session); } private void fillWithDummyFeedbacks() { diff --git a/src/test/java/de/thm/arsnova/services/FeedbackServiceTest.java b/src/test/java/de/thm/arsnova/services/FeedbackServiceTest.java index e96de49ee2e1a51b206a68e319cf8566f49f652f..2ea24a36d5fc5c58173f02f1e978433b3d1399b8 100644 --- a/src/test/java/de/thm/arsnova/services/FeedbackServiceTest.java +++ b/src/test/java/de/thm/arsnova/services/FeedbackServiceTest.java @@ -22,16 +22,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.junit.After; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import de.thm.arsnova.dao.StubDatabaseDao; -import de.thm.arsnova.entities.User; import de.thm.arsnova.exceptions.NoContentException; import de.thm.arsnova.exceptions.NotFoundException; @@ -52,53 +49,6 @@ public class FeedbackServiceTest { @Autowired private StubDatabaseDao databaseDao; - @Before - public final void setup() { - userService.setUserAuthenticated(false); - - feedbackService.saveFeedback("87654321", 0, new TestUser("testuser01")); - feedbackService.saveFeedback("87654321", 0, new TestUser("testuser02")); - feedbackService.saveFeedback("87654321", 1, new TestUser("testuser11")); - feedbackService.saveFeedback("87654321", 1, new TestUser("testuser12")); - feedbackService.saveFeedback("87654321", 1, new TestUser("testuser13")); - feedbackService.saveFeedback("87654321", 2, new TestUser("testuser21")); - feedbackService.saveFeedback("87654321", 2, new TestUser("testuser22")); - feedbackService.saveFeedback("87654321", 2, new TestUser("testuser23")); - feedbackService.saveFeedback("87654321", 2, new TestUser("testuser24")); - feedbackService.saveFeedback("87654321", 2, new TestUser("testuser25")); - feedbackService.saveFeedback("87654321", 3, new TestUser("testuser31")); - feedbackService.saveFeedback("87654321", 3, new TestUser("testuser32")); - feedbackService.saveFeedback("87654321", 3, new TestUser("testuser33")); - feedbackService.saveFeedback("87654321", 3, new TestUser("testuser34")); - feedbackService.saveFeedback("87654321", 3, new TestUser("testuser35")); - feedbackService.saveFeedback("87654321", 3, new TestUser("testuser36")); - feedbackService.saveFeedback("87654321", 3, new TestUser("testuser37")); - - - feedbackService.saveFeedback("18273645", 0, new TestUser("testuser01")); - feedbackService.saveFeedback("18273645", 0, new TestUser("testuser02")); - feedbackService.saveFeedback("18273645", 1, new TestUser("testuser11")); - feedbackService.saveFeedback("18273645", 1, new TestUser("testuser12")); - feedbackService.saveFeedback("18273645", 1, new TestUser("testuser13")); - feedbackService.saveFeedback("18273645", 2, new TestUser("testuser21")); - feedbackService.saveFeedback("18273645", 2, new TestUser("testuser22")); - feedbackService.saveFeedback("18273645", 2, new TestUser("testuser23")); - feedbackService.saveFeedback("18273645", 2, new TestUser("testuser24")); - feedbackService.saveFeedback("18273645", 2, new TestUser("testuser25")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser31")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser32")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser33")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser34")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser35")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser36")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser37")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser38")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser39")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser310")); - feedbackService.saveFeedback("18273645", 3, new TestUser("testuser311")); - - } - @After public final void cleanup() { databaseDao.cleanupTestData(); @@ -162,15 +112,4 @@ public class FeedbackServiceTest { userService.setUserAuthenticated(true); assertEquals(2.1904, feedbackService.getAverageFeedback("18273645"), 0.001); } - - public static class TestUser extends User { - private static final long serialVersionUID = 1L; - - private String username; - private String type; - - public TestUser(String username) { - super( new UsernamePasswordAuthenticationToken(username, "secret") ); - } - } } \ No newline at end of file diff --git a/src/test/java/de/thm/arsnova/services/StatisticsServiceTest.java b/src/test/java/de/thm/arsnova/services/StatisticsServiceTest.java index ec348f3b67f4f70c53846a385ff1806983817693..a0e846e680327d4fac2cd135ba0ee84bf1d85c5a 100644 --- a/src/test/java/de/thm/arsnova/services/StatisticsServiceTest.java +++ b/src/test/java/de/thm/arsnova/services/StatisticsServiceTest.java @@ -67,7 +67,7 @@ public class StatisticsServiceTest { @Test public final void testShouldReturnStatistics() { Statistics actual = statisticsService.getStatistics(); - assertEquals(3, actual.getOpenSessions()); + assertEquals(2, actual.getOpenSessions()); assertEquals(1, actual.getClosedSessions()); } }