From 2526185f311ed37d04159cb3987fbff92574fd57 Mon Sep 17 00:00:00 2001
From: Christoph Thelen <christoph.thelen@mni.thm.de>
Date: Wed, 14 Jan 2015 13:52:45 +0100
Subject: [PATCH] Add simple spring-based caching of Session objects

---
 .../java/de/thm/arsnova/config/ExtraConfig.java  |  9 +++++++++
 src/main/java/de/thm/arsnova/dao/CouchDBDao.java | 16 +++++++++++++---
 .../java/de/thm/arsnova/dao/IDatabaseDao.java    |  2 +-
 .../java/de/thm/arsnova/dao/StubDatabaseDao.java |  4 ++--
 4 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/src/main/java/de/thm/arsnova/config/ExtraConfig.java b/src/main/java/de/thm/arsnova/config/ExtraConfig.java
index 922b7f3f..0e6ba84a 100644
--- a/src/main/java/de/thm/arsnova/config/ExtraConfig.java
+++ b/src/main/java/de/thm/arsnova/config/ExtraConfig.java
@@ -19,6 +19,9 @@ package de.thm.arsnova.config;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Profile;
@@ -33,6 +36,7 @@ import de.thm.arsnova.connector.client.ConnectorClientImpl;
 import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 
 @Configuration
+@EnableCaching
 public class ExtraConfig {
 
 	@Autowired
@@ -98,4 +102,9 @@ public class ExtraConfig {
 		socketServer.setStorepass(socketStorepass);
 		return socketServer;
 	}
+
+	@Bean
+	public CacheManager cacheManager() {
+		return new ConcurrentMapCacheManager();
+	}
 }
diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 24121046..00028f5b 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -39,6 +39,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
@@ -353,6 +356,7 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
+	@Cacheable("sessions")
 	public final Session getSessionFromKeyword(final String keyword) {
 		final NovaView view = new NovaView("session/by_keyword");
 		view.setKey(keyword);
@@ -368,6 +372,7 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
+	@Cacheable("sessions")
 	public final Session getSessionFromId(final String sessionId) {
 		final NovaView view = new NovaView("session/by_id");
 		view.setKey(sessionId);
@@ -410,6 +415,7 @@ public class CouchDBDao implements IDatabaseDao {
 		} catch (final IOException e) {
 			return null;
 		}
+		// session caching is done by loading the created session
 		return getSession(sessionDocument.getString("keyword"));
 	}
 
@@ -667,19 +673,21 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public final void updateSessionOwnerActivity(final Session session) {
+	@CachePut(value = "sessions")
+	public final Session updateSessionOwnerActivity(final Session session) {
 		try {
 			/* Do not clutter CouchDB. Only update once every 3 hours. */
 			if (session.getLastOwnerActivity() > System.currentTimeMillis() - 3 * 3600000) {
-				return;
+				return session;
 			}
 
 			session.setLastOwnerActivity(System.currentTimeMillis());
 			final JSONObject json = JSONObject.fromObject(session);
 			getDatabase().saveDocument(new Document(json));
+			return session;
 		} catch (final IOException e) {
 			LOGGER.error("Failed to update lastOwnerActivity for Session {}", session);
-			return;
+			return session;
 		}
 	}
 
@@ -1275,6 +1283,7 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
+	@CachePut(value = "sessions")
 	public Session updateSession(final Session session) {
 		try {
 			final Document s = database.getDocument(session.get_id());
@@ -1293,6 +1302,7 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
+	@CacheEvict(value = "sessions")
 	public void deleteSession(final Session session) {
 		try {
 			deleteDocument(session.get_id());
diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
index 8d9b1974..09146dc2 100644
--- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
+++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
@@ -60,7 +60,7 @@ public interface IDatabaseDao {
 
 	LoggedIn registerAsOnlineUser(User u, Session s);
 
-	void updateSessionOwnerActivity(Session session);
+	Session updateSessionOwnerActivity(Session session);
 
 	List<String> getQuestionIds(Session session, User user);
 
diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
index 51b41580..6ab18263 100644
--- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
+++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
@@ -225,9 +225,9 @@ public class StubDatabaseDao implements IDatabaseDao {
 	}
 
 	@Override
-	public void updateSessionOwnerActivity(Session session) {
+	public Session updateSessionOwnerActivity(Session session) {
 		// TODO Auto-generated method stub
-
+		return null;
 	}
 
 	@Override
-- 
GitLab