From 33eaeaaa3cd19ee8c63d5e72034aa565b49a4d6c Mon Sep 17 00:00:00 2001 From: Tobias Eidelpes Date: Wed, 7 Apr 2021 16:45:06 +0200 Subject: [PATCH] Implement Key-Value part (1.5) --- .../java/dst/ass1/kv/impl/SessionManager.java | 86 +++++++++++++++++++ .../ass1/kv/impl/SessionManagerFactory.java | 7 +- 2 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 ass1-kv/src/main/java/dst/ass1/kv/impl/SessionManager.java diff --git a/ass1-kv/src/main/java/dst/ass1/kv/impl/SessionManager.java b/ass1-kv/src/main/java/dst/ass1/kv/impl/SessionManager.java new file mode 100644 index 0000000..5118495 --- /dev/null +++ b/ass1-kv/src/main/java/dst/ass1/kv/impl/SessionManager.java @@ -0,0 +1,86 @@ +package dst.ass1.kv.impl; + +import dst.ass1.kv.ISessionManager; +import dst.ass1.kv.SessionCreationFailedException; +import dst.ass1.kv.SessionNotFoundException; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.Transaction; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class SessionManager implements ISessionManager { + private final Jedis jedis; + + public SessionManager(Jedis jedis) { + this.jedis = jedis; + } + + @Override + public String createSession(Long userId, int timeToLive) throws SessionCreationFailedException { + UUID sessionToken = UUID.randomUUID(); + + // Watch keys to avoid interference with other operations + jedis.watch(sessionToken.toString(), userId.toString()); + + Transaction t = jedis.multi(); + Map sessionMap = new HashMap<>(); + sessionMap.put("userId", userId.toString()); + t.hset(sessionToken.toString(), sessionMap); + t.expire(sessionToken.toString(), timeToLive); + + t.set(userId.toString(), sessionToken.toString()); + t.expire(userId.toString(), timeToLive); + + if (t.exec() == null) + throw new SessionCreationFailedException("Could not create session for userId " + userId); + + return sessionToken.toString(); + } + + @Override + public void setSessionVariable(String sessionId, String key, String value) throws SessionNotFoundException { + if (!jedis.exists(sessionId)) + throw new SessionNotFoundException("Session for session id " + sessionId + " could not be found"); + + jedis.watch(sessionId); + Transaction t = jedis.multi(); + t.hset(sessionId, key, value); + t.exec(); + } + + @Override + public String getSessionVariable(String sessionId, String key) throws SessionNotFoundException { + if (!jedis.exists(sessionId)) + throw new SessionNotFoundException("Session for session id " + sessionId + " could not be found"); + + return jedis.hget(sessionId, key); + } + + @Override + public Long getUserId(String sessionId) throws SessionNotFoundException { + return Long.valueOf(getSessionVariable(sessionId, "userId")); + } + + @Override + public int getTimeToLive(String sessionId) throws SessionNotFoundException { + if (!jedis.exists(sessionId)) + throw new SessionNotFoundException("Session for session id " + sessionId + " could not be found"); + + return Math.toIntExact(jedis.ttl(sessionId)); + } + + @Override + public String requireSession(Long userId, int timeToLive) throws SessionCreationFailedException { + if (!jedis.exists(userId.toString())) + return createSession(userId, timeToLive); + else + return jedis.get(userId.toString()); + } + + @Override + public void close() { + jedis.close(); + } +} diff --git a/ass1-kv/src/main/java/dst/ass1/kv/impl/SessionManagerFactory.java b/ass1-kv/src/main/java/dst/ass1/kv/impl/SessionManagerFactory.java index 06b84d7..879c9de 100644 --- a/ass1-kv/src/main/java/dst/ass1/kv/impl/SessionManagerFactory.java +++ b/ass1-kv/src/main/java/dst/ass1/kv/impl/SessionManagerFactory.java @@ -2,6 +2,7 @@ package dst.ass1.kv.impl; import dst.ass1.kv.ISessionManager; import dst.ass1.kv.ISessionManagerFactory; +import redis.clients.jedis.Jedis; import java.util.Properties; @@ -9,9 +10,9 @@ public class SessionManagerFactory implements ISessionManagerFactory { @Override public ISessionManager createSessionManager(Properties properties) { - // TODO - // read "redis.host" and "redis.port" from the properties + Jedis jedis = new Jedis(properties.getProperty("redis.host"), + Integer.parseInt(properties.getProperty("redis.port"))); - return null; + return new SessionManager(jedis); } }