Add template for assignment 1

This commit is contained in:
Philipp Raith
2021-03-10 08:14:26 +01:00
parent 4147115ba2
commit 720d6c193f
103 changed files with 6357 additions and 0 deletions
@@ -0,0 +1,69 @@
package dst.ass1.kv;
public interface ISessionManager {
/**
* Creates a new session id and stores the userId and session timeout under the given id in the session store.
*
* @param userId the user to create the session for
* @param timeToLive the session timeout after which the session expires in seconds
* @return the session id.
* @throws SessionCreationFailedException if the session couldn't be created, e.g., due to a failed transaction
*/
String createSession(Long userId, int timeToLive) throws SessionCreationFailedException;
/**
* Sets a key--value pair in the given session.
*
* @param sessionId the session to store the variable in
* @param key the name of the variable
* @param value the value
* @throws SessionNotFoundException if the session wasn't found
*/
void setSessionVariable(String sessionId, String key, String value) throws SessionNotFoundException;
/**
* Returns the value of the given session variable.
*
* @param sessionId the session id
* @param key the name of the variable
* @return the variable value, or null if it doesn't exist
* @throws SessionNotFoundException if the given session id has expired or doesn't exist
*/
String getSessionVariable(String sessionId, String key) throws SessionNotFoundException;
/**
* Returns the user to whom the given session belongs.
*
* @param sessionId the session id
* @return the user id
* @throws SessionNotFoundException if the given session id has expired or doesn't exist
*/
Long getUserId(String sessionId) throws SessionNotFoundException;
/**
* Returns the current time-to-live for the given session.
*
* @param sessionId the session id
* @return the session ttl in seconds
* @throws SessionNotFoundException if the given session id has expired or doesn't exist
*/
int getTimeToLive(String sessionId) throws SessionNotFoundException;
/**
* Checks whether the given user has an open session, if so, the session id is returned (and the timeout
* parameter ignored), otherwise a new session is created with the given timeout and the newly generated id is
* returned.
*
* @param userId the user to require the session for
* @param timeToLive the session timeout after which the session expires in seconds
* @return the session id.
* @throws SessionCreationFailedException if the session couldn't be created, e.g., due to a failed transaction
*/
String requireSession(Long userId, int timeToLive) throws SessionCreationFailedException;
/**
* Closes whatever underlying connection is required to maintain the session manager.
*/
void close();
}
@@ -0,0 +1,13 @@
package dst.ass1.kv;
import java.util.Properties;
public interface ISessionManagerFactory {
/**
* Creates an implementation of an {@link ISessionManager}.
*
* @param properties the properties to use for instantiation
* @return a session manager object
*/
ISessionManager createSessionManager(Properties properties);
}
@@ -0,0 +1,25 @@
package dst.ass1.kv;
/**
* Exception indicating that a request to create a new session could not be fulfilled.
*/
public class SessionCreationFailedException extends Exception {
private static final long serialVersionUID = 1L;
public SessionCreationFailedException() {
}
public SessionCreationFailedException(String message) {
super(message);
}
public SessionCreationFailedException(String message, Throwable cause) {
super(message, cause);
}
public SessionCreationFailedException(Throwable cause) {
super(cause);
}
}
@@ -0,0 +1,24 @@
package dst.ass1.kv;
/**
* Exception to indicate that <i>this is not the session you are looking for</i>.
*/
public class SessionNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
public SessionNotFoundException() {
}
public SessionNotFoundException(String message) {
super(message);
}
public SessionNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public SessionNotFoundException(Throwable cause) {
super(cause);
}
}
@@ -0,0 +1,17 @@
package dst.ass1.kv.impl;
import dst.ass1.kv.ISessionManager;
import dst.ass1.kv.ISessionManagerFactory;
import java.util.Properties;
public class SessionManagerFactory implements ISessionManagerFactory {
@Override
public ISessionManager createSessionManager(Properties properties) {
// TODO
// read "redis.host" and "redis.port" from the properties
return null;
}
}
@@ -0,0 +1,60 @@
package dst.ass1.kv;
import org.junit.rules.ExternalResource;
import redis.clients.jedis.Jedis;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* Drops the entire key space of a redis instance before and after a test run.
*/
public class RedisCleaner extends ExternalResource {
private Properties properties;
private Jedis jedis;
@Override
protected void before() throws IOException {
properties = loadProperties();
String host = properties.getProperty("redis.host");
int port = Integer.parseInt(properties.getProperty("redis.port"));
jedis = new Jedis(host, port);
// completely clear the redis instance before each test
jedis.flushAll();
}
@Override
protected void after() {
// completely clear the redis instance after each test
try {
jedis.flushAll();
} finally {
// close the connection pool
jedis.close();
}
}
/**
* @return loaded redis properties
*/
public Properties getProperties() {
return properties;
}
public Jedis getJedis() {
return jedis;
}
private Properties loadProperties() throws IOException {
Properties properties = new Properties();
try (InputStream in = getClass().getClassLoader().getResourceAsStream("redis.properties")) {
properties.load(in);
}
return properties;
}
}
@@ -0,0 +1,102 @@
package dst.ass1.kv.tests;
import dst.ass1.kv.ISessionManager;
import dst.ass1.kv.ISessionManagerFactory;
import dst.ass1.kv.RedisCleaner;
import dst.ass1.kv.SessionNotFoundException;
import dst.ass1.kv.impl.SessionManagerFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
public class Ass1_5_1Test {
@Rule
public RedisCleaner redisRule = new RedisCleaner();
private ISessionManager sessionManager;
@Before
public void setUp() {
ISessionManagerFactory sessionManagerFactory = new SessionManagerFactory();
sessionManager = sessionManagerFactory.createSessionManager(redisRule.getProperties());
}
@After
public void tearDown() {
sessionManager.close();
}
@Test
public void createSession_createsSessionId() throws Exception {
String sessionId = sessionManager.createSession(1337L, 15000);
assertNotNull(sessionId);
}
@Test
public void getAndSetSessionVariable_behavesCorrectly() throws Exception {
String sessionId = sessionManager.createSession(1337L, 15000);
sessionManager.setSessionVariable(sessionId, "f00", "bar");
assertEquals("bar", sessionManager.getSessionVariable(sessionId, "f00"));
}
@Test(expected = SessionNotFoundException.class)
public void setSessionVariable_forNonExistingSession_throwsSessionNotFoundException() throws Exception {
sessionManager.setSessionVariable("nonExistingSessionId", "f00", "bar");
}
@Test(expected = SessionNotFoundException.class)
public void getSessionVariable_forNonExistingSession_throwsSessionNotFoundException() throws Exception {
sessionManager.getSessionVariable("nonExistingSessionId", "f00");
}
@Test
public void getSessionVariable_onNonExistingVariable_returnsNull() throws Exception {
String sessionId = sessionManager.createSession(1337L, 15000);
String value = sessionManager.getSessionVariable(sessionId, "f00");
assertNull(value);
}
@Test
public void getUserId_returnsCorrectUserID() throws Exception {
Long userId = 1337L;
String sessionId = sessionManager.createSession(userId, 15000);
assertEquals(userId, sessionManager.getUserId(sessionId));
}
@Test(expected = SessionNotFoundException.class)
public void getUserId_forNonExistingSession_throwsException() throws Exception {
sessionManager.getUserId("nonExistingSessionId");
}
@Test
public void getTimeToLive_returnsCorrectValue() throws Exception {
String sessionId = sessionManager.createSession(1337L, 60);
int ttl = sessionManager.getTimeToLive(sessionId);
assertThat(ttl, allOf(greaterThan(57), lessThan(61)));
}
@Test
public void getTimeToLive_afterExpiry_throwsSessionNotFoundException() throws Exception {
String sessionId = sessionManager.createSession(1337L, 2);
int ttl = sessionManager.getTimeToLive(sessionId);
assertThat(ttl, greaterThan(0));
Thread.sleep(3000);
assertThrows(SessionNotFoundException.class, () -> {
sessionManager.getTimeToLive(sessionId);
});
}
@Test(expected = SessionNotFoundException.class)
public void getTimeToLive_forNonExistingSession_throwsSessionNotFoundException() throws Exception {
sessionManager.getTimeToLive("nonExistingSessionId");
}
}
@@ -0,0 +1,50 @@
package dst.ass1.kv.tests;
import dst.ass1.kv.ISessionManager;
import dst.ass1.kv.ISessionManagerFactory;
import dst.ass1.kv.RedisCleaner;
import dst.ass1.kv.impl.SessionManagerFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class Ass1_5_2Test {
@Rule
public RedisCleaner redisRule = new RedisCleaner();
private ISessionManager sessionManager;
@Before
public void setUp() {
ISessionManagerFactory sessionManagerFactory = new SessionManagerFactory();
sessionManager = sessionManagerFactory.createSessionManager(redisRule.getProperties());
}
@After
public void tearDown() {
sessionManager.close();
}
@Test
public void testRequireSessionForExistingSession_existingIdReturned() throws Exception {
String newId = sessionManager.createSession(1337L, 30000);
assertNotNull(newId);
String requiredId = sessionManager.requireSession(1337L, 15000);
assertEquals(newId, requiredId);
}
@Test
public void testRequireSessionForNonExistingSession_newSessionCreated() throws Exception {
String sessionId = sessionManager.requireSession(1337L, 15000);
assertEquals(Long.valueOf(1337L), sessionManager.getUserId(sessionId));
}
}
@@ -0,0 +1,13 @@
package dst.ass1.kv.tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses( {
Ass1_5_1Test.class,
Ass1_5_2Test.class
})
public class Ass1_5_Suite {
}
+14
View File
@@ -0,0 +1,14 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - %highlight(%5p) [%12.12thread] %cyan(%-40.40logger{39}): %m%n</pattern>
</encoder>
</appender>
<root level="${log.level:-INFO}">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
@@ -0,0 +1,4 @@
# you can change this to, e.g., 127.0.0.1 if you have a local redis instance
redis.host=192.168.99.99
#redis.host=127.0.0.1
redis.port=6379